94 lines
4.2 KiB
Python
94 lines
4.2 KiB
Python
from sqlalchemy import create_engine, text
|
|
|
|
|
|
def _seed_growth_tables(engine):
|
|
with engine.begin() as conn:
|
|
conn.execute(text(
|
|
'CREATE TABLE daily_sales_snapshot ('
|
|
'"商品ID" TEXT, "商品名稱" TEXT, snapshot_date TEXT, "總業績" REAL, "數量" REAL, "商品館" TEXT)'
|
|
))
|
|
conn.execute(text(
|
|
"CREATE TABLE competitor_prices ("
|
|
"sku TEXT, source TEXT, competitor_product_id TEXT, competitor_product_name TEXT, "
|
|
"price REAL, match_score REAL, tags TEXT, crawled_at TEXT, expires_at TEXT)"
|
|
))
|
|
conn.execute(text(
|
|
"CREATE TABLE products ("
|
|
"id INTEGER PRIMARY KEY, i_code TEXT, name TEXT, status TEXT)"
|
|
))
|
|
conn.execute(text(
|
|
"CREATE TABLE price_records ("
|
|
"id INTEGER PRIMARY KEY, product_id INTEGER, price REAL, timestamp TEXT)"
|
|
))
|
|
conn.execute(text("""
|
|
INSERT INTO daily_sales_snapshot
|
|
("商品ID", "商品名稱", snapshot_date, "總業績", "數量", "商品館")
|
|
VALUES
|
|
('PCH-1', '高業績商品', '2026-06-14', 120000, 36, '保養'),
|
|
('PCH-1', '高業績商品', '2026-06-08', 180000, 50, '保養'),
|
|
('PCH-2', '待補對應商品', '2026-06-14', 90000, 18, '彩妝'),
|
|
('PCH-2', '待補對應商品', '2026-06-08', 30000, 8, '彩妝')
|
|
"""))
|
|
conn.execute(text(
|
|
"INSERT INTO products (id, i_code, name, status) "
|
|
"VALUES (1, 'MOMO-1', 'MOMO 參考商品', 'ACTIVE')"
|
|
))
|
|
conn.execute(text(
|
|
"INSERT INTO price_records (product_id, price, timestamp) "
|
|
"VALUES (1, 900, '2026-06-14 10:00:00')"
|
|
))
|
|
conn.execute(text("""
|
|
INSERT INTO competitor_prices
|
|
(sku, source, competitor_product_id, competitor_product_name,
|
|
price, match_score, tags, crawled_at, expires_at)
|
|
VALUES
|
|
('MOMO-1', 'pchome', 'PCH-1', '高業績商品',
|
|
1000, 0.91, '["identity_v2","match_type_exact"]', '2026-06-14 11:00:00', NULL)
|
|
"""))
|
|
|
|
|
|
def test_pchome_growth_opportunities_use_plain_language_and_pause_shopee_coupang():
|
|
from services.pchome_revenue_growth_service import build_pchome_growth_opportunities
|
|
|
|
engine = create_engine("sqlite:///:memory:")
|
|
_seed_growth_tables(engine)
|
|
|
|
payload = build_pchome_growth_opportunities(engine, limit=5)
|
|
|
|
assert payload["success"] is True
|
|
assert payload["system_name"] == "PChome 業績成長自動化作戰系統"
|
|
assert payload["source_scope"]["active_external_sources"] == ["MOMO 外部價格參考"]
|
|
assert payload["source_scope"]["paused_external_sources"] == ["蝦皮", "酷澎"]
|
|
readiness = payload["source_scope"]["source_readiness"]
|
|
sources = {source["code"]: source for source in readiness["sources"]}
|
|
assert sources["momo_reference"]["status_label"] == "正在使用"
|
|
assert sources["shopee"]["status_label"] == "先暫停"
|
|
assert sources["coupang"]["status_label"] == "先暫停"
|
|
assert payload["stats"]["candidate_count"] == 2
|
|
assert payload["stats"]["mapped_count"] == 1
|
|
assert payload["stats"]["needs_mapping_count"] == 1
|
|
|
|
actions = {item["pchome_product_id"]: item["recommended_action"]["label"] for item in payload["opportunities"]}
|
|
assert actions["PCH-1"] == "檢查售價與活動"
|
|
assert actions["PCH-2"] == "先補商品對應"
|
|
assert all("identity" not in " ".join(item["reason_lines"]).lower() for item in payload["opportunities"])
|
|
|
|
|
|
def test_ai_product_pick_sales_join_by_sku_disabled_by_default(monkeypatch):
|
|
from services.ai_product_pick_agent import _sales_join_by_momo_sku_enabled
|
|
|
|
monkeypatch.delenv("PCHOME_SALES_JOIN_BY_MOMO_SKU_ENABLED", raising=False)
|
|
|
|
assert _sales_join_by_momo_sku_enabled() is False
|
|
|
|
|
|
def test_ai_intelligence_template_uses_pchome_growth_name_and_endpoint():
|
|
from pathlib import Path
|
|
|
|
template = Path("templates/ai_intelligence.html").read_text(encoding="utf-8")
|
|
|
|
assert "PChome 業績成長自動化作戰系統" in template
|
|
assert "/api/ai/pchome-growth/opportunities" in template
|
|
assert "growthSourceReadiness" in template
|
|
assert "待補對應" in template
|