UNPKG

10.7 kBJavaScriptView Raw
1const assert = require('assert');
2const fs = require('fs');
3const rimraf = require('rimraf');
4
5const AUTHENTICATION_TOKEN = 'ec25fc7b-6ee2-4bda-b57c-6c9867b30ff4';
6const AJAX_AUTHORIZATION_HEADERS = {
7 'Content-Type': 'application/json', 'Authorization': `Token ${AUTHENTICATION_TOKEN}`
8};
9
10process.setMaxListeners(0);
11
12describe('MemServer.Server general functionality', function() {
13 before(function() {
14 fs.mkdirSync(`./memserver`);
15 fs.mkdirSync(`./memserver/models`);
16 fs.writeFileSync(`${process.cwd()}/memserver/models/user.js`, `
17 import Model from '${process.cwd()}/lib/model';
18
19 export default Model({
20 findFromHeaderToken(headers) {
21 const authorizationHeader = headers.Authorization;
22 const token = authorizationHeader ? authorizationHeader.slice(6) : false;
23
24 return this.findBy({ authentication_token: token }) || false;
25 }
26 });
27 `);
28 fs.writeFileSync(`${process.cwd()}/memserver/models/photo.js`, `
29 import Model from '${process.cwd()}/lib/model';
30
31 export default Model({
32 defaultAttributes: {
33 is_public: true,
34 name() {
35 return 'Some default name';
36 }
37 }
38 });
39 `);
40 fs.writeFileSync(`${process.cwd()}/memserver/models/photo-comment.js`, `
41 import Model from '${process.cwd()}/lib/model';
42
43 export default Model({
44 defaultAttributes: {
45 inserted_at() {
46 return '2017-10-25T20:54:04.447Z';
47 },
48 is_important: true
49 }
50 });
51 `);
52 fs.mkdirSync(`./memserver/fixtures`);
53 fs.writeFileSync(`${process.cwd()}/memserver/fixtures/users.js`, `export default [
54 {
55 id: 1,
56 email: 'contact@izelnakri.com',
57 username: 'izelnakri',
58 authentication_token: '${AUTHENTICATION_TOKEN}'
59 }
60 ];`);
61 fs.writeFileSync(`${process.cwd()}/memserver/fixtures/photos.js`, `export default [
62 {
63 id: 1,
64 name: 'Ski trip',
65 href: 'ski-trip.jpeg',
66 is_public: false,
67 user_id: 1
68 },
69 {
70 id: 2,
71 name: 'Family photo',
72 href: 'family-photo.jpeg',
73 is_public: true,
74 user_id: 1
75 },
76 {
77 id: 3,
78 name: 'Selfie',
79 href: 'selfie.jpeg',
80 is_public: false,
81 user_id: 1
82 }
83 ];`);
84 fs.writeFileSync(`${process.cwd()}/memserver/fixtures/photo-comments.js`, `export default [
85 {
86 uuid: '499ec646-493f-4eea-b92e-e383d94182f4',
87 content: 'What a nice photo!',
88 photo_id: 1,
89 user_id: 1
90 },
91 {
92 uuid: '77653ad3-47e4-4ec2-b49f-57ea36a627e7',
93 content: 'I agree',
94 photo_id: 1,
95 user_id: 2
96 },
97 {
98 uuid: 'd351963d-e725-4092-a37c-1ca1823b57d3',
99 content: 'I was kidding',
100 photo_id: 1,
101 user_id: 1
102 },
103 {
104 uuid: '374c7f4a-85d6-429a-bf2a-0719525f5f29',
105 content: 'Interesting indeed',
106 photo_id: 2,
107 user_id: 1
108 }
109 ];`);
110 });
111
112 beforeEach(function() {
113 Object.keys(require.cache).forEach((key) => delete require.cache[key]);
114 });
115
116 after(function(done) {
117 if (fs.existsSync(`${process.cwd()}/memserver`)) {
118 rimraf.sync(`${process.cwd()}/memserver`);
119 }
120
121 done();
122 });
123
124 describe('server can process custom headers and responses', function() {
125 before(function() {
126 fs.writeFileSync(`${process.cwd()}/memserver/server.js`, `
127 import Response from '../lib/response';
128
129 export default function({ User, Photo }) {
130 this.post('/photos', ({ headers }) => {
131 const user = User.findFromHeaderToken(headers);
132
133 if (!user) {
134 return Response(401, { error: 'Unauthorized' });
135 }
136
137 const photo = Photo.insert({ user_id: user.id });
138
139 return { photo: Photo.serializer(photo) };
140 });
141
142 this.get('/photos', ({ headers }) => {
143 const user = User.findFromHeaderToken(headers);
144
145 if (!user) {
146 return Response(404, { error: 'Not found' });
147 }
148
149 const photos = Photo.findAll({ user_id: user.id });
150
151 return { photos: Photo.serializer(photos) };
152 });
153
154 this.get('/photos/:id', ({ headers, params }) => {
155 const user = User.findFromHeaderToken(headers);
156
157 if (!user) {
158 return Response(401, { error: 'Unauthorized' });
159 }
160
161 const photo = Photo.findBy({ id: params.id, user_id: user.id });
162
163 return photo ? { photo: Photo.serializer(photo) } : Response(404, { error: 'Not found'});
164 });
165
166 this.put('/photos/:id', ({ headers, params }) => {
167 const user = User.findFromHeaderToken(headers);
168
169 if (!user) {
170 return Response(401, { error: 'Unauthorized' });
171 }
172
173 if (Photo.findBy({ id: params.id, user_id: user.id })) {
174 return { photo: Photo.update(params.photo) };
175 }
176 });
177
178 this.delete('/photos/:id', ({ headers, params }) => {
179 const user = User.findFromHeaderToken(headers);
180
181 if (user && Photo.findBy({ id: params.id, user_id: user.id })) {
182 return Photo.delete({ id: params.id });
183 }
184 });
185 }
186 `);
187 });
188
189 it('POST /resources work with custom headers and responses', async function() {
190 this.timeout(5000);
191
192 const MemServer = require('../../lib/index.js');
193 const { Photo } = MemServer.Models;
194
195 MemServer.start();
196 window.$ = require('jquery');
197
198 assert.equal(Photo.count(), 3);
199
200 await window.$.ajax({
201 type: 'POST', url: '/photos', headers: { 'Content-Type': 'application/json' }
202 }).catch((jqXHR) => {
203 assert.equal(jqXHR.status, 401);
204 assert.deepEqual(jqXHR.responseJSON, { error: 'Unauthorized' });
205 });
206
207 await window.$.ajax({
208 type: 'POST', url: '/photos', headers: AJAX_AUTHORIZATION_HEADERS
209 }).then((data, textStatus, jqXHR) => {
210 assert.equal(jqXHR.status, 201);
211 assert.deepEqual(data, {
212 photo: { is_public: true, name: 'Some default name', id: 4, user_id: 1, href: null }
213 });
214 });
215 });
216
217 it('GET /resources works with custom headers and responses', async function() {
218 const MemServer = require('../../lib/index.js');
219 const { Photo } = MemServer.Models;
220
221 MemServer.start();
222 window.$ = require('jquery');
223
224 await window.$.ajax({
225 type: 'GET', url: '/photos', headers: { 'Content-Type': 'application/json' }
226 }).catch((jqXHR) => {
227 assert.equal(jqXHR.status, 404);
228 assert.deepEqual(jqXHR.responseJSON, { error: 'Not found' });
229 });
230
231 await window.$.ajax({
232 type: 'GET', url: '/photos', headers: AJAX_AUTHORIZATION_HEADERS
233 }).then((data, textStatus, jqXHR) => {
234 assert.equal(jqXHR.status, 200);
235 assert.deepEqual(data, { photos: Photo.serializer(Photo.findAll())});
236 });
237 });
238
239 it('GET /resources/:id works with custom headers and responses', async function() {
240 const MemServer = require('../../lib/index.js');
241 const { Photo } = MemServer.Models;
242
243 MemServer.start();
244 window.$ = require('jquery');
245
246 await window.$.ajax({
247 type: 'GET', url: '/photos/1', headers: { 'Content-Type': 'application/json' }
248 }).catch((jqXHR) => {
249 assert.equal(jqXHR.status, 401);
250 assert.deepEqual(jqXHR.responseJSON, { error: 'Unauthorized' });
251 });
252
253 await window.$.ajax({
254 type: 'GET', url: '/photos/1', headers: AJAX_AUTHORIZATION_HEADERS
255 }).then((data, textStatus, jqXHR) => {
256 assert.equal(jqXHR.status, 200);
257 assert.deepEqual(data, { photo: Photo.serializer(Photo.find(1))});
258 });
259 });
260
261 it('PUT /resources/:id works with custom headers and responses', async function() {
262 const MemServer = require('../../lib/index.js');
263 const { Photo } = MemServer.Models;
264
265 MemServer.start();
266 window.$ = require('jquery');
267
268 await window.$.ajax({
269 type: 'PUT', url: '/photos/1', headers: { 'Content-Type': 'application/json' },
270 data: JSON.stringify({ photo: { id: 1, name: 'Photo after edit' }})
271 }).catch((jqXHR) => {
272 assert.equal(jqXHR.status, 401);
273 assert.deepEqual(jqXHR.responseJSON, { error: 'Unauthorized' });
274 });
275
276 await window.$.ajax({
277 type: 'PUT', url: '/photos/1', headers: AJAX_AUTHORIZATION_HEADERS,
278 data: JSON.stringify({ photo: { id: 1, name: 'Photo after edit' } })
279 }).then((data, textStatus, jqXHR) => {
280 assert.equal(jqXHR.status, 200);
281 assert.deepEqual(data, { photo: Photo.serializer(Photo.find(1))});
282 assert.equal(Photo.find(1).name, 'Photo after edit');
283 });
284 });
285
286 it('DELETE /resources/:id works with custom headers and responses', async function() {
287 const MemServer = require('../../lib/index.js');
288 const { Photo } = MemServer.Models;
289
290 MemServer.start();
291 window.$ = require('jquery');
292
293 assert.ok(Photo.find(1), 'User id: 1 exists');
294
295 await window.$.ajax({
296 type: 'DELETE', url: '/photos/1', headers: { 'Content-Type': 'application/json' }
297 }).catch((jqXHR) => {
298 assert.equal(jqXHR.status, 401);
299 assert.deepEqual(jqXHR.responseJSON, { error: 'Unauthorized' });
300 assert.ok(Photo.find(1), 'User id: 1 exists');
301 });
302
303 await window.$.ajax({
304 type: 'DELETE', url: '/photos/1', headers: AJAX_AUTHORIZATION_HEADERS
305 }).then((data, textStatus, jqXHR) => {
306 assert.equal(jqXHR.status, 204);
307 assert.deepEqual(data, undefined);
308 assert.ok(!Photo.find(1), 'User id: 1 gets deleted');
309 });
310 });
311 });
312
313 describe('some edge cases', function() {
314 before(function() {
315 fs.writeFileSync(`${process.cwd()}/memserver/server.js`, `
316 import Response from '../lib/response';
317
318 export default function() {
319 this.get('http://izelnakri.com', () => {
320 return Response(200, { result: 'external urls work!!' })
321 })
322 }
323 `);
324 });
325
326 it('works for external links', async function() {
327 const MemServer = require('../../lib/index.js');
328
329 MemServer.start();
330 window.$ = require('jquery');
331
332 await window.$.ajax({
333 type: 'GET', url: 'http://izelnakri.com', headers: { 'Content-Type': 'application/json' }
334 }).catch((jqXHR) => {
335 assert.equal(jqXHR.status, 200);
336 assert.deepEqual(jqXHR.responseJSON, { result: 'external urls work!!' });
337 });
338 });
339 });
340});