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")
|
||
|
|
}
|
||
|
|
}
|