package core import ( "fmt" "testing" "time" ) func TestNewJWT(t *testing.T) { j := newJWT(JWTOptions{ SigningKey: "testsigning", LifetimeMinutes: 2, }) if fmt.Sprintf("%T", j) != "*core.JWT" { t.Errorf("failed testing new jwt") } } func TestResolveJWT(t *testing.T) { initiateJWTHelper(t) j := resolveJWT() if fmt.Sprintf("%T", j) != "*core.JWT" { t.Errorf("failed testing resolve jwt") } } func TestGenerateToken(t *testing.T) { j := initiateJWTHelper(t) token, err := j.GenerateToken(map[string]interface{}{ "testKey": "testVal", }) if err != nil || token == "" { t.Errorf("error testing generate jwt token") } d, err := j.DecodeToken(token) if err != nil { t.Errorf("error testing generate jwt token: %v", err.Error()) } if d["testKey"] != "testVal" { t.Errorf("error testing generate jwt token: %v", err.Error()) } } func TestDecodeToken(t *testing.T) { expiredToken := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJKIjoiZXlKMFpYTjBTMlY1SWpvaWRHVnpkRlpoYkNKOSIsImV4cCI6MTY4NDkyMzQwOX0.v2aM9OTDJ48L4KnGjfLH3JAFQw4Gkgj5z7cA7txPNag" j := initiateJWTHelper(t) _, err := j.DecodeToken(expiredToken) if err == nil { t.Errorf("failed test decode token") } token, err := j.GenerateToken(map[string]interface{}{ "testKey": "testVal", }) if err != nil || token == "" { t.Errorf("failed testing decode token") } d, err := j.DecodeToken(token) if err != nil { t.Errorf("error testing decode jwt token") } if d["testKey"] != "testVal" { t.Errorf("error testing decode jwt token") } d, err = j.DecodeToken("test-token") if err == nil { t.Errorf("error testing decode jwt token") } } func TestHasExpired(t *testing.T) { expiredToken := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJKIjoiZXlKMFpYTjBTMlY1SWpvaWRHVnpkRlpoYkNKOSIsImV4cCI6MTY4NDkyMzQwOX0.v2aM9OTDJ48L4KnGjfLH3JAFQw4Gkgj5z7cA7txPNag" j := initiateJWTHelper(t) tokenHasExpired, err := j.HasExpired(expiredToken) if !tokenHasExpired { t.Errorf("failed test token has expired check") } if tokenHasExpired && err != nil { t.Errorf("failed test decode token: %v", err.Error()) } token, err := j.GenerateToken(map[string]interface{}{ "testKey": "testVal", }) if err != nil || token == "" { t.Errorf("failed testing decode token") } _, err = j.HasExpired(token) if err != nil { t.Errorf("error testing decode jwt token") } } func TestMapClaims(t *testing.T) { c, err := mapClaims(map[string]interface{}{ "testKey": "testVal", }, time.Now()) if err != nil { t.Errorf("failed testing map claims") } if fmt.Sprintf("%T", c) != "core.claims" { t.Errorf("failed testing map claims") } } func TestLifetimeMinutes(t *testing.T) { j := newJWT(JWTOptions{ SigningKey: "testsigning", LifetimeMinutes: 42, }) if j.LifetimeMinutes() != 42 { t.Errorf("expected lifetime 42, got %d", j.LifetimeMinutes()) } } func TestExpiresAtIgnoreExpiry(t *testing.T) { j := initiateJWTHelper(t) token, err := j.GenerateToken(map[string]interface{}{ "userID": 1, }) if err != nil { t.Fatalf("failed generating token: %v", err) } exp, err := j.ExpiresAtIgnoreExpiry(token) if err != nil { t.Fatalf("failed testing expires at ignore expiry: %v", err) } expected := time.Now().Add(time.Duration(j.LifetimeMinutes()) * time.Minute) if diff := exp.Sub(expected); diff > time.Minute || diff < -time.Minute { t.Errorf("expected expiration close to %v, got %v", expected, exp) } // An expired token must still return its expiration (no validation performed). expiredToken := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJKIjoiZXlKMFpYTjBTMlY1SWpvaWRHVnpkRlpoYkNKOSIsImV4cCI6MTY4NDkyMzQwOX0.v2aM9OTDJ48L4KnGjfLH3JAFQw4Gkgj5z7cA7txPNag" _, err = j.ExpiresAtIgnoreExpiry(expiredToken) if err != nil { t.Errorf("expected to read expiration of an expired token, got error: %v", err) } } func TestExpiresAtIgnoreExpiryInvalid(t *testing.T) { j := initiateJWTHelper(t) _, err := j.ExpiresAtIgnoreExpiry("not-a-token") if err == nil { t.Errorf("expected error for an invalid token") } } func TestDecodeTokenIgnoreExpiry(t *testing.T) { j := initiateJWTHelper(t) // An already expired token should still be decodable. expiredToken := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJKIjoiZXlKMFpYTjBTMlY1SWpvaWRHVnpkRlpoYkNKOSIsImV4cCI6MTY4NDkyMzQwOX0.v2aM9OTDJ48L4KnGjfLH3JAFQw4Gkgj5z7cA7txPNag" _, err := j.DecodeTokenIgnoreExpiry(expiredToken) if err != nil { t.Errorf("expected to decode an expired token ignoring expiry, got: %v", err) } token, err := j.GenerateToken(map[string]interface{}{ "userID": 99, }) if err != nil { t.Fatalf("failed generating token: %v", err) } payload, err := j.DecodeTokenIgnoreExpiry(token) if err != nil { t.Fatalf("failed decoding token ignoring expiry: %v", err) } if fmt.Sprintf("%v", payload["userID"]) != "99" { t.Errorf("expected userID 99, got %v", payload["userID"]) } // An invalid token must fail. if _, err := j.DecodeTokenIgnoreExpiry("invalid"); err == nil { t.Errorf("expected error decoding an invalid token") } } func initiateJWTHelper(t *testing.T) *JWT { t.Helper() j := newJWT(JWTOptions{ SigningKey: "testsigning", LifetimeMinutes: 2, }) return j }