Release v9.3.0 report updates without committing local API keys.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -47,11 +47,13 @@ class EvidenceOnlyReportTest(unittest.TestCase):
|
||||
'meta': {},
|
||||
}
|
||||
|
||||
def test_empty_model_result_does_not_generate_fallback_report(self):
|
||||
def test_empty_model_result_still_generates_reviewable_report(self):
|
||||
result = ensure_experience_solution(self.analysis)
|
||||
self.assertFalse(result['meta']['fallbackReport'])
|
||||
self.assertFalse(result['meta']['reportReady'])
|
||||
self.assertIn('不输出兜底报告', result['meta']['reportBlockedReason'])
|
||||
self.assertTrue(result['meta']['reportReady'])
|
||||
self.assertFalse(result['meta']['reportAuditPassed'])
|
||||
self.assertEqual('needs_review', result['meta']['reportQuality'])
|
||||
self.assertIn('审核未通过', result['meta']['reportNotice'])
|
||||
self.assertEqual('', result['facts']['product']['title'])
|
||||
self.assertEqual(['面料支数', '床单面料材质', '适用床尺寸'], [x['name'] for x in result['facts']['attributes']])
|
||||
self.assertEqual(2, result['baseline']['reviewCount'])
|
||||
@@ -61,18 +63,20 @@ class EvidenceOnlyReportTest(unittest.TestCase):
|
||||
self.assertEqual('下一款明确卖点', cards[0]['label'])
|
||||
self.assertIn('ATTR_0003', cards[0]['evidenceIds'])
|
||||
self.assertEqual([], result['experienceSolution']['productExperience']['gates'])
|
||||
with self.assertRaisesRegex(ValueError, '不输出兜底报告'):
|
||||
render(result, 'fixture')
|
||||
html = render(result, 'fixture')
|
||||
self.assertIn('审核未通过', html)
|
||||
|
||||
def test_analysis_runs_without_model_channel(self):
|
||||
def test_analysis_runs_without_model_channel_uses_evidence_fallback(self):
|
||||
raw = dict(self.analysis['facts'])
|
||||
raw['_model_available'] = False
|
||||
result = analyze(raw)
|
||||
self.assertFalse(result['meta']['modelUsed'])
|
||||
self.assertEqual('9.2.5', result['meta']['engineVersion'])
|
||||
self.assertEqual('9.3.0', result['meta']['engineVersion'])
|
||||
self.assertEqual('home_textile', result['meta']['industryTemplate'])
|
||||
self.assertFalse(result['meta']['fallbackReport'])
|
||||
self.assertFalse(result['meta']['reportReady'])
|
||||
self.assertTrue(result['meta']['reportReady'])
|
||||
self.assertTrue(result['experienceSolution']['reportSummary']['title'])
|
||||
self.assertEqual(7, len(result['roleOutputs']))
|
||||
|
||||
def test_historical_fallback_json_is_rejected(self):
|
||||
result = ensure_experience_solution({
|
||||
@@ -198,9 +202,9 @@ class EvidenceOnlyReportTest(unittest.TestCase):
|
||||
self.assertNotIn('决定成交', output)
|
||||
self.assertNotIn('爆款', output)
|
||||
doc = render(result, 'evidence-only')
|
||||
self.assertIn('老板速览', doc)
|
||||
self.assertIn('下一款先做什么', doc)
|
||||
self.assertIn('V9.2.5', doc)
|
||||
self.assertIn('window.REPORT_DATA=', doc)
|
||||
self.assertIn('Sansong Product Intelligence V9.3.0', doc)
|
||||
self.assertIn('<script src="/report.js"></script>', doc)
|
||||
self.assertNotIn('项目负责人', doc)
|
||||
|
||||
def test_incomplete_final_editor_output_is_repaired_from_real_evidence(self):
|
||||
|
||||
@@ -21,8 +21,9 @@ class V910RegressionTest(unittest.TestCase):
|
||||
def test_missing_sku_not_rendered_as_zero(self):
|
||||
doc=render(self.base_result(),'test')
|
||||
self.assertNotIn('SKU 0',doc)
|
||||
self.assertIn('结构化SKU 未完整采集',doc)
|
||||
self.assertIn('SKU图片数量不等于SKU数量',doc)
|
||||
self.assertNotIn('结构化SKU 未完整采集',doc)
|
||||
self.assertNotIn('SKU图片数量不等于SKU数量',doc)
|
||||
self.assertIn('window.REPORT_DATA=',doc)
|
||||
|
||||
def test_renderer_prefers_local_image_and_keeps_remote_fallback(self):
|
||||
entry={'value':'https://img.example.com/a.jpg','meta':{'localUrl':'/reports/assets/test/main/IMG_MAIN_0001.jpg','sourceUrl':'https://img.example.com/a.jpg'}}
|
||||
|
||||
@@ -33,13 +33,12 @@ class V920ImageDrivenReportTest(unittest.TestCase):
|
||||
|
||||
def test_renderer_is_image_driven_and_professional(self):
|
||||
doc=render(self.fixture(),'v920')
|
||||
for text in ('老板速览','下一款先做什么','主图到底在卖什么','详情页证明了什么','先解决适配,再解决审美','消费者真正感受到什么'):
|
||||
self.assertIn(text,doc)
|
||||
self.assertIn('v92-main-grid',doc)
|
||||
self.assertIn('v925-detail-list',doc)
|
||||
self.assertIn('v92-sku-mosaic',doc)
|
||||
self.assertIn('v92-buyer-grid',doc)
|
||||
self.assertIn('v925-plan-grid',doc)
|
||||
self.assertIn('window.REPORT_DATA=',doc)
|
||||
self.assertIn('<script src="/report.js"></script>',doc)
|
||||
self.assertIn('IMG_MAIN_0001',doc)
|
||||
self.assertIn('IMG_DETAIL_0001',doc)
|
||||
self.assertNotIn('v92-main-grid',doc)
|
||||
self.assertNotIn('v925-detail-list',doc)
|
||||
self.assertNotIn('[数据事实]',doc)
|
||||
self.assertNotIn('[分析判断]',doc)
|
||||
self.assertNotIn('[设计建议]',doc)
|
||||
@@ -48,8 +47,9 @@ class V920ImageDrivenReportTest(unittest.TestCase):
|
||||
|
||||
def test_cover_has_no_card_border_wrapper(self):
|
||||
doc=render(self.fixture(),'v920')
|
||||
self.assertIn('class="v92-cover"',doc)
|
||||
self.assertIn('cover-ratio',doc)
|
||||
self.assertIn('"coverImageId":"IMG_MAIN_0001"',doc)
|
||||
self.assertNotIn('class="v92-cover"',doc)
|
||||
self.assertNotIn('cover-ratio',doc)
|
||||
self.assertNotIn('hero-shot',doc)
|
||||
|
||||
def test_launch_fallback_never_empty_with_real_evidence(self):
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import json, sys, unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT=Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0,str(ROOT/'server'))
|
||||
from audit_report import audit, has_content
|
||||
|
||||
class V930ReportAuditTest(unittest.TestCase):
|
||||
def test_zero_and_false_are_real_content(self):
|
||||
self.assertTrue(has_content(0))
|
||||
self.assertTrue(has_content(False))
|
||||
self.assertFalse(has_content('未采集'))
|
||||
self.assertFalse(has_content({}))
|
||||
|
||||
def test_current_reference_report_has_complete_roles_and_evidence(self):
|
||||
source=ROOT/'server/reports/tmall_1068693788227_20260903_181040_ac150.json'
|
||||
if not source.exists():
|
||||
self.skipTest('reference report is not distributed')
|
||||
result=audit(json.loads(source.read_text('utf-8')))
|
||||
self.assertTrue(result['ok'],result['failures'])
|
||||
self.assertEqual(7,result['roles']['present'])
|
||||
self.assertFalse(result['evidence']['unresolved'])
|
||||
self.assertGreaterEqual(result['sourceCoverage'],12)
|
||||
|
||||
if __name__=='__main__':unittest.main()
|
||||
@@ -2,7 +2,7 @@ import json, re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT=Path(__file__).resolve().parents[1]
|
||||
EXPECTED='9.2.5'
|
||||
EXPECTED='9.3.0'
|
||||
|
||||
def test_version_consistency():
|
||||
assert (ROOT/'VERSION.txt').read_text().strip()==EXPECTED
|
||||
|
||||
Reference in New Issue
Block a user