package auth import ( "errors" "testing" "time" "github.com/google/uuid" ) const qrTestSecret = "test-secret-must-be-at-least-32-bytes-long-xx" func TestCheckInQR_RoundTrip(t *testing.T) { s, err := NewCheckInQRSigner(qrTestSecret, "test", 6*time.Hour) if err != nil { t.Fatalf("new signer: %v", err) } eventID := uuid.New() guestID := uuid.New() now := time.Now().UTC() tok, exp, err := s.Issue(eventID, guestID, now.Add(24*time.Hour), now) if err != nil { t.Fatalf("issue: %v", err) } if !exp.After(now) { t.Fatalf("expiry should be in the future: %v vs now %v", exp, now) } claims, err := s.Parse(tok) if err != nil { t.Fatalf("parse: %v", err) } if claims.EventID != eventID || claims.GuestID != guestID { t.Errorf("ids mismatch: got %v / %v, want %v / %v", claims.EventID, claims.GuestID, eventID, guestID) } } func TestCheckInQR_RejectsWrongSecret(t *testing.T) { signerA, _ := NewCheckInQRSigner(qrTestSecret, "test", time.Hour) signerB, _ := NewCheckInQRSigner("other-secret-must-be-at-least-32-bytes-xx", "test", time.Hour) tok, _, err := signerA.Issue(uuid.New(), uuid.New(), time.Now().Add(time.Hour), time.Now()) if err != nil { t.Fatalf("issue: %v", err) } if _, err := signerB.Parse(tok); !errors.Is(err, ErrInvalidJWT) { t.Errorf("parse with wrong secret: want ErrInvalidJWT, got %v", err) } } func TestCheckInQR_RejectsExpired(t *testing.T) { s, _ := NewCheckInQRSigner(qrTestSecret, "test", time.Second) // Use a "now" far enough in the past that even the eventDate+24h // extension lands before the actual current time. Two days ago for // both: expiry resolves to now-2d+1s OR now-2d+24h, the later wins, // so the token expires at now-1d — still in the past. pastNow := time.Now().UTC().Add(-48 * time.Hour) eventDate := pastNow tok, exp, err := s.Issue(uuid.New(), uuid.New(), eventDate, pastNow) if err != nil { t.Fatalf("issue: %v", err) } if exp.After(time.Now().UTC()) { t.Fatalf("setup bug: expected exp %v in the past", exp) } if _, err := s.Parse(tok); !errors.Is(err, ErrExpiredJWT) { t.Errorf("parse expired: want ErrExpiredJWT, got %v", err) } } func TestCheckInQR_SecretTooShort(t *testing.T) { if _, err := NewCheckInQRSigner("short", "test", time.Hour); err == nil { t.Error("expected error for too-short secret") } }