75 lines
3.0 KiB
Python
75 lines
3.0 KiB
Python
"""Unit tests for anomaly_detection service."""
|
|
|
|
from odoo.tests.common import TransactionCase, tagged
|
|
from odoo.addons.fusion_accounting_reports.services.anomaly_detection import detect
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestAnomalyDetection(TransactionCase):
|
|
|
|
def test_returns_empty_when_no_comparison(self):
|
|
report_result = {
|
|
'rows': [{'id': 'r1', 'label': 'Test', 'amount': 100,
|
|
'amount_comparison': None, 'variance_pct': None}],
|
|
'comparison_period': None,
|
|
}
|
|
self.assertEqual(detect(report_result), [])
|
|
|
|
def test_flags_significant_increase(self):
|
|
report_result = {
|
|
'rows': [{'id': 'r1', 'label': 'Revenue',
|
|
'amount': 12000, 'amount_comparison': 10000,
|
|
'variance_pct': 20.0}],
|
|
'comparison_period': {'date_from': '2025-01-01'},
|
|
}
|
|
anomalies = detect(report_result)
|
|
self.assertEqual(len(anomalies), 1)
|
|
self.assertEqual(anomalies[0]['direction'], 'increase')
|
|
self.assertEqual(anomalies[0]['variance_amount'], 2000)
|
|
|
|
def test_skips_below_absolute_threshold(self):
|
|
report_result = {
|
|
'rows': [{'id': 'r1', 'label': 'Tiny', 'amount': 50,
|
|
'amount_comparison': 30, 'variance_pct': 67}],
|
|
'comparison_period': {'date_from': '2025-01-01'},
|
|
}
|
|
# variance is $20 < default $100 minimum
|
|
self.assertEqual(detect(report_result), [])
|
|
|
|
def test_skips_below_pct_threshold(self):
|
|
report_result = {
|
|
'rows': [{'id': 'r1', 'label': 'Steady',
|
|
'amount': 10500, 'amount_comparison': 10000,
|
|
'variance_pct': 5.0}],
|
|
'comparison_period': {'date_from': '2025-01-01'},
|
|
}
|
|
# 5% < default 10%
|
|
self.assertEqual(detect(report_result), [])
|
|
|
|
def test_severity_high_for_50pct_plus(self):
|
|
report_result = {
|
|
'rows': [{'id': 'r1', 'label': 'Spike',
|
|
'amount': 16000, 'amount_comparison': 10000,
|
|
'variance_pct': 60.0}],
|
|
'comparison_period': {'date_from': '2025-01-01'},
|
|
}
|
|
anomalies = detect(report_result)
|
|
self.assertEqual(anomalies[0]['severity'], 'high')
|
|
|
|
def test_orders_by_severity_then_amount(self):
|
|
report_result = {
|
|
'rows': [
|
|
{'id': 'r1', 'label': 'Med', 'amount': 1300,
|
|
'amount_comparison': 1000, 'variance_pct': 30.0},
|
|
{'id': 'r2', 'label': 'High', 'amount': 16000,
|
|
'amount_comparison': 10000, 'variance_pct': 60.0},
|
|
{'id': 'r3', 'label': 'Low', 'amount': 1150,
|
|
'amount_comparison': 1000, 'variance_pct': 15.0},
|
|
],
|
|
'comparison_period': {'date_from': '2025-01-01'},
|
|
}
|
|
anomalies = detect(report_result)
|
|
# Should be: High first, then Med, then Low
|
|
self.assertEqual(anomalies[0]['severity'], 'high')
|
|
self.assertEqual(anomalies[-1]['severity'], 'low')
|