UNPKG

6.38 kBJavaScriptView Raw
1// Integration - test the router within the whole server functionality
2const server = require('server');
3const run = require('server/test/run');
4const { get, post, put, del, sub, error } = server.router;
5const { status } = server.reply;
6
7
8// Mock middlewares and data:
9const question = { answer: 42 };
10const mirror = ctx => ctx.data;
11const hello = () => 'Hello 世界';
12const throwError = () => {
13 const err = new Error('MockError');
14 err.code = 'test';
15 throw err;
16};
17
18
19
20// CSRF validation is checked in another place; disable it for these tests
21run.options = { security: false };
22
23describe('Basic router types', () => {
24 it('can do a GET request', async () => {
25 const mid = get('/', hello);
26
27 const res = await run(mid).get('/');
28 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
29 });
30
31 it('can skip a request', async () => {
32 let called = false;
33 const notCalled = ctx => {
34 called = true;
35 };
36 const mid = get('/', () => status(200).send('Done'), notCalled);
37
38 await run(mid).get('/');
39 expect(called).toBe(false);
40 });
41
42 it('can do a POST request', async () => {
43 const mid = post('/', ctx => ctx.data);
44
45 const res = await run(mid).post('/', { body: question });
46 expect(res.body).toEqual({ answer: 42 });
47 expect(res.status).toBe(200);
48 });
49
50 it('can do a PUT request', async () => {
51 const mid = post('/', ctx => ctx.data);
52
53 const res = await run(mid).post('/', { body: question });
54 expect(res.body).toEqual({ answer: 42 });
55 expect(res.status).toBe(200);
56 });
57
58 it('can do a DELETE request', async () => {
59 const mid = del('/', ctx => 'Hello 世界');
60
61 const res = await run(mid).del('/', { body: question });
62 expect(res.body).toEqual('Hello 世界');
63 expect(res.status).toBe(200);
64 });
65});
66
67
68describe('Generic paths', () => {
69 it('can do a GET request', async () => {
70 const mid = get(hello);
71
72 const res = await run(mid).get('/');
73 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
74 });
75
76 it('can do a GET request', async () => {
77 const mid = get('*', hello);
78
79 const res = await run(mid).get('/');
80 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
81 });
82
83 // it('can do a POST request', async () => {
84 // const mid = post('/', ctx => ctx.data);
85 //
86 // const res = await run(mid).post('/', { body: question });
87 // expect(res.body).toEqual({ answer: 42 });
88 // expect(res.status).toBe(200);
89 // });
90 //
91 // it('can do a PUT request', async () => {
92 // const mid = post('/', ctx => ctx.data);
93 //
94 // const res = await run(mid).post('/', { body: question });
95 // expect(res.body).toEqual({ answer: 42 });
96 // expect(res.status).toBe(200);
97 // });
98 //
99 // it('can do a DELETE request', async () => {
100 // const mid = del('/', ctx => 'Hello 世界');
101 //
102 // const res = await run(mid).del('/', { body: question });
103 // expect(res.body).toEqual('Hello 世界');
104 // expect(res.status).toBe(200);
105 // });
106});
107
108
109describe('Subdomain router', () => {
110 it('can do a request to a subdomain', async () => {
111 const mid = sub('api', get('/', hello));
112
113 const res = await run((ctx) => {
114 ctx.headers.host = 'api.example.com';
115 }, mid).get('/');
116 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
117 });
118
119 it('can handle regex', async () => {
120 const mid = sub(/^api$/, get('/', hello));
121
122 const res = await run((ctx) => {
123 ctx.headers.host = 'api.example.com';
124 }, mid).get('/');
125 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
126 });
127
128 it('does not do partial match', async () => {
129 const mid = sub(/^api$/, get('/', hello));
130
131 const res = await run((ctx) => {
132 ctx.headers.host = 'bla.api.example.com';
133 }, mid, () => 'Did not match').get('/');
134 expect(res).toMatchObject({ status: 200, body: 'Did not match' });
135 });
136
137 it('can do a request to a multi-level subdomain', async () => {
138 const mid = sub('api.local', get('/', hello));
139
140 const res = await run((ctx) => {
141 ctx.headers.host = 'api.local.example.com';
142 }, mid).get('/');
143 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
144 });
145});
146
147
148describe('Ends where it should end', () => {
149
150 it('uses the matching method', async () => {
151 const mid = [
152 post('/', throwError),
153 put('/', throwError),
154 del('/', throwError),
155 get('/', hello)
156 ];
157
158 const res = await run(mid).get('/');
159 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
160 });
161
162
163 it('uses the matching path', async () => {
164 const mid = [
165 get('/bla', throwError),
166 get('/:id', throwError),
167 get('/', hello)
168 ];
169
170 const res = await run(mid).get('/');
171 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
172 });
173
174
175 it('uses a route only once', async () => {
176 const mid = [
177 get('/', hello),
178 get('/', throwError)
179 ];
180
181 const res = await run(mid).get('/');
182 expect(res).toMatchObject({ status: 200, body: 'Hello 世界' });
183 });
184
185
186 it('parses params correctly', async () => {
187 const mid = get('/:id', ctx => ctx.params.id);
188
189 const res = await run(mid).get('/42?ignored=true');
190 expect(res.body).toBe('42');
191 });
192
193 // A bug shifted the router's middleware on each request so now we test for
194 // multiple request to make sure the middleware remains the same
195 it('does not modify the router', async () => {
196 await run(get('/', hello)).alive(async api => {
197 for (let url of [0, 1, 2]) {
198 const res = await api.get('/');
199 expect(res.body).toBe('Hello 世界');
200 }
201 });
202 });
203
204
205 it('does generic error matching', async () => {
206 let err;
207 const res = await run(throwError, error(ctx => {
208 err = ctx.error;
209 return 'Hello world';
210 })).get('/');
211 expect(res.body).toBe('Hello world');
212 expect(err.message).toMatch(/MockError/);
213 });
214
215 it('does path error matching', async () => {
216 let err;
217 const res = await run(throwError, error('test', ctx => {
218 err = ctx.error;
219 return 'Hello world';
220 })).get('/');
221 expect(res.body).toBe('Hello world');
222 expect(err.message).toMatch(/MockError/);
223 });
224
225 it('does empty error matching', async () => {
226 let err;
227 const res = await run(throwError).get('/');
228 expect(res.status).toBe(500);
229 });
230});