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  }