Skip to content

Commit

Permalink
Merge pull request #2446 from AhsanFarooqDev/DeleteFeaturePhase_handler
Browse files Browse the repository at this point in the history
[UNIT TEST] DeleteFeaturePhase
  • Loading branch information
elraphty authored Jan 15, 2025
2 parents 92f6475 + 2e37973 commit dc6875b
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 69 deletions.
7 changes: 7 additions & 0 deletions handlers/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,13 @@ func (oh *featureHandler) DeleteFeaturePhase(w http.ResponseWriter, r *http.Requ
featureUuid := chi.URLParam(r, "feature_uuid")
phaseUuid := chi.URLParam(r, "phase_uuid")

if !isValidUUID(featureUuid) || !isValidUUID(phaseUuid) {
logger.Log.Info("Malformed UUIDs")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]string{"error": "Malformed UUIDs"})
return
}

err := oh.db.DeleteFeaturePhase(featureUuid, phaseUuid)
if err != nil {
w.WriteHeader(http.StatusNotFound)
Expand Down
216 changes: 147 additions & 69 deletions handlers/features_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -808,89 +809,166 @@ func TestGetFeaturePhaseByUUID(t *testing.T) {
}

func TestDeleteFeaturePhase(t *testing.T) {
teardownSuite := SetupSuite(t)
defer teardownSuite(t)

fHandler := NewFeatureHandler(db.TestDB)

person := db.Person{
Uuid: uuid.New().String(),
OwnerAlias: "test-alias",
UniqueName: "test-unique-name",
OwnerPubKey: "test-pubkey",
PriceToMeet: 0,
Description: "test-description",
tests := []struct {
name string
featureUuid string
phaseUuid string
pubKeyFromAuth interface{}
dbError error
expectedStatus int
expectedBody map[string]string
}{
{
name: "Valid Request with Existing Feature and Phase UUID",
featureUuid: "validFeatureUuid",
phaseUuid: "validPhaseUuid",
pubKeyFromAuth: "validPubKey",
dbError: nil,
expectedStatus: http.StatusOK,
expectedBody: map[string]string{"message": "Phase deleted successfully"},
},
{
name: "Valid Request with Non-Existing Feature UUID",
featureUuid: "nonExistingFeatureUuid",
phaseUuid: "validPhaseUuid",
pubKeyFromAuth: "validPubKey",
dbError: errors.New("Feature not found"),
expectedStatus: http.StatusNotFound,
expectedBody: map[string]string{"error": "no phase found to delete"},
},
{
name: "Valid Request with Non-Existing Phase UUID",
featureUuid: "validFeatureUuids",
phaseUuid: "nonExistingPhaseUuid",
pubKeyFromAuth: "validPubKey",
dbError: errors.New("no phase found to delete"),
expectedStatus: http.StatusNotFound,
expectedBody: map[string]string{"error": "no phase found to delete"},
},
{
name: "Valid Request with Both Non-Existing Feature and Phase UUIDs",
featureUuid: "nonExistingFeatureUuid",
phaseUuid: "nonExistingPhaseUuid",
pubKeyFromAuth: "validPubKey",
dbError: errors.New("no phase found to delete"),
expectedStatus: http.StatusNotFound,
expectedBody: map[string]string{"error": "no phase found to delete"},
},
{
name: "Missing Authorization Key",
featureUuid: "validFeatureUuid",
phaseUuid: "validPhaseUuid",
pubKeyFromAuth: nil,
expectedStatus: http.StatusUnauthorized,
expectedBody: nil,
},
{
name: "Invalid Authorization Key Type",
featureUuid: "validFeatureUuid",
phaseUuid: "validPhaseUuid",
pubKeyFromAuth: 12345, // invalid pub key
expectedStatus: http.StatusUnauthorized,
expectedBody: nil,
},
{
name: "Feature UUID and Phase UUID as Empty Strings",
featureUuid: "",
phaseUuid: "",
pubKeyFromAuth: "validPubKey",
expectedStatus: http.StatusBadRequest,
expectedBody: map[string]string{"error": "Malformed UUIDs"},
},
{
name: "Feature UUID and Phase UUID with Special Characters",
featureUuid: "!@#$%",
phaseUuid: "^&*()",
pubKeyFromAuth: "validPubKey",
expectedStatus: http.StatusBadRequest,
expectedBody: map[string]string{"error": "Malformed UUIDs"},
},
{
name: "Malformed UUIDs",
featureUuid: "malformedFeatureUuid",
phaseUuid: "malformedPhaseUuid@",
pubKeyFromAuth: "validPubKey",
expectedStatus: http.StatusBadRequest,
expectedBody: map[string]string{"error": "Malformed UUIDs"},
},
}
db.TestDB.CreateOrEditPerson(person)

workspace := db.Workspace{
Uuid: uuid.New().String(),
Name: "test-workspace" + uuid.New().String(),
OwnerPubKey: person.OwnerPubKey,
Github: "https://github.com/test",
Website: "https://www.testwebsite.com",
Description: "test-description",
}
db.TestDB.CreateOrEditWorkspace(workspace)
workspace = db.TestDB.GetWorkspaceByUuid(workspace.Uuid)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
teardownSuite := SetupSuite(t)
defer teardownSuite(t)

feature := db.WorkspaceFeatures{
Uuid: uuid.New().String(),
WorkspaceUuid: workspace.Uuid,
Name: "test-feature",
Url: "https://github.com/test-feature",
Priority: 0,
}
db.TestDB.CreateOrEditFeature(feature)
fHandler := NewFeatureHandler(db.TestDB)

featurePhase := db.FeaturePhase{
Uuid: uuid.New().String(),
FeatureUuid: feature.Uuid,
Name: "test-feature-phase",
Priority: 0,
}
db.TestDB.CreateOrEditFeaturePhase(featurePhase)
if tt.featureUuid == "validFeatureUuid" {
person := db.Person{
Uuid: uuid.New().String(),
OwnerAlias: "test-alias",
UniqueName: "test-unique-name",
OwnerPubKey: "validPubKey",
PriceToMeet: 0,
Description: "test-description",
}
db.TestDB.CreateOrEditPerson(person)

ctx := context.WithValue(context.Background(), auth.ContextKey, workspace.OwnerPubKey)
workspace := db.Workspace{
Uuid: uuid.New().String(),
Name: "test-workspace" + uuid.New().String(),
OwnerPubKey: person.OwnerPubKey,
Github: "https://github.com/test",
Website: "https://www.testwebsite.com",
Description: "test-description",
}
db.TestDB.CreateOrEditWorkspace(workspace)
workspace = db.TestDB.GetWorkspaceByUuid(workspace.Uuid)

t.Run("should return error if not authorized", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(fHandler.DeleteFeaturePhase)
feature := db.WorkspaceFeatures{
Uuid: tt.featureUuid,
WorkspaceUuid: workspace.Uuid,
Name: "test-feature",
Url: "https://github.com/test-feature",
Priority: 0,
}
db.TestDB.CreateOrEditFeature(feature)

rctx := chi.NewRouteContext()
rctx.URLParams.Add("feature_uuid", feature.Uuid)
rctx.URLParams.Add("phase_uuid", featurePhase.Uuid)
req, err := http.NewRequestWithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx), http.MethodDelete, "/features/"+feature.Uuid+"/phase/"+featurePhase.Uuid, nil)
if err != nil {
t.Fatal(err)
}
featurePhase := db.FeaturePhase{
Uuid: tt.phaseUuid,
FeatureUuid: feature.Uuid,
Name: "test-feature-phase",
Priority: 0,
}
db.TestDB.CreateOrEditFeaturePhase(featurePhase)
}

handler.ServeHTTP(rr, req)
encodedFeatureUuid := url.QueryEscape(tt.featureUuid)
encodedPhaseUuid := url.QueryEscape(tt.phaseUuid)

assert.Equal(t, http.StatusUnauthorized, rr.Code)
})
req := httptest.NewRequest(http.MethodDelete, "/features/"+encodedFeatureUuid+"/phase/"+encodedPhaseUuid, nil)
w := httptest.NewRecorder()

t.Run("should delete feature phase on successful delete", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(fHandler.DeleteFeaturePhase)
ctx := context.WithValue(req.Context(), auth.ContextKey, tt.pubKeyFromAuth)
req = req.WithContext(ctx)

rctx := chi.NewRouteContext()
rctx.URLParams.Add("feature_uuid", feature.Uuid)
rctx.URLParams.Add("phase_uuid", featurePhase.Uuid)
req, err := http.NewRequestWithContext(context.WithValue(ctx, chi.RouteCtxKey, rctx), http.MethodDelete, "/features/"+feature.Uuid+"/phase/"+featurePhase.Uuid, nil)
if err != nil {
t.Fatal(err)
}
rctx := chi.NewRouteContext()
rctx.URLParams.Add("feature_uuid", encodedFeatureUuid)
rctx.URLParams.Add("phase_uuid", encodedPhaseUuid)
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))

handler.ServeHTTP(rr, req)
fHandler.DeleteFeaturePhase(w, req)

assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, tt.expectedStatus, w.Code)

deletedFeaturePhase, err := db.TestDB.GetFeaturePhaseByUuid(feature.Uuid, featurePhase.Uuid)
assert.Error(t, err)
assert.Equal(t, "no phase found", err.Error())
assert.Equal(t, db.FeaturePhase{}, deletedFeaturePhase)
})
if tt.expectedBody != nil {
var responseBody map[string]string
err := json.NewDecoder(w.Body).Decode(&responseBody)
assert.NoError(t, err)
assert.Equal(t, tt.expectedBody, responseBody)
}
})
}
}

func TestCreateOrEditStory(t *testing.T) {
Expand Down

0 comments on commit dc6875b

Please sign in to comment.