UNPKG

9.37 kBJavaScriptView Raw
1/* eslint-disable no-unused-expressions */
2const { expect } = require('chai');
3
4const Grown = require('../../..')();
5
6Grown.use(require('../../test'));
7Grown.use(require('..'));
8
9/* global beforeEach, describe, it */
10
11describe('Grown.Conn', () => {
12 let server;
13
14 beforeEach(() => {
15 server = new Grown();
16 server.plug(Grown.Conn);
17 server.plug(Grown.Test);
18 });
19
20 describe('Request', () => {
21 const options = {
22 headers: {
23 'content-type': 'application/json',
24 },
25 body: '{"foo":"bar"}',
26 };
27
28 it('should add handful props and methods', () => {
29 return server.request('/', 'POST', options, (err, conn) => {
30 expect(conn.req_headers).to.eql({
31 'content-type': 'application/json',
32 'content-length': '13',
33 });
34
35 expect(conn.is_xhr).to.be.false;
36 expect(conn.is_json).to.be.true;
37 expect(conn.host).to.eql('0.0.0.0');
38 expect(conn.port).to.eql('80');
39 expect(conn.remote_ip).to.eql('0.0.0.0');
40 expect(conn.method).to.eql('POST');
41 expect(conn.params).to.eql({});
42 expect(conn.path_info).to.eql([]);
43 expect(conn.path_params).to.eql({});
44 expect(conn.body_params).to.eql({});
45 expect(conn.request_path).to.eql('/');
46 expect(conn.query_string).to.eql('');
47 expect(conn.query_params).to.eql({});
48 expect(conn.accept_charset).to.eql(['*']);
49 expect(conn.accept_charsets).to.eql(['*']);
50 expect(conn.accept_encoding).to.eql(['identity']);
51 expect(conn.accept_encodings).to.eql(['identity']);
52 expect(conn.accept_language).to.eql(['*']);
53 expect(conn.accept_languages).to.eql(['*']);
54 expect(conn.accept_type).to.eql(['*/*']);
55 expect(conn.accept_types).to.eql(['*/*']);
56
57 expect(conn.has_type('text')).to.be.false;
58 expect(conn.has_type('json')).to.eql('json');
59 expect(err).to.be.null;
60 });
61 });
62
63 it('should handle req.headers', () => {
64 return server.request('/', options, (err, conn) => {
65 expect(conn.get_req_header('content-length')).to.eql('13');
66
67 expect(() => conn.get_req_header(-1)).to.throw(/Invalid req_header/);
68 expect(() => conn.put_req_header(-1)).to.throw(/Invalid req_header/);
69 expect(() => conn.delete_req_header(-1)).to.throw(/Invalid req_header/);
70
71 conn.put_req_header('foo-bar', 'baz buzz');
72 expect(conn.get_req_header('foo-bar')).to.eql('baz buzz');
73 conn.delete_req_header('foo-bar');
74 expect(conn.get_req_header('foo-bar')).to.be.undefined;
75 expect(err).to.be.null;
76 });
77 });
78
79 it('should extract host/port from headers', () => {
80 return server.request('/', {
81 headers: {
82 host: 'localhost:8080',
83 },
84 }, (err, conn) => {
85 expect(conn.host).to.eql('localhost');
86 expect(conn.port).to.eql('8080');
87 expect(err).to.be.null;
88 });
89 });
90 });
91
92 describe('Response', () => {
93 it('should add handful props and methods', () => {
94 return server.request('/', (err, conn) => {
95 expect(conn.has_body).to.be.false;
96 expect(conn.has_status).to.be.true;
97
98 expect(conn.content_type).to.eql('text/html');
99 expect(() => { conn.content_type = 42; }).to.throw(/Invalid type/);
100
101 expect(conn.status_code).to.eql(200);
102 expect(() => { conn.status_code = []; }).to.throw(/Invalid status_code/);
103
104 expect(conn.resp_body).to.be.null;
105 expect(() => { conn.resp_body = []; }).to.throw(/Invalid resp_body/);
106 expect(() => { conn.resp_body = new Array(101).join('A'); }).not.to.throw();
107
108 expect(conn.resp_charset).to.eql('utf8');
109 expect(() => { conn.resp_charset = ''; }).not.to.throw();
110 expect(() => { conn.resp_charset = -1; }).to.throw(/Invalid charset/);
111 expect(err).to.be.null;
112 });
113 });
114
115 it('should handle resp.headers', () => {
116 return server.request('/', (err, conn) => {
117 expect(conn.resp_headers).to.eql({
118 'content-type': 'text/html; charset=utf8',
119 'content-length': 0,
120 });
121 expect(() => { conn.resp_headers = {}; }).not.to.throw();
122 expect(() => { conn.resp_headers = -1; }).to.throw(/Invalid headers/);
123
124 conn.put_resp_header('x-truth', '42');
125 conn.merge_resp_headers({ foo: 'bar', baz: 'buzz' });
126 conn.delete_resp_header('foo');
127
128 expect(conn.get_resp_header('x-truth')).to.eql('42');
129 expect(conn.get_resp_header('foo')).to.be.undefined;
130 expect(conn.get_resp_header('baz')).to.eql('buzz');
131
132 expect(() => conn.put_resp_header(-1)).to.throw(/Invalid resp_header/);
133 expect(() => conn.get_resp_header(-1)).to.throw(/Invalid resp_header/);
134 expect(() => conn.merge_resp_headers(-1)).to.throw(/Invalid resp_header/);
135 expect(() => conn.delete_resp_header(-1)).to.throw(/Invalid resp_header/);
136 expect(err).to.be.null;
137 });
138 });
139
140 it('should handle redirect()', () => {
141 server.mount(conn => {
142 expect(() => conn.redirect(-1)).to.throw(/Invalid location/);
143
144 return conn.redirect('/fix?a=b');
145 });
146
147 return server.request('/', (err, conn) => {
148 expect(conn.resp_headers).to.eql({ location: '/fix?a=b' });
149 expect(err).to.be.null;
150 });
151 });
152
153 it('should handle redirect() with full-urls', () => {
154 server.mount(conn => conn.redirect('https://api.soypache.co:8080'));
155
156 return server.request('/', (err, conn) => {
157 expect(conn.resp_headers).to.eql({ location: 'https://api.soypache.co:8080' });
158 expect(err).to.be.null;
159 });
160 });
161
162 it('should handle redirect() with timeout', () => {
163 server.mount(conn => conn.redirect('/wait', 1000));
164
165 return server.request('/', (err, conn) => {
166 expect(conn.res.body).to.contain('<meta http-equiv="refresh" content="1000;url=/wait">');
167 expect(err).to.be.null;
168 });
169 });
170
171 it('should handle json()', () => {
172 server.mount(conn => {
173 expect(() => conn.json(-1)).to.throw(/Invalid JSON/);
174
175 return conn.json({ foo: 'bar' });
176 });
177
178 return server.request('/', (err, conn) => {
179 expect(conn.res.body).to.eql('{"foo":"bar"}');
180 expect(err).to.be.null;
181 });
182 });
183
184 it('should handle send_file()', () => {
185 server.mount(conn => conn.send_file({ file: __filename }));
186
187 return server.request('/', (err, conn) => {
188 expect(conn.res.body).to.contain('should handle send_file()');
189 expect(err).to.be.null;
190 });
191 });
192
193 it('should handle send()', () => {
194 server.mount(conn => conn.send('OSOM'));
195
196 return server.request('/', (err, conn) => {
197 expect(conn.res.body).to.eql('OSOM');
198 expect(err).to.be.null;
199 });
200 });
201
202 it('should handle send() as buffer', () => {
203 server.mount(conn => conn.send(Buffer.from('OSOM')));
204
205 return server.request('/', (err, conn) => {
206 expect(conn.res.body).to.eql('OSOM');
207 expect(err).to.be.null;
208 });
209 });
210
211 it('should handle send() as stream', () => {
212 server.mount(conn => conn.send(require('fs').createReadStream(__filename)));
213
214 return server.request('/', (err, conn) => {
215 expect(conn.res.body).to.contain('should handle send() as stream');
216 expect(err).to.be.null;
217 });
218 });
219
220 it('should handle send() failures', () => {
221 server.mount(conn => {
222 conn.res.finished = true;
223
224 return conn.send().catch(e => {
225 expect(e.message).to.match(/Already finished/);
226 });
227 });
228
229 return server.request('/', (err, conn) => conn.res.ok(err));
230 });
231
232 it('should handle end()', () => {
233 server.mount(conn => conn.end(201));
234
235 return server.request('/', (err, conn) => conn.res.ok(err, '', 201));
236 });
237
238 it('should handle end() with text', () => {
239 server.mount(conn => conn.end('OSOM'));
240
241 return server.request('/', (err, conn) => conn.res.ok(err, 'OSOM', 200));
242 });
243
244 it('should handle end() with error', () => {
245 server.mount(conn => {
246 const e = new Error('Unexpected');
247
248 e.toString = () => 'FAILURE';
249 delete e.message;
250 return conn.end(e);
251 });
252
253 return server.request('/', (err, conn) => conn.res.ok(err, 'FAILURE', 500));
254 });
255
256 it('should handle end() with message', () => {
257 server.mount(conn => conn.end(400, 'Invalid input'));
258
259 return server.request('/', (err, conn) => conn.res.ok(err, 'Invalid input', 400));
260 });
261
262 it('should handle end() failures', () => {
263 server.mount(conn => {
264 conn.res.finished = true;
265 expect(() => conn.end()).to.throw(/Already finished/);
266 });
267
268 return server.request('/', (err, conn) => conn.res.ok(err, 200));
269 });
270
271 it('should handle shared state', () => {
272 const template = {
273 locals: {
274 foo: 'bar',
275 },
276 };
277
278 let emit;
279
280 server.plug({
281 $install(ctx) {
282 emit = (evt, _ctx, opts) => ctx.emit(evt, _ctx, opts);
283 },
284 });
285
286 server.mount(conn => {
287 conn.state.title = 'Untitled';
288
289 return emit('before_render', conn, template);
290 });
291
292 return server.request('/', (err, conn) => conn.res.ok(err, 200));
293 });
294 });
295});