Files
Odoo-Modules/fusion_accounting_reports/tests/test_reports_controller.py
gsinghpal 5cdd3e756d feat(fusion_accounting_reports): 8 JSON-RPC endpoints for OWL widget
Adds FusionReportsController exposing:
- list_available, run, drill_down
- get_anomalies (with optional persistence to fusion.report.anomaly)
- get_commentary (LLM cache via fusion.report.commentary, force_regenerate flag)
- compare_periods (delegates to run with comparison flag)
- export_pdf / export_xlsx (Phase 2 placeholders for Tasks 34/35)

All endpoints use V19's type='jsonrpc' and route through
fusion.report.engine - no direct ORM aggregation in the controller.

8 new HttpCase tests cover each endpoint. Total: 78 logical tests.

Made-with: Cursor
2026-04-19 15:37:58 -04:00

119 lines
3.9 KiB
Python

"""Controller tests using HttpCase for the 8 JSON-RPC endpoints."""
import json
from odoo.tests.common import HttpCase, new_test_user, tagged
@tagged('post_install', '-at_install')
class TestReportsController(HttpCase):
def setUp(self):
super().setUp()
self.user = new_test_user(
self.env,
login='reports_test_user',
groups='base.group_user,account.group_account_invoice',
)
def _jsonrpc(self, endpoint, params):
self.authenticate('reports_test_user', 'reports_test_user')
url = f'/fusion/reports/{endpoint}'
body = {
'jsonrpc': '2.0',
'method': 'call',
'params': params,
'id': 1,
}
response = self.url_open(
url,
data=json.dumps(body),
headers={'Content-Type': 'application/json'},
)
self.assertEqual(
response.status_code, 200,
f"{endpoint} returned {response.status_code}: {response.text[:300]}",
)
result = response.json()
if 'error' in result:
self.fail(f"{endpoint} errored: {result['error']}")
return result.get('result', {})
def test_list_available(self):
result = self._jsonrpc('list_available', {
'company_id': self.env.company.id,
})
self.assertIn('reports', result)
codes = [r['code'] for r in result['reports']]
self.assertIn('pnl', codes)
def test_run_pnl(self):
result = self._jsonrpc('run', {
'report_type': 'pnl',
'date_from': '2026-01-01',
'date_to': '2026-12-31',
'company_id': self.env.company.id,
})
self.assertEqual(result.get('report_type'), 'pnl')
self.assertIn('rows', result)
def test_run_balance_sheet(self):
result = self._jsonrpc('run', {
'report_type': 'balance_sheet',
'date_from': '2026-01-01',
'date_to': '2026-12-31',
'company_id': self.env.company.id,
})
self.assertEqual(result.get('report_type'), 'balance_sheet')
def test_drill_down_returns_list(self):
line = self.env['account.move.line'].search(
[('parent_state', '=', 'posted')], limit=1,
)
if not line:
self.skipTest("No posted lines in DB")
result = self._jsonrpc('drill_down', {
'account_id': line.account_id.id,
'date_from': str(line.date),
'date_to': str(line.date),
'company_id': line.company_id.id,
})
self.assertIn('rows', result)
def test_get_anomalies_returns_list(self):
result = self._jsonrpc('get_anomalies', {
'report_type': 'pnl',
'date_from': '2026-01-01',
'date_to': '2026-12-31',
'comparison': 'previous_year',
'company_id': self.env.company.id,
})
self.assertIn('anomalies', result)
def test_get_commentary_returns_dict(self):
result = self._jsonrpc('get_commentary', {
'report_type': 'pnl',
'date_from': '2026-01-01',
'date_to': '2026-12-31',
'company_id': self.env.company.id,
})
self.assertIn('summary', result)
self.assertIn('highlights', result)
self.assertIn('concerns', result)
def test_export_pdf_placeholder(self):
result = self._jsonrpc('export_pdf', {
'report_type': 'pnl',
'date_from': '2026-01-01',
'date_to': '2026-12-31',
})
self.assertEqual(result.get('status'), 'not_implemented')
def test_export_xlsx_placeholder(self):
result = self._jsonrpc('export_xlsx', {
'report_type': 'pnl',
'date_from': '2026-01-01',
'date_to': '2026-12-31',
})
self.assertEqual(result.get('status'), 'not_implemented')