initial commit
This commit is contained in:
206
tests/test_main.py
Normal file
206
tests/test_main.py
Normal file
@@ -0,0 +1,206 @@
|
||||
import datetime
|
||||
import json
|
||||
import pickle
|
||||
from types import SimpleNamespace
|
||||
|
||||
from amazonorders.entity.order import Order
|
||||
from amazonorders.entity.item import Item
|
||||
from amazonorders.entity.shipment import Shipment
|
||||
from amazonorders.entity.transaction import Transaction
|
||||
from amazonorders.entity.recipient import Recipient
|
||||
import pytest
|
||||
|
||||
import main
|
||||
|
||||
|
||||
KEYS = {
|
||||
Item: [
|
||||
'title', 'link', 'price', 'seller', 'condition',
|
||||
'return_eligible_date', 'image_link', 'quantity'
|
||||
],
|
||||
Order: [
|
||||
'full_details', 'index', 'shipments', 'items', 'order_number', 'order_details_link',
|
||||
'grand_total', 'order_placed_date', 'recipient', 'payment_method', 'payment_method_last_4',
|
||||
'subtotal', 'shipping_total', 'free_shipping', 'promotion_applied', 'coupon_savings',
|
||||
'reward_points', 'subscription_discount', 'total_before_tax', 'estimated_tax',
|
||||
'refund_total', 'multibuy_discount', 'amazon_discount', 'gift_card', 'gift_wrap',
|
||||
],
|
||||
Transaction: [
|
||||
'completed_date', 'payment_method', 'grand_total', 'is_refund',
|
||||
'order_number', 'order_details_link', 'seller',
|
||||
],
|
||||
Shipment: [
|
||||
'items', 'delivery_status', 'tracking_link',
|
||||
],
|
||||
Recipient: [
|
||||
'name', 'address',
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def to_dict(entity):
|
||||
entity_keys = KEYS[type(entity)]
|
||||
result = {}
|
||||
for k, v in entity.__dict__.items():
|
||||
if k in entity_keys:
|
||||
if type(v) in KEYS:
|
||||
result[k] = to_dict(v)
|
||||
elif type(v) == list and len(v) > 0 and type(v[0]) in KEYS:
|
||||
result[k] = [to_dict(i) for i in v]
|
||||
elif type(v) in (datetime.date, datetime.datetime):
|
||||
result[k] = v.isoformat()
|
||||
else:
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
|
||||
# @pytest.fixture
|
||||
def mock_amz_hist():
|
||||
with open('output/transactions_2025.pkl', 'rb') as f:
|
||||
return pickle.load(f)
|
||||
|
||||
|
||||
# @pytest.fixture
|
||||
def mock_ynab_hist():
|
||||
with open('output/ynab_history.json') as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def test_get_tx_categories(monkeypatch):
|
||||
order = SimpleNamespace(
|
||||
items=[
|
||||
SimpleNamespace(
|
||||
title='An example item',
|
||||
price=17.49
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
item_details={
|
||||
'An example item': SimpleNamespace(
|
||||
category='Example category',
|
||||
description='example',
|
||||
)
|
||||
}
|
||||
|
||||
def classify(_names, _categories):
|
||||
return item_details
|
||||
monkeypatch.setattr('ai.classify', classify)
|
||||
|
||||
res = main.get_tx_categories(order, item_details)
|
||||
assert len(res) == 1
|
||||
assert res[0].category_name == 'Example category'
|
||||
assert res[0].description == 'example'
|
||||
assert res[0].ratio == 1.0
|
||||
|
||||
|
||||
def test_get_categories_multi_items(monkeypatch):
|
||||
order = SimpleNamespace(
|
||||
items=[
|
||||
SimpleNamespace(
|
||||
title='An example item',
|
||||
price=17.49
|
||||
),
|
||||
SimpleNamespace(
|
||||
title='Another example',
|
||||
price=12.34,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
item_details={
|
||||
'An example item': SimpleNamespace(
|
||||
category='Example category',
|
||||
description='example',
|
||||
),
|
||||
'Another example': SimpleNamespace(
|
||||
category='Example category',
|
||||
description='second example',
|
||||
)
|
||||
}
|
||||
|
||||
def classify(_names, _categories):
|
||||
return item_details
|
||||
monkeypatch.setattr('ai.classify', classify)
|
||||
|
||||
res = main.get_tx_categories(order, item_details)
|
||||
assert len(res) == 1
|
||||
assert res[0].category_name == 'Example category'
|
||||
assert res[0].description == 'example, second example'
|
||||
assert res[0].ratio == 1.0
|
||||
|
||||
|
||||
def test_get_categories_multi_categories(monkeypatch):
|
||||
order = SimpleNamespace(
|
||||
items=[
|
||||
SimpleNamespace(
|
||||
title='An example item',
|
||||
price=17.49
|
||||
),
|
||||
SimpleNamespace(
|
||||
title='Another example',
|
||||
price=12.34,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
item_details={
|
||||
'An example item': SimpleNamespace(
|
||||
category='Example category',
|
||||
description='example',
|
||||
),
|
||||
'Another example': SimpleNamespace(
|
||||
category='Other category',
|
||||
description='second example',
|
||||
)
|
||||
}
|
||||
|
||||
def classify(_names, _categories):
|
||||
return item_details
|
||||
monkeypatch.setattr('ai.classify', classify)
|
||||
|
||||
res = main.get_tx_categories(order, item_details)
|
||||
assert len(res) == 2
|
||||
assert res[0].category_name == 'Example category'
|
||||
assert res[0].description == 'example'
|
||||
assert res[0].ratio == pytest.approx(0.59, abs=0.01)
|
||||
|
||||
assert res[1].category_name == 'Other category'
|
||||
assert res[1].description == 'second example'
|
||||
assert res[1].ratio == pytest.approx(0.41, abs=0.01)
|
||||
|
||||
|
||||
def test_build_tx_update_multi():
|
||||
tx_categories = [
|
||||
SimpleNamespace(
|
||||
category_name='Example category',
|
||||
description='example',
|
||||
ratio=0.68,
|
||||
),
|
||||
SimpleNamespace(
|
||||
category_name='Other category',
|
||||
description='second example',
|
||||
ratio=0.32,
|
||||
)
|
||||
]
|
||||
|
||||
category_ids = {
|
||||
'Example category': '123',
|
||||
'Other category': '456',
|
||||
}
|
||||
|
||||
# ynab uses tenths of a cent as its unit
|
||||
tx_total = 23760
|
||||
|
||||
res = main.build_tx_update(tx_categories, category_ids, tx_total)
|
||||
assert len(res.subtransactions) == 2
|
||||
|
||||
sub0 = res.subtransactions[0]
|
||||
assert sub0.category_id == '123'
|
||||
assert sub0.memo == 'example'
|
||||
assert sub0.amount == 16157
|
||||
|
||||
sub1 = res.subtransactions[1]
|
||||
assert sub1.category_id == '456'
|
||||
assert sub1.memo == 'second example'
|
||||
assert sub1.amount == 7603
|
||||
Reference in New Issue
Block a user