github.com/prebid/prebid-server@v0.275.0/currency/rates_test.go (about) 1 package currency 2 3 import ( 4 "encoding/json" 5 "errors" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestUnMarshallRates(t *testing.T) { 12 // Setup: 13 testCases := []struct { 14 desc string 15 ratesJSON string 16 expectedRates Rates 17 expectsError bool 18 expectedError error 19 }{ 20 { 21 desc: "malformed JSON object, return error", 22 ratesJSON: `malformed`, 23 expectedRates: Rates{}, 24 expectsError: true, 25 expectedError: errors.New("invalid character 'm' looking for beginning of value"), 26 }, 27 { 28 desc: "Valid JSON field defining valid conversion object. Expect no error", 29 ratesJSON: `{ 30 "conversions":{ 31 "USD":{ 32 "GBP":0.7662523901 33 }, 34 "GBP":{ 35 "USD":1.3050530256 36 } 37 } 38 }`, 39 expectedRates: Rates{ 40 Conversions: map[string]map[string]float64{ 41 "USD": { 42 "GBP": 0.7662523901, 43 }, 44 "GBP": { 45 "USD": 1.3050530256, 46 }, 47 }, 48 }, 49 expectsError: false, 50 expectedError: nil, 51 }, 52 { 53 desc: "Valid JSON field defines a conversions map with repeated entries, expect error", 54 ratesJSON: `{ 55 "conversions":{ 56 "USD":{ 57 "GBP":0.7662523901, 58 "MXN":20.00 59 }, 60 "USD":{ 61 "GBP":0.7662523901 62 }, 63 } 64 }`, 65 expectedRates: Rates{}, 66 expectsError: true, 67 expectedError: errors.New("invalid character '}' looking for beginning of object key string"), 68 }, 69 } 70 71 for _, tc := range testCases { 72 // Execute: 73 updatedRates := Rates{} 74 err := json.Unmarshal([]byte(tc.ratesJSON), &updatedRates) 75 76 // Verify: 77 assert.Equal(t, err != nil, tc.expectsError, tc.desc) 78 if tc.expectsError { 79 assert.Equal(t, err.Error(), tc.expectedError.Error(), tc.desc) 80 } 81 assert.Equal(t, tc.expectedRates, updatedRates, tc.desc) 82 } 83 } 84 85 func TestGetRate(t *testing.T) { 86 87 // Setup: 88 rates := NewRates(map[string]map[string]float64{ 89 "USD": { 90 "GBP": 0.77208, 91 }, 92 "GBP": { 93 "USD": 1.2952, 94 }, 95 }) 96 97 testCases := []struct { 98 from string 99 to string 100 expectedRate float64 101 hasError bool 102 }{ 103 {from: "USD", to: "GBP", expectedRate: 0.77208, hasError: false}, 104 {from: "GBP", to: "USD", expectedRate: 1.2952, hasError: false}, 105 {from: "GBP", to: "EUR", expectedRate: 0, hasError: true}, 106 {from: "CNY", to: "EUR", expectedRate: 0, hasError: true}, 107 {from: "", to: "EUR", expectedRate: 0, hasError: true}, 108 {from: "CNY", to: "", expectedRate: 0, hasError: true}, 109 {from: "", to: "", expectedRate: 0, hasError: true}, 110 {from: "USD", to: "USD", expectedRate: 1, hasError: false}, 111 } 112 113 for _, tc := range testCases { 114 // Execute: 115 rate, err := rates.GetRate(tc.from, tc.to) 116 117 // Verify: 118 if tc.hasError { 119 assert.NotNil(t, err, "err shouldn't be nil") 120 assert.Equal(t, float64(0), rate, "rate should be 0") 121 } else { 122 assert.Nil(t, err, "err should be nil") 123 assert.Equal(t, tc.expectedRate, rate, "rate doesn't match the expected one") 124 } 125 } 126 } 127 128 func TestGetRate_ReverseConversion(t *testing.T) { 129 130 // Setup: 131 rates := NewRates(map[string]map[string]float64{ 132 "USD": { 133 "GBP": 0.77208, 134 }, 135 "EUR": { 136 "USD": 0.88723, 137 }, 138 }) 139 140 testCases := []struct { 141 from string 142 to string 143 expectedRate float64 144 description string 145 }{ 146 { 147 from: "USD", 148 to: "GBP", 149 expectedRate: 0.77208, 150 description: "case 1 - Rate is present directly and will be returned as is", 151 }, 152 { 153 from: "EUR", 154 to: "USD", 155 expectedRate: 0.88723, 156 description: "case 2 - Rate is present directly and will be returned as is (2)", 157 }, 158 { 159 from: "GBP", 160 to: "USD", 161 expectedRate: 1 / 0.77208, 162 description: "case 3 - Rate is not present but the reverse one is, will return the computed rate from the reverse entry", 163 }, 164 { 165 from: "USD", 166 to: "EUR", 167 expectedRate: 1 / 0.88723, 168 description: "case 4 - Rate is not present but the reverse one is, will return the computed rate from the reverse entry (2)", 169 }, 170 } 171 172 for _, tc := range testCases { 173 // Execute: 174 rate, err := rates.GetRate(tc.from, tc.to) 175 176 // Verify: 177 assert.Nil(t, err, "err should be nil: "+tc.description) 178 assert.Equal(t, tc.expectedRate, rate, "rate doesn't match the expected one: "+tc.description) 179 } 180 } 181 182 func TestGetRate_EmptyRates(t *testing.T) { 183 184 // Setup: 185 rates := NewRates(nil) 186 187 // Execute: 188 rate, err := rates.GetRate("USD", "EUR") 189 190 // Verify: 191 assert.NotNil(t, err, "err shouldn't be nil") 192 assert.Equal(t, float64(0), rate, "rate should be 0") 193 } 194 195 func TestGetRate_NotValidISOCurrency(t *testing.T) { 196 197 // Setup: 198 rates := NewRates(nil) 199 200 testCases := []struct { 201 from string 202 to string 203 expectedRate float64 204 hasError bool 205 }{ 206 {from: "foo", to: "foo", expectedRate: 0, hasError: true}, 207 {from: "bar", to: "foo", expectedRate: 0, hasError: true}, 208 } 209 210 for _, tc := range testCases { 211 // Execute: 212 rate, err := rates.GetRate(tc.from, tc.to) 213 214 // Verify: 215 if tc.hasError { 216 assert.NotNil(t, err, "err shouldn't be nil") 217 assert.Equal(t, float64(0), rate, "rate should be 0") 218 } else { 219 assert.Nil(t, err, "err should be nil") 220 assert.Equal(t, tc.expectedRate, rate, "rate doesn't match the expected one") 221 } 222 } 223 }