Add purchase analysis summaries
This commit is contained in:
149
tests/test_analyze_purchases.py
Normal file
149
tests/test_analyze_purchases.py
Normal file
@@ -0,0 +1,149 @@
|
||||
import csv
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
import analyze_purchases
|
||||
|
||||
|
||||
class AnalyzePurchasesTests(unittest.TestCase):
|
||||
def test_analysis_outputs_cover_required_views(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
purchases_csv = Path(tmpdir) / "purchases.csv"
|
||||
output_dir = Path(tmpdir) / "analysis"
|
||||
|
||||
fieldnames = [
|
||||
"purchase_date",
|
||||
"retailer",
|
||||
"order_id",
|
||||
"catalog_id",
|
||||
"catalog_name",
|
||||
"category",
|
||||
"product_type",
|
||||
"net_line_total",
|
||||
"line_total",
|
||||
"normalized_quantity",
|
||||
"normalized_quantity_unit",
|
||||
"effective_price",
|
||||
"effective_price_unit",
|
||||
"store_name",
|
||||
"store_number",
|
||||
"store_city",
|
||||
"store_state",
|
||||
"is_fee",
|
||||
"is_discount_line",
|
||||
"is_coupon_line",
|
||||
]
|
||||
with purchases_csv.open("w", newline="", encoding="utf-8") as handle:
|
||||
writer = csv.DictWriter(handle, fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
writer.writerows(
|
||||
[
|
||||
{
|
||||
"purchase_date": "2026-03-01",
|
||||
"retailer": "giant",
|
||||
"order_id": "g1",
|
||||
"catalog_id": "cat_banana",
|
||||
"catalog_name": "BANANA",
|
||||
"category": "produce",
|
||||
"product_type": "banana",
|
||||
"net_line_total": "1.29",
|
||||
"line_total": "1.29",
|
||||
"normalized_quantity": "2.19",
|
||||
"normalized_quantity_unit": "lb",
|
||||
"effective_price": "0.589",
|
||||
"effective_price_unit": "lb",
|
||||
"store_name": "Giant",
|
||||
"store_number": "42",
|
||||
"store_city": "Springfield",
|
||||
"store_state": "VA",
|
||||
"is_fee": "false",
|
||||
"is_discount_line": "false",
|
||||
"is_coupon_line": "false",
|
||||
},
|
||||
{
|
||||
"purchase_date": "2026-03-01",
|
||||
"retailer": "giant",
|
||||
"order_id": "g1",
|
||||
"catalog_id": "cat_ice",
|
||||
"catalog_name": "ICE",
|
||||
"category": "frozen",
|
||||
"product_type": "ice",
|
||||
"net_line_total": "3.50",
|
||||
"line_total": "3.50",
|
||||
"normalized_quantity": "20",
|
||||
"normalized_quantity_unit": "lb",
|
||||
"effective_price": "0.175",
|
||||
"effective_price_unit": "lb",
|
||||
"store_name": "Giant",
|
||||
"store_number": "42",
|
||||
"store_city": "Springfield",
|
||||
"store_state": "VA",
|
||||
"is_fee": "false",
|
||||
"is_discount_line": "false",
|
||||
"is_coupon_line": "false",
|
||||
},
|
||||
{
|
||||
"purchase_date": "2026-03-02",
|
||||
"retailer": "costco",
|
||||
"order_id": "c1",
|
||||
"catalog_id": "cat_banana",
|
||||
"catalog_name": "BANANA",
|
||||
"category": "produce",
|
||||
"product_type": "banana",
|
||||
"net_line_total": "1.49",
|
||||
"line_total": "2.98",
|
||||
"normalized_quantity": "3",
|
||||
"normalized_quantity_unit": "lb",
|
||||
"effective_price": "0.4967",
|
||||
"effective_price_unit": "lb",
|
||||
"store_name": "MT VERNON",
|
||||
"store_number": "1115",
|
||||
"store_city": "ALEXANDRIA",
|
||||
"store_state": "VA",
|
||||
"is_fee": "false",
|
||||
"is_discount_line": "false",
|
||||
"is_coupon_line": "false",
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
analyze_purchases.main.callback(
|
||||
purchases_csv=str(purchases_csv),
|
||||
output_dir=str(output_dir),
|
||||
)
|
||||
|
||||
expected_files = [
|
||||
"item_price_over_time.csv",
|
||||
"spend_by_visit.csv",
|
||||
"items_per_visit.csv",
|
||||
"category_spend_over_time.csv",
|
||||
"retailer_store_breakdown.csv",
|
||||
]
|
||||
for name in expected_files:
|
||||
self.assertTrue((output_dir / name).exists(), name)
|
||||
|
||||
with (output_dir / "spend_by_visit.csv").open(newline="", encoding="utf-8") as handle:
|
||||
spend_rows = list(csv.DictReader(handle))
|
||||
self.assertEqual("4.79", spend_rows[0]["visit_spend_total"])
|
||||
|
||||
with (output_dir / "items_per_visit.csv").open(newline="", encoding="utf-8") as handle:
|
||||
item_rows = list(csv.DictReader(handle))
|
||||
self.assertEqual("2", item_rows[0]["item_row_count"])
|
||||
self.assertEqual("2", item_rows[0]["distinct_catalog_count"])
|
||||
|
||||
with (output_dir / "category_spend_over_time.csv").open(newline="", encoding="utf-8") as handle:
|
||||
category_rows = list(csv.DictReader(handle))
|
||||
produce_row = next(row for row in category_rows if row["purchase_date"] == "2026-03-01" and row["category"] == "produce")
|
||||
self.assertEqual("1.29", produce_row["category_spend_total"])
|
||||
|
||||
with (output_dir / "retailer_store_breakdown.csv").open(newline="", encoding="utf-8") as handle:
|
||||
store_rows = list(csv.DictReader(handle))
|
||||
giant_row = next(row for row in store_rows if row["retailer"] == "giant")
|
||||
self.assertEqual("1", giant_row["visit_count"])
|
||||
self.assertEqual("2", giant_row["item_row_count"])
|
||||
self.assertEqual("4.79", giant_row["store_spend_total"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user