package unit import ( "bytes" "encoding/json" "net/http/httptest" "testing" "wish-list-api/api/handlers" "wish-list-api/pkg/entities" wishlist "wish-list-api/pkg/wish-list" "github.com/gofiber/fiber/v2" "github.com/stretchr/testify/assert" "go.mongodb.org/mongo-driver/bson/primitive" ) func setupTestApp() (*fiber.App, *handlers.WishListHandler, wishlist.Repository, *MockAuthService) { app := fiber.New() mockRepo := NewMockWishListRepository() mockAuth := NewMockAuthService().(*MockAuthService) userID := primitive.NewObjectID() user := &entities.User{ ID: userID, Email: "test@example.com", } mockAuth.AddMockUser(user, "valid-token") service := wishlist.NewService(mockRepo) handler := handlers.NewWishListHandler(service, mockAuth) return app, handler, mockRepo, mockAuth } func TestCreateWishListHandler(t *testing.T) { app, handler, _, _ := setupTestApp() app.Post("/wishlist", handler.CreateWishList) t.Run("CreateWishList_Success", func(t *testing.T) { wishList := entities.WishList{ Title: "Test Wishlist", Description: "Test Description", IsPublic: true, } jsonBody, _ := json.Marshal(wishList) req := httptest.NewRequest("POST", "/wishlist", bytes.NewReader(jsonBody)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer valid-token") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 201, resp.StatusCode) }) t.Run("CreateWishList_Unauthorized", func(t *testing.T) { wishList := entities.WishList{ Title: "Test Wishlist", Description: "Test Description", IsPublic: true, } jsonBody, _ := json.Marshal(wishList) req := httptest.NewRequest("POST", "/wishlist", bytes.NewReader(jsonBody)) req.Header.Set("Content-Type", "application/json") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 401, resp.StatusCode) }) t.Run("CreateWishList_InvalidToken", func(t *testing.T) { wishList := entities.WishList{ Title: "Test Wishlist", Description: "Test Description", IsPublic: true, } jsonBody, _ := json.Marshal(wishList) req := httptest.NewRequest("POST", "/wishlist", bytes.NewReader(jsonBody)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer invalid-token") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 401, resp.StatusCode) }) } func TestGetWishListHandler(t *testing.T) { app, handler, repo, mockAuth := setupTestApp() app.Get("/wishlist/:id", handler.GetWishList) userObjID := primitive.NewObjectID() userID := userObjID.Hex() wishList := &entities.WishList{ ID: "test-wishlist-id", Title: "Test Public Wishlist", UserID: userID, IsPublic: true, } repo.CreateWishList(wishList) privateWishList := &entities.WishList{ ID: "private-wishlist-id", Title: "Test Private Wishlist", UserID: userID, IsPublic: false, } repo.CreateWishList(privateWishList) mockAuth.tokens["valid-token"] = userObjID t.Run("GetWishList_Public_Success", func(t *testing.T) { req := httptest.NewRequest("GET", "/wishlist/test-wishlist-id", nil) resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) }) t.Run("GetWishList_Private_Unauthorized", func(t *testing.T) { req := httptest.NewRequest("GET", "/wishlist/private-wishlist-id", nil) resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 401, resp.StatusCode) }) t.Run("GetWishList_Private_AuthorizedOwner", func(t *testing.T) { req := httptest.NewRequest("GET", "/wishlist/private-wishlist-id", nil) req.Header.Set("Authorization", "Bearer valid-token") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) }) t.Run("GetWishList_NotFound", func(t *testing.T) { req := httptest.NewRequest("GET", "/wishlist/non-existent-id", nil) resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 404, resp.StatusCode) }) } func TestUpdateWishListHandler(t *testing.T) { app, handler, repo, mockAuth := setupTestApp() app.Put("/wishlist/:id", handler.UpdateWishList) userID := primitive.NewObjectID() wishList := &entities.WishList{ ID: "test-wishlist-id", Title: "Original Title", UserID: userID.Hex(), IsPublic: true, } repo.CreateWishList(wishList) otherUserWishList := &entities.WishList{ ID: "other-user-wishlist-id", Title: "Other User's Wishlist", UserID: "other-user-id", IsPublic: true, } repo.CreateWishList(otherUserWishList) mockAuth.tokens["valid-token"] = userID t.Run("UpdateWishList_Success", func(t *testing.T) { updatedWishList := entities.WishList{ Title: "Updated Title", Description: "Updated Description", IsPublic: false, } jsonBody, _ := json.Marshal(updatedWishList) req := httptest.NewRequest("PUT", "/wishlist/test-wishlist-id", bytes.NewReader(jsonBody)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer valid-token") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) updatedList, _ := repo.ReadWishList("test-wishlist-id") assert.Equal(t, "Updated Title", updatedList.Title) assert.Equal(t, "Updated Description", updatedList.Description) assert.Equal(t, false, updatedList.IsPublic) }) t.Run("UpdateWishList_Unauthorized", func(t *testing.T) { updatedWishList := entities.WishList{ Title: "Updated Title", Description: "Updated Description", } jsonBody, _ := json.Marshal(updatedWishList) req := httptest.NewRequest("PUT", "/wishlist/test-wishlist-id", bytes.NewReader(jsonBody)) req.Header.Set("Content-Type", "application/json") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 401, resp.StatusCode) }) t.Run("UpdateWishList_NotOwner", func(t *testing.T) { updatedWishList := entities.WishList{ Title: "Updated Title", Description: "Updated Description", } jsonBody, _ := json.Marshal(updatedWishList) req := httptest.NewRequest("PUT", "/wishlist/other-user-wishlist-id", bytes.NewReader(jsonBody)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer valid-token") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 401, resp.StatusCode) }) } func TestDeleteWishListHandler(t *testing.T) { app, handler, repo, mockAuth := setupTestApp() app.Delete("/wishlist/:id", handler.DeleteWishList) userID := primitive.NewObjectID() wishList := &entities.WishList{ ID: "test-wishlist-id", Title: "Test Wishlist", UserID: userID.Hex(), IsPublic: true, } repo.CreateWishList(wishList) otherUserWishList := &entities.WishList{ ID: "other-user-wishlist-id", Title: "Other User's Wishlist", UserID: "other-user-id", IsPublic: true, } repo.CreateWishList(otherUserWishList) mockAuth.tokens["valid-token"] = userID t.Run("DeleteWishList_Success", func(t *testing.T) { req := httptest.NewRequest("DELETE", "/wishlist/test-wishlist-id", nil) req.Header.Set("Authorization", "Bearer valid-token") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) _, err = repo.ReadWishList("test-wishlist-id") assert.Error(t, err) }) t.Run("DeleteWishList_Unauthorized", func(t *testing.T) { req := httptest.NewRequest("DELETE", "/wishlist/other-user-wishlist-id", nil) resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 401, resp.StatusCode) }) t.Run("DeleteWishList_NotOwner", func(t *testing.T) { req := httptest.NewRequest("DELETE", "/wishlist/other-user-wishlist-id", nil) req.Header.Set("Authorization", "Bearer valid-token") resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, 401, resp.StatusCode) }) }