diff --git a/db/db.go b/db/db.go index c4bebd6b6..dfe629082 100644 --- a/db/db.go +++ b/db/db.go @@ -1357,10 +1357,18 @@ func (db database) UpdateBot(uuid string, u map[string]interface{}) bool { func (db database) GetAllTribes() []Tribe { ms := []Tribe{} - db.db.Where("(deleted = 'f' OR de leted is null)").Find(&ms) + db.db.Where("(deleted = 'f' OR deleted is null)").Find(&ms) return ms } +func (db database) DeleteTribe() (bool, error) { + result := db.db.Exec("DELETE FROM tribes") + if result.Error != nil { + return false, result.Error + } + return true, nil +} + func (db database) GetTribesTotal() int64 { var count int64 db.db.Model(&Tribe{}).Where("deleted = 'false' OR deleted is null").Count(&count) diff --git a/handlers/tribes_test.go b/handlers/tribes_test.go index 0c08c65a6..ffad46a7d 100644 --- a/handlers/tribes_test.go +++ b/handlers/tribes_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "github.com/google/uuid" "net/http" "net/http/httptest" "strings" @@ -86,21 +87,23 @@ func TestGetTribesByOwner(t *testing.T) { } func TestGetTribe(t *testing.T) { - mockDb := mocks.NewDatabase(t) - tHandler := NewTribeHandler(mockDb) + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + tHandler := NewTribeHandler(db.TestDB) + + tribe := db.Tribe{ + UUID: uuid.New().String(), + OwnerPubKey: uuid.New().String(), + Name: "tribe", + Description: "description", + Tags: []string{"tag1", "tag2"}, + Badges: pq.StringArray{}, + } + db.TestDB.CreateOrEditTribe(tribe) t.Run("Should test that a tribe can be returned when the right UUID is passed to the request parameter", func(t *testing.T) { // Mock data - mockUUID := "valid_uuid" - mockTribe := db.Tribe{ - UUID: mockUUID, - } - mockChannels := []db.Channel{ - {ID: 1, TribeUUID: mockUUID}, - {ID: 2, TribeUUID: mockUUID}, - } - mockDb.On("GetTribe", mock.Anything).Return(mockTribe).Once() - mockDb.On("GetChannelsByTribe", mock.Anything).Return(mockChannels).Once() + mockUUID := tribe.UUID // Serve request rr := httptest.NewRecorder() @@ -111,6 +114,8 @@ func TestGetTribe(t *testing.T) { t.Fatal(err) } + fetchedTribe := db.TestDB.GetTribe(mockUUID) + handler := http.HandlerFunc(tHandler.GetTribe) handler.ServeHTTP(rr, req) @@ -121,15 +126,13 @@ func TestGetTribe(t *testing.T) { if err != nil { t.Fatalf("Error decoding JSON response: %s", err) } - assert.Equal(t, mockTribe.UUID, responseData["uuid"]) + assert.Equal(t, tribe.UUID, responseData["uuid"]) + assert.Equal(t, tribe, fetchedTribe) }) t.Run("Should test that no tribe is returned when a nonexistent UUID is passed", func(t *testing.T) { - // Mock data - mockDb.ExpectedCalls = nil + nonexistentUUID := "nonexistent_uuid" - mockDb.On("GetTribe", nonexistentUUID).Return(db.Tribe{}).Once() - mockDb.On("GetChannelsByTribe", mock.Anything).Return([]db.Channel{}).Once() // Serve request rr := httptest.NewRecorder() @@ -200,23 +203,43 @@ func TestGetTribesByAppUrl(t *testing.T) { } func TestDeleteTribe(t *testing.T) { - ctx := context.WithValue(context.Background(), auth.ContextKey, "owner_pubkey") - mockDb := mocks.NewDatabase(t) - tHandler := NewTribeHandler(mockDb) + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + personUUID := uuid.New().String() + person := db.Person{ + Uuid: personUUID, + OwnerAlias: "person_alias", + UniqueName: "person_unique_name", + OwnerPubKey: "owner_pubkey", + PriceToMeet: 0, + Description: "this is test user 1", + } + db.TestDB.CreateOrEditPerson(person) + + tribeUUID := uuid.New().String() + tribe := db.Tribe{ + UUID: tribeUUID, + OwnerPubKey: person.OwnerPubKey, + Name: "tribe_name", + Description: "description", + Tags: []string{"tag3", "tag4"}, + AppURL: "tribe_app_url", + } + db.TestDB.CreateOrEditTribe(tribe) + + tHandler := NewTribeHandler(db.TestDB) t.Run("Should test that the owner of a tribe can delete a tribe", func(t *testing.T) { - // Mock data - mockUUID := "valid_uuid" - mockOwnerPubKey := "owner_pubkey" + mockUUID := tribe.AppURL + mockOwnerPubKey := person.OwnerPubKey mockVerifyTribeUUID := func(uuid string, checkTimestamp bool) (string, error) { return mockOwnerPubKey, nil } - mockDb.On("UpdateTribe", mock.Anything, map[string]interface{}{"deleted": true}).Return(true) - tHandler.verifyTribeUUID = mockVerifyTribeUUID - // Create and serve request + ctx := context.WithValue(context.Background(), auth.ContextKey, mockOwnerPubKey) rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.DeleteTribe) @@ -225,7 +248,7 @@ func TestDeleteTribe(t *testing.T) { t.Fatal(err) } chiCtx := chi.NewRouteContext() - chiCtx.URLParams.Add("uuid", "mockUUID") + chiCtx.URLParams.Add("uuid", tribeUUID) req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, chiCtx)) handler.ServeHTTP(rr, req) @@ -233,24 +256,27 @@ func TestDeleteTribe(t *testing.T) { // Verify response assert.Equal(t, http.StatusOK, rr.Code) var responseData bool - errors := json.Unmarshal(rr.Body.Bytes(), &responseData) - assert.NoError(t, errors) + err = json.Unmarshal(rr.Body.Bytes(), &responseData) + assert.NoError(t, err) assert.True(t, responseData) + + // Assert that the tribe is deleted from the DB + deletedTribe := db.TestDB.GetTribe(tribeUUID) + assert.NoError(t, err) + assert.Empty(t, deletedTribe) + assert.Equal(t, db.Tribe{}, deletedTribe) }) t.Run("Should test that a 401 error is returned when a tribe is attempted to be deleted by someone other than the owner", func(t *testing.T) { - // Mock data - ctx := context.WithValue(context.Background(), auth.ContextKey, "pubkey") - mockUUID := "valid_uuid" - mockOwnerPubKey := "owner_pubkey" + ctx := context.WithValue(context.Background(), auth.ContextKey, "other_pubkey") + mockUUID := tribe.AppURL + mockOwnerPubKey := person.OwnerPubKey mockVerifyTribeUUID := func(uuid string, checkTimestamp bool) (string, error) { return mockOwnerPubKey, nil } - tHandler.verifyTribeUUID = mockVerifyTribeUUID - // Create and serve request rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.DeleteTribe) @@ -259,7 +285,7 @@ func TestDeleteTribe(t *testing.T) { t.Fatal(err) } chiCtx := chi.NewRouteContext() - chiCtx.URLParams.Add("uuid", "mockUUID") + chiCtx.URLParams.Add("uuid", tribeUUID) req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, chiCtx)) handler.ServeHTTP(rr, req) @@ -379,55 +405,51 @@ func TestSetTribePreview(t *testing.T) { } func TestCreateOrEditTribe(t *testing.T) { - mockDb := mocks.NewDatabase(t) - tHandler := NewTribeHandler(mockDb) + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + tHandler := NewTribeHandler(db.TestDB) t.Run("Should test that a tribe can be created when the right data is passed", func(t *testing.T) { - // Mock data - mockPubKey := "valid_pubkey" - mockUUID := "valid_uuid" - mockName := "Test Tribe" - mockDescription := "This is a test tribe." - mockTags := []string{"tag1", "tag2"} + tribe := db.Tribe{ + UUID: "uuid", + OwnerPubKey: "pubkey", + Name: "name", + Description: "description", + Tags: []string{"tag3", "tag4"}, + AppURL: "valid_app_url", + Badges: []string{}, + } + + requestBody := map[string]interface{}{ + "UUID": tribe.UUID, + "OwnerPubkey": tribe.OwnerPubKey, + "Name": tribe.Name, + "Description": tribe.Description, + "Tags": tribe.Tags, + "AppURL": tribe.AppURL, + "Badges": tribe.Badges, + } mockVerifyTribeUUID := func(uuid string, checkTimestamp bool) (string, error) { - return mockPubKey, nil + return tribe.OwnerPubKey, nil } tHandler.verifyTribeUUID = mockVerifyTribeUUID - // Mock request body - requestBody := map[string]interface{}{ - "UUID": mockUUID, - "Name": mockName, - "Description": mockDescription, - "Tags": mockTags, - } requestBodyBytes, err := json.Marshal(requestBody) if err != nil { t.Fatal(err) } - // Mock database calls - mockDb.On("GetTribe", mock.Anything).Return(db.Tribe{ - UUID: mockUUID, - OwnerPubKey: mockPubKey, - }).Once() - mockDb.On("CreateOrEditTribe", mock.Anything).Return(db.Tribe{ - UUID: mockUUID, - }, nil) - - // Create request with mock body req, err := http.NewRequest("POST", "/", bytes.NewBuffer(requestBodyBytes)) if err != nil { t.Fatal(err) } - // Set context with mock pub key - ctx := context.WithValue(req.Context(), auth.ContextKey, mockPubKey) + ctx := context.WithValue(req.Context(), auth.ContextKey, tribe.OwnerPubKey) req = req.WithContext(ctx) - // Serve request rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.CreateOrEditTribe) handler.ServeHTTP(rr, req) @@ -439,78 +461,118 @@ func TestCreateOrEditTribe(t *testing.T) { if err != nil { t.Fatalf("Error decoding JSON response: %s", err) } - assert.Equal(t, mockUUID, responseData["uuid"]) + + // Assert that the response data is equal to the tribe POST data sent to the request + assert.Equal(t, tribe.UUID, responseData["uuid"]) + assert.Equal(t, tribe.Name, responseData["name"]) + assert.Equal(t, tribe.Description, responseData["description"]) + assert.ElementsMatch(t, tribe.Tags, responseData["tags"]) + assert.Equal(t, tribe.OwnerPubKey, responseData["owner_pubkey"]) }) } func TestGetTribeByUniqueName(t *testing.T) { - mockDb := mocks.NewDatabase(t) - tHandler := NewTribeHandler(mockDb) + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + tHandler := NewTribeHandler(db.TestDB) t.Run("Should test that a tribe can be fetched by its unique name", func(t *testing.T) { - // Mock data - mockUniqueName := "test_tribe" - mockTribe := db.Tribe{ - UniqueName: mockUniqueName, - UUID: "valid_uuid", - } - mockChannels := []db.Channel{ - {ID: 1, TribeUUID: "UUID"}, - {ID: 2, TribeUUID: "UUID"}, + + tribe := db.Tribe{ + UUID: "uuid", + OwnerPubKey: "pubkey", + Name: "name", + UniqueName: "test_tribe", + Description: "description", + Tags: []string{"tag3", "tag4"}, + AppURL: "valid_app_url", + Badges: []string{}, } + db.TestDB.CreateOrEditTribe(tribe) - // Mock database calls - mockDb.On("GetTribeByUniqueName", mock.Anything).Return(mockTribe) - mockDb.On("GetChannelsByTribe", mock.Anything).Return(mockChannels).Once() + mockUniqueName := tribe.UniqueName + + rr := httptest.NewRecorder() + rctx := chi.NewRouteContext() - // Create request with mock unique name - req, err := http.NewRequest("GET", "/tribe_by_un/"+mockUniqueName, nil) + rctx.URLParams.Add("un", mockUniqueName) + req, err := http.NewRequestWithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx), http.MethodGet, "/tribe_by_un/"+mockUniqueName, nil) if err != nil { t.Fatal(err) } - // Serve request - rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.GetTribeByUniqueName) handler.ServeHTTP(rr, req) // Verify response assert.Equal(t, http.StatusOK, rr.Code) + var responseData map[string]interface{} err = json.Unmarshal(rr.Body.Bytes(), &responseData) if err != nil { t.Fatalf("Error decoding JSON response: %s", err) } assert.Equal(t, mockUniqueName, responseData["unique_name"]) + assert.Equal(t, tribe.UUID, responseData["uuid"]) + assert.Equal(t, tribe.Name, responseData["name"]) + assert.Equal(t, tribe.Description, responseData["description"]) + assert.ElementsMatch(t, tribe.Tags, responseData["tags"]) }) } func TestGetAllTribes(t *testing.T) { - mockDb := mocks.NewDatabase(t) - tHandler := NewTribeHandler(mockDb) + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + tHandler := NewTribeHandler(db.TestDB) t.Run("should return all tribes", func(t *testing.T) { rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.GetAllTribes) + db.TestDB.DeleteTribe() + + tribe := db.Tribe{ + UUID: "uuid", + OwnerPubKey: "pubkey", + Name: "name", + UniqueName: "uniqueName", + Description: "description", + Tags: []string{"tag3", "tag4"}, + AppURL: "AppURl", + Badges: []string{}, + } + + tribe2 := db.Tribe{ + UUID: "uuid2", + OwnerPubKey: "pubkey2", + Name: "name2", + UniqueName: "uniqueName2", + Description: "description2", + Tags: []string{"tag3", "tag4"}, + AppURL: "AppURl2", + Badges: []string{}, + } + + db.TestDB.CreateOrEditTribe(tribe) + db.TestDB.CreateOrEditTribe(tribe2) + expectedTribes := []db.Tribe{ - {UUID: "uuid", Name: "Tribe1"}, - {UUID: "uuid", Name: "Tribe2"}, - {UUID: "uuid", Name: "Tribe3"}, + tribe, + tribe2, } rctx := chi.NewRouteContext() req, err := http.NewRequestWithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx), http.MethodGet, "/", nil) assert.NoError(t, err) - mockDb.On("GetAllTribes", mock.Anything).Return(expectedTribes) handler.ServeHTTP(rr, req) var returnedTribes []db.Tribe err = json.Unmarshal(rr.Body.Bytes(), &returnedTribes) assert.NoError(t, err) assert.Equal(t, http.StatusOK, rr.Code) + assert.Len(t, returnedTribes, 2) assert.EqualValues(t, expectedTribes, returnedTribes) - mockDb.AssertExpectations(t) - }) } diff --git a/handlers/workspaces_test.go b/handlers/workspaces_test.go index bf9cacddc..8c0ade242 100644 --- a/handlers/workspaces_test.go +++ b/handlers/workspaces_test.go @@ -16,9 +16,7 @@ import ( "github.com/google/uuid" "github.com/stakwork/sphinx-tribes/auth" "github.com/stakwork/sphinx-tribes/db" - mocks "github.com/stakwork/sphinx-tribes/mocks" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" ) func TestUnitCreateOrEditWorkspace(t *testing.T) { @@ -596,34 +594,56 @@ func TestGetWorkspaceBudgetHistory(t *testing.T) { } func TestGetWorkspaceBountiesCount(t *testing.T) { - ctx := context.WithValue(context.Background(), auth.ContextKey, "test-key") - mockDb := mocks.NewDatabase(t) - oHandler := NewWorkspaceHandler(mockDb) + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + oHandler := NewWorkspaceHandler(db.TestDB) t.Run("should return the count of workspace bounties", func(t *testing.T) { - workspaceUUID := "valid-uuid" - expectedCount := int64(5) - mockDb.On("GetWorkspaceBountiesCount", mock.AnythingOfType("*http.Request"), workspaceUUID).Return(expectedCount).Once() + rr := httptest.NewRecorder() + handler := http.HandlerFunc(oHandler.GetWorkspaceBountiesCount) + + expectedCount := int(1) + + workspace := db.Workspace{ + Uuid: uuid.New().String(), + Name: uuid.New().String(), + OwnerPubKey: uuid.New().String(), + Github: "https://github.com/bounties", + Website: "https://www.bountieswebsite.com", + Description: "Workspace Bounties Description", + } + db.TestDB.CreateOrEditWorkspace(workspace) + bounty := db.NewBounty{ + Type: "coding", + Title: "existing bounty", + Description: "existing bounty description", + WorkspaceUuid: workspace.Uuid, + OwnerID: "workspace-user", + Price: 2000, + } + + db.TestDB.CreateOrEditBounty(bounty) rctx := chi.NewRouteContext() - rctx.URLParams.Add("uuid", workspaceUUID) - req, err := http.NewRequestWithContext(context.WithValue(ctx, chi.RouteCtxKey, rctx), http.MethodGet, "/bounties/"+workspaceUUID+"/count/", nil) + rctx.URLParams.Add("uuid", workspace.Uuid) + ctx := context.WithValue(context.Background(), auth.ContextKey, workspace.OwnerPubKey) + req, err := http.NewRequestWithContext(context.WithValue(ctx, chi.RouteCtxKey, rctx), http.MethodGet, "/bounties/"+workspace.Uuid+"/count/", nil) if err != nil { t.Fatal(err) } - rr := httptest.NewRecorder() - http.HandlerFunc(oHandler.GetWorkspaceBountiesCount).ServeHTTP(rr, req) + fetchedWorkspace := db.TestDB.GetWorkspaceByUuid(workspace.Uuid) + workspace.ID = fetchedWorkspace.ID - assert.Equal(t, http.StatusOK, rr.Code) + fetchedBounty := db.TestDB.GetWorkspaceBounties(req, bounty.WorkspaceUuid) + bounty.ID = fetchedBounty[0].ID - var count int64 - err = json.Unmarshal(rr.Body.Bytes(), &count) - if err != nil { - t.Fatal(err) - } + handler.ServeHTTP(rr, req) + assert.Equal(t, http.StatusOK, rr.Code) - assert.Equal(t, expectedCount, count) + assert.Equal(t, expectedCount, len(fetchedBounty)) + assert.Equal(t, workspace, fetchedWorkspace) + assert.Equal(t, bounty, fetchedBounty[0]) }) }