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  }