9992fb4ef1
Refactor the application to a Go-based architecture for improved performance and maintainability. Replace the Dockerfile to utilize a multi-stage build process, enhancing image efficiency. Implement comprehensive session store tests to ensure reliability and create new OAuth handlers for managing authentication efficiently. Update documentation to reflect these structural changes.
162 lines
3.6 KiB
Go
162 lines
3.6 KiB
Go
package store
|
|
|
|
import (
|
|
"log/slog"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestSessionStore_CreateAndGet(t *testing.T) {
|
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
|
store := NewSessionStore(logger)
|
|
|
|
session := &Session{
|
|
Email: "test@example.com",
|
|
ClientID: "client-123",
|
|
CodeChallenge: "challenge-abc",
|
|
}
|
|
|
|
store.Create("code-123", session)
|
|
|
|
retrieved, ok := store.Get("code-123")
|
|
if !ok {
|
|
t.Fatal("expected to find session")
|
|
}
|
|
|
|
if retrieved.Email != "test@example.com" {
|
|
t.Errorf("expected email test@example.com, got %s", retrieved.Email)
|
|
}
|
|
|
|
if retrieved.CreatedAt.IsZero() {
|
|
t.Error("expected CreatedAt to be set")
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_Delete(t *testing.T) {
|
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
|
store := NewSessionStore(logger)
|
|
|
|
session := &Session{Email: "test@example.com"}
|
|
store.Create("code-123", session)
|
|
|
|
store.Delete("code-123")
|
|
|
|
_, ok := store.Get("code-123")
|
|
if ok {
|
|
t.Error("expected session to be deleted")
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_Update(t *testing.T) {
|
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
|
store := NewSessionStore(logger)
|
|
|
|
session := &Session{
|
|
Email: "test@example.com",
|
|
Nonce: "old-nonce",
|
|
}
|
|
store.Create("old-code", session)
|
|
|
|
// Update and re-index
|
|
ok := store.Update("old-code", "new-code", func(s *Session) {
|
|
s.Nonce = "new-nonce"
|
|
})
|
|
|
|
if !ok {
|
|
t.Fatal("expected update to succeed")
|
|
}
|
|
|
|
// Old code should not exist
|
|
_, ok = store.Get("old-code")
|
|
if ok {
|
|
t.Error("expected old code to be removed")
|
|
}
|
|
|
|
// New code should exist
|
|
retrieved, ok := store.Get("new-code")
|
|
if !ok {
|
|
t.Fatal("expected to find session with new code")
|
|
}
|
|
|
|
if retrieved.Nonce != "new-nonce" {
|
|
t.Errorf("expected nonce new-nonce, got %s", retrieved.Nonce)
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_UpdateSameCode(t *testing.T) {
|
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
|
store := NewSessionStore(logger)
|
|
|
|
session := &Session{
|
|
Email: "test@example.com",
|
|
Nonce: "old-nonce",
|
|
}
|
|
store.Create("code-123", session)
|
|
|
|
originalTime := session.CreatedAt
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
// Update without re-indexing
|
|
store.Update("code-123", "code-123", func(s *Session) {
|
|
s.Nonce = "new-nonce"
|
|
})
|
|
|
|
retrieved, _ := store.Get("code-123")
|
|
if retrieved.Nonce != "new-nonce" {
|
|
t.Errorf("expected nonce new-nonce, got %s", retrieved.Nonce)
|
|
}
|
|
|
|
// CreatedAt should be refreshed
|
|
if !retrieved.CreatedAt.After(originalTime) {
|
|
t.Error("expected CreatedAt to be refreshed")
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_UpdateNotFound(t *testing.T) {
|
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
|
store := NewSessionStore(logger)
|
|
|
|
ok := store.Update("nonexistent", "new-code", func(s *Session) {})
|
|
if ok {
|
|
t.Error("expected update to fail for nonexistent session")
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_Cleanup(t *testing.T) {
|
|
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
|
store := NewSessionStore(logger)
|
|
|
|
// Create an expired session
|
|
session := &Session{Email: "test@example.com"}
|
|
store.Create("code-123", session)
|
|
|
|
// Manually set CreatedAt to expired time
|
|
store.mu.Lock()
|
|
store.sessions["code-123"].CreatedAt = time.Now().Add(-10 * time.Minute)
|
|
store.mu.Unlock()
|
|
|
|
// Create a valid session
|
|
validSession := &Session{Email: "valid@example.com"}
|
|
store.Create("code-456", validSession)
|
|
|
|
// Run cleanup
|
|
cleaned := store.Cleanup()
|
|
|
|
if cleaned != 1 {
|
|
t.Errorf("expected 1 session cleaned, got %d", cleaned)
|
|
}
|
|
|
|
// Expired session should be gone
|
|
_, ok := store.Get("code-123")
|
|
if ok {
|
|
t.Error("expected expired session to be cleaned up")
|
|
}
|
|
|
|
// Valid session should still exist
|
|
_, ok = store.Get("code-456")
|
|
if !ok {
|
|
t.Error("expected valid session to still exist")
|
|
}
|
|
}
|