package entity import ( "testing" "time" "github.com/stretchr/testify/assert" ) func TestBlacklistEntry_IsExpired(t *testing.T) { tests := []struct { name string entry *BlacklistEntry expected bool }{ { name: "expired entry", entry: &BlacklistEntry{ JTI: "test-jti", UID: "test-uid", TokenID: "test-token", ExpiresAt: time.Now().Add(-time.Hour).Unix(), CreatedAt: time.Now().Unix(), }, expected: true, }, { name: "not expired entry", entry: &BlacklistEntry{ JTI: "test-jti", UID: "test-uid", TokenID: "test-token", ExpiresAt: time.Now().Add(time.Hour).Unix(), CreatedAt: time.Now().Unix(), }, expected: false, }, { name: "exactly at expiry time", entry: &BlacklistEntry{ JTI: "test-jti", UID: "test-uid", TokenID: "test-token", ExpiresAt: time.Now().Unix(), CreatedAt: time.Now().Unix(), }, expected: true, // Equal to current time should be considered expired }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := tt.entry.IsExpired() assert.Equal(t, tt.expected, result) }) } } func TestBlacklistEntry_Validate(t *testing.T) { tests := []struct { name string entry *BlacklistEntry wantErr bool expectedErr error }{ { name: "valid entry", entry: &BlacklistEntry{ JTI: "test-jti", UID: "test-uid", TokenID: "test-token", Reason: "user logout", ExpiresAt: time.Now().Add(time.Hour).Unix(), CreatedAt: time.Now().Unix(), }, wantErr: false, }, { name: "missing JTI", entry: &BlacklistEntry{ JTI: "", UID: "test-uid", TokenID: "test-token", ExpiresAt: time.Now().Add(time.Hour).Unix(), CreatedAt: time.Now().Unix(), }, wantErr: true, expectedErr: ErrInvalidJTI, }, { name: "missing UID", entry: &BlacklistEntry{ JTI: "test-jti", UID: "", TokenID: "test-token", ExpiresAt: time.Now().Add(time.Hour).Unix(), CreatedAt: time.Now().Unix(), }, wantErr: true, expectedErr: ErrInvalidUID, }, { name: "missing TokenID", entry: &BlacklistEntry{ JTI: "test-jti", UID: "test-uid", TokenID: "", ExpiresAt: time.Now().Add(time.Hour).Unix(), CreatedAt: time.Now().Unix(), }, wantErr: true, expectedErr: ErrInvalidTokenID, }, { name: "all fields missing", entry: &BlacklistEntry{ JTI: "", UID: "", TokenID: "", }, wantErr: true, expectedErr: ErrInvalidJTI, // First error encountered }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := tt.entry.Validate() if tt.wantErr { assert.Error(t, err) if tt.expectedErr != nil { assert.Equal(t, tt.expectedErr, err) } } else { assert.NoError(t, err) } }) } } func TestBlacklistEntry_CreatedAt(t *testing.T) { now := time.Now().Unix() entry := &BlacklistEntry{ JTI: "test-jti", UID: "test-uid", TokenID: "test-token", Reason: "security", ExpiresAt: time.Now().Add(time.Hour).Unix(), CreatedAt: now, } assert.Equal(t, now, entry.CreatedAt) } func TestBlacklistEntry_Reason(t *testing.T) { tests := []struct { name string reason string }{ { name: "user logout reason", reason: "user logout", }, { name: "security breach reason", reason: "security breach detected", }, { name: "password reset reason", reason: "password reset", }, { name: "empty reason", reason: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { entry := &BlacklistEntry{ JTI: "test-jti", UID: "test-uid", TokenID: "test-token", Reason: tt.reason, ExpiresAt: time.Now().Add(time.Hour).Unix(), CreatedAt: time.Now().Unix(), } assert.Equal(t, tt.reason, entry.Reason) }) } }