-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathoso.guard.spec.ts
78 lines (66 loc) · 2.81 KB
/
oso.guard.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import { ExecutionContext, ForbiddenException, Type, UnauthorizedException } from '@nestjs/common';
import { HttpArgumentsHost } from '@nestjs/common/interfaces';
import { Reflector } from '@nestjs/core';
import { mock } from 'jest-mock-extended';
import { Oso } from 'oso';
import { OsoInstance } from './oso-instance';
import { authorizeFactory, OsoGuard } from './oso.guard';
describe('OsoGuard', () => {
let handler;
let reflector: Reflector;
let osoInstance: OsoInstance;
let executionContext: ExecutionContext;
let osoGuard: OsoGuard;
let mockGetRequest;
let request;
beforeEach(() => {
handler = jest.fn();
request = {};
reflector = mock<Reflector>();
osoInstance = mock<OsoInstance>();
executionContext = mock<ExecutionContext>();
const httpContext: HttpArgumentsHost = mock<HttpArgumentsHost>();
jest.spyOn(executionContext, 'getHandler').mockReturnValue(handler);
jest.spyOn(executionContext, 'switchToHttp').mockReturnValue(httpContext);
mockGetRequest = jest.spyOn(httpContext, 'getRequest');
mockGetRequest.mockReturnValue(request);
osoGuard = new OsoGuard(reflector, osoInstance);
});
afterEach(() => {
jest.resetAllMocks();
});
it('should be defined', () => {
expect(OsoGuard).toBeDefined();
});
it('should implement canActivate()', async () => {
const mockIsAllowed = jest.spyOn(osoInstance, 'isAllowed');
const handlerClass: Type<any> = mock<Type<any>>();
jest.spyOn(executionContext, 'getClass').mockReturnValue(handlerClass);
mockIsAllowed.mockReturnValueOnce(Promise.resolve(true));
const returnValue = await osoGuard.canActivate(executionContext);
expect(mockIsAllowed).toHaveBeenCalledTimes(1);
expect(returnValue).toBeTruthy();
});
it('should have an authorize factory for the @Authorize decorator', async () => {
// TODO: refactor the plumbing so the different cases may easily have their own tests.
const data = 'data';
const resource = {};
const mockOso = {
isAllowed: jest.fn()
};
request.oso = mockOso;
mockOso.isAllowed.mockReturnValue(Promise.resolve(true));
expect(request.oso).toBeDefined();
let authorizeFunction = authorizeFactory(data, executionContext);
await authorizeFunction(resource);
expect(mockOso.isAllowed).toHaveBeenCalledTimes(1);
// test the case where data is undefined
// TODO: Break these out into separate tests so that it's not so fragile
authorizeFunction = authorizeFactory(undefined, executionContext);
await authorizeFunction(resource);
expect(mockOso.isAllowed).toHaveBeenCalledTimes(2);
// test the unauthorized case: should throw a ForbiddenException
mockOso.isAllowed.mockReturnValueOnce(Promise.resolve(false));
await expect(authorizeFunction(resource)).rejects.toEqual(new ForbiddenException());
});
});