// Copyright (C) 2025 Marius Schellenberger package jwt import ( "bytes" "errors" "testing" "time" ) var claims = Claims{ "sub": "1234567890", "name": "John Doe", "admin": true, "fizz": "buzz", } func TestValidate(t *testing.T) { jwt, err := New( WithExpiry(time.Second), WithBlacklist(NewMemBlacklist()), ) if err != nil { t.Error(err) } token := NewToken(claims.Copy(), nil) err = jwt.Sign(token) if err != nil { t.Error(err) } _, err = DecodeToken("") if err == nil { t.Error(errors.New("token is empty")) } nt, err := DecodeToken(token.String()) if err != nil { t.Error(err) } err = jwt.Verify(nt) if err != nil { t.Error(err) } time.Sleep(time.Second * 2) err = jwt.Verify(nt) if err == nil { t.Error(errors.New("token should be expired")) } err = jwt.Invalidate(nt) if err == nil { t.Error(errors.New("token is expired")) } nt.Claims.Delete(ExpClaim) err = jwt.Sign(nt) if err != nil { t.Error(err) } err = jwt.Verify(nt) if err != nil { t.Error(err) } err = jwt.Invalidate(nt) if err != nil { t.Error(err) } err = jwt.Invalidate(nt) if err == nil { t.Error(errors.New("double invalidate")) } err = jwt.Verify(nt) if err == nil { t.Error(errors.New("token should be blacklisted")) } err = jwt.Stop() if err != nil { t.Error(err) } // should not panic err = jwt.Stop() if err != nil { t.Error(err) } } func TestNonce(t *testing.T) { jwt, err := New( WithExpiry(time.Second), WithNonce(), ) if err != nil { t.Error(err) } token := NewToken(claims.Copy(), nil) err = jwt.Sign(token) if err != nil { t.Error(err) } nt, err := DecodeToken(token.String()) if err != nil { t.Error(err) } err = jwt.Verify(nt) if err != nil { t.Error(err) } nonce := nt.Claims.GetString(NonceClaim) if nonce == "" { t.Error(errors.New("nonce is empty")) } } func TestNoBlacklist(t *testing.T) { jwt, err := New(WithExpiry(time.Second)) if err != nil { t.Error(err) } token := NewToken(claims.Copy(), nil) err = jwt.Sign(token) if err != nil { t.Error(err) } _, err = DecodeToken("") if err == nil { t.Error(errors.New("token is empty")) } nt, err := DecodeToken(token.String()) if err != nil { t.Error(err) } err = jwt.Verify(nt) if err != nil { t.Error(err) } time.Sleep(time.Second * 2) err = jwt.Verify(nt) if err == nil { t.Error(errors.New("token should be expired")) } err = jwt.Invalidate(nt) if err == nil { t.Error(errors.New("blacklisting should be disabled")) } } func TestEmptySecretReader(t *testing.T) { _, err := New( WithExpiry(time.Second), WithSecret(new(bytes.Buffer)), ) if err == nil { t.Error(errors.New("error should be secret reader error")) } } func TestInvalidSecretReader(t *testing.T) { _, err := New( WithExpiry(time.Second), WithSecret(bytes.NewBufferString("123")), ) if err != ErrInvalidKeySize { t.Error(errors.New("error should be invalid key size")) } } func BenchmarkDecodeToken(b *testing.B) { jwt, _ := New() t := NewToken(claims.Copy(), nil) jwt.Sign(t) token := t.String() b.ReportAllocs() for i := 0; i < b.N; i++ { DecodeToken(token) } } func BenchmarkNew(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { New() } } func BenchmarkNewWithBlacklist(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { New(WithBlacklist(NewMemBlacklist())) } } func BenchmarkSignHS256(b *testing.B) { jwt, _ := New() t := NewToken(claims.Copy(), nil) b.ReportAllocs() for i := 0; i < b.N; i++ { jwt.Sign(t) } } func BenchmarkSignHS384(b *testing.B) { jwt, _ := New() t := NewToken(claims.Copy(), NewHash(HS384Name)) b.ReportAllocs() for i := 0; i < b.N; i++ { jwt.Sign(t) } } func BenchmarkSignHS512(b *testing.B) { jwt, _ := New() t := NewToken(claims.Copy(), NewHash(HS512Name)) b.ReportAllocs() for i := 0; i < b.N; i++ { jwt.Sign(t) } } func BenchmarkVerifyHS256(b *testing.B) { jwt, _ := New() t := NewToken(claims.Copy(), nil) jwt.Sign(t) b.ReportAllocs() for i := 0; i < b.N; i++ { jwt.Verify(t) } } func BenchmarkVerifyHS384(b *testing.B) { jwt, _ := New() t := NewToken(claims.Copy(), NewHash(HS384Name)) jwt.Sign(t) b.ReportAllocs() for i := 0; i < b.N; i++ { jwt.Verify(t) } } func BenchmarkVerifyHS512(b *testing.B) { jwt, _ := New() t := NewToken(claims.Copy(), NewHash(HS512Name)) jwt.Sign(t) b.ReportAllocs() for i := 0; i < b.N; i++ { jwt.Verify(t) } }