package tender import ( "testing" "go.mongodb.org/mongo-driver/v2/bson" ) func TestParseAIProcedureRef(t *testing.T) { tests := []struct { ref string folder string notice string ok bool }{ { ref: "PROC_055329e0-3d8f-4eeb-946a-85a451f2e36b/00423458-2026", folder: "055329e0-3d8f-4eeb-946a-85a451f2e36b", notice: "00423458-2026", ok: true, }, { ref: "proc_d3d34785-e10f-4947-8d00-701816777bf5/00332053-2026", folder: "d3d34785-e10f-4947-8d00-701816777bf5", notice: "00332053-2026", ok: true, }, {ref: "", ok: false}, {ref: "507f1f77bcf86cd799439011", ok: false}, {ref: "PROC_no-slash", ok: false}, } for _, tt := range tests { folder, notice, ok := ParseAIProcedureRef(tt.ref) if ok != tt.ok { t.Fatalf("ParseAIProcedureRef(%q) ok=%v want %v", tt.ref, ok, tt.ok) } if !tt.ok { continue } if folder != tt.folder || notice != tt.notice { t.Fatalf("ParseAIProcedureRef(%q) = (%q, %q) want (%q, %q)", tt.ref, folder, notice, tt.folder, tt.notice) } } } func TestFormatAIProcedureRef(t *testing.T) { got := FormatAIProcedureRef("055329e0-3d8f-4eeb-946a-85a451f2e36b", "00423458-2026") want := "PROC_055329e0-3d8f-4eeb-946a-85a451f2e36b/00423458-2026" if got != want { t.Fatalf("FormatAIProcedureRef() = %q want %q", got, want) } } func TestMapProcedureReferencesToTenders(t *testing.T) { candidates := []Tender{ { ContractFolderID: "folder-1", NoticePublicationID: "notice-new", RelatedNoticePublicationIDs: []string{"notice-old"}, }, { ContractFolderID: "folder-1", NoticePublicationID: "notice-legacy", }, { ContractFolderID: "folder-2", NoticePublicationID: "notice-2", }, } refs := []ProcedureReference{ {Ref: "PROC_folder-1/notice-old", ContractFolderID: "folder-1", NoticePublicationID: "notice-old"}, {Ref: "PROC_folder-1/notice-legacy", ContractFolderID: "folder-1", NoticePublicationID: "notice-legacy"}, {Ref: "PROC_folder-2/notice-2", ContractFolderID: "folder-2", NoticePublicationID: "notice-2"}, } got := mapProcedureReferencesToTenders(candidates, refs) if len(got) != 3 { t.Fatalf("mapProcedureReferencesToTenders() len = %d, want 3", len(got)) } if got["PROC_folder-1/notice-old"].NoticePublicationID != "notice-new" { t.Fatalf("expected notice-old ref to resolve to latest merged tender, got %+v", got["PROC_folder-1/notice-old"]) } if got["PROC_folder-1/notice-legacy"].NoticePublicationID != "notice-legacy" { t.Fatalf("expected legacy ref to resolve to legacy tender, got %+v", got["PROC_folder-1/notice-legacy"]) } if got["PROC_folder-2/notice-2"].NoticePublicationID != "notice-2" { t.Fatalf("expected folder-2 ref to resolve, got %+v", got["PROC_folder-2/notice-2"]) } } func TestMapProcedureReferencesToTendersUsesFolderCandidatesWhenNoticeLookupMisses(t *testing.T) { // Notice-old is only present on the merged tender loaded via contract_folder_id. candidates := []Tender{ { ContractFolderID: "folder-1", NoticePublicationID: "notice-new", RelatedNoticePublicationIDs: []string{"notice-old"}, }, } refs := []ProcedureReference{ {Ref: "PROC_folder-1/notice-old", ContractFolderID: "folder-1", NoticePublicationID: "notice-old"}, } got := mapProcedureReferencesToTenders(candidates, refs) if len(got) != 1 { t.Fatalf("mapProcedureReferencesToTenders() len = %d, want 1", len(got)) } if got["PROC_folder-1/notice-old"].NoticePublicationID != "notice-new" { t.Fatalf("expected folder candidate to resolve notice-old ref, got %+v", got["PROC_folder-1/notice-old"]) } } func TestMergeTenderCandidatesDedupesByMongoID(t *testing.T) { first := Tender{ContractFolderID: "folder-1", NoticePublicationID: "notice-a"} first.ID, _ = bson.ObjectIDFromHex("507f1f77bcf86cd799439011") second := Tender{ContractFolderID: "folder-1", NoticePublicationID: "notice-b"} second.ID = first.ID got := mergeTenderCandidates([]Tender{first}, []Tender{second}) if len(got) != 1 { t.Fatalf("mergeTenderCandidates() len = %d, want 1", len(got)) } }