remove deprecated International Monetary Fund exchange rate data source
This commit is contained in:
@@ -509,7 +509,6 @@ custom_map_tile_server_default_zoom_level = 14
|
||||
# "swiss_national_bank": https://www.snb.ch/en/the-snb/mandates-goals/statistics/statistics-pub/current_interest_exchange_rates
|
||||
# "national_bank_of_ukraine": https://bank.gov.ua/ua/markets/exchangerates
|
||||
# "central_bank_of_uzbekistan": https://cbu.uz/en/arkhiv-kursov-valyut/
|
||||
# "international_monetary_fund": https://www.imf.org/external/np/fin/data/param_rms_mth.aspx
|
||||
# "user_custom": users set their own exchange rates data in the UI
|
||||
data_source = euro_central_bank
|
||||
|
||||
|
||||
@@ -295,22 +295,6 @@ func TestExchangeRatesApiLatestExchangeRateHandler_CentralBankOfUzbekistanDataSo
|
||||
checkExchangeRatesHaveSpecifiedCurrencies(t, exchangeRateResponse.BaseCurrency, supportedCurrencyCodes, exchangeRateResponse.ExchangeRates)
|
||||
}
|
||||
|
||||
func TestExchangeRatesApiLatestExchangeRateHandler_InternationalMonetaryFundDataSource(t *testing.T) {
|
||||
exchangeRateResponse := executeLatestExchangeRateHandler(t, settings.InternationalMonetaryFundDataSource)
|
||||
|
||||
if exchangeRateResponse == nil {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, "USD", exchangeRateResponse.BaseCurrency)
|
||||
|
||||
supportedCurrencyCodes := []string{"AED", "AUD", "BND", "BRL", "BWP", "CAD", "CHF", "CLP", "CNY", "CZK",
|
||||
"DKK", "DZD", "EUR", "GBP", "ILS", "INR", "JPY", "KRW", "KWD", "MUR", "MXN", "MYR", "NOK", "NZD",
|
||||
"OMR", "PEN", "PHP", "PLN", "QAR", "SAR", "SEK", "SGD", "THB", "TTD", "UYU"}
|
||||
|
||||
checkExchangeRatesHaveSpecifiedCurrencies(t, exchangeRateResponse.BaseCurrency, supportedCurrencyCodes, exchangeRateResponse.ExchangeRates)
|
||||
}
|
||||
|
||||
func executeLatestExchangeRateHandler(t *testing.T, dataSourceType string) *models.LatestExchangeRateResponse {
|
||||
if os.Getenv("BUILD_PIPELINE") == "1" && os.Getenv("CHECK_3RD_API") != "1" {
|
||||
return nil
|
||||
|
||||
@@ -67,9 +67,6 @@ func InitializeExchangeRatesDataSource(config *settings.Config) error {
|
||||
} else if config.ExchangeRatesDataSource == settings.CentralBankOfUzbekistanDataSource {
|
||||
Container.current = newCommonHttpExchangeRatesDataProvider(config, &CentralBankOfUzbekistanDataSource{})
|
||||
return nil
|
||||
} else if config.ExchangeRatesDataSource == settings.InternationalMonetaryFundDataSource {
|
||||
Container.current = newCommonHttpExchangeRatesDataProvider(config, &InternationalMonetaryFundDataSource{})
|
||||
return nil
|
||||
} else if config.ExchangeRatesDataSource == settings.UserCustomExchangeRatesDataSource {
|
||||
Container.current = newUserCustomExchangeRatesDataProvider()
|
||||
return nil
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
package exchangerates
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
orderedmap "github.com/wk8/go-ordered-map/v2"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/models"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/utils"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/validators"
|
||||
)
|
||||
|
||||
const internationalMonetaryFundExchangeRateUrl = "https://www.imf.org/external/np/fin/data/rms_five.aspx?tsvflag=Y"
|
||||
const internationalMonetaryFundExchangeRateReferenceUrl = "https://www.imf.org/external/np/fin/data/param_rms_mth.aspx"
|
||||
const internationalMonetaryFundDataSource = "International Monetary Fund"
|
||||
const internationalMonetaryFundBaseCurrency = "USD"
|
||||
|
||||
const internationalMonetaryFundDataUpdateDateFormat = "January 02, 2006 15:04"
|
||||
const internationalMonetaryFundDataUpdateDateTimezone = "America/New_York"
|
||||
|
||||
var internationalMonetaryFundCurrencyNameCodeMap map[string]string
|
||||
|
||||
// InternationalMonetaryFundDataSource defines the structure of exchange rates data source of international monetary fund
|
||||
type InternationalMonetaryFundDataSource struct {
|
||||
HttpExchangeRatesDataSource
|
||||
}
|
||||
|
||||
func init() {
|
||||
internationalMonetaryFundCurrencyNameCodeMap = make(map[string]string, 38)
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Chinese yuan"] = "CNY"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Euro"] = "EUR"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Japanese yen"] = "JPY"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["U.K. pound"] = "GBP"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["U.S. dollar"] = "USD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Algerian dinar"] = "DZD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Australian dollar"] = "AUD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Botswana pula"] = "BWP"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Brazilian real"] = "BRL"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Brunei dollar"] = "BND"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Canadian dollar"] = "CAD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Chilean peso"] = "CLP"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Czech koruna"] = "CZK"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Danish krone"] = "DKK"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Indian rupee"] = "INR"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Israeli New Shekel"] = "ILS"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Korean won"] = "KRW"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Kuwaiti dinar"] = "KWD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Malaysian ringgit"] = "MYR"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Mauritian rupee"] = "MUR"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Mexican peso"] = "MXN"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["New Zealand dollar"] = "NZD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Norwegian krone"] = "NOK"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Omani rial"] = "OMR"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Peruvian sol"] = "PEN"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Philippine peso"] = "PHP"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Polish zloty"] = "PLN"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Qatari riyal"] = "QAR"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Saudi Arabian riyal"] = "SAR"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Singapore dollar"] = "SGD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Swedish krona"] = "SEK"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Swiss franc"] = "CHF"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Thai baht"] = "THB"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Trinidadian dollar"] = "TTD"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["U.A.E. dirham"] = "AED"
|
||||
internationalMonetaryFundCurrencyNameCodeMap["Uruguayan peso"] = "UYU"
|
||||
}
|
||||
|
||||
// BuildRequests returns the international monetary fund exchange rates http requests
|
||||
func (e *InternationalMonetaryFundDataSource) BuildRequests() ([]*http.Request, error) {
|
||||
req, err := http.NewRequest("GET", internationalMonetaryFundExchangeRateUrl, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("User-Agent", "") // Do not set custom user agent
|
||||
|
||||
return []*http.Request{req}, nil
|
||||
}
|
||||
|
||||
// Parse returns the common response entity according to the international monetary fund data source raw response
|
||||
func (e *InternationalMonetaryFundDataSource) Parse(c core.Context, content []byte) (*models.LatestExchangeRateResponse, error) {
|
||||
lines := strings.Split(string(content), "\n")
|
||||
|
||||
if len(lines) < 1 {
|
||||
log.Errorf(c, "[international_monetary_fund_datasource.Parse] content is invalid, content is %s", string(content))
|
||||
return nil, errs.ErrFailedToRequestRemoteApi
|
||||
}
|
||||
|
||||
exchangeRatesToSDR := orderedmap.New[string, float64]()
|
||||
latestUpdateDate := ""
|
||||
|
||||
findSDRsPerCurrencyUnitLine := false
|
||||
findExchangeRateDataHeader := false
|
||||
|
||||
for i := 0; i < len(lines); i++ {
|
||||
line := lines[i]
|
||||
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
line = strings.ReplaceAll(line, "\r", "")
|
||||
|
||||
if strings.Index(line, "Currency units per SDR") == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if strings.Index(line, "SDRs per Currency unit") == 0 {
|
||||
findSDRsPerCurrencyUnitLine = true
|
||||
continue
|
||||
}
|
||||
|
||||
if findExchangeRateDataHeader {
|
||||
items := strings.Split(line, "\t")
|
||||
|
||||
if len(items) != 6 {
|
||||
continue
|
||||
}
|
||||
|
||||
currencyCode, exchangeRate := e.parseExchangeRate(c, line, items)
|
||||
|
||||
if currencyCode != nil && exchangeRate != nil {
|
||||
exchangeRatesToSDR.Set(*currencyCode, *exchangeRate)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if findSDRsPerCurrencyUnitLine {
|
||||
items := strings.Split(line, "\t")
|
||||
|
||||
if len(items) != 6 {
|
||||
continue
|
||||
}
|
||||
|
||||
if items[0] == "Currency" {
|
||||
findExchangeRateDataHeader = true
|
||||
latestUpdateDate = items[1]
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if latestUpdateDate == "" {
|
||||
log.Errorf(c, "[international_monetary_fund_datasource.Parse] latest update date is empty")
|
||||
return nil, errs.ErrFailedToRequestRemoteApi
|
||||
}
|
||||
|
||||
if exchangeRatesToSDR.Len() < 1 {
|
||||
log.Errorf(c, "[international_monetary_fund_datasource.Parse] exchange rates date is empty")
|
||||
return nil, errs.ErrFailedToRequestRemoteApi
|
||||
}
|
||||
|
||||
defaultCurrencyExchangeRateToSDR, exists := exchangeRatesToSDR.Get(internationalMonetaryFundBaseCurrency)
|
||||
|
||||
if !exists {
|
||||
log.Errorf(c, "[international_monetary_fund_datasource.Parse] exchange rates date does not have default currency \"%s\"", internationalMonetaryFundBaseCurrency)
|
||||
return nil, errs.ErrFailedToRequestRemoteApi
|
||||
}
|
||||
|
||||
exchangeRates := make(models.LatestExchangeRateSlice, 0, exchangeRatesToSDR.Len())
|
||||
|
||||
for pair := exchangeRatesToSDR.Oldest(); pair != nil; pair = pair.Next() {
|
||||
exchangeRates = append(exchangeRates, &models.LatestExchangeRate{
|
||||
Currency: pair.Key,
|
||||
Rate: utils.Float64ToString(defaultCurrencyExchangeRateToSDR / pair.Value),
|
||||
})
|
||||
}
|
||||
|
||||
timezone, err := time.LoadLocation(internationalMonetaryFundDataUpdateDateTimezone)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[international_monetary_fund_datasource.Parse] failed to get timezone, timezone name is %s", internationalMonetaryFundDataUpdateDateTimezone)
|
||||
return nil, errs.ErrFailedToRequestRemoteApi
|
||||
}
|
||||
|
||||
updateDateTime := latestUpdateDate + " 11:00" // The IMF posts Representative and SDR exchange rates every 20 minutes from 11:00 AM to 6:00 PM U.S. EST Monday to Friday except for these holidays
|
||||
updateTime, err := time.ParseInLocation(internationalMonetaryFundDataUpdateDateFormat, updateDateTime, timezone)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf(c, "[international_monetary_fund_datasource.Parse] failed to parse update date, datetime is %s", updateDateTime)
|
||||
return nil, errs.ErrFailedToRequestRemoteApi
|
||||
}
|
||||
|
||||
latestExchangeRateResp := &models.LatestExchangeRateResponse{
|
||||
DataSource: internationalMonetaryFundDataSource,
|
||||
ReferenceUrl: internationalMonetaryFundExchangeRateReferenceUrl,
|
||||
UpdateTime: updateTime.Unix(),
|
||||
BaseCurrency: internationalMonetaryFundBaseCurrency,
|
||||
ExchangeRates: exchangeRates,
|
||||
}
|
||||
|
||||
return latestExchangeRateResp, nil
|
||||
}
|
||||
|
||||
func (e *InternationalMonetaryFundDataSource) parseExchangeRate(c core.Context, line string, lineItems []string) (*string, *float64) {
|
||||
currencyCode, exists := internationalMonetaryFundCurrencyNameCodeMap[lineItems[0]]
|
||||
|
||||
if !exists {
|
||||
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] unknown currency name %s, line is %s", lineItems[0], line)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if _, exists := validators.AllCurrencyNames[currencyCode]; !exists {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for i := 1; i < 6; i++ {
|
||||
item := lineItems[i]
|
||||
|
||||
if item == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
rate, err := utils.StringToFloat64(item)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] failed to parse rate, line is %s", line)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if rate <= 0 {
|
||||
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] rate is invalid, line is %s", line)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return ¤cyCode, &rate
|
||||
}
|
||||
|
||||
log.Warnf(c, "[international_monetary_fund_datasource.parseExchangeRate] no exchange rate data exists for currency \"%s\", line is %s", currencyCode, line)
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package exchangerates
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/models"
|
||||
)
|
||||
|
||||
const internationalMonetaryFundMinimumRequiredContent = "SDRs per Currency unit and Currency units per SDR (1)\n" +
|
||||
"last five days\n" +
|
||||
"SDRs per Currency unit (2)\n" +
|
||||
"\n" +
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n" +
|
||||
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n" +
|
||||
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_StandardDataExtractBaseCurrency(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(internationalMonetaryFundMinimumRequiredContent))
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, "USD", actualLatestExchangeRateResponse.BaseCurrency)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_StandardDataExtractUpdateTime(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(internationalMonetaryFundMinimumRequiredContent))
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Equal(t, int64(1724857200), actualLatestExchangeRateResponse.UpdateTime)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_StandardDataExtractExchangeRates(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(internationalMonetaryFundMinimumRequiredContent))
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{
|
||||
Currency: "USD",
|
||||
Rate: "1",
|
||||
})
|
||||
assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{
|
||||
Currency: "CNY",
|
||||
Rate: "7.128474224426247",
|
||||
})
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_BlankContent(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
_, err := dataSource.Parse(context, []byte(""))
|
||||
assert.NotEqual(t, nil, err)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_OnlyHeader(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)"))
|
||||
assert.NotEqual(t, nil, err)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_OnlyHeaderAndTitle(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"))
|
||||
assert.NotEqual(t, nil, err)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_MissingHeader(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
_, err := dataSource.Parse(context, []byte("Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"+
|
||||
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
|
||||
assert.NotEqual(t, nil, err)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_MissingDefaultCurrencyData(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"))
|
||||
assert.NotEqual(t, nil, err)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_DefaultCurrencyDataInvalid(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
_, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"Chinese yuan\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"+
|
||||
"U.S. dollar\t0\t0\t0\t0\t0\n"))
|
||||
assert.NotEqual(t, nil, err)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_InvalidCurrency(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"Foo bar\t0.1040520000\t0.1039250000\t0.1040370000\t0.1040850000\t0.1040570000\n"+
|
||||
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_InvalidRate(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"Chinese yuan\tnull\tnull\tnull\tnull\tnull\n"+
|
||||
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
|
||||
|
||||
actualLatestExchangeRateResponse, err = dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"Chinese yuan\t0\t0\t0\t0\t0\n"+
|
||||
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
|
||||
|
||||
actualLatestExchangeRateResponse, err = dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"Chinese yuan\t\t\t\t\t\n"+
|
||||
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"))
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 1)
|
||||
}
|
||||
|
||||
func TestInternationalMonetaryFundDataSource_LatestDateNotHasRate(t *testing.T) {
|
||||
dataSource := &InternationalMonetaryFundDataSource{}
|
||||
context := core.NewNullContext()
|
||||
|
||||
actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("SDRs per Currency unit and Currency units per SDR (1)\n"+
|
||||
"last five days\n"+
|
||||
"SDRs per Currency unit (2)\n"+
|
||||
"\n"+
|
||||
"Currency\tAugust 28, 2024\tAugust 27, 2024\tAugust 26, 2024\tAugust 23, 2024\tAugust 22, 2024\n"+
|
||||
"U.S. dollar\t0.7417320000\t0.7410250000\t0.7408270000\t0.7429280000\t0.7423020000\n"+
|
||||
"U.A.E. dirham\t\t0.2017770000\t0.2017230000\t\t0.2021240000\n"))
|
||||
|
||||
assert.Equal(t, nil, err)
|
||||
assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{
|
||||
Currency: "AED",
|
||||
Rate: "3.675998751096507",
|
||||
})
|
||||
}
|
||||
+17
-19
@@ -125,24 +125,23 @@ const (
|
||||
|
||||
// Exchange rates data source types
|
||||
const (
|
||||
ReserveBankOfAustraliaDataSource string = "reserve_bank_of_australia"
|
||||
BankOfCanadaDataSource string = "bank_of_canada"
|
||||
CzechNationalBankDataSource string = "czech_national_bank"
|
||||
DanmarksNationalbankDataSource string = "danmarks_national_bank"
|
||||
EuroCentralBankDataSource string = "euro_central_bank"
|
||||
NationalBankOfGeorgiaDataSource string = "national_bank_of_georgia"
|
||||
CentralBankOfHungaryDataSource string = "central_bank_of_hungary"
|
||||
BankOfIsraelDataSource string = "bank_of_israel"
|
||||
CentralBankOfMyanmarDataSource string = "central_bank_of_myanmar"
|
||||
NorgesBankDataSource string = "norges_bank"
|
||||
NationalBankOfPolandDataSource string = "national_bank_of_poland"
|
||||
NationalBankOfRomaniaDataSource string = "national_bank_of_romania"
|
||||
BankOfRussiaDataSource string = "bank_of_russia"
|
||||
SwissNationalBankDataSource string = "swiss_national_bank"
|
||||
NationalBankOfUkraineDataSource string = "national_bank_of_ukraine"
|
||||
CentralBankOfUzbekistanDataSource string = "central_bank_of_uzbekistan"
|
||||
InternationalMonetaryFundDataSource string = "international_monetary_fund"
|
||||
UserCustomExchangeRatesDataSource string = "user_custom"
|
||||
ReserveBankOfAustraliaDataSource string = "reserve_bank_of_australia"
|
||||
BankOfCanadaDataSource string = "bank_of_canada"
|
||||
CzechNationalBankDataSource string = "czech_national_bank"
|
||||
DanmarksNationalbankDataSource string = "danmarks_national_bank"
|
||||
EuroCentralBankDataSource string = "euro_central_bank"
|
||||
NationalBankOfGeorgiaDataSource string = "national_bank_of_georgia"
|
||||
CentralBankOfHungaryDataSource string = "central_bank_of_hungary"
|
||||
BankOfIsraelDataSource string = "bank_of_israel"
|
||||
CentralBankOfMyanmarDataSource string = "central_bank_of_myanmar"
|
||||
NorgesBankDataSource string = "norges_bank"
|
||||
NationalBankOfPolandDataSource string = "national_bank_of_poland"
|
||||
NationalBankOfRomaniaDataSource string = "national_bank_of_romania"
|
||||
BankOfRussiaDataSource string = "bank_of_russia"
|
||||
SwissNationalBankDataSource string = "swiss_national_bank"
|
||||
NationalBankOfUkraineDataSource string = "national_bank_of_ukraine"
|
||||
CentralBankOfUzbekistanDataSource string = "central_bank_of_uzbekistan"
|
||||
UserCustomExchangeRatesDataSource string = "user_custom"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -1180,7 +1179,6 @@ func loadExchangeRatesConfiguration(config *Config, configFile *ini.File, sectio
|
||||
dataSource == SwissNationalBankDataSource ||
|
||||
dataSource == NationalBankOfUkraineDataSource ||
|
||||
dataSource == CentralBankOfUzbekistanDataSource ||
|
||||
dataSource == InternationalMonetaryFundDataSource ||
|
||||
dataSource == UserCustomExchangeRatesDataSource {
|
||||
config.ExchangeRatesDataSource = dataSource
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user