aboutsummaryrefslogtreecommitdiffhomepage
path: root/backend/auth/auth_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/auth/auth_test.go')
-rw-r--r--backend/auth/auth_test.go125
1 files changed, 125 insertions, 0 deletions
diff --git a/backend/auth/auth_test.go b/backend/auth/auth_test.go
new file mode 100644
index 0000000..00d4527
--- /dev/null
+++ b/backend/auth/auth_test.go
@@ -0,0 +1,125 @@
+package auth
+
+import (
+ "context"
+ "errors"
+ "testing"
+
+ "github.com/jackc/pgx/v5"
+ "golang.org/x/crypto/bcrypt"
+
+ "albatross-2026-backend/db"
+)
+
+type mockQuerier struct {
+ db.Querier
+ getUserAuthByUsernameFunc func(ctx context.Context, username string) (db.GetUserAuthByUsernameRow, error)
+}
+
+func (m *mockQuerier) GetUserAuthByUsername(ctx context.Context, username string) (db.GetUserAuthByUsernameRow, error) {
+ if m.getUserAuthByUsernameFunc != nil {
+ return m.getUserAuthByUsernameFunc(ctx, username)
+ }
+ return db.GetUserAuthByUsernameRow{}, pgx.ErrNoRows
+}
+
+type mockTxManager struct{}
+
+func (m *mockTxManager) RunInTx(_ context.Context, fn func(q db.Querier) error) error {
+ return fn(&mockQuerier{})
+}
+
+func TestLogin_PasswordAuth_Success(t *testing.T) {
+ hash, err := bcrypt.GenerateFromPassword([]byte("correct-password"), bcrypt.MinCost)
+ if err != nil {
+ t.Fatalf("failed to generate hash: %v", err)
+ }
+ hashStr := string(hash)
+
+ a := NewAuthenticator(
+ &mockQuerier{
+ getUserAuthByUsernameFunc: func(_ context.Context, _ string) (db.GetUserAuthByUsernameRow, error) {
+ return db.GetUserAuthByUsernameRow{
+ UserID: 42,
+ AuthType: "password",
+ PasswordHash: &hashStr,
+ }, nil
+ },
+ },
+ &mockTxManager{},
+ )
+
+ userID, err := a.Login(context.Background(), "testuser", "correct-password")
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if userID != 42 {
+ t.Errorf("expected userID 42, got %d", userID)
+ }
+}
+
+func TestLogin_PasswordAuth_WrongPassword(t *testing.T) {
+ hash, err := bcrypt.GenerateFromPassword([]byte("correct-password"), bcrypt.MinCost)
+ if err != nil {
+ t.Fatalf("failed to generate hash: %v", err)
+ }
+ hashStr := string(hash)
+
+ a := NewAuthenticator(
+ &mockQuerier{
+ getUserAuthByUsernameFunc: func(_ context.Context, _ string) (db.GetUserAuthByUsernameRow, error) {
+ return db.GetUserAuthByUsernameRow{
+ UserID: 42,
+ AuthType: "password",
+ PasswordHash: &hashStr,
+ }, nil
+ },
+ },
+ &mockTxManager{},
+ )
+
+ _, err = a.Login(context.Background(), "testuser", "wrong-password")
+ if err == nil {
+ t.Fatal("expected error for wrong password, got nil")
+ }
+}
+
+func TestLogin_PasswordAuth_NilHash(t *testing.T) {
+ a := NewAuthenticator(
+ &mockQuerier{
+ getUserAuthByUsernameFunc: func(_ context.Context, _ string) (db.GetUserAuthByUsernameRow, error) {
+ return db.GetUserAuthByUsernameRow{
+ UserID: 42,
+ AuthType: "password",
+ PasswordHash: nil,
+ }, nil
+ },
+ },
+ &mockTxManager{},
+ )
+
+ _, err := a.Login(context.Background(), "testuser", "any")
+ if err == nil {
+ t.Fatal("expected error for nil password hash, got nil")
+ }
+ if err.Error() != "inconsistent data: password auth type but no password hash" {
+ t.Errorf("unexpected error message: %s", err.Error())
+ }
+}
+
+func TestLogin_DBError(t *testing.T) {
+ dbErr := errors.New("database connection failed")
+ a := NewAuthenticator(
+ &mockQuerier{
+ getUserAuthByUsernameFunc: func(_ context.Context, _ string) (db.GetUserAuthByUsernameRow, error) {
+ return db.GetUserAuthByUsernameRow{}, dbErr
+ },
+ },
+ &mockTxManager{},
+ )
+
+ _, err := a.Login(context.Background(), "testuser", "any")
+ if !errors.Is(err, dbErr) {
+ t.Errorf("expected db error, got: %v", err)
+ }
+}