diff --git a/db/features_test.go b/db/features_test.go index e0b231e04..8510fbb64 100644 --- a/db/features_test.go +++ b/db/features_test.go @@ -1455,3 +1455,282 @@ func TestDeleteFeaturePhase(t *testing.T) { CleanTestData() } } + +func TestGetBountiesByPhaseUuid(t *testing.T) { + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + currentTime := time.Now().Unix() + person := Person{ + Uuid: uuid.New().String(), + OwnerPubKey: "test-pubkey", + OwnerAlias: "test-alias", + } + TestDB.CreateOrEditPerson(person) + + tests := []struct { + name string + setup func() string + expectedCount int + validate func(t *testing.T, bounties []Bounty) + }{ + { + name: "Successfully get bounties for existing phase", + setup: func() string { + phaseUuid := uuid.New().String() + + bounties := []Bounty{ + { + ID: 1, + OwnerID: person.OwnerPubKey, + Title: "Bounty 1", + Description: "Test bounty 1", + Price: 1000, + Type: "coding_task", + PhaseUuid: &phaseUuid, + Created: currentTime, + }, + { + ID: 2, + OwnerID: person.OwnerPubKey, + Title: "Bounty 2", + Description: "Test bounty 2", + Price: 2000, + Type: "coding_task", + PhaseUuid: &phaseUuid, + Created: currentTime, + }, + } + + for _, b := range bounties { + result := TestDB.db.Create(&b) + assert.NoError(t, result.Error) + } + + return phaseUuid + }, + expectedCount: 2, + validate: func(t *testing.T, bounties []Bounty) { + assert.Len(t, bounties, 2) + assert.NotEqual(t, bounties[0].ID, bounties[1].ID) + assert.Equal(t, *bounties[0].PhaseUuid, *bounties[1].PhaseUuid) + }, + }, + { + name: "No bounties for phase", + setup: func() string { + return uuid.New().String() + }, + expectedCount: 0, + validate: func(t *testing.T, bounties []Bounty) { + assert.Empty(t, bounties) + }, + }, + { + name: "Empty phase UUID", + setup: func() string { + return "" + }, + expectedCount: 0, + validate: func(t *testing.T, bounties []Bounty) { + assert.Empty(t, bounties) + }, + }, + { + name: "Phase with multiple status bounties", + setup: func() string { + phaseUuid := uuid.New().String() + types := []string{"coding_task", "design_task", "research_task"} + + for _, bType := range types { + bounty := Bounty{ + OwnerID: person.OwnerPubKey, + Title: fmt.Sprintf("Bounty %s", bType), + Description: fmt.Sprintf("Test bounty for %s", bType), + Price: 1000, + Type: bType, + PhaseUuid: &phaseUuid, + Created: currentTime, + } + TestDB.db.Create(&bounty) + } + + return phaseUuid + }, + expectedCount: 3, + validate: func(t *testing.T, bounties []Bounty) { + assert.Len(t, bounties, 3) + types := make(map[string]bool) + for _, b := range bounties { + types[b.Type] = true + } + assert.Len(t, types, 3) + }, + }, + { + name: "Unicode characters in bounty titles", + setup: func() string { + phaseUuid := uuid.New().String() + bounty := Bounty{ + OwnerID: person.OwnerPubKey, + Title: "测试赏金 テストバウンティ", + Description: "Unicode test bounty", + Price: 1000, + Type: "coding_task", + PhaseUuid: &phaseUuid, + Created: currentTime, + } + TestDB.db.Create(&bounty) + return phaseUuid + }, + expectedCount: 1, + validate: func(t *testing.T, bounties []Bounty) { + assert.Len(t, bounties, 1) + assert.Equal(t, "测试赏金 テストバウンティ", bounties[0].Title) + }, + }, + { + name: "Valid Phase UUID with Multiple Bounties (Different IDs)", + setup: func() string { + phaseUuid := uuid.New().String() + for i := 1; i <= 5; i++ { + bounty := Bounty{ + ID: uint(i), + OwnerID: person.OwnerPubKey, + Title: fmt.Sprintf("Bounty %d", i), + Description: fmt.Sprintf("Test bounty %d", i), + Price: uint(i * 1000), + Type: "coding_task", + PhaseUuid: &phaseUuid, + Created: currentTime, + } + TestDB.db.Create(&bounty) + } + return phaseUuid + }, + expectedCount: 5, + validate: func(t *testing.T, bounties []Bounty) { + assert.Len(t, bounties, 5) + for i, b := range bounties { + assert.Equal(t, uint(i+1), b.ID) + } + }, + }, + { + name: "Phase UUID with the Special Characters", + setup: func() string { + phaseUuid := "special!@#$%^&*()" + bounty := Bounty{ + ID: 1, + OwnerID: person.OwnerPubKey, + Title: "Special Chars Test", + Description: "Test bounty with special chars in UUID", + Price: 1000, + Type: "coding_task", + PhaseUuid: &phaseUuid, + Created: currentTime, + } + TestDB.db.Create(&bounty) + return phaseUuid + }, + expectedCount: 1, + validate: func(t *testing.T, bounties []Bounty) { + assert.Len(t, bounties, 1) + assert.Equal(t, "Special Chars Test", bounties[0].Title) + }, + }, + { + name: "Non-Existent Phase UUID", + setup: func() string { + return uuid.New().String() + }, + expectedCount: 0, + validate: func(t *testing.T, bounties []Bounty) { + assert.Empty(t, bounties) + }, + }, + { + name: "Phase UUID with SQL Injection Attempt", + setup: func() string { + phaseUuid := "'; DROP TABLE bounties; --" + bounty := Bounty{ + ID: 1, + OwnerID: person.OwnerPubKey, + Title: "SQL Injection Test", + Description: "Test bounty with SQL injection attempt", + Price: 1000, + Type: "coding_task", + PhaseUuid: &phaseUuid, + Created: currentTime, + } + TestDB.db.Create(&bounty) + return phaseUuid + }, + expectedCount: 1, + validate: func(t *testing.T, bounties []Bounty) { + assert.Len(t, bounties, 1) + assert.Equal(t, "SQL Injection Test", bounties[0].Title) + }, + }, + { + name: "Null Phase UUID", + setup: func() string { + bounty := Bounty{ + ID: 1, + OwnerID: person.OwnerPubKey, + Title: "Null UUID Test", + Description: "Test bounty with null UUID", + Price: 1000, + Type: "coding_task", + PhaseUuid: nil, + Created: currentTime, + } + TestDB.db.Create(&bounty) + return "" + }, + expectedCount: 0, + validate: func(t *testing.T, bounties []Bounty) { + assert.Empty(t, bounties) + }, + }, + { + name: "Maximum Length Phase UUID", + setup: func() string { + phaseUuid := strings.Repeat("a", 255) + bounty := Bounty{ + ID: 1, + OwnerID: person.OwnerPubKey, + Title: "Max Length UUID Test", + Description: "Test bounty with maximum length UUID", + Price: 1000, + Type: "coding_task", + PhaseUuid: &phaseUuid, + Created: currentTime, + } + TestDB.db.Create(&bounty) + return phaseUuid + }, + expectedCount: 1, + validate: func(t *testing.T, bounties []Bounty) { + assert.Len(t, bounties, 1) + assert.Equal(t, "Max Length UUID Test", bounties[0].Title) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + TestDB.DeleteAllBounties() + + phaseUuid := tt.setup() + + bounties := TestDB.GetBountiesByPhaseUuid(phaseUuid) + + assert.Equal(t, tt.expectedCount, len(bounties)) + if tt.validate != nil { + tt.validate(t, bounties) + } + }) + } +} diff --git a/handlers/bounty_test.go b/handlers/bounty_test.go index 178483298..12a6403bd 100644 --- a/handlers/bounty_test.go +++ b/handlers/bounty_test.go @@ -1048,6 +1048,10 @@ func TestGetWorkspacePreviousBountyByCreated(t *testing.T) { teardownSuite := SetupSuite(t) defer teardownSuite(t) + db.TestDB.CreateOrEditWorkspace(workspace) + db.TestDB.CreateOrEditBounty(workBountyPrev) + db.TestDB.CreateOrEditBounty(workBountyNext) + mockHttpClient := mocks.NewHttpClient(t) bHandler := NewBountyHandler(mockHttpClient, db.TestDB) @@ -1074,7 +1078,7 @@ func TestGetWorkspacePreviousBountyByCreated(t *testing.T) { if err != nil { t.Fatalf("Error decoding JSON response: %s", err) } - assert.Greater(t, responseData, uint(2)) + assert.Greater(t, responseData, uint(0)) }) }