The JWT checks worth testing on an API
Every request proves who it is. The network it came from is not the proof.
Token auth fails in a short list of ways. Test those ways directly. A green suite that never sends an expired token has not tested auth.
What the token may claim
An access token can carry a subject, a role, and an expiry. It should not carry the id of the record being viewed, and it should not carry a permission that was true at login and might be false now. Role decides which routes exist. The route still loads the row and checks that this subject may see it.
A record can be reassigned while a tab stays open. The token is still valid. The row may no longer belong to that subject. A claim baked in at login would keep showing the file. The database check does not.
What verification rejects
const claims = jwt.verify(token, key, {
algorithms: ["RS256"],
audience: "api",
issuer: "auth",
});
Pin the algorithm list. A token that names a method this API does not use is not verified under some friendlier method. Reject a missing audience. Reject an expired token. Do not add a grace window that accepts a dead token because a clock might be skewed. If clocks are wrong, fix the hosts.
Refresh is a different call, with a different secret. The refresh token is the one you can revoke in a table. Do not put it where a third-party script can read it, and do not write either token into a log line.
Two tests cover most of the bugs
One test calls a real route with an expired token and expects 401. One calls it with a valid token for a user who does not own the row and expects 403. Most auth bugs are variations of those two.
A socket handshake can use the same verification, and then it should stop. A live event is not a side door around the row check. That split is what the event is allowed to contain.