291 lines
7.0 KiB
Go
291 lines
7.0 KiB
Go
package models
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
func TestAccessTokenCreation(t *testing.T) {
|
|
token := &AccessToken{
|
|
Email: TestEmail,
|
|
SessionID: SessionID,
|
|
Exp: time.Now().Add(15 * time.Minute).Unix(),
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),
|
|
},
|
|
}
|
|
|
|
if token.Email != TestEmail {
|
|
t.Errorf("Expected email 'test@example.com', got '%s'", token.Email)
|
|
}
|
|
|
|
if token.SessionID != SessionID {
|
|
t.Errorf("Expected session ID 'session-123', got '%s'", token.SessionID)
|
|
}
|
|
|
|
if token.Exp == 0 {
|
|
t.Error("Expected Exp to be set, got 0")
|
|
}
|
|
}
|
|
|
|
func TestAccessTokenExpiration(t *testing.T) {
|
|
expTime := time.Now().Add(15 * time.Minute)
|
|
token := &AccessToken{
|
|
Exp: expTime.Unix(),
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
ExpiresAt: jwt.NewNumericDate(expTime),
|
|
},
|
|
}
|
|
|
|
// Check if token is not expired
|
|
if time.Now().Unix() > token.Exp {
|
|
t.Error("Token should not be expired")
|
|
}
|
|
|
|
// Test expired token
|
|
expiredToken := &AccessToken{
|
|
Email: TestEmail,
|
|
SessionID: "session-456",
|
|
Exp: time.Now().Add(-1 * time.Hour).Unix(),
|
|
}
|
|
|
|
if expiredToken.Email != TestEmail {
|
|
t.Errorf("Expected email 'test@example.com', got '%s'", expiredToken.Email)
|
|
}
|
|
|
|
if expiredToken.SessionID != "session-456" {
|
|
t.Errorf("Expected session ID 'session-456', got '%s'", expiredToken.SessionID)
|
|
}
|
|
|
|
if time.Now().Unix() <= expiredToken.Exp {
|
|
t.Error("Token should be expired")
|
|
}
|
|
}
|
|
|
|
func TestJWTSessionCreation(t *testing.T) {
|
|
now := time.Now()
|
|
session := &JWTSession{
|
|
ID: "session-id-123",
|
|
UserID: "user-456",
|
|
RefreshTokenHash: "hash123",
|
|
UserAgent: "Mozilla/5.0",
|
|
IPAddress: "192.168.1.1",
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
ExpiresAt: now.Add(7 * 24 * time.Hour),
|
|
IsRevoked: false,
|
|
}
|
|
|
|
if session.ID != "session-id-123" {
|
|
t.Errorf("Expected session ID 'session-id-123', got '%s'", session.ID)
|
|
}
|
|
|
|
if session.UserID != "user-456" {
|
|
t.Errorf("Expected user ID 'user-456', got '%s'", session.UserID)
|
|
}
|
|
|
|
if session.RefreshTokenHash != "hash123" {
|
|
t.Errorf("Expected refresh token hash 'hash123', got '%s'", session.RefreshTokenHash)
|
|
}
|
|
|
|
if session.UserAgent != "Mozilla/5.0" {
|
|
t.Errorf("Expected user agent 'Mozilla/5.0', got '%s'", session.UserAgent)
|
|
}
|
|
|
|
if session.IPAddress != "192.168.1.1" {
|
|
t.Errorf("Expected IP address '192.168.1.1', got '%s'", session.IPAddress)
|
|
}
|
|
|
|
if session.CreatedAt.IsZero() {
|
|
t.Error("Expected CreatedAt to be set")
|
|
}
|
|
|
|
if session.UpdatedAt.IsZero() {
|
|
t.Error("Expected UpdatedAt to be set")
|
|
}
|
|
|
|
if session.ExpiresAt.IsZero() {
|
|
t.Error("Expected ExpiresAt to be set")
|
|
}
|
|
|
|
if session.IsRevoked {
|
|
t.Error("Expected session to not be revoked")
|
|
}
|
|
}
|
|
|
|
func TestJWTSessionIsExpired(t *testing.T) {
|
|
now := time.Now()
|
|
|
|
// Active session
|
|
activeSession := &JWTSession{
|
|
ID: "active-session",
|
|
ExpiresAt: now.Add(1 * time.Hour),
|
|
IsRevoked: false,
|
|
}
|
|
|
|
if activeSession.ID != "active-session" {
|
|
t.Errorf("Expected ID 'active-session', got '%s'", activeSession.ID)
|
|
}
|
|
|
|
if activeSession.IsRevoked {
|
|
t.Error("Active session should not be revoked")
|
|
}
|
|
|
|
if activeSession.ExpiresAt.Before(now) {
|
|
t.Error("Active session should not be expired")
|
|
}
|
|
|
|
// Expired session
|
|
expiredSession := &JWTSession{
|
|
ID: "expired-session",
|
|
ExpiresAt: now.Add(-1 * time.Hour),
|
|
IsRevoked: false,
|
|
}
|
|
|
|
if expiredSession.ID != "expired-session" {
|
|
t.Errorf("Expected ID 'expired-session', got '%s'", expiredSession.ID)
|
|
}
|
|
|
|
if expiredSession.IsRevoked {
|
|
t.Error("Expired session should not be marked as revoked initially")
|
|
}
|
|
|
|
if !expiredSession.ExpiresAt.Before(now) {
|
|
t.Error("Expired session should be marked as expired")
|
|
}
|
|
}
|
|
|
|
func TestJWTSessionRevokedStatus(t *testing.T) {
|
|
session := &JWTSession{
|
|
ID: "test-session",
|
|
IsRevoked: false,
|
|
}
|
|
|
|
if session.ID != "test-session" {
|
|
t.Errorf("Expected ID 'test-session', got '%s'", session.ID)
|
|
}
|
|
|
|
if session.IsRevoked {
|
|
t.Error("New session should not be revoked")
|
|
}
|
|
|
|
// Simulate revocation
|
|
session.IsRevoked = true
|
|
|
|
if !session.IsRevoked {
|
|
t.Error("Session should be revoked after setting IsRevoked to true")
|
|
}
|
|
}
|
|
|
|
func TestExpiredSessionCreation(t *testing.T) {
|
|
expiredSession := ExpiredSession{
|
|
ID: "expired-id-123",
|
|
UserID: "user-789",
|
|
RefreshTokenHash: "expired-hash",
|
|
}
|
|
|
|
if expiredSession.ID != "expired-id-123" {
|
|
t.Errorf("Expected ID 'expired-id-123', got '%s'", expiredSession.ID)
|
|
}
|
|
|
|
if expiredSession.UserID != "user-789" {
|
|
t.Errorf("Expected UserID 'user-789', got '%s'", expiredSession.UserID)
|
|
}
|
|
|
|
if expiredSession.RefreshTokenHash != "expired-hash" {
|
|
t.Errorf("Expected RefreshTokenHash 'expired-hash', got '%s'", expiredSession.RefreshTokenHash)
|
|
}
|
|
}
|
|
|
|
func TestJWTSessionUpdateActivity(t *testing.T) {
|
|
now := time.Now()
|
|
session := &JWTSession{
|
|
ID: SessionID,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
if session.ID != SessionID {
|
|
t.Errorf("expected session ID %s, got %s", SessionID, session.ID)
|
|
}
|
|
|
|
// Simulate activity update
|
|
time.Sleep(10 * time.Millisecond)
|
|
newUpdateTime := time.Now()
|
|
session.UpdatedAt = newUpdateTime
|
|
|
|
if !session.UpdatedAt.After(session.CreatedAt) {
|
|
t.Error("UpdatedAt should be after CreatedAt after activity update")
|
|
}
|
|
|
|
if session.UpdatedAt.Before(now) {
|
|
t.Error("UpdatedAt should be more recent than original time")
|
|
}
|
|
}
|
|
|
|
func TestJWTSessionSecurityFields(t *testing.T) {
|
|
session := &JWTSession{
|
|
ID: SessionID,
|
|
UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
|
|
IPAddress: "192.168.1.100",
|
|
}
|
|
|
|
if session.ID != SessionID {
|
|
t.Errorf("Expected ID %s", session.ID)
|
|
}
|
|
|
|
// Test user agent validation
|
|
expectedUserAgent := "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
|
if session.UserAgent != expectedUserAgent {
|
|
t.Errorf("Expected user agent '%s', got '%s'", expectedUserAgent, session.UserAgent)
|
|
}
|
|
|
|
// Test IP address validation
|
|
expectedIP := "192.168.1.100"
|
|
if session.IPAddress != expectedIP {
|
|
t.Errorf("Expected IP address '%s', got '%s'", expectedIP, session.IPAddress)
|
|
}
|
|
|
|
// Test mismatch scenario
|
|
if session.UserAgent == "Different Browser" {
|
|
t.Error("User agent should not match different value")
|
|
}
|
|
|
|
if session.IPAddress == "10.0.0.1" {
|
|
t.Error("IP address should not match different value")
|
|
}
|
|
}
|
|
|
|
func TestJWTSessionTimeValidation(t *testing.T) {
|
|
now := time.Now()
|
|
futureTime := now.Add(7 * 24 * time.Hour)
|
|
|
|
session := &JWTSession{
|
|
ID: SessionID,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
ExpiresAt: futureTime,
|
|
}
|
|
|
|
if session.ID != SessionID {
|
|
t.Errorf("Expected ID %s, got %s", SessionID, session.ID)
|
|
}
|
|
|
|
// CreatedAt should not be after UpdatedAt
|
|
if session.CreatedAt.After(session.UpdatedAt) {
|
|
t.Error("CreatedAt should not be after UpdatedAt")
|
|
}
|
|
|
|
// ExpiresAt should be after CreatedAt
|
|
if !session.ExpiresAt.After(session.CreatedAt) {
|
|
t.Error("ExpiresAt should be after CreatedAt")
|
|
}
|
|
|
|
// Session should not be expired
|
|
if session.ExpiresAt.Before(now) {
|
|
t.Error("Session should not be expired yet")
|
|
}
|
|
}
|