-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathdocument.controller.spec.ts
More file actions
150 lines (129 loc) · 6.02 KB
/
document.controller.spec.ts
File metadata and controls
150 lines (129 loc) · 6.02 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import { UnauthorizedException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Test, TestingModule } from '@nestjs/testing';
import { doc } from 'prettier';
import { OsoInstance } from '../oso/oso-instance';
import { OsoGuard } from '../oso/oso.guard';
import { OsoModule } from '../oso/oso.module';
import { DocumentController } from './document.controller';
import { DocumentService } from './document.service';
import { CreateDocumentDto, DocumentSetDto, FindDocumentDto } from './dto/document.dto';
import { Document } from './entity/document';
import { mock } from 'jest-mock-extended';
import { User } from 'src/users/entity/user';
import { Project } from 'src/project/project.service';
jest.mock('./document.service');
describe('Document Controller', () => {
let service: DocumentService;
let controller: DocumentController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [OsoModule],
controllers: [DocumentController],
providers: [DocumentService, OsoGuard],
exports: [OsoModule]
}).compile();
service = module.get<DocumentService>(DocumentService);
controller = module.get<DocumentController>(DocumentController);
});
afterEach(() => {
jest.resetAllMocks();
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
it('should find a document by id', async () => {
// prepare the return promise from DocumentService.findOne()
const expectedOwner = mock<User>();
const expectedProject = mock<Project>();
const expectedDocument: Document = new Document(100, expectedOwner, expectedProject, 'The document', true);
// mock Oso's authorize function
const mockAuthorize = jest.fn();
// mock param to have the document id
const id = expectedDocument.id.toString();
// mock service.findOne()
const mockFindOne = jest.spyOn(service, 'findOne');
// set the expected return promise from service.findOne()
mockFindOne.mockReturnValueOnce(Promise.resolve(expectedDocument));
// call the function under test
const actualDocument = await controller.findOne(id, mockAuthorize);
const documentContent = actualDocument.document;
// expect service.findOne to have been called
expect(mockFindOne).toHaveBeenCalledTimes(1);
expect(mockFindOne).toHaveBeenCalledWith(Number.parseInt(id));
// ensure authorize was called
expect(mockAuthorize).toHaveBeenCalledTimes(1);
expect(documentContent).toEqual(expectedDocument.document);
});
it('should return undefined when findOne does not find a document', async () => {
const mockFindOne = jest.spyOn(service, 'findOne');
const empty: Document = undefined;
mockFindOne.mockReturnValueOnce(Promise.resolve(empty));
const authorize = jest.fn();
const id = '100';
const expectedReturnValue = await controller.findOne(id, authorize);
expect(mockFindOne).toHaveBeenCalledTimes(1);
expect(mockFindOne).toHaveBeenCalledWith(Number.parseInt(id));
expect(authorize).toHaveBeenCalledTimes(1);
expect(authorize).toHaveBeenCalledWith(empty);
expect(expectedReturnValue).toEqual(empty);
});
it('should find and validate access to all documents', async () => {
const expectedProject: Project = mock<Project>();
const expectedOwner: User = mock<User>();
const expectedDocuments: Document[] = [
new Document(100, expectedOwner, expectedProject, 'First document', true),
new Document(100, expectedOwner, expectedProject, 'Second document', true)
];
const authorize = jest.fn();
const mockFindAll = jest.spyOn(service, 'findAll');
mockFindAll.mockReturnValue(Promise.resolve(expectedDocuments));
// call the function under test
const actualDocuments: DocumentSetDto = await controller.findAll(authorize);
// expect service.findAll to have been called
expect(mockFindAll).toHaveBeenCalledTimes(1);
// TODO: Add authorize() and test for call: https://github.com/oletizi/oso-nest-demo/issues/13
// expect authorize() function to have been called on each document
expect(authorize).toHaveBeenCalledTimes(expectedDocuments.length);
expectedDocuments.map((document) => expect(authorize).toHaveBeenCalledWith(document));
// expect the return value to equal an appropriate document set
expect(actualDocuments).toEqual(new DocumentSetDto(expectedDocuments));
});
it('should find all documents and filter access to unauthorized documents', async () => {
const expectedUser: User = mock<User>();
const expectedProject: Project = mock<Project>();
const allDocuments: Document[] = [
new Document(1, expectedUser, expectedProject, 'some content', true),
new Document(2, expectedUser, expectedProject, 'some other content', true)
];
const mockFindAll = jest.spyOn(service, 'findAll');
const mockAuthorize = jest.fn();
mockFindAll.mockReturnValue(Promise.resolve(allDocuments));
mockAuthorize.mockImplementation((document) => {
if (document.id === 1) {
throw new UnauthorizedException();
}
});
// call method under test
const actualDocuments = await controller.findAll(mockAuthorize);
// ensure all documents were checked for authorization
allDocuments.map((document) => expect(mockAuthorize).toHaveBeenCalledWith(document));
// ensure the unauthorized documents were filtered
expect(actualDocuments.documents.length).toEqual(allDocuments.length - 1);
});
it('should create a document', async () => {
const expectedId = 100;
const mockCreate = jest.spyOn(service, 'create');
mockCreate.mockReturnValueOnce(Promise.resolve(expectedId));
const doc = new CreateDocumentDto();
doc.document = 'new document';
const request = {
user: { id: 1 }
};
const authorize = jest.fn();
const id: number = await controller.create(authorize, request, doc);
// DocumentService.create() should have been called with the document DTO
expect(mockCreate).toHaveBeenCalledWith(doc, authorize);
expect(id).toEqual(expectedId);
});
});