Skip to content

Commit 974909a

Browse files
committed
add authentication tests
1 parent 7685bd1 commit 974909a

File tree

2 files changed

+127
-10
lines changed

2 files changed

+127
-10
lines changed

tests/auth/apikey.test.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
import supertest from 'supertest';
21
import app from '../../src/app';
2+
import supertest from 'supertest';
33
import ApiKeyRepo from '../../src/database/repository/ApiKeyRepo';
44
import { IApiKey } from '../../src/database/model/ApiKey';
55

6+
export const API_KEY = 'abc';
7+
8+
export const mockFindApiKey = jest.fn(async (key: string) => {
9+
if (key == API_KEY) return <IApiKey>{ key: API_KEY };
10+
else return null;
11+
});
12+
613
describe('apikey validation', () => {
714

15+
const endpoint = '/v1/dummy/test';
816
const request = supertest(app);
9-
const API_KEY = 'abc';
10-
11-
const mockFindApiKey = jest.fn(async key => {
12-
if (key == API_KEY) return <IApiKey>{ key: API_KEY };
13-
else return null;
14-
});
1517

1618
ApiKeyRepo.findByKey = mockFindApiKey;
1719

@@ -20,15 +22,15 @@ describe('apikey validation', () => {
2022
});
2123

2224
it('Should fail with 400 if api-key header is not passed', async () => {
23-
const response = await request.get('/v1/test');
25+
const response = await request.get(endpoint);
2426
expect(response.status).toBe(400);
2527
expect(mockFindApiKey).toBeCalledTimes(0);
2628
});
2729

2830
it('Should fail with 403 if wrong api-key header is passed', async () => {
2931
const wrongApiKey = '123';
3032
const response = await request
31-
.get('/v1')
33+
.get(endpoint)
3234
.set('x-api-key', wrongApiKey);
3335
expect(response.status).toBe(403);
3436
expect(mockFindApiKey).toBeCalledTimes(1);
@@ -37,7 +39,7 @@ describe('apikey validation', () => {
3739

3840
it('Should pass with 404 if correct api-key header is passed and when route is not handelled', async () => {
3941
const response = await request
40-
.get('/v1')
42+
.get(endpoint)
4143
.set('x-api-key', API_KEY);
4244
expect(response.status).toBe(404);
4345
expect(mockFindApiKey).toBeCalledTimes(1);

tests/auth/authentication.test.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import app from '../../src/app';
2+
import supertest, { SuperTest } from 'supertest';
3+
import ApiKeyRepo from '../../src/database/repository/ApiKeyRepo';
4+
import UserRepo from '../../src/database/repository/UserRepo';
5+
import { IUser } from '../../src/database/model/User';
6+
import { Types } from 'mongoose';
7+
import { mockFindApiKey, API_KEY } from './apikey.test';
8+
import JWT, { ValidationParams, JwtPayload } from '../../src/core/JWT';
9+
import { BadTokenError } from '../../src/core/ApiError';
10+
import { IKeystore } from '../../src/database/model/Keystore';
11+
import KeystoreRepo from '../../src/database/repository/KeystoreRepo';
12+
13+
export const ACCESS_TOKEN = 'xyz';
14+
15+
export const USER_ID = new Types.ObjectId('5e7b95923085872d3c378f35'); // random id with object id format
16+
17+
const mockUserFindById = jest.fn(async (id: Types.ObjectId) => {
18+
if (USER_ID.equals(id)) return <IUser>{ _id: new Types.ObjectId(id) };
19+
else return null;
20+
});
21+
22+
const mockJwtValidate = jest.fn(
23+
async (token: string, validations: ValidationParams): Promise<JwtPayload> => {
24+
if (token == ACCESS_TOKEN) return <JwtPayload>{ prm: 'abcdef' };
25+
throw new BadTokenError();
26+
});
27+
28+
const mockKeystoreFindForKey = jest.fn(
29+
async (client: IUser, key: string): Promise<IKeystore> => (<IKeystore>{ client: client, primaryKey: key }));
30+
31+
jest.mock('../../src/auth/authUtils', () => ({
32+
get validateTokenData() {
33+
return jest.fn(async (payload: JwtPayload, userId: Types.ObjectId): Promise<JwtPayload> => payload);
34+
}
35+
}));
36+
37+
describe('authentication validation', () => {
38+
39+
const endpoint = '/v1/profile/my/test';
40+
const request = supertest(app);
41+
42+
UserRepo.findById = mockUserFindById;
43+
ApiKeyRepo.findByKey = mockFindApiKey;
44+
JWT.validate = mockJwtValidate;
45+
KeystoreRepo.findforKey = mockKeystoreFindForKey;
46+
47+
beforeEach(() => {
48+
mockUserFindById.mockClear();
49+
mockJwtValidate.mockClear();
50+
mockKeystoreFindForKey.mockClear();
51+
});
52+
53+
it('Should response with 400 if x-access-token header is not passed', async () => {
54+
const response = await addHeaders(request.get(endpoint))
55+
.set('x-user-id', USER_ID.toHexString());
56+
expect(response.status).toBe(400);
57+
expect(response.body.message).toMatch(/x-access-token/);
58+
expect(mockUserFindById).toBeCalledTimes(0);
59+
});
60+
61+
it('Should response with 400 if x-user-id header is not passed', async () => {
62+
const response = await addHeaders(request.get(endpoint))
63+
.set('x-access-token', ACCESS_TOKEN);
64+
expect(response.status).toBe(400);
65+
expect(response.body.message).toMatch(/x-user-id/);
66+
expect(mockUserFindById).toBeCalledTimes(0);
67+
});
68+
69+
it('Should response with 400 if x-user-id header is not mongoose id', async () => {
70+
const response = await addHeaders(request.get(endpoint))
71+
.set('x-access-token', ACCESS_TOKEN)
72+
.set('x-user-id', '123');
73+
expect(response.status).toBe(400);
74+
expect(response.body.message).toMatch(/x-user-id/);
75+
expect(mockUserFindById).toBeCalledTimes(0);
76+
});
77+
78+
it('Should response with 401 if wrong x-user-id header is provided', async () => {
79+
const response = await addHeaders(request.get(endpoint))
80+
.set('x-access-token', ACCESS_TOKEN)
81+
.set('x-user-id', '5e7b8c22d347fc2407c564a6'); // some random mongoose id
82+
expect(response.status).toBe(401);
83+
expect(response.body.message).toMatch(/not registered/);
84+
expect(mockUserFindById).toBeCalledTimes(1);
85+
});
86+
87+
it('Should response with 401 if wrong x-access-token header is provided', async () => {
88+
const response = await addHeaders(request.get(endpoint))
89+
.set('x-access-token', '123')
90+
.set('x-user-id', USER_ID);
91+
expect(response.status).toBe(401);
92+
expect(response.body.message).toMatch(/token/i);
93+
expect(mockUserFindById).toBeCalledTimes(1);
94+
});
95+
96+
it('Should response with 404 if correct x-access-token and x-user-id header are provided', async () => {
97+
const response = await addHeaders(request.get(endpoint))
98+
.set('x-access-token', ACCESS_TOKEN)
99+
.set('x-user-id', USER_ID.toHexString());
100+
expect(response.body.message).not.toMatch(/not registered/);
101+
expect(response.body.message).not.toMatch(/token/i);
102+
expect(response.status).toBe(404);
103+
expect(mockUserFindById).toBeCalledTimes(1);
104+
});
105+
});
106+
107+
export const addHeaders = (request: any) => request
108+
.set('Content-Type', 'application/json')
109+
.set('x-api-key', API_KEY);
110+
111+
export const addAuthHeaders = (request: any) => request
112+
.set('Content-Type', 'application/json')
113+
.set('x-api-key', API_KEY)
114+
.set('x-access-token', ACCESS_TOKEN)
115+
.set('x-user-id', USER_ID);

0 commit comments

Comments
 (0)