"""Smoke tests for the fusion_unreconciled_bank_line_mv materialized view. NOTE on the explicit ``self.env.cr.commit()`` calls below: PostgreSQL's ``REFRESH MATERIALIZED VIEW`` only sees data from *committed* transactions. ``TransactionCase`` rolls back at the end of each test, so without an explicit commit the freshly-inserted bank line would not be visible to the refresh and the assertions would fail. The trade-off is that the records we create *are* persisted; we therefore unlink them in a ``finally`` block to keep test isolation. If this proves too brittle later we can convert this case to extend ``BaseCase`` (no rollback) and clean up explicitly. For Phase 1 the commit-+-finally pattern is the simpler choice. """ from odoo.tests.common import TransactionCase, tagged from . import _factories as f @tagged('post_install', '-at_install') class TestUnreconciledBankLineMV(TransactionCase): def setUp(self): super().setUp() self.partner = self.env['res.partner'].create({ 'name': 'MV Test Partner', }) # Force a refresh so we see freshly-inserted lines from prior tests. # First refresh after creation may need to be blocking; the # _refresh helper handles fallback automatically. self.env['fusion.unreconciled.bank.line.mv']._refresh( concurrently=False) def test_mv_exists_and_is_queryable(self): # Smoke: the model can be searched without error. rows = self.env['fusion.unreconciled.bank.line.mv'].search( [], limit=10) self.assertIsNotNone(rows) def test_mv_includes_unreconciled_line(self): bank_line = f.make_bank_line( self.env, amount=999.99, partner=self.partner) # MV refresh sees committed data only; commit, refresh, assert, # then unlink to keep test isolation. self.env.cr.commit() try: self.env['fusion.unreconciled.bank.line.mv']._refresh( concurrently=False) mv_row = self.env['fusion.unreconciled.bank.line.mv'].search([ ('id', '=', bank_line.id), ]) self.assertTrue( mv_row, "MV should contain freshly-inserted unreconciled line") self.assertAlmostEqual(mv_row.amount, 999.99, places=2) # No suggestion yet -> band 'none', confidence 0. self.assertEqual(mv_row.confidence_band, 'none') self.assertEqual(mv_row.attachment_count, 0) finally: bank_line.unlink() self.env.cr.commit() def test_mv_excludes_reconciled_line(self): bank_line, recv_lines = f.make_reconcileable_pair( self.env, amount=100.00, partner=self.partner) self.env['fusion.reconcile.engine'].reconcile_one( bank_line, against_lines=recv_lines) self.env.cr.commit() try: self.env['fusion.unreconciled.bank.line.mv']._refresh( concurrently=False) mv_row = self.env['fusion.unreconciled.bank.line.mv'].search([ ('id', '=', bank_line.id), ]) self.assertFalse( mv_row, "Reconciled line should be excluded from MV") finally: # Best-effort unwind for test isolation. Use the engine's # standard undo path since reconcile_one rewrites the bank # move's line_ids. try: bank_line.action_undo_reconciliation() except Exception: pass try: bank_line.unlink() except Exception: pass self.env.cr.commit() def test_mv_confidence_band_high_for_high_conf_suggestion(self): bank_line = f.make_bank_line( self.env, amount=500.00, partner=self.partner) f.make_suggestion( self.env, statement_line=bank_line, confidence=0.92) self.env.cr.commit() try: self.env['fusion.unreconciled.bank.line.mv']._refresh( concurrently=False) mv_row = self.env['fusion.unreconciled.bank.line.mv'].search([ ('id', '=', bank_line.id), ]) self.assertTrue(mv_row, "MV row should exist for suggestion line") # 0.92 falls in the 'high' band per the SQL CASE (>= 0.85). self.assertEqual(mv_row.confidence_band, 'high') self.assertAlmostEqual(mv_row.top_confidence, 0.92, places=2) finally: # Unlink suggestion first (cascade would handle it but explicit # is safer if the test order reuses partner records). self.env['fusion.reconcile.suggestion'].search([ ('statement_line_id', '=', bank_line.id), ]).unlink() bank_line.unlink() self.env.cr.commit()