github.com/prebid/prebid-server/v2@v2.18.0/endpoints/currency_rates_test.go (about) 1 package endpoints 2 3 import ( 4 "math/cmplx" 5 "net/http" 6 "net/http/httptest" 7 "testing" 8 "time" 9 10 "github.com/prebid/prebid-server/v2/currency" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestCurrencyRatesEndpoint(t *testing.T) { 15 // Setup: 16 var testCases = []struct { 17 inputConverter rateConverter 18 inputFetchingInterval time.Duration 19 expectedBody string 20 expectedCode int 21 description string 22 }{ 23 { 24 nil, 25 time.Duration(0), 26 `{"active": false}`, 27 http.StatusOK, 28 "case 1 - rate converter is nil", 29 }, 30 { 31 newRateConverterMock( 32 "https://sync.test.com", 33 time.Date(2019, 3, 2, 12, 54, 56, 651387237, time.UTC), 34 newConversionMock(&map[string]map[string]float64{ 35 "USD": { 36 "USD": 1.0, 37 }, 38 }), 39 ), 40 5 * time.Minute, 41 `{ 42 "active": true, 43 "source": "https://sync.test.com", 44 "fetchingIntervalNs": 300000000000, 45 "lastUpdated": "2019-03-02T12:54:56.651387237Z", 46 "rates": { 47 "USD": { 48 "USD": 1 49 } 50 } 51 }`, 52 http.StatusOK, 53 "case 2 - rate converter is set and has some rates", 54 }, 55 { 56 newRateConverterMock( 57 "", 58 time.Time{}, 59 nil, 60 ), 61 time.Duration(0), 62 `{ 63 "active": true, 64 "source": "", 65 "fetchingIntervalNs": 0, 66 "lastUpdated": "0001-01-01T00:00:00Z" 67 }`, 68 http.StatusOK, 69 "case 3 - rate converter is set and doesn't have any rates set", 70 }, 71 { 72 newRateConverterMockWithInfo( 73 newUnmarshableConverterInfoMock(), 74 ), 75 time.Duration(0), 76 "", 77 http.StatusInternalServerError, 78 "case 4 - invalid rates input for marshaling", 79 }, 80 { 81 newRateConverterMockWithNilInfo(), 82 time.Duration(0), 83 `{ 84 "active": true 85 }`, 86 http.StatusOK, 87 "case 5 - rate converter is set but returns nil Infos", 88 }, 89 } 90 91 for _, tc := range testCases { 92 93 handler := NewCurrencyRatesEndpoint(tc.inputConverter, tc.inputFetchingInterval) 94 w := httptest.NewRecorder() 95 96 // Execute: 97 handler(w, nil) 98 99 // Verify: 100 assert.Equal(t, tc.expectedCode, w.Code, tc.description) 101 if tc.expectedBody != "" { 102 assert.JSONEq(t, tc.expectedBody, w.Body.String(), tc.description) 103 } else { 104 assert.Equal(t, tc.expectedBody, w.Body.String(), tc.description) 105 } 106 } 107 } 108 109 type conversionMock struct { 110 rates *map[string]map[string]float64 111 } 112 113 func (m conversionMock) GetRates() *map[string]map[string]float64 { 114 return m.rates 115 } 116 117 func newConversionMock(rates *map[string]map[string]float64) *conversionMock { 118 return &conversionMock{ 119 rates: rates, 120 } 121 } 122 123 type converterInfoMock struct { 124 source string 125 lastUpdated time.Time 126 rates *map[string]map[string]float64 127 additionalInfo interface{} 128 } 129 130 func (m converterInfoMock) Source() string { 131 return m.source 132 } 133 134 func (m converterInfoMock) LastUpdated() time.Time { 135 return m.lastUpdated 136 } 137 138 func (m converterInfoMock) Rates() *map[string]map[string]float64 { 139 return m.rates 140 } 141 142 func (m converterInfoMock) AdditionalInfo() interface{} { 143 return m.additionalInfo 144 } 145 146 type unmarshableConverterInfoMock struct{} 147 148 func (m unmarshableConverterInfoMock) Source() string { 149 return "" 150 } 151 152 func (m unmarshableConverterInfoMock) LastUpdated() time.Time { 153 return time.Time{} 154 } 155 156 func (m unmarshableConverterInfoMock) Rates() *map[string]map[string]float64 { 157 return nil 158 } 159 160 func (m unmarshableConverterInfoMock) AdditionalInfo() interface{} { 161 cmplx.Sqrt(-5 + 12i) 162 return cmplx.Sqrt(-5 + 12i) 163 } 164 165 func newUnmarshableConverterInfoMock() unmarshableConverterInfoMock { 166 return unmarshableConverterInfoMock{} 167 } 168 169 type rateConverterMock struct { 170 syncSourceURL string 171 rates *conversionMock 172 lastUpdated time.Time 173 rateConverterInfos currency.ConverterInfo 174 shouldReturnNilInfo bool 175 } 176 177 func (m rateConverterMock) GetInfo() currency.ConverterInfo { 178 179 if m.shouldReturnNilInfo { 180 return nil 181 } 182 183 if m.rateConverterInfos != nil { 184 return m.rateConverterInfos 185 } 186 187 var rates *map[string]map[string]float64 188 if m.rates == nil { 189 rates = nil 190 } else { 191 rates = m.rates.GetRates() 192 } 193 return converterInfoMock{ 194 source: m.syncSourceURL, 195 lastUpdated: m.lastUpdated, 196 rates: rates, 197 } 198 } 199 200 func newRateConverterMock( 201 syncSourceURL string, 202 lastUpdated time.Time, 203 rates *conversionMock) rateConverterMock { 204 return rateConverterMock{ 205 syncSourceURL: syncSourceURL, 206 rates: rates, 207 lastUpdated: lastUpdated, 208 } 209 } 210 211 func newRateConverterMockWithInfo(rateConverterInfos currency.ConverterInfo) rateConverterMock { 212 return rateConverterMock{ 213 rateConverterInfos: rateConverterInfos, 214 } 215 } 216 217 func newRateConverterMockWithNilInfo() rateConverterMock { 218 return rateConverterMock{ 219 shouldReturnNilInfo: true, 220 } 221 }