mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 23:44:22 +00:00
Update tests to use test user struct
This commit is contained in:
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -31,14 +31,18 @@ type testHarness struct {
|
||||
JWTManager auth.JWTManager
|
||||
SessionManager auth.SessionManager
|
||||
CookieManager auth.CookieManager
|
||||
AdminUser *models.User
|
||||
AdminSession *models.Session
|
||||
RegularUser *models.User
|
||||
RegularSession *models.Session
|
||||
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
|
||||
func setupTestHarness(t *testing.T) *testHarness {
|
||||
t.Helper()
|
||||
@@ -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,59 +224,53 @@ 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 ""
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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 {
|
||||
csrfToken := h.addCSRFCookie(t, req)
|
||||
req.Header.Set("X-CSRF-Token", csrfToken)
|
||||
}
|
||||
}
|
||||
|
||||
return h.executeRequest(req)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user