changes
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
from odoo.tests.common import TransactionCase, tagged
|
||||
from odoo.addons.fusion_accounting_ai.services.data_adapters.base import (
|
||||
DataAdapter, AdapterMode,
|
||||
)
|
||||
from odoo.addons.fusion_accounting_ai.services.data_adapters import get_adapter
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestDataAdapterBase(TransactionCase):
|
||||
"""Verify the data adapter base class chooses the correct backend."""
|
||||
|
||||
def test_adapter_mode_pure_community(self):
|
||||
"""With no fusion native and no Enterprise, adapter selects COMMUNITY."""
|
||||
adapter = DataAdapter(self.env)
|
||||
mode = adapter._select_mode(
|
||||
fusion_native_model='fusion.bank.rec.widget',
|
||||
enterprise_module='account_accountant',
|
||||
)
|
||||
self.assertIn(mode, (AdapterMode.FUSION, AdapterMode.ENTERPRISE, AdapterMode.COMMUNITY))
|
||||
|
||||
def test_adapter_falls_back_when_fusion_model_missing(self):
|
||||
"""Adapter must not error when the fusion native model isn't loaded."""
|
||||
adapter = DataAdapter(self.env)
|
||||
mode = adapter._select_mode(
|
||||
fusion_native_model='fusion.never.exists',
|
||||
enterprise_module='also_does_not_exist',
|
||||
)
|
||||
self.assertEqual(mode, AdapterMode.COMMUNITY)
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestBankRecAdapter(TransactionCase):
|
||||
"""Verify the bank-rec adapter returns rows in any install profile."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.journal = self.env['account.journal'].create({
|
||||
'name': 'Test Bank',
|
||||
'type': 'bank',
|
||||
'code': 'TBNK',
|
||||
})
|
||||
self.statement = self.env['account.bank.statement'].create({
|
||||
'name': 'Test Statement',
|
||||
'journal_id': self.journal.id,
|
||||
})
|
||||
self.line = self.env['account.bank.statement.line'].create({
|
||||
'statement_id': self.statement.id,
|
||||
'journal_id': self.journal.id,
|
||||
'date': '2026-04-18',
|
||||
'payment_ref': 'Test Payment',
|
||||
'amount': 100.0,
|
||||
})
|
||||
|
||||
def test_list_unreconciled_returns_our_test_line(self):
|
||||
"""The adapter should find the unreconciled line we just created."""
|
||||
adapter = get_adapter(self.env, 'bank_rec')
|
||||
rows = adapter.list_unreconciled(journal_id=self.journal.id, limit=10)
|
||||
ids = [r['id'] for r in rows]
|
||||
self.assertIn(self.line.id, ids,
|
||||
f"Expected line {self.line.id} in unreconciled list, got: {ids}")
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestReportsAdapter(TransactionCase):
|
||||
"""Verify the reports adapter computes a trial-balance-shaped result."""
|
||||
|
||||
def test_trial_balance_returns_rows_in_pure_community(self):
|
||||
adapter = get_adapter(self.env, 'reports')
|
||||
result = adapter.trial_balance()
|
||||
self.assertIsInstance(result, list)
|
||||
for row in result:
|
||||
self.assertIn('account_id', row)
|
||||
self.assertIn('balance', row)
|
||||
|
||||
def test_run_report_returns_lines_or_error_dict(self):
|
||||
"""run_report() must always return either an Enterprise-shaped
|
||||
{'report_name', 'lines'} dict or an {'error': ...} dict — never raise."""
|
||||
adapter = get_adapter(self.env, 'reports')
|
||||
result = adapter.run_report(ref_id='account_reports.profit_and_loss')
|
||||
self.assertIsInstance(result, dict)
|
||||
# Either a report_name+lines response or an error — both valid
|
||||
self.assertTrue(
|
||||
('lines' in result and 'report_name' in result) or 'error' in result,
|
||||
f"Unexpected result shape: {result!r}",
|
||||
)
|
||||
|
||||
def test_run_report_with_unknown_ref_returns_error(self):
|
||||
adapter = get_adapter(self.env, 'reports')
|
||||
result = adapter.run_report(ref_id='nonexistent.report.xml_id')
|
||||
self.assertIsInstance(result, dict)
|
||||
self.assertIn('error', result)
|
||||
|
||||
def test_export_report_returns_dict(self):
|
||||
adapter = get_adapter(self.env, 'reports')
|
||||
result = adapter.export_report(
|
||||
ref_id='account_reports.profit_and_loss', fmt='pdf',
|
||||
)
|
||||
self.assertIsInstance(result, dict)
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestFollowupAdapter(TransactionCase):
|
||||
def test_overdue_invoices_returns_list(self):
|
||||
adapter = get_adapter(self.env, 'followup')
|
||||
rows = adapter.overdue_invoices(days_overdue=30)
|
||||
self.assertIsInstance(rows, list)
|
||||
|
||||
def test_overdue_invoices_row_has_contact_fields(self):
|
||||
"""The enriched shape must include email, phone, and amount_total so
|
||||
the accounts_receivable tool wrapper can render them."""
|
||||
adapter = get_adapter(self.env, 'followup')
|
||||
rows = adapter.overdue_invoices(days_overdue=30, limit=5)
|
||||
for row in rows:
|
||||
for key in (
|
||||
'id', 'name', 'partner_id', 'partner_name',
|
||||
'partner_email', 'partner_phone',
|
||||
'invoice_date_due', 'amount_total', 'amount_residual',
|
||||
'days_overdue',
|
||||
):
|
||||
self.assertIn(key, row, f"Missing key {key!r} in overdue row")
|
||||
|
||||
def test_aged_receivables_returns_bucket_shape(self):
|
||||
adapter = get_adapter(self.env, 'followup')
|
||||
result = adapter.aged_receivables(company_id=self.env.company.id)
|
||||
self.assertIn('total', result)
|
||||
self.assertIn('buckets', result)
|
||||
self.assertIn('line_count', result)
|
||||
for bucket in ('current', '1_30', '31_60', '61_90', '90_plus'):
|
||||
self.assertIn(bucket, result['buckets'])
|
||||
|
||||
def test_aged_payables_returns_bucket_shape(self):
|
||||
adapter = get_adapter(self.env, 'followup')
|
||||
result = adapter.aged_payables(company_id=self.env.company.id)
|
||||
self.assertIn('total', result)
|
||||
self.assertIn('buckets', result)
|
||||
self.assertIn('line_count', result)
|
||||
for bucket in ('current', '1_30', '31_60', '61_90', '90_plus'):
|
||||
self.assertIn(bucket, result['buckets'])
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestAssetsAdapter(TransactionCase):
|
||||
def test_list_assets_returns_dict_with_assets(self):
|
||||
# Phase 3 (fusion_accounting_assets) wired list_assets to return
|
||||
# {count, total, assets} — consistent with bank_rec.list_unreconciled etc.
|
||||
adapter = get_adapter(self.env, 'assets')
|
||||
rows = adapter.list_assets()
|
||||
self.assertIsInstance(rows, dict)
|
||||
self.assertIn('assets', rows)
|
||||
self.assertIsInstance(rows['assets'], list)
|
||||
Reference in New Issue
Block a user