Skip to content

Commit 83b29be

Browse files
committed
add JWT tests
1 parent 5acbd89 commit 83b29be

File tree

4 files changed

+141
-5
lines changed

4 files changed

+141
-5
lines changed

src/core/JWT.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default class JWT {
3838
const cert = await this.readPublicKey();
3939
try {
4040
// @ts-ignore
41-
return await promisify(verify)(token, cert, validations);
41+
return <JwtPayload>await promisify(verify)(token, cert, validations);
4242
} catch (e) {
4343
Logger.debug(e);
4444
if (e && e.name === 'TokenExpiredError') throw new TokenExpiredError();
@@ -58,11 +58,11 @@ export default class JWT {
5858
return <JwtPayload>await promisify(verify)(token, cert, validations);
5959
} catch (e) {
6060
Logger.debug(e);
61-
if (e.name === 'TokenExpiredError') {
61+
if (e && e.name === 'TokenExpiredError') {
6262
// if the token has expired but was encryped by the private key
6363
// then decode it to get the payload
6464
// @ts-ignore
65-
return <JwtPayload>await promisify(decode)(token);
65+
return <JwtPayload>decode(token);
6666
}
6767
else {
6868
// throws error if the token has not been encrypted by the private key

src/core/Logger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ export default createLogger({
3737
new transports.Console({
3838
level: logLevel,
3939
format: format.combine(
40-
format.colorize(),
4140
format.errors({ stack: true }),
42-
format.json())
41+
format.prettyPrint()
42+
)
4343
}),
4444
],
4545
exceptionHandlers: [

tests/core/jwt/index.test.ts

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { readFileSpy, ACCESS_TOKEN } from './mock';
2+
import JWT, { JwtPayload, ValidationParams } from '../../../src/core/JWT';
3+
import { BadTokenError, TokenExpiredError } from '../../../src/core/ApiError';
4+
5+
describe('JWT class tests', () => {
6+
7+
const issuer = 'issuer';
8+
const audience = 'audience';
9+
const subject = 'subject';
10+
const param = 'param';
11+
const validity = 1;
12+
13+
it('Should throw error for invalid token in JWT.decode', async () => {
14+
15+
beforeEach(() => {
16+
readFileSpy.mockClear();
17+
});
18+
19+
try {
20+
await JWT.decode('abc', new ValidationParams(issuer, audience, subject));
21+
} catch (e) {
22+
expect(e).toBeInstanceOf(BadTokenError);
23+
}
24+
25+
expect(readFileSpy).toBeCalledTimes(1);
26+
});
27+
28+
it('Should generate a token for JWT.encode', async () => {
29+
30+
beforeEach(() => {
31+
readFileSpy.mockClear();
32+
});
33+
34+
const payload = new JwtPayload(issuer, audience, subject, param, validity);
35+
const token = await JWT.encode(payload);
36+
37+
expect(typeof token).toBe('string');
38+
expect(readFileSpy).toBeCalledTimes(1);
39+
});
40+
41+
it('Should decode a valid token for JWT.decode', async () => {
42+
43+
beforeEach(() => {
44+
readFileSpy.mockClear();
45+
});
46+
47+
const payload = new JwtPayload(issuer, audience, subject, param, validity);
48+
const token = await JWT.encode(payload);
49+
const decoded = await JWT.decode(token, new ValidationParams(issuer, audience, subject));
50+
51+
expect(decoded).toMatchObject(payload);
52+
expect(readFileSpy).toBeCalledTimes(2);
53+
});
54+
55+
it('Should parse an expired token for JWT.decode', async () => {
56+
57+
beforeEach(() => {
58+
readFileSpy.mockClear();
59+
});
60+
61+
const time = Math.floor(Date.now() / 1000);
62+
63+
const payload = <JwtPayload>{
64+
aud: audience,
65+
sub: subject,
66+
iss: issuer,
67+
iat: time,
68+
exp: time,
69+
prm: param,
70+
};
71+
const token = await JWT.encode(payload);
72+
const decoded = await JWT.decode(token, new ValidationParams(issuer, audience, subject));
73+
74+
expect(decoded).toMatchObject(payload);
75+
expect(readFileSpy).toBeCalledTimes(2);
76+
});
77+
78+
it('Should throw error for invalid token in JWT.validate', async () => {
79+
80+
beforeEach(() => {
81+
readFileSpy.mockClear();
82+
});
83+
84+
try {
85+
await JWT.validate('abc', new ValidationParams(issuer, audience, subject));
86+
} catch (e) {
87+
expect(e).toBeInstanceOf(BadTokenError);
88+
}
89+
90+
expect(readFileSpy).toBeCalledTimes(1);
91+
});
92+
93+
it('Should validate a valid token for JWT.validate', async () => {
94+
95+
beforeEach(() => {
96+
readFileSpy.mockClear();
97+
});
98+
99+
const payload = new JwtPayload(issuer, audience, subject, param, validity);
100+
const token = await JWT.encode(payload);
101+
const decoded = await JWT.validate(token, new ValidationParams(issuer, audience, subject));
102+
103+
expect(decoded).toMatchObject(payload);
104+
expect(readFileSpy).toBeCalledTimes(2);
105+
});
106+
107+
it('Should validate a token expiry for JWT.validate', async () => {
108+
109+
beforeEach(() => {
110+
readFileSpy.mockClear();
111+
});
112+
113+
const time = Math.floor(Date.now() / 1000);
114+
115+
const payload = <JwtPayload>{
116+
aud: audience,
117+
sub: subject,
118+
iss: issuer,
119+
iat: time,
120+
exp: time,
121+
prm: param,
122+
};
123+
const token = await JWT.encode(payload);
124+
try {
125+
await JWT.validate(token, new ValidationParams(issuer, audience, subject));
126+
} catch (e) {
127+
expect(e).toBeInstanceOf(TokenExpiredError);
128+
}
129+
expect(readFileSpy).toBeCalledTimes(2);
130+
});
131+
});

tests/core/jwt/mock.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import fs from 'fs';
2+
3+
export const ACCESS_TOKEN = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZnRlcmFjYWRlbXkuY29tIiwiYXVkIjoiYWZ0ZXJhY2FkZW15X3VzZXJzIiwic3ViIjoiNWU3Yjk1OTIzMDg1ODcyZDNjMzc4ZjM1IiwiaWF0IjoxNTg1Mzk5MDY0LCJleHAiOjE1ODc5OTEwNjQsInBybSI6Ijk1MTY0ZTBlZjFiMDI1ZDJlNGI3ZGNmMzQwNjI0YTc0MTgwZjdhM2RhYWFiMzZhMDU1OTgwNjQ2ZGUzNmFlMGI2N2ZjODZjNGNkNmYxZmQzOTk0Y2Q0MWE5YmE3NjliMWFhMzQ0OTE4YWNiOTFkYmZhYjQ0ZmU0ZmMxZjc4ZGYyIn0.NYojtQhOx151ObtYiPLRIZkNV36ptMj-ZCihgcs2WZu4EDKsLjn3vuBpyK0BNESO1QBOMBh631vm3mCYTl3bCg';
4+
5+
export const readFileSpy = jest.spyOn(fs, 'readFile');

0 commit comments

Comments
 (0)