Files
honeyDueAPI/internal/services/auth_service_test.go
T
Trey t 81578f6e27
Backend CI / Test (push) Has been cancelled
Backend CI / Contract Tests (push) Has been cancelled
Backend CI / Lint (push) Has been cancelled
Backend CI / Secret Scanning (push) Has been cancelled
Backend CI / Build (push) Has been cancelled
feat(auth): replace hand-rolled auth with Ory Kratos — phase 2 backend
Delegates all credential management (login, register, password reset,
email verification, social sign-in) to Ory Kratos. The Go API now acts
as a resource server: the new KratosAuth middleware validates sessions
against the Kratos whoami endpoint, writes the local User mirror into
Echo context, and all existing domain handlers continue working
unchanged. Hand-rolled token auth, AuthToken model, apple_auth/
google_auth services, and the auth refresh flow are removed. Tests are
updated to use the fake-token middleware pattern so existing integration
assertions require no rewrite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 17:55:56 -05:00

181 lines
5.6 KiB
Go

package services
import (
"context"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/treytartt/honeydue-api/internal/config"
"github.com/treytartt/honeydue-api/internal/dto/requests"
"github.com/treytartt/honeydue-api/internal/repositories"
"github.com/treytartt/honeydue-api/internal/testutil"
)
func setupAuthService(t *testing.T) (*AuthService, *repositories.UserRepository) {
db := testutil.SetupTestDB(t)
userRepo := repositories.NewUserRepository(db)
notifRepo := repositories.NewNotificationRepository(db)
cfg := &config.Config{}
service := NewAuthService(userRepo, cfg)
service.SetNotificationRepository(notifRepo)
return service, userRepo
}
// === GetCurrentUser ===
func TestAuthService_GetCurrentUser(t *testing.T) {
db := testutil.SetupTestDB(t)
userRepo := repositories.NewUserRepository(db)
cfg := &config.Config{}
service := NewAuthService(userRepo, cfg)
user := testutil.CreateTestUser(t, db, "testuser", "test@test.com", "Password123")
// Create profile
userRepo.GetOrCreateProfile(user.ID)
resp, err := service.GetCurrentUser(context.Background(), user.ID)
require.NoError(t, err)
assert.Equal(t, "testuser", resp.Username)
assert.Equal(t, "test@test.com", resp.Email)
assert.Equal(t, "kratos", resp.AuthProvider) // All users are Kratos-managed
}
// === UpdateProfile ===
func TestAuthService_UpdateProfile(t *testing.T) {
db := testutil.SetupTestDB(t)
userRepo := repositories.NewUserRepository(db)
cfg := &config.Config{}
service := NewAuthService(userRepo, cfg)
user := testutil.CreateTestUser(t, db, "testuser", "test@test.com", "Password123")
userRepo.GetOrCreateProfile(user.ID)
newFirst := "John"
newLast := "Doe"
req := &requests.UpdateProfileRequest{
FirstName: &newFirst,
LastName: &newLast,
}
resp, err := service.UpdateProfile(context.Background(), user.ID, req)
require.NoError(t, err)
assert.Equal(t, "John", resp.FirstName)
assert.Equal(t, "Doe", resp.LastName)
}
func TestAuthService_UpdateProfile_DuplicateEmail(t *testing.T) {
db := testutil.SetupTestDB(t)
userRepo := repositories.NewUserRepository(db)
cfg := &config.Config{}
service := NewAuthService(userRepo, cfg)
testutil.CreateTestUser(t, db, "user1", "user1@test.com", "Password123")
user2 := testutil.CreateTestUser(t, db, "user2", "user2@test.com", "Password123")
userRepo.GetOrCreateProfile(user2.ID)
takenEmail := "user1@test.com"
req := &requests.UpdateProfileRequest{
Email: &takenEmail,
}
_, err := service.UpdateProfile(context.Background(), user2.ID, req)
testutil.AssertAppError(t, err, http.StatusConflict, "error.email_already_taken")
}
func TestAuthService_UpdateProfile_SameEmail(t *testing.T) {
db := testutil.SetupTestDB(t)
userRepo := repositories.NewUserRepository(db)
cfg := &config.Config{}
service := NewAuthService(userRepo, cfg)
user := testutil.CreateTestUser(t, db, "testuser", "test@test.com", "Password123")
userRepo.GetOrCreateProfile(user.ID)
sameEmail := "test@test.com"
req := &requests.UpdateProfileRequest{
Email: &sameEmail,
}
// Same email should not trigger duplicate error
resp, err := service.UpdateProfile(context.Background(), user.ID, req)
require.NoError(t, err)
assert.Equal(t, "test@test.com", resp.Email)
}
func TestAuthService_UpdateProfile_ChangeEmail(t *testing.T) {
db := testutil.SetupTestDB(t)
userRepo := repositories.NewUserRepository(db)
cfg := &config.Config{}
service := NewAuthService(userRepo, cfg)
user := testutil.CreateTestUser(t, db, "testuser", "test@test.com", "Password123")
userRepo.GetOrCreateProfile(user.ID)
newEmail := "newemail@test.com"
req := &requests.UpdateProfileRequest{
Email: &newEmail,
}
resp, err := service.UpdateProfile(context.Background(), user.ID, req)
require.NoError(t, err)
assert.Equal(t, "newemail@test.com", resp.Email)
}
// === DeleteAccount ===
func TestAuthService_DeleteAccount_WithConfirmation(t *testing.T) {
service, userRepo := setupAuthService(t)
user := testutil.CreateTestUser(t, (*userRepo).DB(), "testuser", "test@test.com", "")
_ = user
confirmation := "DELETE"
_, err := service.DeleteAccount(context.Background(), user.ID, nil, &confirmation)
require.NoError(t, err)
}
func TestAuthService_DeleteAccount_WrongConfirmation(t *testing.T) {
service, userRepo := setupAuthService(t)
user := testutil.CreateTestUser(t, (*userRepo).DB(), "testuser", "test@test.com", "")
wrongConf := "delete"
_, err := service.DeleteAccount(context.Background(), user.ID, nil, &wrongConf)
testutil.AssertAppError(t, err, http.StatusBadRequest, "error.confirmation_required")
}
func TestAuthService_DeleteAccount_NoConfirmation(t *testing.T) {
service, userRepo := setupAuthService(t)
user := testutil.CreateTestUser(t, (*userRepo).DB(), "testuser", "test@test.com", "")
_, err := service.DeleteAccount(context.Background(), user.ID, nil, nil)
testutil.AssertAppError(t, err, http.StatusBadRequest, "error.confirmation_required")
}
func TestAuthService_DeleteAccount_UserNotFound(t *testing.T) {
service, _ := setupAuthService(t)
confirmation := "DELETE"
_, err := service.DeleteAccount(context.Background(), 99999, nil, &confirmation)
testutil.AssertAppError(t, err, http.StatusNotFound, "error.user_not_found")
}
// === SetNotificationRepository ===
func TestAuthService_SetNotificationRepository(t *testing.T) {
db := testutil.SetupTestDB(t)
userRepo := repositories.NewUserRepository(db)
notifRepo := repositories.NewNotificationRepository(db)
cfg := &config.Config{}
service := NewAuthService(userRepo, cfg)
assert.Nil(t, service.notificationRepo)
service.SetNotificationRepository(notifRepo)
assert.NotNil(t, service.notificationRepo)
}