Files
Odoo-Modules/fusion_plating/fusion_plating_quality/tests/test_dashboard_snapshot.py
gsinghpal e271908109 feat(quality_dashboard): populate section items (Task 3)
_fetch_section_items pulls top-5 open records per type, ranked
overdue-first by oldest create_date. _build_item shapes each row
with id/name/customer/subtitle/urgency/open_action. _resolve_partner
defensively walks partner_id -> job_id.partner_id -> ncr_id.partner_id
per type. _build_subtitle generates the human-readable second line.

Tests cover empty list, 5-cap on 8-record set, and required item
keys (id/name/customer/subtitle/urgency/open_action).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 12:20:50 -04:00

112 lines
4.5 KiB
Python

# -*- 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)
class TestDashboardSnapshotItems(TransactionCase):
"""Per-section items list — ranking + cap + shape."""
def _build(self):
from odoo.addons.fusion_plating_quality.controllers.fp_quality_dashboard \
import FpQualityDashboardSnapshot
return FpQualityDashboardSnapshot(self.env).build()
def _get_section(self, snap, type_code):
for s in snap['sections']:
if s['type'] == type_code:
return s
return None
def test_section_items_empty_when_no_records(self):
snap = self._build()
cert_sec = self._get_section(snap, 'cert')
if cert_sec is None:
self.skipTest('fp.certificate not installed')
self.assertEqual(cert_sec['items'], [])
def test_section_items_capped_at_5(self):
if 'fusion.plating.quality.hold' not in self.env:
self.skipTest('fusion.plating.quality.hold not installed')
partner = self.env['res.partner'].create({'name': 'Cust'})
# Create 8 holds in the same open state
Hold = self.env['fusion.plating.quality.hold']
for i in range(8):
Hold.create({
'partner_id': partner.id,
'state': 'on_hold',
'reason': f'test hold {i}',
})
snap = self._build()
sec = self._get_section(snap, 'hold')
self.assertEqual(len(sec['items']), 5)
self.assertEqual(sec['open'], 8)
def test_item_has_required_keys(self):
if 'fusion.plating.quality.hold' not in self.env:
self.skipTest('fusion.plating.quality.hold not installed')
partner = self.env['res.partner'].create({'name': 'Cust'})
hold = self.env['fusion.plating.quality.hold'].create({
'partner_id': partner.id, 'state': 'on_hold', 'reason': 'x',
})
snap = self._build()
sec = self._get_section(snap, 'hold')
self.assertEqual(len(sec['items']), 1)
item = sec['items'][0]
for k in ('id', 'name', 'customer', 'subtitle',
'urgency', 'open_action'):
self.assertIn(k, item, f'item missing key {k!r}')
self.assertEqual(item['open_action']['res_model'],
'fusion.plating.quality.hold')
self.assertEqual(item['open_action']['res_id'], hold.id)