fix(analytics): align yoy and detail table contracts
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
This commit is contained in:
@@ -14,7 +14,13 @@ from routes.monthly_routes import (
|
||||
_resolve_monthly_period,
|
||||
get_monthly_summary_data,
|
||||
)
|
||||
from routes.sales_routes import _filter_growth_payload, _sorted_valid_month_labels
|
||||
import routes.sales_routes as sales_routes
|
||||
from routes.sales_routes import (
|
||||
_filter_growth_payload,
|
||||
_period_month_keys,
|
||||
_project_yoy_period,
|
||||
_sorted_valid_month_labels,
|
||||
)
|
||||
from services.analysis_period_service import make_analysis_period, make_month_period
|
||||
|
||||
|
||||
@@ -284,10 +290,72 @@ def test_monthly_frontend_has_replayable_period_and_no_fixed_years():
|
||||
|
||||
def test_sales_frontend_uses_live_period_linked_api_routes():
|
||||
script = (ROOT / "web/static/js/page-sales-analysis.js").read_text(encoding="utf-8")
|
||||
template = (ROOT / "templates/sales_analysis.html").read_text(encoding="utf-8")
|
||||
|
||||
assert "buildPeriodApiUrl" in script
|
||||
assert "new URLSearchParams(window.location.search)" in script
|
||||
assert "/api/sales_analysis/yoy_comparison" in script
|
||||
assert "/api/sales_analysis/table_data" in script
|
||||
assert "d.growth_rate" in script
|
||||
assert "d.monthly_breakdown" in script
|
||||
assert "columns," in script
|
||||
assert 'data-field="product_id"' in template
|
||||
assert 'data-field="amount"' in template
|
||||
assert "fetch(`/api/yoy?" not in script
|
||||
assert "'/api/sales_table?'" not in script
|
||||
|
||||
|
||||
def test_yoy_period_projects_selected_dates_to_each_comparison_year():
|
||||
start, end = _project_yoy_period(2025, "2026-04-01", "2026-04-30")
|
||||
|
||||
assert start == date(2025, 4, 1)
|
||||
assert end == date(2025, 4, 30)
|
||||
assert _period_month_keys(start, end) == ["2025-04"]
|
||||
|
||||
|
||||
def test_yoy_api_uses_only_the_selected_period_for_totals_and_chart(monkeypatch):
|
||||
engine = create_engine("sqlite:///:memory:")
|
||||
with engine.begin() as conn:
|
||||
conn.exec_driver_sql(
|
||||
'CREATE TABLE realtime_sales_monthly ("日期" TEXT, "總業績" REAL, "數量" REAL, "總成本" REAL)'
|
||||
)
|
||||
conn.exec_driver_sql(
|
||||
"""
|
||||
INSERT INTO realtime_sales_monthly ("日期", "總業績", "數量", "總成本")
|
||||
VALUES
|
||||
('2025/04/10', 100, 2, 60),
|
||||
('2025/05/10', 900, 9, 100),
|
||||
('2026/04/10', 150, 3, 80),
|
||||
('2026/05/10', 1200, 12, 200)
|
||||
"""
|
||||
)
|
||||
|
||||
class FakeDatabaseManager:
|
||||
def __init__(self):
|
||||
self.engine = engine
|
||||
|
||||
monkeypatch.setattr(sales_routes, "DatabaseManager", FakeDatabaseManager)
|
||||
app = Flask(__name__)
|
||||
with app.test_request_context(
|
||||
"/api/sales_analysis/yoy_comparison"
|
||||
"?year1=2025&year2=2026&metric=revenue"
|
||||
"&start_date=2026-04-01&end_date=2026-04-30"
|
||||
):
|
||||
response = sales_routes.api_yoy_comparison.__wrapped__()
|
||||
|
||||
payload = response.get_json()
|
||||
assert payload["period"]["linked"] is True
|
||||
assert payload["period"]["year1"] == {
|
||||
"start_date": "2025-04-01",
|
||||
"end_date": "2025-04-30",
|
||||
}
|
||||
assert payload["year1"]["total"] == 100
|
||||
assert payload["year2"]["total"] == 150
|
||||
assert payload["growth_rate"] == 50
|
||||
assert payload["monthly_breakdown"] == [{
|
||||
"month": 4,
|
||||
"month_label": "4月",
|
||||
"year1_value": 100,
|
||||
"year2_value": 150,
|
||||
"growth_rate": 50,
|
||||
}]
|
||||
|
||||
Reference in New Issue
Block a user