| Test Case | Status | Expected | Decoded Payload / Error |
|---|---|---|---|
| Valid Token | PASS | SHOULD SUCCEED | {
"iss": "https://issuer.example",
"aud": [
"https://myapi.example"
],
"sub": "user123",
"jti": "8b593f022668628235895b14f40669bc",
"iat": 1758266368,
"exp": 1758269968,
"role": "admin"
} |
| Expired Token | PASS | SHOULD ERROR | Token decode failed: Token expired. |
| Missing Claim (sub) | PASS | SHOULD ERROR | Failed to generate JWT token. |
| Invalid Signature (tampered payload) | PASS | SHOULD ERROR | Token decode failed: Invalid signature. |
| Invalid Signature (signed by different key) | PASS | SHOULD ERROR | Token decode failed: Invalid signature. |
| Not Yet Valid (nbf in future beyond leeway) | PASS | SHOULD ERROR | Token decode failed: Token not yet valid. |
| Invalid Audience | PASS | SHOULD ERROR | Failed to generate JWT token. |
| Invalid Issuer | PASS | SHOULD ERROR | Failed to generate JWT token. |
| Malformed JWT (two segments) | PASS | SHOULD ERROR | Token decode failed: Invalid JWT structure. |
| Empty Payload | PASS | SHOULD ERROR | Failed to generate JWT token. |
| Algorithm Header Tampered (alg=none) | PASS | SHOULD ERROR | Token decode failed: Unsupported or missing algorithm. |
| Oversized Payload | PASS | SHOULD ERROR | Failed to generate JWT token. |
| Future iat within leeway (should succeed) | PASS | SHOULD SUCCEED | {
"iss": "https://issuer.example",
"aud": [
"https://myapi.example"
],
"sub": "user789",
"jti": "21e4772b9d38bf8dbed50cbba5da8cf1",
"iat": 1758266398,
"exp": 1758269968
} |
| nbf slightly in future within leeway (should succeed) | PASS | SHOULD SUCCEED | {
"iss": "https://issuer.example",
"aud": [
"https://myapi.example"
],
"sub": "user999",
"jti": "86456521739cdf5d668b6063d7fc317c",
"iat": 1758266368,
"nbf": 1758266398,
"exp": 1758269968
} |
Notes: This harness first tries to use the library's `JwtEncode::sign()` (preserving its encode-time enforcement). If signing fails but the test intends to exercise verify-time failures, the harness will manually construct and sign a RS256 JWT to allow `JwtDecode::verify()` to be exercised. Tests that are supposed to fail during generation should indicate that by using `"expectedErrorContains": "generate jwt"` (substring match is used). Leeway applied to verify(): 60s.