Refactor tender service methods for rejected tenders and enhance unit tests
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
- Renamed `buildRejectedTenderIDSetForCompanies` to `buildRejectedTenderIDSetsForCompanies` to better reflect its functionality of returning a map of excluded tender IDs by company. - Updated the implementation to return a nested map structure for better organization of excluded tender IDs per company. - Added a new test function `TestIsRecommendedTenderExcludedForAllCompanies` to validate the visibility of tenders based on company-specific exclusions. - Enhanced existing tests to ensure comprehensive coverage of the new logic for handling rejected tenders. This update improves the clarity and functionality of the tender recommendation process by refining the handling of rejected tenders and expanding test coverage.
This commit is contained in:
@@ -46,15 +46,15 @@ func (s *tenderService) buildRejectedTenderIDSet(ctx context.Context, companyID
|
|||||||
return excluded, nil
|
return excluded, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *tenderService) buildRejectedTenderIDSetForCompanies(ctx context.Context, companyIDs []string) (map[string]struct{}, error) {
|
func (s *tenderService) buildRejectedTenderIDSetsForCompanies(ctx context.Context, companyIDs []string) (map[string]map[string]struct{}, error) {
|
||||||
excluded := make(map[string]struct{})
|
excludedByCompany := make(map[string]map[string]struct{})
|
||||||
if s.rejectedTenderLister == nil {
|
if s.rejectedTenderLister == nil {
|
||||||
return excluded, nil
|
return excludedByCompany, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
normalized := normalizeRecommendationCompanyScope(companyIDs)
|
normalized := normalizeRecommendationCompanyScope(companyIDs)
|
||||||
if len(normalized) == 0 {
|
if len(normalized) == 0 {
|
||||||
return excluded, nil
|
return excludedByCompany, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([][]string, len(normalized))
|
results := make([][]string, len(normalized))
|
||||||
@@ -75,11 +75,13 @@ func (s *tenderService) buildRejectedTenderIDSetForCompanies(ctx context.Context
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ids := range results {
|
for i, companyID := range normalized {
|
||||||
addTenderIDsToSet(excluded, ids)
|
excluded := make(map[string]struct{})
|
||||||
|
addTenderIDsToSet(excluded, results[i])
|
||||||
|
excludedByCompany[companyID] = excluded
|
||||||
}
|
}
|
||||||
|
|
||||||
return excluded, nil
|
return excludedByCompany, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addTenderIDsToSet(set map[string]struct{}, ids []string) {
|
func addTenderIDsToSet(set map[string]struct{}, ids []string) {
|
||||||
@@ -117,3 +119,18 @@ func isRecommendedTenderExcluded(tender Tender, tenderRef string, excluded map[s
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isRecommendedTenderExcludedForAllCompanies(tender Tender, tenderRef string, excludedByCompany map[string]map[string]struct{}, companyIDs []string) bool {
|
||||||
|
normalized := normalizeRecommendationCompanyScope(companyIDs)
|
||||||
|
if len(normalized) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, companyID := range normalized {
|
||||||
|
if !isRecommendedTenderExcluded(tender, tenderRef, excludedByCompany[companyID]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ func TestIsRecommendedTenderExcluded(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildRejectedTenderIDSetForCompanies(t *testing.T) {
|
func TestBuildRejectedTenderIDSetsForCompanies(t *testing.T) {
|
||||||
service := &tenderService{
|
service := &tenderService{
|
||||||
rejectedTenderLister: stubRejectedTenderLister{
|
rejectedTenderLister: stubRejectedTenderLister{
|
||||||
byCompany: map[string][]string{
|
byCompany: map[string][]string{
|
||||||
@@ -81,17 +81,48 @@ func TestBuildRejectedTenderIDSetForCompanies(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
got, err := service.buildRejectedTenderIDSetForCompanies(context.Background(), []string{"company-a", "company-b", "company-a"})
|
got, err := service.buildRejectedTenderIDSetsForCompanies(context.Background(), []string{"company-a", "company-b", "company-a"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("buildRejectedTenderIDSetForCompanies() error = %v", err)
|
t.Fatalf("buildRejectedTenderIDSetsForCompanies() error = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tenderID := range []string{"tender-1", "tender-2", "tender-3"} {
|
if _, ok := got["company-a"]["tender-1"]; !ok {
|
||||||
if _, ok := got[tenderID]; !ok {
|
t.Fatalf("expected company-a exclusions to contain tender-1")
|
||||||
t.Fatalf("expected excluded set to contain %q", tenderID)
|
|
||||||
}
|
}
|
||||||
|
if _, ok := got["company-a"]["tender-2"]; !ok {
|
||||||
|
t.Fatalf("expected company-a exclusions to contain tender-2")
|
||||||
}
|
}
|
||||||
if len(got) != 3 {
|
if _, ok := got["company-b"]["tender-2"]; !ok {
|
||||||
t.Fatalf("buildRejectedTenderIDSetForCompanies() len = %d, want 3", len(got))
|
t.Fatalf("expected company-b exclusions to contain tender-2")
|
||||||
|
}
|
||||||
|
if _, ok := got["company-b"]["tender-3"]; !ok {
|
||||||
|
t.Fatalf("expected company-b exclusions to contain tender-3")
|
||||||
|
}
|
||||||
|
if len(got) != 2 {
|
||||||
|
t.Fatalf("buildRejectedTenderIDSetsForCompanies() len = %d, want 2", len(got))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsRecommendedTenderExcludedForAllCompanies(t *testing.T) {
|
||||||
|
tender := Tender{
|
||||||
|
Model: mongo.Model{},
|
||||||
|
ContractFolderID: "055329e0-3d8f-4eeb-946a-85a451f2e36b",
|
||||||
|
NoticePublicationID: "00423458-2026",
|
||||||
|
}
|
||||||
|
tender.ID, _ = bson.ObjectIDFromHex("507f1f77bcf86cd799439011")
|
||||||
|
|
||||||
|
procRef := FormatAIProcedureRef(tender.ContractFolderID, tender.NoticePublicationID)
|
||||||
|
excludedByCompany := map[string]map[string]struct{}{
|
||||||
|
"company-a": {procRef: {}},
|
||||||
|
"company-b": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
if isRecommendedTenderExcludedForAllCompanies(tender, procRef, excludedByCompany, []string{"company-a", "company-b"}) {
|
||||||
|
t.Fatalf("expected tender to remain visible when not all companies rejected it")
|
||||||
|
}
|
||||||
|
|
||||||
|
excludedByCompany["company-b"][procRef] = struct{}{}
|
||||||
|
if !isRecommendedTenderExcludedForAllCompanies(tender, procRef, excludedByCompany, []string{"company-a", "company-b"}) {
|
||||||
|
t.Fatalf("expected tender to be hidden when all companies rejected it")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -973,10 +973,13 @@ func (s *tenderService) Recommend(ctx context.Context, form *SearchForm, paginat
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var excluded map[string]struct{}
|
var (
|
||||||
|
excluded map[string]struct{}
|
||||||
|
excludedByCompany map[string]map[string]struct{}
|
||||||
|
)
|
||||||
if form.ExcludeRejectedTenders {
|
if form.ExcludeRejectedTenders {
|
||||||
if len(companyIDs) > 0 {
|
if len(companyIDs) > 0 {
|
||||||
excluded, err = s.buildRejectedTenderIDSetForCompanies(ctx, companyIDs)
|
excludedByCompany, err = s.buildRejectedTenderIDSetsForCompanies(ctx, companyIDs)
|
||||||
} else {
|
} else {
|
||||||
excluded, err = s.buildRejectedTenderIDSet(ctx, companyID)
|
excluded, err = s.buildRejectedTenderIDSet(ctx, companyID)
|
||||||
}
|
}
|
||||||
@@ -999,7 +1002,11 @@ func (s *tenderService) Recommend(ctx context.Context, form *SearchForm, paginat
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if isRecommendedTenderExcluded(tender, tenderRef, excluded) {
|
if len(companyIDs) > 0 {
|
||||||
|
if isRecommendedTenderExcludedForAllCompanies(tender, tenderRef, excludedByCompany, companyIDs) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if isRecommendedTenderExcluded(tender, tenderRef, excluded) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if form.OnlyActiveDeadlines && !tender.IsRecommendable(now) {
|
if form.OnlyActiveDeadlines && !tender.IsRecommendable(now) {
|
||||||
|
|||||||
Reference in New Issue
Block a user