import json import os import subprocess import tempfile import textwrap import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] GO_RUNTIME_TEST = r''' package formula import ( "strings" "testing" "time" ) func TestL2HubSpotLeadDateMixedRepresentationTransforms(t *testing.T) { engine := NewEngine() transforms := map[string]struct { sourceField string expression string }{ __L2_TRANSFORM_CASES__ } const epochMillis = int64(1784263333123) wantISO := time.Date(2026, 7, 17, 4, 42, 13, 123000000, time.UTC) wantEpoch := time.UnixMilli(epochMillis).UTC() for transformName, transform := range transforms { t.Run(transformName, func(t *testing.T) { for _, tc := range []struct { name string value interface{} want *time.Time wantErrorContains string }{ {name: "hydrated ISO string uses lazy datetime branch", value: "2026-07-17T04:42:13.123Z", want: &wantISO}, {name: "decimal epoch string uses epoch branch", value: "1784263333123", want: &wantEpoch}, {name: "numeric coalesced value uses epoch branch", value: epochMillis, want: &wantEpoch}, {name: "blank string remains null", value: ""}, {name: "null remains null", value: nil}, {name: "malformed nonblank fails closed", value: "not-a-datetime-or-epoch", wantErrorContains: "integral epoch-millisecond"}, } { t.Run(tc.name, func(t *testing.T) { got, err := engine.Evaluate(transform.expression, &Context{Record: map[string]interface{}{transform.sourceField: tc.value}}) if tc.wantErrorContains != "" { if err == nil || !strings.Contains(err.Error(), tc.wantErrorContains) { t.Fatalf("Evaluate error = %v, want substring %q", err, tc.wantErrorContains) } return } if err != nil { t.Fatalf("Evaluate error = %v, want nil", err) } if tc.want == nil { if got != nil { t.Fatalf("Evaluate = %#v, want nil", got) } return } gotTime, ok := got.(time.Time) if !ok || !gotTime.Equal(*tc.want) { t.Fatalf("Evaluate = %#v, want %s", got, tc.want.Format(time.RFC3339Nano)) } }) } }) } for _, value := range []interface{}{"1784263333123", epochMillis, "", nil} { got, err := engine.Evaluate(`DATETIMEVALUE($Record.Value)`, &Context{Record: map[string]interface{}{"Value": value}}) if err != nil || got != nil { t.Fatalf("DATETIMEVALUE(%#v) = %#v, %v; want nil, nil", value, got, err) } } } ''' class HubSpotLeadDateFormulaRuntimeTest(unittest.TestCase): def test_current_l0_evaluator_executes_mixed_representation_contract(self): nexuscrm_root = os.environ.get("NEXUSCRM_ROOT") if not nexuscrm_root: self.fail("NEXUSCRM_ROOT must point to the exact NexusCRM checkout under test") upstream = Path(nexuscrm_root).resolve() formula_dir = upstream / "nexuscrm-kernel" / "pkg" / "formula" self.assertTrue(formula_dir.is_dir(), f"formula package not found under {upstream}") expected_head = os.environ.get("NEXUSCRM_EXPECTED_HEAD") if expected_head: actual_head = subprocess.check_output( ["git", "rev-parse", "HEAD"], cwd=upstream, text=True ).strip() self.assertEqual(actual_head, expected_head) mapping_path = ( REPO_ROOT / "packs" / "PingCAP-HubSpot-Companion" / "field_mappings" / "contact_lead_inbound.json" ) mapping_groups = json.loads(mapping_path.read_text(encoding="utf-8")) full_group = next( group for group in mapping_groups if group["actionType"] == "hubspotContactLeadInbound" ) date_sources = { "hs_v2_date_entered_lead": "hubspotContactLeadInboundDeltaHsV2DateEnteredLead", "hs_v2_date_entered_subscriber": "hubspotContactLeadInboundDeltaHsV2DateEnteredSubscriber", "agreement_time__c": "hubspotContactLeadInboundDeltaAgreementTimeC", "created_at__c": "hubspotContactLeadInboundDeltaCreatedAtC", "tied_card_time__c": "hubspotContactLeadInboundDeltaTiedCardTimeC", } transform_cases = [] for source_field, delta_action in date_sources.items(): delta_group = next( group for group in mapping_groups if group["actionType"] == delta_action ) for mode, group in (("full", full_group), ("delta", delta_group)): transform = next( mapping["transformExpression"] for mapping in group["mappings"] if mapping["sourceField"] == source_field ) transform_cases.append( f"\t\t{json.dumps(source_field + '/' + mode)}: " f"{{{json.dumps(source_field)}, {json.dumps(transform)}}}," ) with tempfile.TemporaryDirectory(prefix="nexuscrm-l2-formula-") as temp_dir: temp = Path(temp_dir) backing_test = temp / "l2_hubspot_disqualified_date_test.go" backing_test.write_text( textwrap.dedent(GO_RUNTIME_TEST) .replace("__L2_TRANSFORM_CASES__", "\n".join(transform_cases)), encoding="utf-8", ) overlay_target = formula_dir / "l2_hubspot_disqualified_date_test.go" overlay = temp / "overlay.json" overlay.write_text( json.dumps({"Replace": {str(overlay_target): str(backing_test)}}), encoding="utf-8", ) completed = subprocess.run( [ "go", "test", f"-overlay={overlay}", "./pkg/formula", "-run", "^TestL2HubSpotLeadDateMixedRepresentationTransforms$", "-count=1", ], cwd=upstream / "nexuscrm-kernel", env={**os.environ, "GOWORK": "off"}, text=True, capture_output=True, check=False, ) self.assertEqual( completed.returncode, 0, f"go test failed\nstdout:\n{completed.stdout}\nstderr:\n{completed.stderr}", ) if __name__ == "__main__": unittest.main()