174 lines
5.9 KiB
Ruby
174 lines
5.9 KiB
Ruby
|
|
# frozen_string_literal: true
|
||
|
|
|
||
|
|
require_relative "../../helper"
|
||
|
|
require "provider/adapters/bdp"
|
||
|
|
|
||
|
|
class Provider < Sequel::Model(:providers)
|
||
|
|
module Adapters
|
||
|
|
describe BDP do
|
||
|
|
before do
|
||
|
|
VCR.insert_cassette("bdp", match_requests_on: [:method, :uri])
|
||
|
|
end
|
||
|
|
|
||
|
|
after { VCR.eject_cassette }
|
||
|
|
|
||
|
|
let(:adapter) { BDP.new }
|
||
|
|
|
||
|
|
it "parses JSON-stat with foreign base and PTE quote" do
|
||
|
|
json = {
|
||
|
|
"size" => [1, 1, 1, 1, 1, 1, 1, 2],
|
||
|
|
"value" => [184.244, 185.487],
|
||
|
|
"extension" => {
|
||
|
|
"series" => [
|
||
|
|
{
|
||
|
|
"id" => 180121,
|
||
|
|
"label" => "US, Dollars (USD) against Escudo - daily",
|
||
|
|
"dimension_category" => [{ "dimension_id" => 12, "category_id" => 826 }],
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
"dimension" => {
|
||
|
|
"12" => { "category" => { "index" => ["826"] } },
|
||
|
|
"reference_date" => { "category" => { "index" => ["1998-01-02", "1998-01-05"] } },
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
records = adapter.parse(json)
|
||
|
|
|
||
|
|
_(records.length).must_equal(2)
|
||
|
|
_(records.first[:base]).must_equal("USD")
|
||
|
|
_(records.first[:quote]).must_equal("PTE")
|
||
|
|
_(records.first[:rate]).must_equal(184.244)
|
||
|
|
_(records.first[:date]).must_equal(Date.new(1998, 1, 2))
|
||
|
|
end
|
||
|
|
|
||
|
|
it "interleaves multiple counterparties using counterparty index ordering" do
|
||
|
|
json = {
|
||
|
|
"value" => [184.244, 185.487, 288.532, 288.186],
|
||
|
|
"extension" => {
|
||
|
|
"series" => [
|
||
|
|
{
|
||
|
|
"label" => "US, Dollars (USD) against Escudo - daily",
|
||
|
|
"dimension_category" => [{ "dimension_id" => 12, "category_id" => 826 }],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"label" => "United Kingdom, Pounds (GBP) against Escudo - daily",
|
||
|
|
"dimension_category" => [{ "dimension_id" => 12, "category_id" => 824 }],
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
"dimension" => {
|
||
|
|
"12" => { "category" => { "index" => ["826", "824"] } },
|
||
|
|
"reference_date" => { "category" => { "index" => ["1998-12-30", "1998-12-31"] } },
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
records = adapter.parse(json)
|
||
|
|
usd = records.select { |r| r[:base] == "USD" }
|
||
|
|
gbp = records.select { |r| r[:base] == "GBP" }
|
||
|
|
|
||
|
|
_(usd.map { |r| r[:rate] }).must_equal([184.244, 185.487])
|
||
|
|
_(gbp.map { |r| r[:rate] }).must_equal([288.532, 288.186])
|
||
|
|
end
|
||
|
|
|
||
|
|
it "skips null observations" do
|
||
|
|
json = {
|
||
|
|
"value" => [184.244, nil],
|
||
|
|
"extension" => {
|
||
|
|
"series" => [
|
||
|
|
{
|
||
|
|
"label" => "US, Dollars (USD) against Escudo - daily",
|
||
|
|
"dimension_category" => [{ "dimension_id" => 12, "category_id" => 826 }],
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
"dimension" => {
|
||
|
|
"12" => { "category" => { "index" => ["826"] } },
|
||
|
|
"reference_date" => { "category" => { "index" => ["1998-01-02", "1998-01-03"] } },
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
records = adapter.parse(json)
|
||
|
|
|
||
|
|
_(records.length).must_equal(1)
|
||
|
|
_(records.first[:date]).must_equal(Date.new(1998, 1, 2))
|
||
|
|
end
|
||
|
|
|
||
|
|
it "remaps the European Currency Unit label from ECU to ISO 4217 XEU" do
|
||
|
|
json = {
|
||
|
|
"value" => [122.93],
|
||
|
|
"extension" => {
|
||
|
|
"series" => [
|
||
|
|
{
|
||
|
|
"label" => "ECU - Banco do Portugal (ECU) against Escudo - daily",
|
||
|
|
"dimension_category" => [{ "dimension_id" => 12, "category_id" => 2777 }],
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
"dimension" => {
|
||
|
|
"12" => { "category" => { "index" => ["2777"] } },
|
||
|
|
"reference_date" => { "category" => { "index" => ["1998-12-31"] } },
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
records = adapter.parse(json)
|
||
|
|
|
||
|
|
_(records.length).must_equal(1)
|
||
|
|
_(records.first[:base]).must_equal("XEU")
|
||
|
|
end
|
||
|
|
|
||
|
|
it "skips series whose label has no parenthesised ISO code" do
|
||
|
|
# BdP labels usually carry a code, but if a series ever omits it we should
|
||
|
|
# drop it cleanly rather than emit malformed records.
|
||
|
|
json = {
|
||
|
|
"value" => [42.0],
|
||
|
|
"extension" => {
|
||
|
|
"series" => [
|
||
|
|
{
|
||
|
|
"label" => "Some unlabelled series against Escudo - daily",
|
||
|
|
"dimension_category" => [{ "dimension_id" => 12, "category_id" => 999 }],
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
"dimension" => {
|
||
|
|
"12" => { "category" => { "index" => ["999"] } },
|
||
|
|
"reference_date" => { "category" => { "index" => ["1998-01-02"] } },
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
_(adapter.parse(json)).must_be_empty
|
||
|
|
end
|
||
|
|
|
||
|
|
it "returns an empty dataset when the response has no series" do
|
||
|
|
json = { "size" => [0], "value" => [], "extension" => { "series" => [] }, "dimension" => {} }
|
||
|
|
|
||
|
|
_(adapter.parse(json)).must_be_empty
|
||
|
|
end
|
||
|
|
|
||
|
|
it "fetches rates for a historical date range" do
|
||
|
|
dataset = adapter.fetch(after: Date.new(1998, 12, 28), upto: Date.new(1998, 12, 31))
|
||
|
|
|
||
|
|
_(dataset).wont_be_empty
|
||
|
|
_(dataset.map { |r| r[:quote] }.uniq).must_equal(["PTE"])
|
||
|
|
end
|
||
|
|
|
||
|
|
it "fetches multiple currencies per date and follows pagination" do
|
||
|
|
dataset = adapter.fetch(after: Date.new(1998, 12, 28), upto: Date.new(1998, 12, 31))
|
||
|
|
bases = dataset.map { |r| r[:base] }.uniq
|
||
|
|
|
||
|
|
# Pagination across all source-filtered series must surface BEF/ATS (page 3) too.
|
||
|
|
_(bases).must_include("USD")
|
||
|
|
_(bases).must_include("ATS")
|
||
|
|
end
|
||
|
|
|
||
|
|
it "returns USD/PTE in a plausible range for late-1998" do
|
||
|
|
dataset = adapter.fetch(after: Date.new(1998, 12, 28), upto: Date.new(1998, 12, 31))
|
||
|
|
usd = dataset.find { |r| r[:base] == "USD" && r[:date] == Date.new(1998, 12, 30) }
|
||
|
|
|
||
|
|
_(usd).wont_be_nil
|
||
|
|
_(usd[:rate]).must_be_close_to(171.0, 5.0)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|