From 6cb352629a70f473f5eac2fbb70ae512e29b03c4 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Mon, 25 May 2026 12:19:06 -0400 Subject: [PATCH] test(quality_dashboard): scaffold + shape tests (Task 1) Tests for empty-DB all-clear, canonical section order, and required keys on each section. All fail until Task 2 lands the snapshot helper. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../fusion_plating_quality/tests/__init__.py | 1 + .../tests/test_dashboard_snapshot.py | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 fusion_plating/fusion_plating_quality/tests/test_dashboard_snapshot.py diff --git a/fusion_plating/fusion_plating_quality/tests/__init__.py b/fusion_plating/fusion_plating_quality/tests/__init__.py index 1e698a17..3f7fa727 100644 --- a/fusion_plating/fusion_plating_quality/tests/__init__.py +++ b/fusion_plating/fusion_plating_quality/tests/__init__.py @@ -1,2 +1,3 @@ # -*- coding: utf-8 -*- from . import test_part_catalog_contract_review_enforcement +from . import test_dashboard_snapshot diff --git a/fusion_plating/fusion_plating_quality/tests/test_dashboard_snapshot.py b/fusion_plating/fusion_plating_quality/tests/test_dashboard_snapshot.py new file mode 100644 index 00000000..e5220932 --- /dev/null +++ b/fusion_plating/fusion_plating_quality/tests/test_dashboard_snapshot.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +"""Quality Dashboard snapshot endpoint tests. + +Spec: docs/superpowers/specs/2026-05-25-quality-dashboard-redesign-design.md +Plan: docs/superpowers/plans/2026-05-25-quality-dashboard-redesign-plan.md +""" +from odoo.tests.common import TransactionCase + + +class TestDashboardSnapshotShape(TransactionCase): + """Response shape + section ordering tests.""" + + def _build(self): + from odoo.addons.fusion_plating_quality.controllers.fp_quality_dashboard \ + import FpQualityDashboardSnapshot + return FpQualityDashboardSnapshot(self.env).build() + + def test_snapshot_has_expected_top_level_keys(self): + snap = self._build() + self.assertIn('banner', snap) + self.assertIn('sections', snap) + self.assertIn('computed_at', snap) + + def test_section_order_is_canonical(self): + snap = self._build() + types_present = [s['type'] for s in snap['sections']] + # Canonical order — cert, hold, ncr, rma, capa, check. + # Some types may be absent if their model isn't installed; the + # PRESENT ones must appear in this relative order. + canonical = ['cert', 'hold', 'ncr', 'rma', 'capa', 'check'] + order_in_canonical = [canonical.index(t) for t in types_present] + self.assertEqual( + order_in_canonical, sorted(order_in_canonical), + f"sections out of order: got {types_present}", + ) + + def test_empty_db_returns_all_clear(self): + snap = self._build() + self.assertTrue(snap['banner']['all_clear']) + self.assertEqual(snap['banner']['items'], []) + self.assertEqual(snap['banner']['total_matching'], 0) + + def test_each_section_has_required_keys(self): + snap = self._build() + for section in snap['sections']: + for key in ('type', 'label', 'icon', 'open', 'overdue', + 'items', 'open_kanban_xmlid'): + self.assertIn( + key, section, + f"section {section.get('type')} missing key {key!r}", + ) + self.assertIsInstance(section['items'], list) + self.assertIsInstance(section['open'], int) + self.assertIsInstance(section['overdue'], int)