From 3acf5f235af6b22bbf2ce2bc321e01c242553108 Mon Sep 17 00:00:00 2001 From: elraphty Date: Mon, 4 Nov 2024 22:24:56 +0100 Subject: [PATCH 1/4] added TestGetFeatureStories test --- db/structsv2.go | 15 +++++++ handlers/features.go | 41 +++++++++++++++++ handlers/features_test.go | 94 +++++++++++++++++++++++++++++++++++++++ routes/features.go | 6 +++ 4 files changed, 156 insertions(+) diff --git a/db/structsv2.go b/db/structsv2.go index c0ba2f0e5..734a17c99 100644 --- a/db/structsv2.go +++ b/db/structsv2.go @@ -58,3 +58,18 @@ type V2TagRes struct { Status string `json:"status"` // "COMPLETE", "PENDING", or "FAILED" Error string `json:"error"` } + +type FeatureStories struct { + UserStory string `json:"userStory"` + Rationale string `json:"rationale"` + Order uint `json:"order"` +} + +type FeatureOutput struct { + FeatureUuid string `json:"featureUuid"` + Stories []FeatureStories `json:"stories"` +} + +type FeatureStoriesReponse struct { + Output FeatureOutput `json:"feature_output"` +} diff --git a/handlers/features.go b/handlers/features.go index 54ca50858..d727f4028 100644 --- a/handlers/features.go +++ b/handlers/features.go @@ -4,7 +4,9 @@ import ( "encoding/json" "fmt" "io" + "log" "net/http" + "time" "github.com/go-chi/chi" "github.com/rs/xid" @@ -404,3 +406,42 @@ func (oh *featureHandler) GetBountiesCountByFeatureAndPhaseUuid(w http.ResponseW w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(bountiesCount) } + +func (oh *featureHandler) GetFeatureStories(w http.ResponseWriter, r *http.Request) { + featureStories := db.FeatureStoriesReponse{} + featureUuid := featureStories.Output.FeatureUuid + + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&featureStories) + if err != nil { + w.WriteHeader(http.StatusNotAcceptable) + fmt.Fprintf(w, "Error decoding request body: %v", err) + return + } + + for _, story := range featureStories.Output.Stories { + // check if feature story exists + feature := oh.db.GetFeatureByUuid(featureUuid) + + if feature.ID == 0 { + log.Println("Feature ID does not exists", featureUuid) + continue + } + + now := time.Now() + + // Add story to database + featureStory := db.FeatureStory{ + Uuid: xid.New().String(), + Description: story.UserStory, + FeatureUuid: featureUuid, + Created: &now, + Updated: &now, + } + + oh.db.CreateOrEditFeatureStory(featureStory) + log.Println("Created user story for : ", featureStory.FeatureUuid) + } + + w.WriteHeader(http.StatusOK) +} diff --git a/handlers/features_test.go b/handlers/features_test.go index 96f118109..24c014ddf 100644 --- a/handlers/features_test.go +++ b/handlers/features_test.go @@ -1385,3 +1385,97 @@ func TestGetBountiesCountByFeatureAndPhaseUuid(t *testing.T) { assert.Equal(t, http.StatusOK, rr.Code) }) } + +func TestGetFeatureStories(t *testing.T) { + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + fHandler := NewFeatureHandler(db.TestDB) + + person := db.Person{ + Uuid: uuid.New().String(), + OwnerAlias: "test-get-feature-stories-alias", + UniqueName: "test-get-feature-stories-unique-name", + OwnerPubKey: "test-get-feature-stories-pubkey", + PriceToMeet: 0, + Description: "test-get-feature-stories-description", + } + db.TestDB.CreateOrEditPerson(person) + + workspace := db.Workspace{ + Uuid: uuid.New().String(), + Name: "test-get-feature-stories-workspace-name", + OwnerPubKey: person.OwnerPubKey, + Github: "https://github.com/test", + Website: "https://www.testwebsite.com", + Description: "test-get-feature-stories-description", + } + db.TestDB.CreateOrEditWorkspace(workspace) + workspace = db.TestDB.GetWorkspaceByUuid(workspace.Uuid) + + feature := db.WorkspaceFeatures{ + Uuid: uuid.New().String(), + WorkspaceUuid: workspace.Uuid, + Name: "test-get-feature-stories-feature-name", + Url: "https://github.com/test-get-feature-stories-feature-url", + Priority: 0, + } + + db.TestDB.CreateOrEditFeature(feature) + + ctx := context.WithValue(context.Background(), auth.ContextKey, workspace.OwnerPubKey) + + story := db.FeatureStories{ + UserStory: "This is a test user story", + Rationale: "This is a test rationale", + Order: 1, + } + + story2 := db.FeatureStories{ + UserStory: "This is a test user story 2", + Rationale: "This is a test rationale 2", + Order: 2, + } + + story3 := db.FeatureStories{ + UserStory: "This is a test user story 3", + Rationale: "This is a test rationale 3", + Order: 3, + } + + stories := []db.FeatureStories{ + story, + story2, + story3, + } + + featureStories := db.FeatureStoriesReponse{ + Output: db.FeatureOutput{ + FeatureUuid: feature.Uuid, + Stories: stories, + }, + } + + requestBody, _ := json.Marshal(featureStories) + + t.Run("should return the correct bounty count if user is authorized", func(t *testing.T) { + rctx := chi.NewRouteContext() + req, err := http.NewRequestWithContext(context.WithValue(ctx, chi.RouteCtxKey, rctx), http.MethodPost, "/features/stories", bytes.NewReader(requestBody)) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + http.HandlerFunc(fHandler.GetBountiesCountByFeatureAndPhaseUuid).ServeHTTP(rr, req) + + var returnedBountiesCount int64 + err = json.Unmarshal(rr.Body.Bytes(), &returnedBountiesCount) + assert.NoError(t, err) + + featureStories, _ := db.TestDB.GetFeatureStoriesByFeatureUuid(feature.Uuid) + featureStoriesCount := len(featureStories) + + assert.Equal(t, int64(featureStoriesCount), int64(3)) + assert.Equal(t, http.StatusOK, rr.Code) + }) +} diff --git a/routes/features.go b/routes/features.go index b46e1bfb5..b10508f2a 100644 --- a/routes/features.go +++ b/routes/features.go @@ -10,6 +10,12 @@ import ( func FeatureRoutes() chi.Router { r := chi.NewRouter() featureHandlers := handlers.NewFeatureHandler(&db.DB) + + r.Group(func(r chi.Router) { + r.Post("/stories", featureHandlers.GetFeatureStories) + + }) + r.Group(func(r chi.Router) { r.Use(auth.PubKeyContext) From aadcaa0c58a85affd034966ca52304d0a92d9b93 Mon Sep 17 00:00:00 2001 From: elraphty Date: Mon, 4 Nov 2024 22:41:22 +0100 Subject: [PATCH 2/4] added test for not found featureUuid --- handlers/features_test.go | 65 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/handlers/features_test.go b/handlers/features_test.go index 24c014ddf..e752305a9 100644 --- a/handlers/features_test.go +++ b/handlers/features_test.go @@ -1421,8 +1421,16 @@ func TestGetFeatureStories(t *testing.T) { Priority: 0, } - db.TestDB.CreateOrEditFeature(feature) + feature2 := db.WorkspaceFeatures{ + Uuid: uuid.New().String(), + WorkspaceUuid: workspace.Uuid, + Name: "test-get-feature-stories-feature-name-2", + Url: "https://github.com/test-get-feature-stories-feature-url-2", + Priority: 0, + } + db.TestDB.CreateOrEditFeature(feature) + db.TestDB.CreateOrEditFeature(feature2) ctx := context.WithValue(context.Background(), auth.ContextKey, workspace.OwnerPubKey) story := db.FeatureStories{ @@ -1443,12 +1451,36 @@ func TestGetFeatureStories(t *testing.T) { Order: 3, } + story4 := db.FeatureStories{ + UserStory: "This is a test user story 4", + Rationale: "This is a test rationale 4", + Order: 4, + } + + story5 := db.FeatureStories{ + UserStory: "This is a test user story 5", + Rationale: "This is a test rationale 5", + Order: 5, + } + + story6 := db.FeatureStories{ + UserStory: "This is a test user story 6", + Rationale: "This is a test rationale 6", + Order: 6, + } + stories := []db.FeatureStories{ story, story2, story3, } + stories2 := []db.FeatureStories{ + story4, + story5, + story6, + } + featureStories := db.FeatureStoriesReponse{ Output: db.FeatureOutput{ FeatureUuid: feature.Uuid, @@ -1456,9 +1488,17 @@ func TestGetFeatureStories(t *testing.T) { }, } + featureStories2 := db.FeatureStoriesReponse{ + Output: db.FeatureOutput{ + FeatureUuid: "Fake-feature-uuid", + Stories: stories2, + }, + } + requestBody, _ := json.Marshal(featureStories) + requestBody2, _ := json.Marshal(featureStories2) - t.Run("should return the correct bounty count if user is authorized", func(t *testing.T) { + t.Run("Should add user stories from stakwork to the feature stories table", func(t *testing.T) { rctx := chi.NewRouteContext() req, err := http.NewRequestWithContext(context.WithValue(ctx, chi.RouteCtxKey, rctx), http.MethodPost, "/features/stories", bytes.NewReader(requestBody)) if err != nil { @@ -1478,4 +1518,25 @@ func TestGetFeatureStories(t *testing.T) { assert.Equal(t, int64(featureStoriesCount), int64(3)) assert.Equal(t, http.StatusOK, rr.Code) }) + + t.Run("Should not add user stories from stakwork to the feature stories table if the feature uuid is not found", func(t *testing.T) { + rctx := chi.NewRouteContext() + req, err := http.NewRequestWithContext(context.WithValue(ctx, chi.RouteCtxKey, rctx), http.MethodPost, "/features/stories", bytes.NewReader(requestBody2)) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + http.HandlerFunc(fHandler.GetBountiesCountByFeatureAndPhaseUuid).ServeHTTP(rr, req) + + var returnedBountiesCount int64 + err = json.Unmarshal(rr.Body.Bytes(), &returnedBountiesCount) + assert.NoError(t, err) + + featureStories, _ := db.TestDB.GetFeatureStoriesByFeatureUuid(feature2.Uuid) + featureStoriesCount := len(featureStories) + + assert.Equal(t, int64(featureStoriesCount), int64(0)) + assert.Equal(t, http.StatusOK, rr.Code) + }) } From 8acc7dca71ac647566f3e6416ee2704966473eca Mon Sep 17 00:00:00 2001 From: elraphty Date: Mon, 4 Nov 2024 22:44:36 +0100 Subject: [PATCH 3/4] change handlers to GetFeatureStories --- handlers/features_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handlers/features_test.go b/handlers/features_test.go index e752305a9..a3e93ccd9 100644 --- a/handlers/features_test.go +++ b/handlers/features_test.go @@ -1506,7 +1506,7 @@ func TestGetFeatureStories(t *testing.T) { } rr := httptest.NewRecorder() - http.HandlerFunc(fHandler.GetBountiesCountByFeatureAndPhaseUuid).ServeHTTP(rr, req) + http.HandlerFunc(fHandler.GetFeatureStories).ServeHTTP(rr, req) var returnedBountiesCount int64 err = json.Unmarshal(rr.Body.Bytes(), &returnedBountiesCount) @@ -1527,7 +1527,7 @@ func TestGetFeatureStories(t *testing.T) { } rr := httptest.NewRecorder() - http.HandlerFunc(fHandler.GetBountiesCountByFeatureAndPhaseUuid).ServeHTTP(rr, req) + http.HandlerFunc(fHandler.GetFeatureStories).ServeHTTP(rr, req) var returnedBountiesCount int64 err = json.Unmarshal(rr.Body.Bytes(), &returnedBountiesCount) From a238db237037a1a8f8a1bf7742f75e4f232de97c Mon Sep 17 00:00:00 2001 From: elraphty Date: Mon, 4 Nov 2024 23:17:54 +0100 Subject: [PATCH 4/4] fixed tests errors --- handlers/features.go | 5 ++++- handlers/features_test.go | 9 +++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/handlers/features.go b/handlers/features.go index d727f4028..8423efb34 100644 --- a/handlers/features.go +++ b/handlers/features.go @@ -409,10 +409,12 @@ func (oh *featureHandler) GetBountiesCountByFeatureAndPhaseUuid(w http.ResponseW func (oh *featureHandler) GetFeatureStories(w http.ResponseWriter, r *http.Request) { featureStories := db.FeatureStoriesReponse{} - featureUuid := featureStories.Output.FeatureUuid decoder := json.NewDecoder(r.Body) err := decoder.Decode(&featureStories) + + featureUuid := featureStories.Output.FeatureUuid + if err != nil { w.WriteHeader(http.StatusNotAcceptable) fmt.Fprintf(w, "Error decoding request body: %v", err) @@ -444,4 +446,5 @@ func (oh *featureHandler) GetFeatureStories(w http.ResponseWriter, r *http.Reque } w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode("User stories added successfuly") } diff --git a/handlers/features_test.go b/handlers/features_test.go index a3e93ccd9..28ec99429 100644 --- a/handlers/features_test.go +++ b/handlers/features_test.go @@ -1431,6 +1431,7 @@ func TestGetFeatureStories(t *testing.T) { db.TestDB.CreateOrEditFeature(feature) db.TestDB.CreateOrEditFeature(feature2) + ctx := context.WithValue(context.Background(), auth.ContextKey, workspace.OwnerPubKey) story := db.FeatureStories{ @@ -1508,8 +1509,8 @@ func TestGetFeatureStories(t *testing.T) { rr := httptest.NewRecorder() http.HandlerFunc(fHandler.GetFeatureStories).ServeHTTP(rr, req) - var returnedBountiesCount int64 - err = json.Unmarshal(rr.Body.Bytes(), &returnedBountiesCount) + var featureStoriesReponse string + err = json.Unmarshal(rr.Body.Bytes(), &featureStoriesReponse) assert.NoError(t, err) featureStories, _ := db.TestDB.GetFeatureStoriesByFeatureUuid(feature.Uuid) @@ -1529,8 +1530,8 @@ func TestGetFeatureStories(t *testing.T) { rr := httptest.NewRecorder() http.HandlerFunc(fHandler.GetFeatureStories).ServeHTTP(rr, req) - var returnedBountiesCount int64 - err = json.Unmarshal(rr.Body.Bytes(), &returnedBountiesCount) + var featureStoriesReponse string + err = json.Unmarshal(rr.Body.Bytes(), &featureStoriesReponse) assert.NoError(t, err) featureStories, _ := db.TestDB.GetFeatureStoriesByFeatureUuid(feature2.Uuid)