from __future__ import annotations import unittest import argparse from scripts.probe_derived_field_consistency import ( RollupSpec, Violation, check_opp_rate, check_rollup_headers, display_id, group_children, iso_date, parse_rollup_specs, ) def _spec(parent_field, calc_type="SUM", summary_field="Net_fees__c", parent_object="Quote", summary_object="QuoteLineItem", relationship_field="QuoteId"): return RollupSpec( parent_object=parent_object, parent_field=parent_field, calc_type=calc_type, summary_object=summary_object, summary_field=summary_field, relationship_field=relationship_field, ) QUOTE_SPECS = [_spec("TCV_Amount_c__c"), _spec("NetFees__c")] ORDER_SPECS = [ _spec("Net_Fees__c", summary_field="Net_fees__c", parent_object="Order", summary_object="OrderItem", relationship_field="OrderId"), _spec("TotalAmount", summary_field="TotalPrice", parent_object="Order", summary_object="OrderItem", relationship_field="OrderId"), _spec("Count_Product_Lines__c", calc_type="COUNT", summary_field="*", parent_object="Order", summary_object="OrderItem", relationship_field="OrderId"), ] def _quote(qid: str, tcv, net): return {"Id": qid, "TCV_Amount_c__c": tcv, "NetFees__c": net} def _qli(qid: str, net): return {"Id": f"{qid}-l", "QuoteId": qid, "Net_fees__c": net} class QuoteMoneyTest(unittest.TestCase): def _check(self, quotes, lines): return check_rollup_headers("quote-money", quotes, lines, QUOTE_SPECS) def test_matching_rollup_passes(self) -> None: quotes = [_quote("Q1", "600.00", "600.00")] lines = group_children( [_qli("Q1", "400"), {"Id": "x", "QuoteId": "Q1", "Net_fees__c": "200"}], "QuoteId" ) result = self._check(quotes, lines) self.assertEqual(result.parents_checked, 1) self.assertEqual(result.violations, []) def test_blank_header_with_children_is_a_violation(self) -> None: quotes = [_quote("Q1", None, None)] result = self._check(quotes, group_children([_qli("Q1", "100")], "QuoteId")) self.assertEqual({v.check for v in result.violations}, {"TCV_Amount_c__c", "NetFees__c"}) def test_drifted_header_beyond_tolerance_is_a_violation(self) -> None: quotes = [_quote("Q1", "100.02", "100.00")] result = self._check(quotes, group_children([_qli("Q1", "100.00")], "QuoteId")) self.assertEqual([v.check for v in result.violations], ["TCV_Amount_c__c"]) def test_drift_exactly_at_tolerance_is_a_violation(self) -> None: quotes = [_quote("Q1", "100.01", "100.01")] result = self._check(quotes, group_children([_qli("Q1", "100.00")], "QuoteId")) self.assertEqual({v.check for v in result.violations}, {"TCV_Amount_c__c", "NetFees__c"}) def test_sub_tolerance_drift_passes(self) -> None: quotes = [_quote("Q1", "100.005", "100.00")] result = self._check(quotes, group_children([_qli("Q1", "100.00")], "QuoteId")) self.assertEqual(result.violations, []) def test_all_null_children_accept_null_or_zero_header(self) -> None: lines = group_children([_qli("Q1", None), _qli("Q2", None)], "QuoteId") ok = self._check([_quote("Q1", None, "0")], lines) self.assertEqual(ok.violations, []) bad = self._check([_quote("Q2", "50", None)], lines) self.assertEqual([v.check for v in bad.violations], ["TCV_Amount_c__c"]) def test_childless_quote_with_blank_or_zero_headers_passes(self) -> None: result = self._check([_quote("Q1", None, "0")], {}) self.assertEqual(result.parents_checked, 1) self.assertEqual(result.violations, []) def test_childless_quote_with_stale_nonzero_header_is_a_violation(self) -> None: result = self._check([_quote("Q1", "500", None)], {}) self.assertEqual([v.check for v in result.violations], ["TCV_Amount_c__c"]) class ConfigDrivenColumnTest(unittest.TestCase): """The summary column must come from the spec, not from any restatement: the same data must pass under one spec and fail under a re-sourced one.""" def test_re_sourced_spec_changes_the_checked_column(self) -> None: lines = group_children( [{"Id": "l1", "QuoteId": "Q1", "Net_fees__c": "100", "Net_Fees_Total__c": "999"}], "QuoteId", ) quotes = [_quote("Q1", "100", "100")] old = check_rollup_headers("quote-money", quotes, lines, QUOTE_SPECS) self.assertEqual(old.violations, []) re_sourced = [ _spec("TCV_Amount_c__c", summary_field="Net_Fees_Total__c"), _spec("NetFees__c", summary_field="Net_Fees_Total__c"), ] new = check_rollup_headers("quote-money", quotes, lines, re_sourced) self.assertEqual( {v.check for v in new.violations}, {"TCV_Amount_c__c", "NetFees__c"} ) def test_count_is_row_count_regardless_of_named_summary_nulls(self) -> None: # The engine's recompute is COUNT(*) whatever summaryField says # (installs canonicalize named COUNT columns to '*'); a probe that # counted non-null values would flag correct data as violated. specs = [ _spec("Count_Product_Lines__c", calc_type="COUNT", summary_field="Net_fees__c", parent_object="Order", summary_object="OrderItem", relationship_field="OrderId") ] items = group_children( [ {"Id": "i1", "OrderId": "O1", "Net_fees__c": "5"}, {"Id": "i2", "OrderId": "O1", "Net_fees__c": None}, ], "OrderId", ) ok = check_rollup_headers( "order-headers", [{"Id": "O1", "Count_Product_Lines__c": "2"}], items, specs ) self.assertEqual(ok.violations, []) bad = check_rollup_headers( "order-headers", [{"Id": "O1", "Count_Product_Lines__c": "1"}], items, specs ) self.assertEqual([v.check for v in bad.violations], ["Count_Product_Lines__c"]) def test_blank_count_with_children_is_a_violation(self) -> None: specs = [ _spec("Count_Product_Lines__c", calc_type="COUNT", summary_field="*", parent_object="Order", summary_object="OrderItem", relationship_field="OrderId") ] items = group_children([{"Id": "i1", "OrderId": "O1"}], "OrderId") bad = check_rollup_headers( "order-headers", [{"Id": "O1", "Count_Product_Lines__c": None}], items, specs ) self.assertEqual([v.check for v in bad.violations], ["Count_Product_Lines__c"]) def test_identifier_validation_fails_closed_on_malformed_config_values(self) -> None: base = { "calcType": "SUM", "summaryObject": "QuoteLineItem", "summaryField": "Net_fees__c", "relationshipField": "QuoteId", } for key, value in ( ("relationshipField", "OrderId "), ("summaryField", "Net_fees__c'; DROP"), ("summaryObject", "Quote Line"), ): config = dict(base) config[key] = value with self.assertRaisesRegex(SystemExit, "not a plain identifier"): parse_rollup_specs( "Quote", ("NetFees__c",), [{"Id": "f", "ApiName": "NetFees__c", "RollupConfig": config}], ) def test_minmax_date_rollups(self) -> None: specs = [ _spec("Overall_Start_Date__c", calc_type="MIN", summary_field="Service_Start_Date__c"), _spec("Overall_End_Date__c", calc_type="MAX", summary_field="Service_End_Date__c"), ] lines = group_children( [ {"Id": "l1", "QuoteId": "Q1", "Service_Start_Date__c": "2026-10-26", "Service_End_Date__c": "2027-10-25"}, {"Id": "l2", "QuoteId": "Q1", "Service_Start_Date__c": "2026-11-01", "Service_End_Date__c": None}, ], "QuoteId", ) ok = check_rollup_headers( "quote-money", [{"Id": "Q1", "Overall_Start_Date__c": "2026-10-26", "Overall_End_Date__c": "2027-10-25"}], lines, specs, ) self.assertEqual(ok.violations, []) stale = check_rollup_headers( "quote-money", [{"Id": "Q1", "Overall_Start_Date__c": None, "Overall_End_Date__c": "2027-10-25"}], lines, specs, ) self.assertEqual([v.check for v in stale.violations], ["Overall_Start_Date__c"]) def test_minmax_empty_children_require_blank_header(self) -> None: specs = [_spec("Overall_End_Date__c", calc_type="MAX", summary_field="Service_End_Date__c")] ok = check_rollup_headers( "quote-money", [{"Id": "Q1", "Overall_End_Date__c": None}], {}, specs ) self.assertEqual(ok.violations, []) stale = check_rollup_headers( "quote-money", [{"Id": "Q1", "Overall_End_Date__c": "2027-01-01"}], {}, specs ) self.assertEqual([v.check for v in stale.violations], ["Overall_End_Date__c"]) def test_min_numeric_domain(self) -> None: specs = [_spec("Cheapest__c", calc_type="MIN", summary_field="Discount__c")] lines = group_children( [{"Id": "l1", "QuoteId": "Q1", "Discount__c": "30"}, {"Id": "l2", "QuoteId": "Q1", "Discount__c": "9"}], "QuoteId", ) ok = check_rollup_headers( "quote-money", [{"Id": "Q1", "Cheapest__c": "9"}], lines, specs ) self.assertEqual(ok.violations, []) bad = check_rollup_headers( "quote-money", [{"Id": "Q1", "Cheapest__c": "30"}], lines, specs ) self.assertEqual([v.check for v in bad.violations], ["Cheapest__c"]) def test_minmax_numeric_domain_uses_decimal_compare(self) -> None: specs = [_spec("Deepest__c", calc_type="MAX", summary_field="Discount__c")] lines = group_children( [{"Id": "l1", "QuoteId": "Q1", "Discount__c": "30"}, {"Id": "l2", "QuoteId": "Q1", "Discount__c": "9"}], "QuoteId", ) ok = check_rollup_headers( "quote-money", [{"Id": "Q1", "Deepest__c": "30.0"}], lines, specs ) self.assertEqual(ok.violations, []) # string compare would call "9" > "30"; Decimal domain must win bad = check_rollup_headers( "quote-money", [{"Id": "Q1", "Deepest__c": "9"}], lines, specs ) self.assertEqual([v.check for v in bad.violations], ["Deepest__c"]) _SYNC_BASE = { "calcType": "SUM", "summaryObject": "QuoteLineItem", "summaryField": "Net_fees__c", "relationshipField": "QuoteId", } def test_eventual_maintenance_mode_fails_closed(self) -> None: config = dict(self._SYNC_BASE, maintenanceMode="eventual") with self.assertRaisesRegex(SystemExit, "delta queue"): parse_rollup_specs( "Quote", ("NetFees__c",), [{"Id": "f", "ApiName": "NetFees__c", "RollupConfig": config}], ) def test_synchronous_or_absent_maintenance_mode_passes(self) -> None: for mode in (None, "", "synchronous", "SYNCHRONOUS"): config = dict(self._SYNC_BASE) if mode is not None: config["maintenanceMode"] = mode specs = parse_rollup_specs( "Quote", ("NetFees__c",), [{"Id": "f", "ApiName": "NetFees__c", "RollupConfig": config}], ) self.assertEqual(specs[0].summary_field, "Net_fees__c", mode) def test_duplicate_metadata_rows_fail_closed(self) -> None: config = { "calcType": "SUM", "summaryObject": "QuoteLineItem", "summaryField": "Net_fees__c", "relationshipField": "QuoteId", } rows = [ {"Id": "f1", "ApiName": "NetFees__c", "RollupConfig": config}, {"Id": "f2", "ApiName": "NetFees__c", "RollupConfig": config}, ] with self.assertRaisesRegex(SystemExit, "multiple live"): parse_rollup_specs("Quote", ("NetFees__c",), rows) class SpecParsingTest(unittest.TestCase): def _row(self, name, config): return {"Id": f"fld_{name}", "ApiName": name, "RollupConfig": config} GOOD = { "calcType": "SUM", "summaryObject": "QuoteLineItem", "summaryField": "Net_fees__c", "relationshipField": "QuoteId", } def test_good_config_parses(self) -> None: specs = parse_rollup_specs("Quote", ("NetFees__c",), [self._row("NetFees__c", self.GOOD)]) self.assertEqual( specs, [ RollupSpec( parent_object="Quote", parent_field="NetFees__c", calc_type="SUM", summary_object="QuoteLineItem", summary_field="Net_fees__c", relationship_field="QuoteId", ) ], ) def test_count_star_parses(self) -> None: config = dict(self.GOOD, calcType="COUNT", summaryField="*") specs = parse_rollup_specs("Order", ("N__c",), [self._row("N__c", config)]) self.assertEqual(specs[0].calc_type, "COUNT") self.assertEqual(specs[0].summary_field, "*") def test_missing_config_fails_closed(self) -> None: with self.assertRaisesRegex(SystemExit, "no RollupConfig"): parse_rollup_specs("Quote", ("NetFees__c",), [self._row("NetFees__c", None)]) def test_absent_field_row_fails_closed(self) -> None: with self.assertRaisesRegex(SystemExit, "no _System_Field row"): parse_rollup_specs("Quote", ("NetFees__c",), []) def test_string_encoded_config_parses(self) -> None: import json as _json specs = parse_rollup_specs( "Quote", ("NetFees__c",), [self._row("NetFees__c", _json.dumps(self.GOOD))] ) self.assertEqual(specs[0].summary_field, "Net_fees__c") def test_malformed_string_config_fails_closed(self) -> None: with self.assertRaisesRegex(SystemExit, "not valid JSON"): parse_rollup_specs("Quote", ("NetFees__c",), [self._row("NetFees__c", "{nope")]) def test_filtered_rollup_fails_closed(self) -> None: config = dict(self.GOOD, filter="Status__c = 'Received'") with self.assertRaisesRegex(SystemExit, "filter"): parse_rollup_specs("Quote", ("NetFees__c",), [self._row("NetFees__c", config)]) def test_unsupported_calc_type_fails_closed(self) -> None: for calc in ("AVG", ""): config = dict(self.GOOD, calcType=calc) with self.assertRaisesRegex(SystemExit, "not supported"): parse_rollup_specs("Quote", ("NetFees__c",), [self._row("NetFees__c", config)]) def test_missing_source_fields_fail_closed(self) -> None: for key in ("summaryObject", "relationshipField", "summaryField"): config = dict(self.GOOD) config[key] = "" with self.assertRaises(SystemExit, msg=key): parse_rollup_specs("Quote", ("NetFees__c",), [self._row("NetFees__c", config)]) def test_sum_over_star_fails_closed(self) -> None: config = dict(self.GOOD, summaryField="*") with self.assertRaisesRegex(SystemExit, "not a checkable"): parse_rollup_specs("Quote", ("NetFees__c",), [self._row("NetFees__c", config)]) class OrderHeadersTest(unittest.TestCase): def _order(self, oid: str, net, total, count): return {"Id": oid, "Net_Fees__c": net, "TotalAmount": total, "Count_Product_Lines__c": count} def _item(self, oid: str, net, price): return {"Id": f"{oid}-i", "OrderId": oid, "Net_fees__c": net, "TotalPrice": price} def _check(self, orders, items): return check_rollup_headers("order-headers", orders, items, ORDER_SPECS) def test_consistent_order_passes(self) -> None: items = group_children([self._item("O1", "10", "12"), self._item("O1", "5", "6")], "OrderId") result = self._check([self._order("O1", "15", "18", "2")], items) self.assertEqual(result.violations, []) def test_each_broken_pair_is_reported(self) -> None: items = group_children([self._item("O1", "10", "12")], "OrderId") result = self._check([self._order("O1", None, "99", None)], items) self.assertEqual( {v.check for v in result.violations}, {"Net_Fees__c", "TotalAmount", "Count_Product_Lines__c"}, ) def test_childless_order_with_stale_headers_is_a_violation(self) -> None: result = self._check([self._order("O1", "35.84", None, "1")], {}) self.assertEqual( {v.check for v in result.violations}, {"Net_Fees__c", "Count_Product_Lines__c"}, ) def test_childless_order_with_blank_or_zero_headers_passes(self) -> None: result = self._check([self._order("O1", None, "0", None)], {}) self.assertEqual(result.parents_checked, 1) self.assertEqual(result.violations, []) def test_count_must_match_exactly(self) -> None: items = group_children([self._item("O1", "1", "1"), self._item("O1", "1", "1")], "OrderId") result = self._check([self._order("O1", "2", "2", "1")], items) self.assertEqual([v.check for v in result.violations], ["Count_Product_Lines__c"]) def test_fractional_count_is_a_violation_not_truncated(self) -> None: items = group_children([self._item("O1", "1", "1")], "OrderId") result = self._check([self._order("O1", "1", "1", "1.5")], items) self.assertEqual([v.check for v in result.violations], ["Count_Product_Lines__c"]) class OppRateTest(unittest.TestCase): def _opp(self, oid: str, currency, rate, modified): return { "Id": oid, "CurrencyIsoCode": currency, "Rate__c": rate, "LastModifiedDate": modified, } def test_non_usd_saved_after_since_without_rate_is_a_violation(self) -> None: opps = [self._opp("A", "JPY", None, "2026-08-02T10:00:00.000Z")] result = check_opp_rate(opps, since="2026-08-01T00:00:00") self.assertEqual(len(result.violations), 1) def test_saved_exactly_at_since_is_a_violation(self) -> None: opps = [self._opp("A", "JPY", None, "2026-08-01T00:00:00.000Z")] result = check_opp_rate(opps, since="2026-08-01T00:00:00") self.assertEqual(len(result.violations), 1) def test_non_usd_saved_before_since_is_dormant_not_violation(self) -> None: opps = [self._opp("A", "JPY", None, "2026-07-01T10:00:00.000Z")] result = check_opp_rate(opps, since="2026-08-01T00:00:00") self.assertEqual(result.violations, []) self.assertEqual(result.info["dormant_blank_non_usd"], 1) def test_without_since_blanks_are_dormant(self) -> None: opps = [self._opp("A", "CNY", None, "2026-08-02T10:00:00.000Z")] result = check_opp_rate(opps, since=None) self.assertEqual(result.violations, []) self.assertEqual(result.info["dormant_blank_non_usd"], 1) def test_usd_and_stamped_rows_pass(self) -> None: opps = [ self._opp("A", "USD", None, "2026-08-02T10:00:00.000Z"), self._opp("B", "JPY", "156.658", "2026-08-02T10:00:00.000Z"), ] result = check_opp_rate(opps, since="2026-08-01T00:00:00") self.assertEqual(result.violations, []) self.assertEqual(result.parents_checked, 1) class SinceValidationTest(unittest.TestCase): def test_valid_iso_date_passes_through(self) -> None: self.assertEqual(iso_date("2026-08-01"), "2026-08-01") def test_malformed_dates_fail_closed(self) -> None: for raw in ("2026-8-1", "last-month", "2026/08/01", "20260801x"): with self.assertRaises(argparse.ArgumentTypeError, msg=raw): iso_date(raw) class RedactionTest(unittest.TestCase): UUID = "178d3617-a3d6-40a4-be4a-1aed42239149" def test_ids_are_redacted_by_default(self) -> None: self.assertEqual(display_id(self.UUID, show_ids=False), "178d3617…") v = Violation("s", self.UUID, "c", None, "1") self.assertEqual(v.as_dict()["id"], "178d3617…") self.assertNotIn(self.UUID, str(v.as_dict())) def test_opt_in_shows_full_id(self) -> None: self.assertEqual(display_id(self.UUID, show_ids=True), self.UUID) self.assertEqual(Violation("s", self.UUID, "c", None, "1").as_dict(True)["id"], self.UUID) if __name__ == "__main__": unittest.main()