diff --git a/conf/ezbookkeeping.ini b/conf/ezbookkeeping.ini index a417c9e8..de2fb8fe 100644 --- a/conf/ezbookkeeping.ini +++ b/conf/ezbookkeeping.ini @@ -526,7 +526,6 @@ custom_map_tile_server_default_zoom_level = 14 [exchange_rates] # Exchange rates data source, supports the following types: -# "reserve_bank_of_australia": https://www.rba.gov.au/statistics/frequency/exchange-rates.html # "bank_of_canada": https://www.bankofcanada.ca/rates/exchange/daily-exchange-rates/ # "czech_national_bank": https://www.cnb.cz/en/financial-markets/foreign-exchange-market/central-bank-exchange-rate-fixing/central-bank-exchange-rate-fixing/ # "danmarks_national_bank": https://www.nationalbanken.dk/en/what-we-do/stable-prices-monetary-policy-and-the-danish-economy/exchange-rates diff --git a/pkg/exchangerates/common_http_exchange_rates_data_provider_test.go b/pkg/exchangerates/common_http_exchange_rates_data_provider_test.go index 506ab48e..e2ec22a7 100644 --- a/pkg/exchangerates/common_http_exchange_rates_data_provider_test.go +++ b/pkg/exchangerates/common_http_exchange_rates_data_provider_test.go @@ -14,21 +14,6 @@ import ( "github.com/mayswind/ezbookkeeping/pkg/utils" ) -func TestExchangeRatesApiLatestExchangeRateHandler_ReserveBankOfAustraliaDataSource(t *testing.T) { - exchangeRateResponse := executeLatestExchangeRateHandler(t, settings.ReserveBankOfAustraliaDataSource) - - if exchangeRateResponse == nil { - return - } - - assert.Equal(t, "AUD", exchangeRateResponse.BaseCurrency) - - supportedCurrencyCodes := []string{"CAD", "CHF", "CNY", "EUR", "GBP", "HKD", "IDR", "INR", "JPY", "KRW", - "MYR", "NZD", "PGK", "PHP", "SGD", "THB", "TWD", "USD", "VND"} - - checkExchangeRatesHaveSpecifiedCurrencies(t, exchangeRateResponse.BaseCurrency, supportedCurrencyCodes, exchangeRateResponse.ExchangeRates) -} - func TestExchangeRatesApiLatestExchangeRateHandler_BankOfCanadaDataSource(t *testing.T) { exchangeRateResponse := executeLatestExchangeRateHandler(t, settings.BankOfCanadaDataSource) diff --git a/pkg/exchangerates/exchange_rates_data_provider_container.go b/pkg/exchangerates/exchange_rates_data_provider_container.go index 270be60d..df115b0c 100644 --- a/pkg/exchangerates/exchange_rates_data_provider_container.go +++ b/pkg/exchangerates/exchange_rates_data_provider_container.go @@ -19,10 +19,7 @@ var ( // InitializeExchangeRatesDataSource initializes the current exchange rates data source according to the config func InitializeExchangeRatesDataSource(config *settings.Config) error { - if config.ExchangeRatesDataSource == settings.ReserveBankOfAustraliaDataSource { - Container.current = newCommonHttpExchangeRatesDataProvider(config, &ReserveBankOfAustraliaDataSource{}) - return nil - } else if config.ExchangeRatesDataSource == settings.BankOfCanadaDataSource { + if config.ExchangeRatesDataSource == settings.BankOfCanadaDataSource { Container.current = newCommonHttpExchangeRatesDataProvider(config, &BankOfCanadaDataSource{}) return nil } else if config.ExchangeRatesDataSource == settings.CzechNationalBankDataSource { diff --git a/pkg/exchangerates/reserve_bank_of_australia_datasource.go b/pkg/exchangerates/reserve_bank_of_australia_datasource.go deleted file mode 100644 index b2e15eb0..00000000 --- a/pkg/exchangerates/reserve_bank_of_australia_datasource.go +++ /dev/null @@ -1,161 +0,0 @@ -package exchangerates - -import ( - "bytes" - "encoding/xml" - "net/http" - "time" - - "golang.org/x/net/html/charset" - - "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 reserveBankOfAustraliaExchangeRateUrl = "https://www.rba.gov.au/rss/rss-cb-exchange-rates.xml" -const reserveBankOfAustraliaExchangeRateReferenceUrl = "https://www.rba.gov.au/statistics/frequency/exchange-rates.html" -const reserveBankOfAustraliaDataSource = "Reserve Bank of Australia" -const reserveBankOfAustraliaBaseCurrency = "AUD" - -const reserveBankOfAustraliaDataUpdateDateFormat = "2006-01-02T15:04:05Z07:00" - -// ReserveBankOfAustraliaDataSource defines the structure of exchange rates data source of the reserve bank of Australia -type ReserveBankOfAustraliaDataSource struct { - HttpExchangeRatesDataSource -} - -// ReserveBankOfAustraliaData represents the whole data from the reserve bank of Australia -type ReserveBankOfAustraliaData struct { - XMLName xml.Name `xml:"RDF"` - Channel *ReserveBankOfAustraliaRssChannel `xml:"channel"` - Items []*ReserveBankOfAustraliaRssItem `xml:"item"` -} - -// ReserveBankOfAustraliaRssChannel represents the rss channel from the reserve bank of Australia -type ReserveBankOfAustraliaRssChannel struct { - Date string `xml:"date"` -} - -// ReserveBankOfAustraliaRssItem represents the rss item from the reserve bank of Australia -type ReserveBankOfAustraliaRssItem struct { - Statistics *ReserveBankOfAustraliaItemStatistics `xml:"statistics"` -} - -// ReserveBankOfAustraliaItemStatistics represents the item statistics from the reserve bank of Australia -type ReserveBankOfAustraliaItemStatistics struct { - ExchangeRate *ReserveBankOfAustraliaExchangeRate `xml:"exchangeRate"` -} - -// ReserveBankOfAustraliaExchangeRate represents the exchange rate from the reserve bank of Australia -type ReserveBankOfAustraliaExchangeRate struct { - BaseCurrency string `xml:"baseCurrency"` - TargetCurrency string `xml:"targetCurrency"` - Observation *ReserveBankOfAustraliaExchangeRateObservation `xml:"observation"` -} - -// ReserveBankOfAustraliaExchangeRateObservation represents the exchange rate data from the reserve bank of Australia -type ReserveBankOfAustraliaExchangeRateObservation struct { - Value string `xml:"value"` - Unit string `xml:"unit"` -} - -// ToLatestExchangeRateResponse returns a view-object according to original data from the reserve bank of Australia -func (e *ReserveBankOfAustraliaData) ToLatestExchangeRateResponse(c core.Context) *models.LatestExchangeRateResponse { - if e.Channel == nil { - log.Errorf(c, "[reserve_bank_of_australia_datasource.ToLatestExchangeRateResponse] rss channel does not exist") - return nil - } - - if len(e.Items) < 1 { - log.Errorf(c, "[reserve_bank_of_australia_datasource.ToLatestExchangeRateResponse] rss items is empty") - return nil - } - - exchangeRates := make(models.LatestExchangeRateSlice, 0, len(e.Items)) - - for i := 0; i < len(e.Items); i++ { - item := e.Items[i] - - if item.Statistics == nil || item.Statistics.ExchangeRate == nil || item.Statistics.ExchangeRate.Observation == nil { - continue - } - - if item.Statistics.ExchangeRate.BaseCurrency != reserveBankOfAustraliaBaseCurrency || item.Statistics.ExchangeRate.Observation.Unit != reserveBankOfAustraliaBaseCurrency { - continue - } - - if _, exists := validators.AllCurrencyNames[item.Statistics.ExchangeRate.TargetCurrency]; !exists { - continue - } - - if _, err := utils.StringToFloat64(item.Statistics.ExchangeRate.Observation.Value); err != nil { - continue - } - - exchangeRates = append(exchangeRates, item.Statistics.ExchangeRate.ToLatestExchangeRate()) - } - - updateDateTime := e.Channel.Date - updateTime, err := time.Parse(reserveBankOfAustraliaDataUpdateDateFormat, updateDateTime) - - if err != nil { - log.Errorf(c, "[reserve_bank_of_australia_datasource.ToLatestExchangeRateResponse] failed to parse update date, datetime is %s", updateDateTime) - return nil - } - - latestExchangeRateResp := &models.LatestExchangeRateResponse{ - DataSource: reserveBankOfAustraliaDataSource, - ReferenceUrl: reserveBankOfAustraliaExchangeRateReferenceUrl, - UpdateTime: updateTime.Unix(), - BaseCurrency: reserveBankOfAustraliaBaseCurrency, - ExchangeRates: exchangeRates, - } - - return latestExchangeRateResp -} - -// ToLatestExchangeRate returns a data pair according to original data from the reserve bank of Australia -func (e *ReserveBankOfAustraliaExchangeRate) ToLatestExchangeRate() *models.LatestExchangeRate { - return &models.LatestExchangeRate{ - Currency: e.TargetCurrency, - Rate: e.Observation.Value, - } -} - -// BuildRequests returns the reserve bank of Australia exchange rates http requests -func (e *ReserveBankOfAustraliaDataSource) BuildRequests() ([]*http.Request, error) { - req, err := http.NewRequest("GET", reserveBankOfAustraliaExchangeRateUrl, nil) - - if err != nil { - return nil, err - } - - return []*http.Request{req}, nil -} - -// Parse returns the common response entity according to the the reserve bank of Australia data source raw response -func (e *ReserveBankOfAustraliaDataSource) Parse(c core.Context, content []byte) (*models.LatestExchangeRateResponse, error) { - xmlDecoder := xml.NewDecoder(bytes.NewReader(content)) - xmlDecoder.CharsetReader = charset.NewReaderLabel - - reserveBankOfAustraliaData := &ReserveBankOfAustraliaData{} - err := xmlDecoder.Decode(reserveBankOfAustraliaData) - - if err != nil { - log.Errorf(c, "[reserve_bank_of_australia_datasource.Parse] failed to parse xml data, content is %s, because %s", string(content), err.Error()) - return nil, errs.ErrFailedToRequestRemoteApi - } - - latestExchangeRateResponse := reserveBankOfAustraliaData.ToLatestExchangeRateResponse(c) - - if latestExchangeRateResponse == nil { - log.Errorf(c, "[reserve_bank_of_australia_datasource.Parse] failed to parse latest exchange rate data, content is %s", string(content)) - return nil, errs.ErrFailedToRequestRemoteApi - } - - return latestExchangeRateResponse, nil -} diff --git a/pkg/exchangerates/reserve_bank_of_australia_datasource_test.go b/pkg/exchangerates/reserve_bank_of_australia_datasource_test.go deleted file mode 100644 index d9140a5c..00000000 --- a/pkg/exchangerates/reserve_bank_of_australia_datasource_test.go +++ /dev/null @@ -1,268 +0,0 @@ -package exchangerates - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/mayswind/ezbookkeeping/pkg/core" - "github.com/mayswind/ezbookkeeping/pkg/models" -) - -const reserveBankOfAustraliaMinimumRequiredContent = "\n" + - "\n" + - " \n" + - " 2021-04-01T16:45:00+11:00\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 0.7543\n" + - " AUD\n" + - " \n" + - " AUD\n" + - " USD\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 4.9577\n" + - " AUD\n" + - " \n" + - " AUD\n" + - " CNY\n" + - " \n" + - " \n" + - " \n" + - "" - -func TestReserveBankOfAustraliaDataSource_StandardDataExtractBaseCurrency(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(reserveBankOfAustraliaMinimumRequiredContent)) - assert.Equal(t, nil, err) - assert.Equal(t, "AUD", actualLatestExchangeRateResponse.BaseCurrency) -} - -func TestReserveBankOfAustraliaDataSource_StandardDataExtractUpdateTime(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(reserveBankOfAustraliaMinimumRequiredContent)) - assert.Equal(t, nil, err) - assert.Equal(t, int64(1617255900), actualLatestExchangeRateResponse.UpdateTime) -} - -func TestReserveBankOfAustraliaDataSource_StandardDataExtractExchangeRates(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte(reserveBankOfAustraliaMinimumRequiredContent)) - assert.Equal(t, nil, err) - assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{ - Currency: "USD", - Rate: "0.7543", - }) - assert.Contains(t, actualLatestExchangeRateResponse.ExchangeRates, &models.LatestExchangeRate{ - Currency: "CNY", - Rate: "4.9577", - }) -} - -func TestReserveBankOfAustraliaDataSource_BlankContent(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - _, err := dataSource.Parse(context, []byte("")) - assert.NotEqual(t, nil, err) -} - -func TestReserveBankOfAustraliaDataSource_OnlyXMLHeader(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - _, err := dataSource.Parse(context, []byte("")) - assert.NotEqual(t, nil, err) -} - -func TestReserveBankOfAustraliaDataSource_EmptyRDFContent(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - _, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - "")) - assert.NotEqual(t, nil, err) -} - -func TestReserveBankOfAustraliaDataSource_EmptyChannelContent(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - _, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - " \n"+ - " "+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " 0.7543\n"+ - " AUD\n"+ - " \n"+ - " AUD\n"+ - " USD\n"+ - " \n"+ - " \n"+ - " \n"+ - "")) - assert.NotEqual(t, nil, err) -} - -func TestReserveBankOfAustraliaDataSource_NoItem(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - _, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - " \n"+ - " 2021-04-01T16:45:00+11:00\n"+ - " \n"+ - "")) - assert.NotEqual(t, nil, err) -} - -func TestReserveBankOfAustraliaDataSource_BaseCurrencyNotEqualPreset(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - " \n"+ - " 2021-04-01T16:45:00+11:00\n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " 0.7543\n"+ - " AUD\n"+ - " \n"+ - " USD\n"+ - " USD\n"+ - " \n"+ - " \n"+ - " \n"+ - "")) - assert.Equal(t, nil, err) - assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 0) -} - -func TestReserveBankOfAustraliaDataSource_UnitCurrencyNotEqualPreset(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - " \n"+ - " 2021-04-01T16:45:00+11:00\n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " 0.7543\n"+ - " USD\n"+ - " \n"+ - " AUD\n"+ - " USD\n"+ - " \n"+ - " \n"+ - " \n"+ - "")) - assert.Equal(t, nil, err) - assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 0) -} - -func TestReserveBankOfAustraliaDataSource_InvalidCurrency(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - " \n"+ - " 2021-04-01T16:45:00+11:00\n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " 1\n"+ - " AUD\n"+ - " \n"+ - " AUD\n"+ - " XXX\n"+ - " \n"+ - " \n"+ - " \n"+ - "")) - assert.Equal(t, nil, err) - assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 0) -} - -func TestReserveBankOfAustraliaDataSource_EmptyRate(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - " \n"+ - " 2021-04-01T16:45:00+11:00\n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " AUD\n"+ - " \n"+ - " AUD\n"+ - " USD\n"+ - " \n"+ - " \n"+ - " \n"+ - "")) - assert.Equal(t, nil, err) - assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 0) -} - -func TestReserveBankOfAustraliaDataSource_InvalidRate(t *testing.T) { - dataSource := &ReserveBankOfAustraliaDataSource{} - context := core.NewNullContext() - - actualLatestExchangeRateResponse, err := dataSource.Parse(context, []byte("\n"+ - "\n"+ - " \n"+ - " 2021-04-01T16:45:00+11:00\n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " \n"+ - " null\n"+ - " AUD\n"+ - " \n"+ - " AUD\n"+ - " USD\n"+ - " \n"+ - " \n"+ - " \n"+ - "")) - assert.Equal(t, nil, err) - assert.Len(t, actualLatestExchangeRateResponse.ExchangeRates, 0) -} diff --git a/pkg/settings/setting.go b/pkg/settings/setting.go index a3ea6d33..8d9ed33e 100644 --- a/pkg/settings/setting.go +++ b/pkg/settings/setting.go @@ -128,7 +128,6 @@ 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" @@ -1198,8 +1197,7 @@ func loadMapConfiguration(config *Config, configFile *ini.File, sectionName stri func loadExchangeRatesConfiguration(config *Config, configFile *ini.File, sectionName string) error { dataSource := getConfigItemStringValue(configFile, sectionName, "data_source") - if dataSource == ReserveBankOfAustraliaDataSource || - dataSource == BankOfCanadaDataSource || + if dataSource == BankOfCanadaDataSource || dataSource == CzechNationalBankDataSource || dataSource == DanmarksNationalbankDataSource || dataSource == EuroCentralBankDataSource ||