diff --git a/db/db.go b/db/db.go index 6d6aef943..baba0d813 100644 --- a/db/db.go +++ b/db/db.go @@ -1217,6 +1217,8 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty { PhaseUuid := keys.Get("phase_uuid") PhasePriority := keys.Get("phase_priority") accessRestriction := keys.Get("access_restriction") + myAssigned := keys.Get("myAssigned") + myAssigned := keys.Get("myAssigned") if workspaceUuid == "" && orgUuid != "" { workspaceUuid = orgUuid @@ -1257,6 +1259,14 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty { accessRestrictionQuery = fmt.Sprintf("AND access_restriction = '%s'", accessRestriction) } + myAssignedQuery := "" + if myAssigned == "true" { + pubKeyFromAuth, _ := r.Context().Value(auth.ContextKey).(string) + if pubKeyFromAuth != "" { + myAssignedQuery = fmt.Sprintf("AND assignee = '%s'", pubKeyFromAuth) + } + } + var statusConditions []string if open == "true" { @@ -1304,7 +1314,7 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty { query := "SELECT * FROM public.bounty WHERE show != false" - allQuery := query + " " + statusQuery + " " + searchQuery + " " + workspaceQuery + " " + languageQuery + " " + phaseUuidQuery + " " + phasePriorityQuery + " " + accessRestrictionQuery + " " + orderQuery + " " + limitQuery + allQuery := query + " " + statusQuery + " " + searchQuery + " " + workspaceQuery + " " + languageQuery + " " + phaseUuidQuery + " " + phasePriorityQuery + " " + accessRestrictionQuery + " " + myAssignedQuery + " " + orderQuery + " " + limitQuery theQuery := db.db.Raw(allQuery) diff --git a/handlers/bounty_test.go b/handlers/bounty_test.go index c9b24b987..2e665a2d0 100644 --- a/handlers/bounty_test.go +++ b/handlers/bounty_test.go @@ -1250,6 +1250,128 @@ func TestGetAllBounties(t *testing.T) { }) } +func TestGetAllBountiesMyAssigned(t *testing.T) { + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + mockHttpClient := mocks.NewHttpClient(t) + bHandler := NewBountyHandler(mockHttpClient, db.TestDB) + + t.Run("should return only bounties assigned to authenticated user", func(t *testing.T) { + now := time.Now().Unix() + assignedBounty := db.NewBounty{ + Type: "coding", + Title: "Assigned Bounty", + Description: "Bounty assigned to me", + Assignee: "test-user-pubkey", + OwnerID: "test-owner", + Show: true, + Created: now, + } + db.TestDB.CreateOrEditBounty(assignedBounty) + + unassignedBounty := db.NewBounty{ + Type: "coding", + Title: "Unassigned Bounty", + Description: "Bounty not assigned to me", + Assignee: "other-user-pubkey", + OwnerID: "test-owner", + Show: true, + Created: now + 1, + } + db.TestDB.CreateOrEditBounty(unassignedBounty) + + rr := httptest.NewRecorder() + handler := http.HandlerFunc(bHandler.GetAllBounties) + + rctx := chi.NewRouteContext() + req, _ := http.NewRequestWithContext( + context.WithValue(context.Background(), auth.ContextKey, "test-user-pubkey"), + http.MethodGet, + "/all?myAssigned=true", + nil, + ) + req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx)) + + handler.ServeHTTP(rr, req) + + var returnedBounty []db.BountyResponse + err := json.Unmarshal(rr.Body.Bytes(), &returnedBounty) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, rr.Code) + assert.NotEmpty(t, returnedBounty) + + for _, b := range returnedBounty { + assert.Equal(t, "test-user-pubkey", b.Assignee) + } + }) + + t.Run("should return all bounties when myAssigned is not set", func(t *testing.T) { + rr := httptest.NewRecorder() + handler := http.HandlerFunc(bHandler.GetAllBounties) + + rctx := chi.NewRouteContext() + req, _ := http.NewRequestWithContext( + context.WithValue(context.Background(), auth.ContextKey, "test-user-pubkey"), + http.MethodGet, + "/all", + nil, + ) + req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx)) + + handler.ServeHTTP(rr, req) + + var returnedBounty []db.BountyResponse + err := json.Unmarshal(rr.Body.Bytes(), &returnedBounty) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, rr.Code) + assert.NotEmpty(t, returnedBounty) + }) + + t.Run("should return empty when no bounties assigned to user", func(t *testing.T) { + rr := httptest.NewRecorder() + handler := http.HandlerFunc(bHandler.GetAllBounties) + + rctx := chi.NewRouteContext() + req, _ := http.NewRequestWithContext( + context.WithValue(context.Background(), auth.ContextKey, "nonexistent-user"), + http.MethodGet, + "/all?myAssigned=true", + nil, + ) + req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx)) + + handler.ServeHTTP(rr, req) + + var returnedBounty []db.BountyResponse + err := json.Unmarshal(rr.Body.Bytes(), &returnedBounty) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, rr.Code) + assert.Empty(t, returnedBounty) + }) + + t.Run("should handle myAssigned with other filters", func(t *testing.T) { + rr := httptest.NewRecorder() + handler := http.HandlerFunc(bHandler.GetAllBounties) + + rctx := chi.NewRouteContext() + req, _ := http.NewRequestWithContext( + context.WithValue(context.Background(), auth.ContextKey, "test-user-pubkey"), + http.MethodGet, + "/all?myAssigned=true&Open=true", + nil, + ) + req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx)) + + handler.ServeHTTP(rr, req) + + var returnedBounty []db.BountyResponse + err := json.Unmarshal(rr.Body.Bytes(), &returnedBounty) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, rr.Code) + }) +} + func MockNewWSServer(t *testing.T) (*httptest.Server, *websocket.Conn) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {