package tender import "testing" func TestAggregateProcurementLotEstimatedValue(t *testing.T) { value, currency := AggregateProcurementLotEstimatedValue([]ProcurementLot{ {EstimatedValue: 100000, Currency: "EUR"}, {EstimatedValue: 250000, Currency: "EUR"}, }) if value != 350000 { t.Fatalf("expected total 350000, got %v", value) } if currency != "EUR" { t.Fatalf("expected currency EUR, got %q", currency) } } func TestAggregateProcurementLotEstimatedValueRejectsMixedCurrencies(t *testing.T) { value, currency := AggregateProcurementLotEstimatedValue([]ProcurementLot{ {EstimatedValue: 100000, Currency: "EUR"}, {EstimatedValue: 250000, Currency: "USD"}, }) if value != 0 || currency != "" { t.Fatalf("expected no aggregation for mixed currencies, got value=%v currency=%q", value, currency) } } func TestAggregateProcurementLotEstimatedValueAllowsEmptyLotCurrency(t *testing.T) { value, currency := AggregateProcurementLotEstimatedValue([]ProcurementLot{ {EstimatedValue: 100000, Currency: "EUR"}, {EstimatedValue: 250000}, }) if value != 350000 { t.Fatalf("expected total 350000, got %v", value) } if currency != "EUR" { t.Fatalf("expected currency EUR, got %q", currency) } } func TestResolvedEstimatedValueAndCurrencyUsesLotsWhenTopLevelMissing(t *testing.T) { tender := &Tender{ Currency: "EUR", ProcurementLots: []ProcurementLot{ {LotID: "LOT-0001", EstimatedValue: 500000, Currency: "EUR"}, }, } value, currency := tender.ResolvedEstimatedValueAndCurrency() if value != 500000 { t.Fatalf("expected 500000, got %v", value) } if currency != "EUR" { t.Fatalf("expected EUR, got %q", currency) } } func TestResolvedEstimatedValueAndCurrencyPrefersTopLevel(t *testing.T) { tender := &Tender{ EstimatedValue: 900000, Currency: "USD", ProcurementLots: []ProcurementLot{ {EstimatedValue: 100000, Currency: "EUR"}, }, } value, currency := tender.ResolvedEstimatedValueAndCurrency() if value != 900000 { t.Fatalf("expected 900000, got %v", value) } if currency != "USD" { t.Fatalf("expected USD, got %q", currency) } } func TestTenderPublicationSubmissionDeadline(t *testing.T) { pubDate := int64(1_700_000_000) tender := Tender{PublicationDate: pubDate} got := tender.PublicationSubmissionDeadline() if got <= pubDate { t.Fatalf("expected submission deadline after publication_date, got %d (publication_date=%d)", got, pubDate) } withStored := Tender{PublicationDate: pubDate, SubmissionDeadline: pubDate + 999} if deadline := withStored.PublicationSubmissionDeadline(); deadline != pubDate+999 { t.Fatalf("expected stored submission_deadline, got %d", deadline) } } func TestTenderHasActivePublicationWindow(t *testing.T) { now := int64(1_700_000_000) tests := []struct { name string tender Tender want bool }{ { name: "future submission deadline", tender: Tender{SubmissionDeadline: now + 3600}, want: true, }, { name: "past submission deadline", tender: Tender{SubmissionDeadline: now - 3600}, want: false, }, { name: "future tender deadline only", tender: Tender{TenderDeadline: now + 86400}, want: false, }, { name: "publication date only with open window", tender: Tender{PublicationDate: now - 3600}, want: true, }, { name: "no publication or submission deadline", tender: Tender{}, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := tt.tender.HasActivePublicationWindow(now); got != tt.want { t.Fatalf("HasActivePublicationWindow() = %v, want %v", got, tt.want) } }) } } func TestTenderIsRecommendable(t *testing.T) { now := int64(1_700_000_000) tests := []struct { name string tender Tender want bool }{ { name: "active with future submission deadline", tender: Tender{Status: TenderStatusActive, SubmissionDeadline: now + 3600}, want: true, }, { name: "active with past submission deadline", tender: Tender{Status: TenderStatusActive, SubmissionDeadline: now - 3600}, want: false, }, { name: "active with future tender deadline but past submission deadline", tender: Tender{Status: TenderStatusActive, TenderDeadline: now + 86400, SubmissionDeadline: now - 3600}, want: false, }, { name: "active with future tender deadline only", tender: Tender{Status: TenderStatusActive, TenderDeadline: now + 86400}, want: false, }, { name: "active with submission deadline at now", tender: Tender{Status: TenderStatusActive, SubmissionDeadline: now}, want: false, }, { name: "active without publication or submission deadline", tender: Tender{Status: TenderStatusActive}, want: false, }, { name: "active with publication date only and open submission window", tender: Tender{Status: TenderStatusActive, PublicationDate: now - 3600}, want: true, }, { name: "expired status with future submission deadline", tender: Tender{Status: TenderStatusExpired, SubmissionDeadline: now + 3600}, want: false, }, { name: "awarded with future submission deadline", tender: Tender{Status: TenderStatusAwarded, SubmissionDeadline: now + 3600}, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := tt.tender.IsRecommendable(now); got != tt.want { t.Fatalf("IsRecommendable() = %v, want %v", got, tt.want) } }) } }