Skip to content

Commit

Permalink
Dev: better test coverage for fx rates updater
Browse files Browse the repository at this point in the history
  • Loading branch information
lwitkowski committed Aug 6, 2024
1 parent a8cb0f3 commit 0a390fb
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 12 deletions.
4 changes: 3 additions & 1 deletion backend/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ class ExchangeRate(Base):
engine = create_engine('postgresql+psycopg2://{0}:{1}@{2}:{3}/{4}'.format(DB_USER, DB_PW, DB_HOST, DB_PORT, DB_NAME))
Session = sessionmaker(bind=engine)

def truncate_offers():
def truncate_all_tables():
session = Session()
session.execute(text("TRUNCATE aircraft_offer"))
session.execute(text("TRUNCATE exchange_rates"))
session.commit()
session.close()

Expand Down Expand Up @@ -103,6 +104,7 @@ def offer_url_exists(offer_url):
finally:
session.close()


def get_exchange_rates_as_dict(session):
all_exchange_rates = session.query(ExchangeRate).all()
exchange_rates = dict()
Expand Down
13 changes: 9 additions & 4 deletions backend/exchange_rates.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@

def fetch_exchange_rates_from_ecb():
start_time = time.time()
count = 0
response = requests.get(ECB_FX_RATES_URL).text
et = ET.fromstring(response)
count = update_exchange_rates(response)
logger.info("Updated %d exchange rates in %.2fs", count, (time.time() - start_time))

def update_exchange_rates(xmlData):
count = 0
et = ET.fromstring(xmlData)
for element in et.iter():
curr_name = element.get('currency')
if curr_name is None:
Expand All @@ -22,8 +26,8 @@ def fetch_exchange_rates_from_ecb():
logger.debug("Fetched exchange rate: {0} for currency {1}".format(str(curr_rate), str(curr_name)))
db.update_exchange_rate(db.ExchangeRate(currency=curr_name, rate=curr_rate))
count += 1
return count

logger.info("Updated %d exchange rates in %.2fs", count, (time.time() - start_time))

def get_currency_code(o):
currency_str = o
Expand All @@ -36,7 +40,8 @@ def get_currency_code(o):
'$': 'USD',
'US$': 'USD',
'£': 'GBP',
'Fr.': 'CHF'
'Fr.': 'CHF',
'A$': 'AUD',
}
if currency_str in iso_code_mapping:
return iso_code_mapping[currency_str]
Expand Down
41 changes: 41 additions & 0 deletions backend/tests/eurofxref-daily.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time='2024-07-02'>
<Cube currency='USD' rate='1.0729'/>
<Cube currency='JPY' rate='173.31'/>
<Cube currency='BGN' rate='1.9558'/>
<Cube currency='CZK' rate='25.185'/>
<Cube currency='DKK' rate='7.4590'/>
<Cube currency='GBP' rate='0.84755'/>
<Cube currency='HUF' rate='395.60'/>
<Cube currency='PLN' rate='4.3250'/>
<Cube currency='RON' rate='4.9769'/>
<Cube currency='SEK' rate='11.4170'/>
<Cube currency='CHF' rate='0.9697'/>
<Cube currency='ISK' rate='149.30'/>
<Cube currency='NOK' rate='11.4795'/>
<Cube currency='TRY' rate='35.0707'/>
<Cube currency='AUD' rate='1.6120'/>
<Cube currency='BRL' rate='6.0479'/>
<Cube currency='CAD' rate='1.4727'/>
<Cube currency='CNY' rate='7.8014'/>
<Cube currency='HKD' rate='8.3829'/>
<Cube currency='IDR' rate='17570.19'/>
<Cube currency='ILS' rate='4.0411'/>
<Cube currency='INR' rate='89.5417'/>
<Cube currency='KRW' rate='1488.26'/>
<Cube currency='MXN' rate='19.6825'/>
<Cube currency='MYR' rate='5.0630'/>
<Cube currency='NZD' rate='1.7693'/>
<Cube currency='PHP' rate='63.097'/>
<Cube currency='SGD' rate='1.4569'/>
<Cube currency='THB' rate='39.526'/>
<Cube currency='ZAR' rate='19.8161'/>
</Cube>
</Cube>
</gesmes:Envelope>
2 changes: 1 addition & 1 deletion backend/tests/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class DbTest(unittest.TestCase):

def setUp(self):
db.truncate_offers()
db.truncate_all_tables()

def test_should_store_and_fetch_offer(self):
# given
Expand Down
30 changes: 26 additions & 4 deletions backend/tests/test_exchange_rates.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
import unittest
from ddt import ddt
from price_parser import Price
from exchange_rates import get_currency_code

import tests.test__testcontainers_setup
import db
import exchange_rates

@ddt
class ExchangeRatesTest(unittest.TestCase):

def setUp(self):
db.truncate_all_tables()

def test_get_currency_code(self):
self.assertEqual("EUR", get_currency_code(Price.fromstring("12.000,00 €")))
self.assertEqual("GBP", get_currency_code(Price.fromstring("16,23 £")))
self.assertEqual("CHF", get_currency_code(Price.fromstring("12 SFr.")))
self.assertEqual("EUR", exchange_rates.get_currency_code(Price.fromstring("12.000,00 €")))
self.assertEqual("GBP", exchange_rates.get_currency_code(Price.fromstring("16,23 £")))
self.assertEqual("CHF", exchange_rates.get_currency_code(Price.fromstring("12 SFr.")))
self.assertEqual("AUD", exchange_rates.get_currency_code(Price.fromstring("12 A$")))


def test_should_update_fx_rates_in_db(self):
# when
exchange_rates.update_exchange_rates(readFile("tests/eurofxref-daily.xml"))

# then
fxRates = db.get_exchange_rates_as_dict(db.Session())
self.assertEqual("4.3250", fxRates["PLN"])


def readFile(name: str):
with open(name, 'r') as file:
return file.read()
4 changes: 2 additions & 2 deletions backend/tests/test_pipelines.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class DuplicateDetectionTest(unittest.TestCase):

def setUp(self):
db.truncate_offers()
db.truncate_all_tables()

self.sample_offer = buildOfferWithUrl("https://offers.com/1")
self.detection = pipelines.DuplicateDetection()
Expand Down Expand Up @@ -111,7 +111,7 @@ def test_regular_offers_are_not_dropped(self, offer_title):
class StoragePipelineTest(unittest.TestCase):

def setUp(self):
db.truncate_offers()
db.truncate_all_tables()
self.storage = pipelines.StoragePipeline()

def test_should_store_offer(self):
Expand Down

0 comments on commit 0a390fb

Please sign in to comment.