mirror of
https://github.com/Dvorinka/SEEN.git
synced 2026-06-04 12:33:02 +00:00
166 lines
4.2 KiB
Go
166 lines
4.2 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/tdvorak/seen/backend/internal/config"
|
|
"github.com/tdvorak/seen/backend/internal/domain"
|
|
"github.com/tdvorak/seen/backend/internal/repositories/postgres"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type inMemoryRepo struct {
|
|
usersByEmail map[string]domain.User
|
|
sessions map[string]domain.Session
|
|
}
|
|
|
|
func newInMemoryRepo() *inMemoryRepo {
|
|
return &inMemoryRepo{
|
|
usersByEmail: make(map[string]domain.User),
|
|
sessions: make(map[string]domain.Session),
|
|
}
|
|
}
|
|
|
|
func (r *inMemoryRepo) CreateUser(_ context.Context, user domain.User) error {
|
|
if _, exists := r.usersByEmail[user.Email]; exists {
|
|
return postgres.ErrUserAlreadyExists
|
|
}
|
|
r.usersByEmail[user.Email] = user
|
|
return nil
|
|
}
|
|
|
|
func (r *inMemoryRepo) FindUserByEmail(_ context.Context, email string) (*domain.User, error) {
|
|
user, exists := r.usersByEmail[email]
|
|
if !exists {
|
|
return nil, nil
|
|
}
|
|
copy := user
|
|
return ©, nil
|
|
}
|
|
|
|
func (r *inMemoryRepo) FindUserByID(_ context.Context, userID uuid.UUID) (*domain.User, error) {
|
|
for _, user := range r.usersByEmail {
|
|
if user.ID == userID {
|
|
copy := user
|
|
return ©, nil
|
|
}
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func (r *inMemoryRepo) CreateSession(_ context.Context, session domain.Session) error {
|
|
r.sessions[session.RefreshToken] = session
|
|
return nil
|
|
}
|
|
|
|
func (r *inMemoryRepo) FindSessionByRefreshToken(_ context.Context, refreshToken string) (*domain.Session, error) {
|
|
session, exists := r.sessions[refreshToken]
|
|
if !exists {
|
|
return nil, nil
|
|
}
|
|
copy := session
|
|
return ©, nil
|
|
}
|
|
|
|
func (r *inMemoryRepo) RevokeSession(_ context.Context, sessionID uuid.UUID) error {
|
|
now := time.Now().UTC()
|
|
for token, session := range r.sessions {
|
|
if session.ID == sessionID {
|
|
session.RevokedAt = &now
|
|
r.sessions[token] = session
|
|
return nil
|
|
}
|
|
}
|
|
return errors.New("session not found")
|
|
}
|
|
|
|
func TestRegisterValidation(t *testing.T) {
|
|
svc := NewService(newInMemoryRepo(), config.AuthConfig{AccessTokenTTLMinutes: 10, RefreshTokenTTLHours: 1, JWTSecret: "test"}, zap.NewNop())
|
|
|
|
_, err := svc.Register(context.Background(), RegisterInput{
|
|
Email: "",
|
|
Password: "short",
|
|
})
|
|
if !errors.Is(err, ErrInvalidInput) {
|
|
t.Fatalf("expected invalid input error, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestRegisterAndLoginFlow(t *testing.T) {
|
|
repo := newInMemoryRepo()
|
|
svc := NewService(repo, config.AuthConfig{AccessTokenTTLMinutes: 10, RefreshTokenTTLHours: 1, JWTSecret: "test"}, zap.NewNop())
|
|
|
|
registered, err := svc.Register(context.Background(), RegisterInput{
|
|
Email: "user@example.com",
|
|
Password: "password123",
|
|
DisplayName: "Seen User",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("register failed: %v", err)
|
|
}
|
|
|
|
if registered.AccessToken == "" || registered.RefreshToken == "" {
|
|
t.Fatalf("expected issued tokens")
|
|
}
|
|
|
|
loggedIn, err := svc.Login(context.Background(), LoginInput{
|
|
Email: "user@example.com",
|
|
Password: "password123",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("login failed: %v", err)
|
|
}
|
|
|
|
if loggedIn.AccessToken == "" {
|
|
t.Fatalf("expected login access token")
|
|
}
|
|
}
|
|
|
|
func TestLoginWrongPassword(t *testing.T) {
|
|
repo := newInMemoryRepo()
|
|
svc := NewService(repo, config.AuthConfig{AccessTokenTTLMinutes: 10, RefreshTokenTTLHours: 1, JWTSecret: "test"}, zap.NewNop())
|
|
|
|
_, err := svc.Register(context.Background(), RegisterInput{
|
|
Email: "user@example.com",
|
|
Password: "password123",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("register failed: %v", err)
|
|
}
|
|
|
|
_, err = svc.Login(context.Background(), LoginInput{
|
|
Email: "user@example.com",
|
|
Password: "wrongpass",
|
|
})
|
|
if !errors.Is(err, ErrInvalidCredentials) {
|
|
t.Fatalf("expected invalid credentials error, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUserFromAccessToken(t *testing.T) {
|
|
repo := newInMemoryRepo()
|
|
svc := NewService(repo, config.AuthConfig{AccessTokenTTLMinutes: 10, RefreshTokenTTLHours: 1, JWTSecret: "test"}, zap.NewNop())
|
|
|
|
authResult, err := svc.Register(context.Background(), RegisterInput{
|
|
Email: "user@example.com",
|
|
Password: "password123",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("register failed: %v", err)
|
|
}
|
|
|
|
user, err := svc.UserFromAccessToken(context.Background(), authResult.AccessToken)
|
|
if err != nil {
|
|
t.Fatalf("user from access token failed: %v", err)
|
|
}
|
|
|
|
if user.Email != "user@example.com" {
|
|
t.Fatalf("expected user email, got %s", user.Email)
|
|
}
|
|
}
|