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  }