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