Skip to content

Commit

Permalink
Merge pull request #1695 from stakwork/feat/bounty_db_test
Browse files Browse the repository at this point in the history
Refactored bounty creation flow from mock DB to real DB
  • Loading branch information
elraphty committed Jun 17, 2024
2 parents edf471b + 2816386 commit 60d5861
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 89 deletions.
10 changes: 8 additions & 2 deletions handlers/bounty.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,14 @@ func (h *bountyHandler) CreateOrEditBounty(w http.ResponseWriter, r *http.Reques

bounty := db.NewBounty{}
body, err := io.ReadAll(r.Body)

r.Body.Close()

if err != nil {
fmt.Println("[bounty read]", err)
w.WriteHeader(http.StatusNotAcceptable)
return
}

err = json.Unmarshal(body, &bounty)
if err != nil {
fmt.Println("[bounty]", err)
Expand Down Expand Up @@ -230,7 +236,7 @@ func (h *bountyHandler) CreateOrEditBounty(w http.ResponseWriter, r *http.Reques
bounty.Tribe = "None"
}

if bounty.Show == false && bounty.ID != 0 {
if !bounty.Show && bounty.ID != 0 {
h.db.UpdateBountyBoolColumn(bounty, "show")
}

Expand Down
162 changes: 75 additions & 87 deletions handlers/bounty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strconv"
Expand All @@ -29,18 +30,64 @@ import (
"github.com/stretchr/testify/mock"
)

func setupSuite(_ *testing.T) func(tb testing.TB) {
db.InitTestDB()

return func(_ testing.TB) {
log.Println("Teardown test")
}
}

func addExisitingDB(existingBounty db.NewBounty) {
bounty := db.TestDB.GetBounty(1)
if bounty.ID == 0 {
// add existing bounty to db
db.TestDB.CreateOrEditBounty(existingBounty)
}
}

func TestCreateOrEditBounty(t *testing.T) {
teardownSuite := setupSuite(t)
defer teardownSuite(t)

existingBounty := db.NewBounty{
Type: "coding",
Title: "existing bounty",
Description: "existing bounty description",
WorkspaceUuid: "work-1",
OwnerID: "first-user",
Price: 2000,
}

// Add initial Bounty
addExisitingDB(existingBounty)

newBounty := db.NewBounty{
Type: "coding",
Title: "new bounty",
Description: "new bounty description",
WorkspaceUuid: "work-1",
OwnerID: "test-key",
Price: 1500,
}

failedBounty := db.NewBounty{
Type: "coding",
Title: "new bounty",
Description: "failed bounty description",
WorkspaceUuid: "work-1",
Price: 1500,
}

ctx := context.WithValue(context.Background(), auth.ContextKey, "test-key")
mockDb := dbMocks.NewDatabase(t)
mockClient := mocks.NewHttpClient(t)
mockUserHasManageBountyRolesTrue := func(pubKeyFromAuth string, uuid string) bool {
return true
}
mockUserHasManageBountyRolesFalse := func(pubKeyFromAuth string, uuid string) bool {
return false
}
bHandler := NewBountyHandler(mockClient, mockDb)
bHandler := NewBountyHandler(mockClient, db.TestDB)

t.Run("should return error if body is not a valid json", func(t *testing.T) {
rr := httptest.NewRecorder()
Expand Down Expand Up @@ -102,52 +149,39 @@ func TestCreateOrEditBounty(t *testing.T) {
assert.Equal(t, http.StatusBadRequest, rr.Code)
})

t.Run("return error if trying to update other user bounty", func(t *testing.T) {
t.Run("return error if trying to update other user's bounty", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBounty)
bHandler.userHasManageBountyRoles = mockUserHasManageBountyRolesFalse

existingBounty := db.NewBounty{
ID: 1,
Type: "coding",
Title: "first bounty",
Description: "first bounty description",
WorkspaceUuid: "work-1",
Assignee: "user1",
updatedBounty := existingBounty
updatedBounty.ID = 1
updatedBounty.Show = true
updatedBounty.WorkspaceUuid = ""

json, err := json.Marshal(updatedBounty)
if err != nil {
fmt.Println("Could not marshal json data")
}
mockDb.On("UpdateBountyBoolColumn", mock.AnythingOfType("db.NewBounty"), "show").Return(existingBounty)
mockDb.On("GetBounty", uint(1)).Return(existingBounty).Once()

body := []byte(`{"id": 1, "type": "bounty_type", "title": "first bounty", "description": "my first bounty", "tribe": "random-value", "assignee": "john-doe", "owner_id": "second-user"}`)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", bytes.NewReader(body))
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", bytes.NewReader(json))
if err != nil {
t.Fatal(err)
}

handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusBadRequest, rr.Code)
assert.Contains(t, strings.TrimRight(rr.Body.String(), "\n"), "Cannot edit another user's bounty")
mockDb.AssertExpectations(t)
})

t.Run("return error if user does not have required roles", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBounty)
bHandler.userHasManageBountyRoles = mockUserHasManageBountyRolesFalse

existingBounty := db.NewBounty{
ID: 1,
Type: "coding",
Title: "first bounty",
Description: "first bounty description",
WorkspaceUuid: "work-1",
OwnerID: "second-user",
}
updatedBounty := existingBounty
updatedBounty.Title = "first bounty updated"
mockDb.On("UpdateBountyBoolColumn", mock.AnythingOfType("db.NewBounty"), "show").Return(existingBounty)
mockDb.On("UpdateBountyNullColumn", mock.AnythingOfType("db.NewBounty"), "assignee").Return(existingBounty)
mockDb.On("GetBounty", uint(1)).Return(existingBounty).Once()
updatedBounty.Title = "Existing bounty updated"
updatedBounty.ID = 1

body, _ := json.Marshal(updatedBounty)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", bytes.NewReader(body))
Expand All @@ -156,7 +190,6 @@ func TestCreateOrEditBounty(t *testing.T) {
}

handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusBadRequest, rr.Code)
})

Expand All @@ -165,20 +198,9 @@ func TestCreateOrEditBounty(t *testing.T) {
handler := http.HandlerFunc(bHandler.CreateOrEditBounty)
bHandler.userHasManageBountyRoles = mockUserHasManageBountyRolesTrue

existingBounty := db.NewBounty{
ID: 1,
Type: "coding",
Title: "first bounty",
Description: "first bounty description",
WorkspaceUuid: "work-1",
OwnerID: "second-user",
}
updatedBounty := existingBounty
updatedBounty.Title = "first bounty updated"
mockDb.On("UpdateBountyBoolColumn", mock.AnythingOfType("db.NewBounty"), "show").Return(existingBounty)
mockDb.On("UpdateBountyNullColumn", mock.AnythingOfType("db.NewBounty"), "assignee").Return(existingBounty)
mockDb.On("GetBounty", uint(1)).Return(existingBounty).Once()
mockDb.On("CreateOrEditBounty", mock.AnythingOfType("db.NewBounty")).Return(updatedBounty, nil).Once()
updatedBounty.ID = 1

body, _ := json.Marshal(updatedBounty)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", bytes.NewReader(body))
Expand All @@ -187,34 +209,19 @@ func TestCreateOrEditBounty(t *testing.T) {
}

handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
mockDb.AssertExpectations(t)

bounty := db.TestDB.GetBounty(1)
assert.Equal(t, bounty.Title, updatedBounty.Title)
})

t.Run("should not update created at when bounty is updated", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBounty)
bHandler.userHasManageBountyRoles = mockUserHasManageBountyRolesTrue

now := time.Now().UnixMilli()
existingBounty := db.NewBounty{
ID: 1,
Type: "coding",
Title: "first bounty",
Description: "first bounty description",
WorkspaceUuid: "work-1",
OwnerID: "second-user",
Created: now,
}
updatedBounty := existingBounty
updatedBounty.Title = "first bounty updated"
mockDb.On("UpdateBountyBoolColumn", mock.AnythingOfType("db.NewBounty"), "show").Return(existingBounty)
mockDb.On("UpdateBountyNullColumn", mock.AnythingOfType("db.NewBounty"), "assignee").Return(existingBounty)
mockDb.On("GetBounty", uint(1)).Return(existingBounty).Once()
mockDb.On("CreateOrEditBounty", mock.MatchedBy(func(b db.NewBounty) bool {
return b.Created == now
})).Return(updatedBounty, nil).Once()
updatedBounty.Title = "second bounty updated"

body, _ := json.Marshal(updatedBounty)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", bytes.NewReader(body))
Expand All @@ -223,25 +230,19 @@ func TestCreateOrEditBounty(t *testing.T) {
}

handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
mockDb.AssertExpectations(t)

var returnedBounty db.Bounty
err = json.Unmarshal(rr.Body.Bytes(), &returnedBounty)
assert.NoError(t, err)
assert.NotEqual(t, returnedBounty.Created, returnedBounty.Updated)
// Check the response body or any other expected behavior
})

t.Run("should return error if failed to add new bounty", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBounty)
newBounty := db.NewBounty{
Type: "coding",
Title: "first bounty",
Description: "first bounty description",
WorkspaceUuid: "org-1",
OwnerID: "test-key",
}
mockDb.On("UpdateBountyNullColumn", mock.AnythingOfType("db.NewBounty"), "assignee").Return(db.NewBounty{Assignee: "test-key"})
mockDb.On("CreateOrEditBounty", mock.AnythingOfType("db.NewBounty")).Return(db.NewBounty{}, errors.New("failed to add")).Once()

body, _ := json.Marshal(newBounty)
body, _ := json.Marshal(failedBounty)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", bytes.NewReader(body))
if err != nil {
t.Fatal(err)
Expand All @@ -250,22 +251,11 @@ func TestCreateOrEditBounty(t *testing.T) {
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusBadRequest, rr.Code)
mockDb.AssertExpectations(t)
})

t.Run("add bounty if not present", func(t *testing.T) {
t.Run("add bounty if error not present", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBounty)
newBounty := db.NewBounty{
Type: "coding",
Title: "first bounty",
Description: "first bounty description",
WorkspaceUuid: "work-1",
OrgUuid: "org-1",
OwnerID: "test-key",
}
mockDb.On("UpdateBountyNullColumn", mock.AnythingOfType("db.NewBounty"), "assignee").Return(db.Bounty{Assignee: "test-key"})
mockDb.On("CreateOrEditBounty", mock.AnythingOfType("db.NewBounty")).Return(newBounty, nil).Once()

body, _ := json.Marshal(newBounty)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/", bytes.NewReader(body))
Expand All @@ -274,9 +264,7 @@ func TestCreateOrEditBounty(t *testing.T) {
}

handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
mockDb.AssertExpectations(t)
})
}

Expand Down

0 comments on commit 60d5861

Please sign in to comment.