Skip to content

Commit

Permalink
Attemped unit tests + refactoring code
Browse files Browse the repository at this point in the history
  • Loading branch information
abyan-n committed Oct 17, 2024
1 parent e9e6eea commit bfffd54
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 17 deletions.
43 changes: 29 additions & 14 deletions backend/internal/handlers/friendship/friendship.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
package friendship

import (
"fmt"
"github.com/GenerateNU/nightlife/internal/models"
"github.com/gofiber/fiber/v2"
"log"
"github.com/google/uuid"
)

// POST endpoint to create friendship between two users in DB
func (s *Service) CreateFriendship(c *fiber.Ctx) error {
fmt.Println("Creating a friendship")
var req models.Friendship

var req models.Friendship
// Parse the request body and check for errors
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Cannot parse JSON",
})
}

if err := c.BodyParser(&req); err != nil {
log.Printf("Error parsing JSON: %v, Request: %+v", err, req)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Cannot parse JSON",
})
}
// Ensure both user ids are present
if req.UserID1 == uuid.Nil || req.UserID2 == uuid.Nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Both user_id1 and user_id2 are required",
})
}

if err := s.store.CreateFriendship(c.Context(), req); err != nil {
return err
}
// Set default friendship status if not provided (just an edge case)
if req.FriendshipStatus == "" {
req.FriendshipStatus = models.Pending
}

return c.Status(fiber.StatusCreated).JSON(req)
// Call CreateFriendship method to interact with db
if err := s.store.CreateFriendship(c.Context(), req); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Failed to create friendship",
})
}

// On success, return 201 and req body
return c.Status(fiber.StatusCreated).JSON(req)
}


229 changes: 229 additions & 0 deletions backend/internal/handlers/friendship/friendship_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
package friendship

import (
"bytes"
"context"
"encoding/json"
"errors"
"github.com/GenerateNU/nightlife/internal/models"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"net/http"
"net/http/httptest"
"testing"
)

// Mock Service structure
type MockStore struct {
// Add fields for your mocked functions
CreateFriendshipFn func(ctx context.Context, friendship models.Friendship) error
CreatePreferencesFn func(ctx context.Context, preferences models.Preferences) error
UpdateProfilePreferencesFn func(ctx context.Context, userID uuid.UUID, pref1, pref2, pref3, pref4 string) error
DeleteAccountFn func(ctx context.Context, userID uuid.UUID) error
RemoveFriendFn func(ctx context.Context, userID uuid.UUID, friendID string) error
GetProfileByColumnFn func(ctx context.Context, column, value string) (models.Profile, error)
GetAllUsersFn func(ctx context.Context) ([]models.Profile, error)
GetAllUserRatingsFn func(ctx context.Context, userID uuid.UUID) ([]models.UserRating, error)
DeleteVenueFn func(ctx context.Context, venueID uuid.UUID) error
DeleteReviewForVenueFn func(ctx context.Context, reviewID int8) error
GetAllVenueRatingsFn func(ctx context.Context, venueID uuid.UUID) ([]models.VenueRatings, error)
GetAllTestsFn func(ctx context.Context) ([]models.Test, error)
}

// Implement all the Store interface methods for the mock

// Implement the CreateFriendship method for the MockStore
func (m *MockStore) CreateFriendship(ctx context.Context, friendship models.Friendship) error {
if m.CreateFriendshipFn != nil {
return m.CreateFriendshipFn(ctx, friendship)
}
return nil
}

// Implement the CreatePreferences method for the MockStore
func (m *MockStore) CreatePreferences(ctx context.Context, preferences models.Preferences) error {
if m.CreatePreferencesFn != nil {
return m.CreatePreferencesFn(ctx, preferences)
}
return nil
}

// Implement the UpdateProfilePreferences method for the MockStore
func (m *MockStore) UpdateProfilePreferences(ctx context.Context, userID uuid.UUID, pref1, pref2, pref3, pref4 string) error {
if m.UpdateProfilePreferencesFn != nil {
return m.UpdateProfilePreferencesFn(ctx, userID, pref1, pref2, pref3, pref4)
}
return nil
}

// Implement the DeleteAccount method for the MockStore
func (m *MockStore) DeleteAccount(ctx context.Context, userID uuid.UUID) error {
if m.DeleteAccountFn != nil {
return m.DeleteAccountFn(ctx, userID)
}
return nil
}

// Implement the RemoveFriend method for the MockStore
func (m *MockStore) RemoveFriend(ctx context.Context, userID uuid.UUID, friendID string) error {
if m.RemoveFriendFn != nil {
return m.RemoveFriendFn(ctx, userID, friendID)
}
return nil
}

// Implement the GetProfileByColumn method for the MockStore
func (m *MockStore) GetProfileByColumn(ctx context.Context, column, value string) (models.Profile, error) {
if m.GetProfileByColumnFn != nil {
return m.GetProfileByColumnFn(ctx, column, value)
}
return models.Profile{}, nil
}

// Implement the GetAllUsers method for the MockStore
func (m *MockStore) GetAllUsers(ctx context.Context) ([]models.Profile, error) {
if m.GetAllUsersFn != nil {
return m.GetAllUsersFn(ctx)
}
return nil, nil
}

// Implement the GetAllUserRatings method for the MockStore
func (m *MockStore) GetAllUserRatings(ctx context.Context, userID uuid.UUID) ([]models.UserRating, error) {
if m.GetAllUserRatingsFn != nil {
return m.GetAllUserRatingsFn(ctx, userID)
}
return nil, nil
}

// Implement the DeleteVenue method for the MockStore
func (m *MockStore) DeleteVenue(ctx context.Context, venueID uuid.UUID) error {
if m.DeleteVenueFn != nil {
return m.DeleteVenueFn(ctx, venueID)
}
return nil
}

// Implement the DeleteReviewForVenue method for the MockStore
func (m *MockStore) DeleteReviewForVenue(ctx context.Context, reviewID int8) error {
if m.DeleteReviewForVenueFn != nil {
return m.DeleteReviewForVenueFn(ctx, reviewID)
}
return nil
}

// Implement the GetAllVenueRatings method for the MockStore
func (m *MockStore) GetAllVenueRatings(ctx context.Context, venueID uuid.UUID) ([]models.VenueRatings, error) {
if m.GetAllVenueRatingsFn != nil {
return m.GetAllVenueRatingsFn(ctx, venueID)
}
return nil, nil
}

// Implement the GetAllTests method for the MockStore
func (m *MockStore) GetAllTests(ctx context.Context) ([]models.Test, error) {
if m.GetAllTestsFn != nil {
return m.GetAllTestsFn(ctx)
}
return nil, nil
}

// Implement the Close method for the MockStore to satisfy the storage.Storage interface
func (m *MockStore) Close() {

}

// Test for the POST endpoint CreateFriendship
func TestCreateFriendship(t *testing.T) {
// Create a new Fiber app
app := fiber.New()

// Set up the mock store
mockStore := &MockStore{}

// Set up the service with the mock store
service := &Service{
store: mockStore,
}

// Add the route to Fiber
app.Post("/add-friend", service.CreateFriendship)

// Define the test cases
tests := []struct {
name string
inputJSON string
mockResponse error
expectedStatus int
expectedBody string
}{
{
name: "successful creation",
inputJSON: `{"user_id1": "00000000-0000-0000-0000-000000000001", "user_id2": "00000000-0000-0000-0000-000000000002"}`,
mockResponse: nil,
expectedStatus: fiber.StatusCreated,
expectedBody: `{"user_id1":"00000000-0000-0000-0000-000000000001","user_id2":"00000000-0000-0000-0000-000000000002"}`,
},
{
name: "invalid JSON body",
inputJSON: `{"invalid_json"}`,
mockResponse: nil,
expectedStatus: fiber.StatusBadRequest,
expectedBody: `{"error":"Cannot parse JSON"}`,
},
{
name: "store error",
inputJSON: `{"user_id1": "00000000-0000-0000-0000-000000000001", "user_id2": "00000000-0000-0000-0000-000000000002"}`,
mockResponse: errors.New("db error"),
expectedStatus: fiber.StatusInternalServerError,
expectedBody: `{"error":"Failed to create friendship"}`,
},
}

// Iterate over the test cases
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Mock the CreateFriendship function behavior based on the test case
mockStore.CreateFriendshipFn = func(ctx context.Context, friendship models.Friendship) error {

Check failure on line 187 in backend/internal/handlers/friendship/friendship_test.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
return tt.mockResponse
}

// Create the HTTP request
req := httptest.NewRequest(http.MethodPost, "/add-friend", bytes.NewBuffer([]byte(tt.inputJSON)))
req.Header.Set("Content-Type", "application/json")

// Test the request using Fiber's app.Test() method
resp, err := app.Test(req, -1)
if err != nil {
t.Fatalf("Error making the request: %v", err)
}

// Check the status code
if resp.StatusCode != tt.expectedStatus {
t.Errorf("expected status %d, got %d", tt.expectedStatus, resp.StatusCode)
}

// Check the response body
if tt.expectedBody != "" {
var response map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
t.Fatalf("Error unmarshalling response: %v", err)
}

// Convert the expected response from string to a map for comparison
expectedResponse := make(map[string]interface{})
if err := json.Unmarshal([]byte(tt.expectedBody), &expectedResponse); err != nil {
t.Fatalf("Error unmarshalling expected body: %v", err)
}

// Compare the actual response to the expected one
for key, value := range expectedResponse {
if response[key] != value {
t.Errorf("expected %v for key %v, got %v", value, key, response[key])
}
}
}
})
}
}

4 changes: 1 addition & 3 deletions backend/internal/handlers/friendship/routes.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package friendship

import (
//"github.com/GenerateNU/nightlife/internal/auth"
"github.com/GenerateNU/nightlife/internal/types"
"github.com/gofiber/fiber/v2"
)
Expand All @@ -13,9 +12,8 @@ func Routes(app *fiber.App, params types.Params) {

//create a grouping
protected := app.Group("/friendships")
//.Use(auth.Protected(&params.Supabase))

//create a route
protected.Post("/api/friendship", service.CreateFriendship)
protected.Post("/add-friend", service.CreateFriendship)

}

0 comments on commit bfffd54

Please sign in to comment.