From 69af630332fdfd7a857e27506b251953837d5bd8 Mon Sep 17 00:00:00 2001 From: LordMathis Date: Sun, 8 Dec 2024 15:03:39 +0100 Subject: [PATCH] Update tests to use test user struct --- .../admin_handlers_integration_test.go | 60 +++++------ .../auth_handlers_integration_test.go | 52 ++++++--- .../file_handlers_integration_test.go | 42 ++++---- .../handlers/git_handlers_integration_test.go | 24 ++--- server/internal/handlers/integration_test.go | 101 +++++++++--------- .../user_handlers_integration_test.go | 82 +++++--------- .../workspace_handlers_integration_test.go | 48 ++++----- 7 files changed, 200 insertions(+), 209 deletions(-) diff --git a/server/internal/handlers/admin_handlers_integration_test.go b/server/internal/handlers/admin_handlers_integration_test.go index d633f92..2fc5bae 100644 --- a/server/internal/handlers/admin_handlers_integration_test.go +++ b/server/internal/handlers/admin_handlers_integration_test.go @@ -35,7 +35,7 @@ func TestAdminHandlers_Integration(t *testing.T) { t.Run("user management", func(t *testing.T) { t.Run("list users", func(t *testing.T) { // Test with admin session - rr := h.makeRequest(t, http.MethodGet, "/api/v1/admin/users", nil, h.AdminSession) + rr := h.makeRequest(t, http.MethodGet, "/api/v1/admin/users", nil, h.AdminTestUser) require.Equal(t, http.StatusOK, rr.Code) var users []*models.User @@ -44,11 +44,11 @@ func TestAdminHandlers_Integration(t *testing.T) { // Should have at least our admin and regular test users assert.GreaterOrEqual(t, len(users), 2) - assert.True(t, containsUser(users, h.AdminUser), "Admin user not found in users list") - assert.True(t, containsUser(users, h.RegularUser), "Regular user not found in users list") + assert.True(t, containsUser(users, h.AdminTestUser.userModel), "Admin user not found in users list") + assert.True(t, containsUser(users, h.RegularTestUser.userModel), "Regular user not found in users list") // Test with non-admin session - rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/users", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/users", nil, h.RegularTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) // Test without session @@ -65,7 +65,7 @@ func TestAdminHandlers_Integration(t *testing.T) { } // Test with admin session - rr := h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.AdminSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.AdminTestUser) require.Equal(t, http.StatusOK, rr.Code) var createdUser models.User @@ -77,7 +77,7 @@ func TestAdminHandlers_Integration(t *testing.T) { assert.NotZero(t, createdUser.LastWorkspaceID) // Test duplicate email - rr = h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.AdminSession) + rr = h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.AdminTestUser) assert.Equal(t, http.StatusConflict, rr.Code) // Test invalid request (missing required fields) @@ -85,44 +85,44 @@ func TestAdminHandlers_Integration(t *testing.T) { Email: "invalid@test.com", // Missing password and role } - rr = h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", invalidReq, h.AdminSession) + rr = h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", invalidReq, h.AdminTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) // Test with non-admin session - rr = h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.RegularSession) + rr = h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.RegularTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) }) t.Run("get user", func(t *testing.T) { - path := fmt.Sprintf("/api/v1/admin/users/%d", h.RegularUser.ID) + path := fmt.Sprintf("/api/v1/admin/users/%d", h.RegularTestUser.session.UserID) // Test with admin session - rr := h.makeRequest(t, http.MethodGet, path, nil, h.AdminSession) + rr := h.makeRequest(t, http.MethodGet, path, nil, h.AdminTestUser) require.Equal(t, http.StatusOK, rr.Code) var user models.User err := json.NewDecoder(rr.Body).Decode(&user) require.NoError(t, err) - assert.Equal(t, h.RegularUser.ID, user.ID) + assert.Equal(t, h.RegularTestUser.session.UserID, user.ID) // Test non-existent user - rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/users/999999", nil, h.AdminSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/users/999999", nil, h.AdminTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) // Test with non-admin session - rr = h.makeRequest(t, http.MethodGet, path, nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, path, nil, h.RegularTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) }) t.Run("update user", func(t *testing.T) { - path := fmt.Sprintf("/api/v1/admin/users/%d", h.RegularUser.ID) + path := fmt.Sprintf("/api/v1/admin/users/%d", h.RegularTestUser.session.UserID) updateReq := handlers.UpdateUserRequest{ DisplayName: "Updated Name", Role: models.RoleViewer, } // Test with admin session - rr := h.makeRequest(t, http.MethodPut, path, updateReq, h.AdminSession) + rr := h.makeRequest(t, http.MethodPut, path, updateReq, h.AdminTestUser) require.Equal(t, http.StatusOK, rr.Code) var updatedUser models.User @@ -132,7 +132,7 @@ func TestAdminHandlers_Integration(t *testing.T) { assert.Equal(t, updateReq.Role, updatedUser.Role) // Test with non-admin session - rr = h.makeRequest(t, http.MethodPut, path, updateReq, h.RegularSession) + rr = h.makeRequest(t, http.MethodPut, path, updateReq, h.RegularTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) }) @@ -145,7 +145,7 @@ func TestAdminHandlers_Integration(t *testing.T) { Role: models.RoleEditor, } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.AdminSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.AdminTestUser) require.Equal(t, http.StatusOK, rr.Code) var createdUser models.User @@ -155,20 +155,20 @@ func TestAdminHandlers_Integration(t *testing.T) { path := fmt.Sprintf("/api/v1/admin/users/%d", createdUser.ID) // Test deleting own account (should fail) - adminPath := fmt.Sprintf("/api/v1/admin/users/%d", h.AdminUser.ID) - rr = h.makeRequest(t, http.MethodDelete, adminPath, nil, h.AdminSession) + adminPath := fmt.Sprintf("/api/v1/admin/users/%d", h.AdminTestUser.session.UserID) + rr = h.makeRequest(t, http.MethodDelete, adminPath, nil, h.AdminTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) // Test with admin session - rr = h.makeRequest(t, http.MethodDelete, path, nil, h.AdminSession) + rr = h.makeRequest(t, http.MethodDelete, path, nil, h.AdminTestUser) assert.Equal(t, http.StatusNoContent, rr.Code) // Verify user is deleted - rr = h.makeRequest(t, http.MethodGet, path, nil, h.AdminSession) + rr = h.makeRequest(t, http.MethodGet, path, nil, h.AdminTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) // Test with non-admin session - rr = h.makeRequest(t, http.MethodDelete, path, nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodDelete, path, nil, h.RegularTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) }) }) @@ -177,15 +177,15 @@ func TestAdminHandlers_Integration(t *testing.T) { t.Run("list workspaces", func(t *testing.T) { // Create a test workspace first workspace := &models.Workspace{ - UserID: h.RegularUser.ID, + UserID: h.RegularTestUser.session.UserID, Name: "Test Workspace", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) // Test with admin session - rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/workspaces", nil, h.AdminSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/workspaces", nil, h.AdminTestUser) require.Equal(t, http.StatusOK, rr.Code) var workspaces []*handlers.WorkspaceStats @@ -207,7 +207,7 @@ func TestAdminHandlers_Integration(t *testing.T) { } // Test with non-admin session - rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/workspaces", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/workspaces", nil, h.RegularTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) }) }) @@ -215,14 +215,14 @@ func TestAdminHandlers_Integration(t *testing.T) { t.Run("system stats", func(t *testing.T) { // Create some test data workspace := &models.Workspace{ - UserID: h.RegularUser.ID, + UserID: h.RegularTestUser.session.UserID, Name: "Stats Test Workspace", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) // Test with admin session - rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/stats", nil, h.AdminSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/stats", nil, h.AdminTestUser) require.Equal(t, http.StatusOK, rr.Code) var stats handlers.SystemStats @@ -237,7 +237,7 @@ func TestAdminHandlers_Integration(t *testing.T) { assert.GreaterOrEqual(t, stats.TotalSize, int64(0)) // Test with non-admin session - rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/stats", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/admin/stats", nil, h.RegularTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) }) } diff --git a/server/internal/handlers/auth_handlers_integration_test.go b/server/internal/handlers/auth_handlers_integration_test.go index 4214aef..51703f0 100644 --- a/server/internal/handlers/auth_handlers_integration_test.go +++ b/server/internal/handlers/auth_handlers_integration_test.go @@ -40,17 +40,17 @@ func TestAuthHandlers_Integration(t *testing.T) { case "access_token": foundAccessToken = true assert.True(t, cookie.HttpOnly, "access_token cookie must be HttpOnly") - assert.Equal(t, http.SameSiteStrictMode, cookie.SameSite) + assert.Equal(t, http.SameSiteLaxMode, cookie.SameSite) assert.Equal(t, 900, cookie.MaxAge) // 15 minutes case "refresh_token": foundRefreshToken = true assert.True(t, cookie.HttpOnly, "refresh_token cookie must be HttpOnly") - assert.Equal(t, http.SameSiteStrictMode, cookie.SameSite) + assert.Equal(t, http.SameSiteLaxMode, cookie.SameSite) assert.Equal(t, 604800, cookie.MaxAge) // 7 days case "csrf_token": foundCSRF = true assert.False(t, cookie.HttpOnly, "csrf_token cookie must not be HttpOnly") - assert.Equal(t, http.SameSiteStrictMode, cookie.SameSite) + assert.Equal(t, http.SameSiteLaxMode, cookie.SameSite) assert.Equal(t, 900, cookie.MaxAge) // 15 minutes } } @@ -148,7 +148,8 @@ func TestAuthHandlers_Integration(t *testing.T) { t.Run("successful token refresh", func(t *testing.T) { // Need lower level helpers for precise cookie control req := h.newRequest(t, http.MethodPost, "/api/v1/auth/refresh", nil) - h.addAuthCookies(t, req, h.RegularSession, true) // Adds both tokens + h.addAuthCookies(t, req, h.RegularTestUser) // Adds both tokens + h.addCSRFCookie(t, req) rr := h.executeRequest(req) require.Equal(t, http.StatusOK, rr.Code) @@ -181,8 +182,7 @@ func TestAuthHandlers_Integration(t *testing.T) { name: "missing refresh token cookie", setup: func(req *http.Request) { // Only add access token - token, _ := h.JWTManager.GenerateAccessToken(h.RegularSession.UserID, "admin") - req.AddCookie(h.CookieManager.GenerateAccessTokenCookie(token)) + req.AddCookie(h.CookieManager.GenerateAccessTokenCookie(h.RegularTestUser.accessToken)) }, wantCode: http.StatusBadRequest, }, @@ -191,11 +191,16 @@ func TestAuthHandlers_Integration(t *testing.T) { setup: func(req *http.Request) { expiredSession := &models.Session{ ID: "expired", - UserID: h.RegularUser.ID, + UserID: h.RegularTestUser.session.UserID, RefreshToken: "expired-token", ExpiresAt: time.Now().Add(-1 * time.Hour), } - h.addAuthCookies(t, req, expiredSession, true) + expiredSessionUser := &testUser{ + userModel: h.RegularTestUser.userModel, + accessToken: h.RegularTestUser.accessToken, + session: expiredSession, + } + h.addAuthCookies(t, req, expiredSessionUser) }, wantCode: http.StatusUnauthorized, }, @@ -226,7 +231,8 @@ func TestAuthHandlers_Integration(t *testing.T) { t.Run("successful logout", func(t *testing.T) { // Need CSRF token for POST request req := h.newRequest(t, http.MethodPost, "/api/v1/auth/logout", nil) - csrfToken := h.addAuthCookies(t, req, h.RegularSession, true) + h.addAuthCookies(t, req, h.RegularTestUser) + csrfToken := h.addCSRFCookie(t, req) req.Header.Set("X-CSRF-Token", csrfToken) rr := h.executeRequest(req) require.Equal(t, http.StatusNoContent, rr.Code) @@ -238,7 +244,7 @@ func TestAuthHandlers_Integration(t *testing.T) { } // Verify session is actually invalidated - rr = h.makeRequest(t, http.MethodGet, "/api/v1/auth/me", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/auth/me", nil, h.RegularTestUser) assert.Equal(t, http.StatusUnauthorized, rr.Code) }) @@ -251,7 +257,8 @@ func TestAuthHandlers_Integration(t *testing.T) { { name: "missing CSRF token", setup: func(req *http.Request) { - h.addAuthCookies(t, req, h.RegularSession, true) + h.addAuthCookies(t, req, h.RegularTestUser) + h.addCSRFCookie(t, req) // Deliberately not setting X-CSRF-Token header }, wantCode: http.StatusForbidden, @@ -259,7 +266,8 @@ func TestAuthHandlers_Integration(t *testing.T) { { name: "mismatched CSRF token", setup: func(req *http.Request) { - h.addAuthCookies(t, req, h.RegularSession, true) + h.addAuthCookies(t, req, h.RegularTestUser) + h.addCSRFCookie(t, req) req.Header.Set("X-CSRF-Token", "wrong-token") }, wantCode: http.StatusForbidden, @@ -286,13 +294,13 @@ func TestAuthHandlers_Integration(t *testing.T) { t.Run("get current user", func(t *testing.T) { t.Run("successful get current user", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodGet, "/api/v1/auth/me", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, "/api/v1/auth/me", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var user models.User err := json.NewDecoder(rr.Body).Decode(&user) require.NoError(t, err) - assert.Equal(t, h.RegularUser.Email, user.Email) + assert.Equal(t, h.RegularTestUser.userModel.Email, user.Email) }) t.Run("auth edge cases", func(t *testing.T) { @@ -317,7 +325,12 @@ func TestAuthHandlers_Integration(t *testing.T) { RefreshToken: "invalid", ExpiresAt: time.Now().Add(time.Hour), } - h.addAuthCookies(t, req, invalidSession, false) + invalidSessionUser := &testUser{ + userModel: h.RegularTestUser.userModel, + accessToken: h.RegularTestUser.accessToken, + session: invalidSession, + } + h.addAuthCookies(t, req, invalidSessionUser) }, wantCode: http.StatusUnauthorized, }, @@ -326,11 +339,16 @@ func TestAuthHandlers_Integration(t *testing.T) { setup: func(req *http.Request) { expiredSession := &models.Session{ ID: "expired", - UserID: h.RegularUser.ID, + UserID: h.RegularTestUser.session.UserID, RefreshToken: "expired-token", ExpiresAt: time.Now().Add(-1 * time.Hour), } - h.addAuthCookies(t, req, expiredSession, false) + expiredSessionUser := &testUser{ + userModel: h.RegularTestUser.userModel, + accessToken: h.RegularTestUser.accessToken, + session: expiredSession, + } + h.addAuthCookies(t, req, expiredSessionUser) }, wantCode: http.StatusUnauthorized, }, diff --git a/server/internal/handlers/file_handlers_integration_test.go b/server/internal/handlers/file_handlers_integration_test.go index 0a72fab..3888786 100644 --- a/server/internal/handlers/file_handlers_integration_test.go +++ b/server/internal/handlers/file_handlers_integration_test.go @@ -24,10 +24,10 @@ func TestFileHandlers_Integration(t *testing.T) { t.Run("file operations", func(t *testing.T) { // Setup: Create a workspace first workspace := &models.Workspace{ - UserID: h.RegularUser.ID, + UserID: h.RegularTestUser.session.UserID, Name: "File Test Workspace", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) err := json.NewDecoder(rr.Body).Decode(workspace) @@ -37,7 +37,7 @@ func TestFileHandlers_Integration(t *testing.T) { baseURL := fmt.Sprintf("/api/v1/workspaces/%s/files", url.PathEscape(workspace.Name)) t.Run("list empty directory", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var files []storage.FileNode @@ -51,16 +51,16 @@ func TestFileHandlers_Integration(t *testing.T) { filePath := "test.md" // Save file - rr := h.makeRequestRaw(t, http.MethodPost, baseURL+"/"+filePath, strings.NewReader(content), h.RegularSession) + rr := h.makeRequestRaw(t, http.MethodPost, baseURL+"/"+filePath, strings.NewReader(content), h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) // Get file content - rr = h.makeRequest(t, http.MethodGet, baseURL+"/"+filePath, nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, baseURL+"/"+filePath, nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) assert.Equal(t, content, rr.Body.String()) // List directory should now show the file - rr = h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var files []storage.FileNode @@ -80,12 +80,12 @@ func TestFileHandlers_Integration(t *testing.T) { // Create all files for path, content := range files { - rr := h.makeRequest(t, http.MethodPost, baseURL+"/"+path, content, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/"+path, content, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) } // List all files - rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var fileNodes []storage.FileNode @@ -116,11 +116,11 @@ func TestFileHandlers_Integration(t *testing.T) { // Look up a file that exists in multiple locations filename := "readme.md" dupContent := "Another readme" - rr := h.makeRequest(t, http.MethodPost, baseURL+"/projects/"+filename, dupContent, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/projects/"+filename, dupContent, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) // Search for the file - rr = h.makeRequest(t, http.MethodGet, baseURL+"/lookup?filename="+filename, nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, baseURL+"/lookup?filename="+filename, nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var response struct { @@ -131,7 +131,7 @@ func TestFileHandlers_Integration(t *testing.T) { assert.Len(t, response.Paths, 2) // Search for non-existent file - rr = h.makeRequest(t, http.MethodGet, baseURL+"/lookup?filename=nonexistent.md", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, baseURL+"/lookup?filename=nonexistent.md", nil, h.RegularTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) @@ -140,21 +140,21 @@ func TestFileHandlers_Integration(t *testing.T) { content := "This file will be deleted" // Create file - rr := h.makeRequest(t, http.MethodPost, baseURL+"/"+filePath, content, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/"+filePath, content, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) // Delete file - rr = h.makeRequest(t, http.MethodDelete, baseURL+"/"+filePath, nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodDelete, baseURL+"/"+filePath, nil, h.RegularTestUser) require.Equal(t, http.StatusNoContent, rr.Code) // Verify file is gone - rr = h.makeRequest(t, http.MethodGet, baseURL+"/"+filePath, nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, baseURL+"/"+filePath, nil, h.RegularTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) t.Run("last opened file", func(t *testing.T) { // Initially should be empty - rr := h.makeRequest(t, http.MethodGet, baseURL+"/last", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, baseURL+"/last", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var response struct { @@ -170,11 +170,11 @@ func TestFileHandlers_Integration(t *testing.T) { }{ FilePath: "docs/readme.md", } - rr = h.makeRequest(t, http.MethodPut, baseURL+"/last", updateReq, h.RegularSession) + rr = h.makeRequest(t, http.MethodPut, baseURL+"/last", updateReq, h.RegularTestUser) require.Equal(t, http.StatusNoContent, rr.Code) // Verify update - rr = h.makeRequest(t, http.MethodGet, baseURL+"/last", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, baseURL+"/last", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) err = json.NewDecoder(rr.Body).Decode(&response) @@ -183,7 +183,7 @@ func TestFileHandlers_Integration(t *testing.T) { // Test invalid file path updateReq.FilePath = "nonexistent.md" - rr = h.makeRequest(t, http.MethodPut, baseURL+"/last", updateReq, h.RegularSession) + rr = h.makeRequest(t, http.MethodPut, baseURL+"/last", updateReq, h.RegularTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) @@ -209,7 +209,7 @@ func TestFileHandlers_Integration(t *testing.T) { assert.Equal(t, http.StatusUnauthorized, rr.Code) // Test with wrong user's session - rr = h.makeRequest(t, tc.method, tc.path, tc.body, h.AdminSession) + rr = h.makeRequest(t, tc.method, tc.path, tc.body, h.AdminTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) } @@ -226,11 +226,11 @@ func TestFileHandlers_Integration(t *testing.T) { for _, path := range maliciousPaths { t.Run(path, func(t *testing.T) { // Try to read - rr := h.makeRequest(t, http.MethodGet, baseURL+"/"+path, nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, baseURL+"/"+path, nil, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) // Try to write - rr = h.makeRequest(t, http.MethodPost, baseURL+"/"+path, "malicious content", h.RegularSession) + rr = h.makeRequest(t, http.MethodPost, baseURL+"/"+path, "malicious content", h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) }) } diff --git a/server/internal/handlers/git_handlers_integration_test.go b/server/internal/handlers/git_handlers_integration_test.go index c9ddba2..ee6b9ca 100644 --- a/server/internal/handlers/git_handlers_integration_test.go +++ b/server/internal/handlers/git_handlers_integration_test.go @@ -22,7 +22,7 @@ func TestGitHandlers_Integration(t *testing.T) { t.Run("git operations", func(t *testing.T) { // Setup: Create a workspace with Git enabled workspace := &models.Workspace{ - UserID: h.RegularUser.ID, + UserID: h.RegularTestUser.session.UserID, Name: "Git Test Workspace", GitEnabled: true, GitURL: "https://github.com/test/repo.git", @@ -32,7 +32,7 @@ func TestGitHandlers_Integration(t *testing.T) { GitCommitMsgTemplate: "Update: {{message}}", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) err := json.NewDecoder(rr.Body).Decode(workspace) @@ -50,7 +50,7 @@ func TestGitHandlers_Integration(t *testing.T) { "message": commitMsg, } - rr := h.makeRequest(t, http.MethodPost, baseURL+"/commit", requestBody, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/commit", requestBody, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var response map[string]string @@ -70,7 +70,7 @@ func TestGitHandlers_Integration(t *testing.T) { "message": "", } - rr := h.makeRequest(t, http.MethodPost, baseURL+"/commit", requestBody, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/commit", requestBody, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) assert.Equal(t, 0, h.MockGit.GetCommitCount(), "Commit should not be called") }) @@ -83,7 +83,7 @@ func TestGitHandlers_Integration(t *testing.T) { "message": "Test message", } - rr := h.makeRequest(t, http.MethodPost, baseURL+"/commit", requestBody, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/commit", requestBody, h.RegularTestUser) assert.Equal(t, http.StatusInternalServerError, rr.Code) h.MockGit.SetError(nil) // Reset error state @@ -94,7 +94,7 @@ func TestGitHandlers_Integration(t *testing.T) { h.MockGit.Reset() t.Run("successful pull", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodPost, baseURL+"/pull", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/pull", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var response map[string]string @@ -109,7 +109,7 @@ func TestGitHandlers_Integration(t *testing.T) { h.MockGit.Reset() h.MockGit.SetError(fmt.Errorf("mock git error")) - rr := h.makeRequest(t, http.MethodPost, baseURL+"/pull", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, baseURL+"/pull", nil, h.RegularTestUser) assert.Equal(t, http.StatusInternalServerError, rr.Code) h.MockGit.SetError(nil) // Reset error state @@ -145,7 +145,7 @@ func TestGitHandlers_Integration(t *testing.T) { assert.Equal(t, http.StatusUnauthorized, rr.Code) // Test with wrong user's session - rr = h.makeRequest(t, tc.method, tc.path, tc.body, h.AdminSession) + rr = h.makeRequest(t, tc.method, tc.path, tc.body, h.AdminTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) } @@ -156,11 +156,11 @@ func TestGitHandlers_Integration(t *testing.T) { // Create a workspace without Git enabled nonGitWorkspace := &models.Workspace{ - UserID: h.RegularUser.ID, + UserID: h.RegularTestUser.session.UserID, Name: "Non-Git Workspace", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", nonGitWorkspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", nonGitWorkspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) err := json.NewDecoder(rr.Body).Decode(nonGitWorkspace) @@ -170,11 +170,11 @@ func TestGitHandlers_Integration(t *testing.T) { // Try to commit commitMsg := map[string]string{"message": "test"} - rr = h.makeRequest(t, http.MethodPost, nonGitBaseURL+"/commit", commitMsg, h.RegularSession) + rr = h.makeRequest(t, http.MethodPost, nonGitBaseURL+"/commit", commitMsg, h.RegularTestUser) assert.Equal(t, http.StatusInternalServerError, rr.Code) // Try to pull - rr = h.makeRequest(t, http.MethodPost, nonGitBaseURL+"/pull", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodPost, nonGitBaseURL+"/pull", nil, h.RegularTestUser) assert.Equal(t, http.StatusInternalServerError, rr.Code) }) }) diff --git a/server/internal/handlers/integration_test.go b/server/internal/handlers/integration_test.go index bdb53fd..5e91a9d 100644 --- a/server/internal/handlers/integration_test.go +++ b/server/internal/handlers/integration_test.go @@ -25,18 +25,22 @@ import ( // testHarness encapsulates all the dependencies needed for testing type testHarness struct { - Server *app.Server - DB db.TestDatabase - Storage storage.Manager - JWTManager auth.JWTManager - SessionManager auth.SessionManager - CookieManager auth.CookieManager - AdminUser *models.User - AdminSession *models.Session - RegularUser *models.User - RegularSession *models.Session - TempDirectory string - MockGit *MockGitClient + Server *app.Server + DB db.TestDatabase + Storage storage.Manager + JWTManager auth.JWTManager + SessionManager auth.SessionManager + CookieManager auth.CookieManager + AdminTestUser *testUser + RegularTestUser *testUser + TempDirectory string + MockGit *MockGitClient +} + +type testUser struct { + userModel *models.User + accessToken string + session *models.Session } // setupTestHarness creates a new test environment @@ -110,6 +114,7 @@ func setupTestHarness(t *testing.T) *testHarness { Storage: storageSvc, JWTManager: jwtSvc, SessionManager: sessionSvc, + CookieService: cookieSvc, } // Create server @@ -127,13 +132,11 @@ func setupTestHarness(t *testing.T) *testHarness { } // Create test users - adminUser, adminSession := h.createTestUser(t, "admin@test.com", "admin123", models.RoleAdmin) - regularUser, regularSession := h.createTestUser(t, "user@test.com", "user123", models.RoleEditor) + adminTestUser := h.createTestUser(t, "admin@test.com", "admin123", models.RoleAdmin) + regularTestUser := h.createTestUser(t, "user@test.com", "user123", models.RoleEditor) - h.AdminUser = adminUser - h.AdminSession = adminSession - h.RegularUser = regularUser - h.RegularSession = regularSession + h.AdminTestUser = adminTestUser + h.RegularTestUser = regularTestUser return h } @@ -152,7 +155,7 @@ func (h *testHarness) teardown(t *testing.T) { } // createTestUser creates a test user and returns the user and access token -func (h *testHarness) createTestUser(t *testing.T, email, password string, role models.UserRole) (*models.User, *models.Session) { +func (h *testHarness) createTestUser(t *testing.T, email, password string, role models.UserRole) *testUser { t.Helper() hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) @@ -178,12 +181,16 @@ func (h *testHarness) createTestUser(t *testing.T, email, password string, role t.Fatalf("Failed to initialize user workspace: %v", err) } - session, _, err := h.SessionManager.CreateSession(user.ID, string(user.Role)) + session, accessToken, err := h.SessionManager.CreateSession(user.ID, string(user.Role)) if err != nil { t.Fatalf("Failed to create session: %v", err) } - return user, session + return &testUser{ + userModel: user, + accessToken: accessToken, + session: session, + } } func (h *testHarness) newRequest(t *testing.T, method, path string, body interface{}) *http.Request { @@ -217,58 +224,52 @@ func (h *testHarness) executeRequest(req *http.Request) *httptest.ResponseRecord } // addAuthCookies adds authentication cookies to request -func (h *testHarness) addAuthCookies(t *testing.T, req *http.Request, session *models.Session, addCSRF bool) string { +func (h *testHarness) addAuthCookies(t *testing.T, req *http.Request, testUser *testUser) { t.Helper() - if session == nil { - return "" + if testUser == nil || testUser.session == nil { + return } - accessToken, err := h.JWTManager.GenerateAccessToken(session.UserID, "admin") - if err != nil { - t.Fatalf("Failed to generate access token: %v", err) - } + req.AddCookie(h.CookieManager.GenerateAccessTokenCookie(testUser.accessToken)) + req.AddCookie(h.CookieManager.GenerateRefreshTokenCookie(testUser.session.RefreshToken)) +} - req.AddCookie(h.CookieManager.GenerateAccessTokenCookie(accessToken)) - req.AddCookie(h.CookieManager.GenerateRefreshTokenCookie(session.RefreshToken)) +func (h *testHarness) addCSRFCookie(t *testing.T, req *http.Request) string { + t.Helper() - if addCSRF { - csrfToken := "test-csrf-token" - req.AddCookie(h.CookieManager.GenerateCSRFCookie(csrfToken)) - return csrfToken - } - return "" + csrfToken := "test-csrf-token" + req.AddCookie(h.CookieManager.GenerateCSRFCookie(csrfToken)) + return csrfToken } // makeRequest is the main helper for making JSON requests -func (h *testHarness) makeRequest(t *testing.T, method, path string, body interface{}, session *models.Session) *httptest.ResponseRecorder { +func (h *testHarness) makeRequest(t *testing.T, method, path string, body interface{}, testUser *testUser) *httptest.ResponseRecorder { t.Helper() req := h.newRequest(t, method, path, body) + h.addAuthCookies(t, req, testUser) - if session != nil { - needsCSRF := method != http.MethodGet && method != http.MethodHead && method != http.MethodOptions - csrfToken := h.addAuthCookies(t, req, session, needsCSRF) - if needsCSRF { - req.Header.Set("X-CSRF-Token", csrfToken) - } + needsCSRF := method != http.MethodGet && method != http.MethodHead && method != http.MethodOptions + if needsCSRF { + csrfToken := h.addCSRFCookie(t, req) + req.Header.Set("X-CSRF-Token", csrfToken) } return h.executeRequest(req) } // makeRequestRawWithHeaders adds support for custom headers with raw body -func (h *testHarness) makeRequestRaw(t *testing.T, method, path string, body io.Reader, session *models.Session) *httptest.ResponseRecorder { +func (h *testHarness) makeRequestRaw(t *testing.T, method, path string, body io.Reader, testUser *testUser) *httptest.ResponseRecorder { t.Helper() req := h.newRequestRaw(t, method, path, body) + h.addAuthCookies(t, req, testUser) - if session != nil { - needsCSRF := method != http.MethodGet && method != http.MethodHead && method != http.MethodOptions - csrfToken := h.addAuthCookies(t, req, session, needsCSRF) - if needsCSRF { - req.Header.Set("X-CSRF-Token", csrfToken) - } + needsCSRF := method != http.MethodGet && method != http.MethodHead && method != http.MethodOptions + if needsCSRF { + csrfToken := h.addCSRFCookie(t, req) + req.Header.Set("X-CSRF-Token", csrfToken) } return h.executeRequest(req) diff --git a/server/internal/handlers/user_handlers_integration_test.go b/server/internal/handlers/user_handlers_integration_test.go index 480d64a..5246228 100644 --- a/server/internal/handlers/user_handlers_integration_test.go +++ b/server/internal/handlers/user_handlers_integration_test.go @@ -18,22 +18,22 @@ func TestUserHandlers_Integration(t *testing.T) { h := setupTestHarness(t) defer h.teardown(t) - currentEmail := h.RegularUser.Email + currentEmail := h.RegularTestUser.userModel.Email currentPassword := "user123" t.Run("get current user", func(t *testing.T) { t.Run("successful get", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodGet, "/api/v1/auth/me", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, "/api/v1/auth/me", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var user models.User err := json.NewDecoder(rr.Body).Decode(&user) require.NoError(t, err) - assert.Equal(t, h.RegularUser.ID, user.ID) - assert.Equal(t, h.RegularUser.Email, user.Email) - assert.Equal(t, h.RegularUser.DisplayName, user.DisplayName) - assert.Equal(t, h.RegularUser.Role, user.Role) + assert.Equal(t, h.RegularTestUser.userModel.ID, user.ID) + assert.Equal(t, h.RegularTestUser.userModel.Email, user.Email) + assert.Equal(t, h.RegularTestUser.userModel.DisplayName, user.DisplayName) + assert.Equal(t, h.RegularTestUser.userModel.Role, user.Role) assert.Empty(t, user.PasswordHash, "Password hash should not be included in response") }) @@ -49,7 +49,7 @@ func TestUserHandlers_Integration(t *testing.T) { DisplayName: "Updated Name", } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var user models.User @@ -64,7 +64,7 @@ func TestUserHandlers_Integration(t *testing.T) { CurrentPassword: currentPassword, } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var user models.User @@ -80,7 +80,7 @@ func TestUserHandlers_Integration(t *testing.T) { Email: "anotheremail@test.com", } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) }) @@ -90,7 +90,7 @@ func TestUserHandlers_Integration(t *testing.T) { CurrentPassword: "wrongpassword", } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) assert.Equal(t, http.StatusUnauthorized, rr.Code) }) @@ -100,7 +100,7 @@ func TestUserHandlers_Integration(t *testing.T) { NewPassword: "newpassword123", } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) // Verify can login with new password @@ -120,7 +120,7 @@ func TestUserHandlers_Integration(t *testing.T) { NewPassword: "newpass123", } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) }) @@ -130,7 +130,7 @@ func TestUserHandlers_Integration(t *testing.T) { NewPassword: "newpass123", } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) assert.Equal(t, http.StatusUnauthorized, rr.Code) }) @@ -140,68 +140,40 @@ func TestUserHandlers_Integration(t *testing.T) { NewPassword: "short", } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) }) t.Run("duplicate email", func(t *testing.T) { updateReq := handlers.UpdateProfileRequest{ - Email: h.AdminUser.Email, + Email: h.AdminTestUser.userModel.Email, CurrentPassword: currentPassword, } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser) assert.Equal(t, http.StatusConflict, rr.Code) }) }) t.Run("delete account", func(t *testing.T) { - // Create a new user that we can delete - createReq := handlers.CreateUserRequest{ - Email: "todelete@test.com", - DisplayName: "To Delete", - Password: "password123", - Role: models.RoleEditor, - } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/admin/users", createReq, h.AdminSession) - require.Equal(t, http.StatusOK, rr.Code) - - var newUser models.User - err := json.NewDecoder(rr.Body).Decode(&newUser) - require.NoError(t, err) - - // Get session for new user - loginReq := handlers.LoginRequest{ - Email: createReq.Email, - Password: createReq.Password, - } - - rr = h.makeRequest(t, http.MethodPost, "/api/v1/auth/login", loginReq, nil) - require.Equal(t, http.StatusOK, rr.Code) - - var loginResp handlers.LoginResponse - err = json.NewDecoder(rr.Body).Decode(&loginResp) - require.NoError(t, err) - - // Create a session struct for the new user - userSession := &models.Session{ - ID: loginResp.SessionID, - UserID: newUser.ID, - RefreshToken: "", - ExpiresAt: loginResp.ExpiresAt, - } + deleteUserPassword := "password123" + testDeleteUser := h.createTestUser(t, "todelete@test.com", deleteUserPassword, models.RoleEditor) t.Run("successful delete", func(t *testing.T) { deleteReq := handlers.DeleteAccountRequest{ - Password: createReq.Password, + Password: deleteUserPassword, } - rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, userSession) + rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, testDeleteUser) require.Equal(t, http.StatusNoContent, rr.Code) // Verify user is deleted - rr = h.makeRequest(t, http.MethodPost, "/api/v1/auth/login", loginReq, nil) + loginReq := handlers.LoginRequest{ + Email: testDeleteUser.userModel.Email, + Password: deleteUserPassword, + } + rr = h.makeRequest(t, http.MethodPost, "/api/v1/auth/login", loginReq, testDeleteUser) assert.Equal(t, http.StatusUnauthorized, rr.Code) }) @@ -210,7 +182,7 @@ func TestUserHandlers_Integration(t *testing.T) { Password: "wrongpassword", } - rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, h.RegularSession) + rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, h.RegularTestUser) assert.Equal(t, http.StatusUnauthorized, rr.Code) }) @@ -219,7 +191,7 @@ func TestUserHandlers_Integration(t *testing.T) { Password: "admin123", // Admin password from test harness } - rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, h.AdminSession) + rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, h.AdminTestUser) assert.Equal(t, http.StatusForbidden, rr.Code) }) }) diff --git a/server/internal/handlers/workspace_handlers_integration_test.go b/server/internal/handlers/workspace_handlers_integration_test.go index dbb92d7..d1b95a6 100644 --- a/server/internal/handlers/workspace_handlers_integration_test.go +++ b/server/internal/handlers/workspace_handlers_integration_test.go @@ -20,7 +20,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { t.Run("list workspaces", func(t *testing.T) { t.Run("successful list", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var workspaces []*models.Workspace @@ -41,14 +41,14 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { Name: "Test Workspace", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var created models.Workspace err := json.NewDecoder(rr.Body).Decode(&created) require.NoError(t, err) assert.Equal(t, workspace.Name, created.Name) - assert.Equal(t, h.RegularUser.ID, created.UserID) + assert.Equal(t, h.RegularTestUser.session.UserID, created.UserID) assert.NotZero(t, created.ID) }) @@ -64,7 +64,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { GitCommitEmail: "test@example.com", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var created models.Workspace @@ -86,7 +86,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { // Missing required Git settings } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) }) }) @@ -95,7 +95,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { workspace := &models.Workspace{ Name: "Test Workspace Operations", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) err := json.NewDecoder(rr.Body).Decode(workspace) require.NoError(t, err) @@ -105,7 +105,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { t.Run("get workspace", func(t *testing.T) { t.Run("successful get", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var got models.Workspace @@ -116,13 +116,13 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { }) t.Run("nonexistent workspace", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/nonexistent", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/nonexistent", nil, h.RegularTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) t.Run("unauthorized access", func(t *testing.T) { // Try accessing with another user's token - rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.AdminSession) + rr := h.makeRequest(t, http.MethodGet, baseURL, nil, h.AdminTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) }) @@ -131,7 +131,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { t.Run("update name", func(t *testing.T) { workspace.Name = "Updated Workspace" - rr := h.makeRequest(t, http.MethodPut, baseURL, workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, baseURL, workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var updated models.Workspace @@ -152,7 +152,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { ShowHiddenFiles: true, } - rr := h.makeRequest(t, http.MethodPut, baseURL, update, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, baseURL, update, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var updated models.Workspace @@ -176,7 +176,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { GitCommitEmail: "test@example.com", } - rr := h.makeRequest(t, http.MethodPut, baseURL, update, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, baseURL, update, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var updated models.Workspace @@ -200,14 +200,14 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { // Missing required Git settings } - rr := h.makeRequest(t, http.MethodPut, baseURL, update, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, baseURL, update, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) }) }) t.Run("last workspace", func(t *testing.T) { t.Run("get last workspace", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/last", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/last", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var response struct { @@ -225,11 +225,11 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { WorkspaceName: workspace.Name, } - rr := h.makeRequest(t, http.MethodPut, "/api/v1/workspaces/last", req, h.RegularSession) + rr := h.makeRequest(t, http.MethodPut, "/api/v1/workspaces/last", req, h.RegularTestUser) require.Equal(t, http.StatusNoContent, rr.Code) // Verify the update - rr = h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/last", nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/last", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var response struct { @@ -243,7 +243,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { t.Run("delete workspace", func(t *testing.T) { // Get current workspaces to know how many we have - rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces", nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodGet, "/api/v1/workspaces", nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var existingWorkspaces []*models.Workspace @@ -254,13 +254,13 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { newWorkspace := &models.Workspace{ Name: "Workspace To Delete", } - rr = h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", newWorkspace, h.RegularSession) + rr = h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", newWorkspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) err = json.NewDecoder(rr.Body).Decode(newWorkspace) require.NoError(t, err) t.Run("successful delete", func(t *testing.T) { - rr := h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(newWorkspace.Name), nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(newWorkspace.Name), nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) var response struct { @@ -271,7 +271,7 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { assert.NotEmpty(t, response.NextWorkspaceName) // Verify workspace is deleted - rr = h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/"+url.PathEscape(newWorkspace.Name), nil, h.RegularSession) + rr = h.makeRequest(t, http.MethodGet, "/api/v1/workspaces/"+url.PathEscape(newWorkspace.Name), nil, h.RegularTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) @@ -279,13 +279,13 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { // Delete all but one workspace for i := 0; i < len(existingWorkspaces)-1; i++ { ws := existingWorkspaces[i] - rr := h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(ws.Name), nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(ws.Name), nil, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) } // Try to delete the last remaining workspace lastWs := existingWorkspaces[len(existingWorkspaces)-1] - rr := h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(lastWs.Name), nil, h.RegularSession) + rr := h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(lastWs.Name), nil, h.RegularTestUser) assert.Equal(t, http.StatusBadRequest, rr.Code) }) @@ -294,11 +294,11 @@ func TestWorkspaceHandlers_Integration(t *testing.T) { workspace := &models.Workspace{ Name: "Unauthorized Delete Test", } - rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularSession) + rr := h.makeRequest(t, http.MethodPost, "/api/v1/workspaces", workspace, h.RegularTestUser) require.Equal(t, http.StatusOK, rr.Code) // Try to delete with wrong user's token - rr = h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(workspace.Name), nil, h.AdminSession) + rr = h.makeRequest(t, http.MethodDelete, "/api/v1/workspaces/"+url.PathEscape(workspace.Name), nil, h.AdminTestUser) assert.Equal(t, http.StatusNotFound, rr.Code) }) })