mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 15:44:21 +00:00
203 lines
6.2 KiB
Go
203 lines
6.2 KiB
Go
//go:build integration
|
|
|
|
package handlers_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"lemma/internal/handlers"
|
|
"lemma/internal/models"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestUserHandlers_Integration(t *testing.T) {
|
|
runWithDatabases(t, testUserHandlers)
|
|
}
|
|
|
|
func testUserHandlers(t *testing.T, dbConfig DatabaseConfig) {
|
|
h := setupTestHarness(t, dbConfig)
|
|
defer h.teardown(t)
|
|
|
|
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.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.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")
|
|
})
|
|
|
|
t.Run("unauthorized", func(t *testing.T) {
|
|
rr := h.makeRequest(t, http.MethodGet, "/api/v1/auth/me", nil, nil)
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
})
|
|
})
|
|
|
|
t.Run("update profile", func(t *testing.T) {
|
|
t.Run("update display name only", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
DisplayName: "Updated Name",
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, 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, updateReq.DisplayName, user.DisplayName)
|
|
})
|
|
|
|
t.Run("update email", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
Email: "newemail@test.com",
|
|
CurrentPassword: currentPassword,
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, 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, updateReq.Email, user.Email)
|
|
|
|
currentEmail = updateReq.Email
|
|
})
|
|
|
|
t.Run("update email without password", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
Email: "anotheremail@test.com",
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser)
|
|
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
|
})
|
|
|
|
t.Run("update email with wrong password", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
Email: "wrongpass@test.com",
|
|
CurrentPassword: "wrongpassword",
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser)
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
})
|
|
|
|
t.Run("update password", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
CurrentPassword: currentPassword,
|
|
NewPassword: "newpassword123",
|
|
}
|
|
|
|
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
|
|
loginReq := handlers.LoginRequest{
|
|
Email: currentEmail,
|
|
Password: "newpassword123",
|
|
}
|
|
|
|
rr = h.makeRequest(t, http.MethodPost, "/api/v1/auth/login", loginReq, nil)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
currentPassword = updateReq.NewPassword
|
|
})
|
|
|
|
t.Run("update password without current password", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
NewPassword: "newpass123",
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser)
|
|
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
|
})
|
|
|
|
t.Run("update password with wrong current password", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
CurrentPassword: "wrongpassword",
|
|
NewPassword: "newpass123",
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodPut, "/api/v1/profile", updateReq, h.RegularTestUser)
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
})
|
|
|
|
t.Run("update with short password", func(t *testing.T) {
|
|
updateReq := handlers.UpdateProfileRequest{
|
|
CurrentPassword: currentPassword,
|
|
NewPassword: "short",
|
|
}
|
|
|
|
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.AdminTestUser.userModel.Email,
|
|
CurrentPassword: currentPassword,
|
|
}
|
|
|
|
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) {
|
|
|
|
deleteUserPassword := "password123"
|
|
testDeleteUser := h.createTestUser(t, "todelete@test.com", deleteUserPassword, models.RoleEditor)
|
|
|
|
t.Run("successful delete", func(t *testing.T) {
|
|
deleteReq := handlers.DeleteAccountRequest{
|
|
Password: deleteUserPassword,
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, testDeleteUser)
|
|
require.Equal(t, http.StatusNoContent, rr.Code)
|
|
|
|
// Verify user is deleted
|
|
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)
|
|
})
|
|
|
|
t.Run("delete with wrong password", func(t *testing.T) {
|
|
deleteReq := handlers.DeleteAccountRequest{
|
|
Password: "wrongpassword",
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, h.RegularTestUser)
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
})
|
|
|
|
t.Run("prevent last admin deletion", func(t *testing.T) {
|
|
deleteReq := handlers.DeleteAccountRequest{
|
|
Password: "admin123", // Admin password from test harness
|
|
}
|
|
|
|
rr := h.makeRequest(t, http.MethodDelete, "/api/v1/profile", deleteReq, h.AdminTestUser)
|
|
assert.Equal(t, http.StatusForbidden, rr.Code)
|
|
})
|
|
})
|
|
}
|