UNPKG

10.5 kBJavaScriptView Raw
1'use strict';
2const lib = require('./rest'),
3 url = 'http://domain.com/foo',
4 url2 = 'https://domain.com/bar';
5
6describe('rest', () => {
7 afterEach(() => {
8 fetch.resetMocks();
9 });
10
11 it('catches on rejection', () => {
12 fetch.mockRejectOnce(new Error('nope'));
13 return lib.get(url).toPromise(Promise).catch((e) => {
14 expect(e.message).toBe('nope');
15 expect(e.details).toBe(url);
16 });
17 });
18
19 it('catches on auth redirect', () => {
20 fetch.mockResponseOnce('{}', { status: 401 });
21 return lib.get(url).toPromise(Promise).catch((e) => {
22 expect(e.message).toBe('Unauthorized');
23 expect(e.details).toBe(url);
24 });
25 });
26
27 it('catches on client errors', () => {
28 fetch.mockResponseOnce('{}', { status: 400 });
29 return lib.get(url).toPromise(Promise).catch((e) => {
30 expect(e.message).toBe('Bad Request');
31 expect(e.details).toBe(url);
32 });
33 });
34
35 it('catches on server errors', () => {
36 fetch.mockResponseOnce('{}', { status: 500 });
37 return lib.get(url).toPromise(Promise).catch((e) => {
38 expect(e.message).toBe('Internal Server Error');
39 expect(e.details).toBe(url);
40 });
41 });
42
43 describe('get', () => {
44 it('gets json', () => {
45 fetch.mockResponseOnce(JSON.stringify({ a: 'b' }));
46 return lib.get(url).toPromise(Promise).then((res) => {
47 expect(res).toEqual({ a: 'b' });
48 });
49 });
50
51 it('gets text', () => {
52 fetch.mockResponseOnce('hi');
53 return lib.get(url, { type: 'text' }).toPromise(Promise).then((res) => {
54 expect(res).toBe('hi');
55 });
56 });
57
58 it('uses https agent for ssl calls', () => {
59 fetch.mockResponseOnce(JSON.stringify({ a: 'b' }));
60 return lib.get(url2).toPromise(Promise).then(() => {
61 expect(fetch.mock.calls[0][1].agent).not.toBeNull();
62 });
63 });
64
65 it('uses headers', () => {
66 fetch.mockResponseOnce(JSON.stringify({ a: 'b' }));
67 return lib.get(url, { headers: { Authorization: 'Token abc' }}).toPromise(Promise).then(() => {
68 expect(fetch.mock.calls[0][1].headers).toEqual({ Authorization: 'Token abc' });
69 });
70 });
71 });
72
73 describe('put', () => {
74 const key = 'some api key',
75 json = { a: 'b' },
76 jsonString = JSON.stringify(json);
77
78 it('throws error if no api key specified', () => {
79 expect(() => lib.put(url, json)).toThrow('Please specify API key to do PUT requests against Clay!');
80 });
81
82 it('sends json', () => {
83 fetch.mockResponseOnce(json);
84 return lib.put(url, json, { key }).toPromise(Promise).then((res) => {
85 expect(res).toEqual({ type: 'success', message: url });
86 expect(fetch).toHaveBeenCalledWith(url, {
87 method: 'PUT',
88 agent: null,
89 body: jsonString,
90 headers: {
91 Authorization: `Token ${key}`,
92 'Content-Type': 'application/json; charset=UTF-8'
93 }
94 });
95 });
96 });
97
98 it('sends json with empty body', () => {
99 fetch.mockResponseOnce(json);
100 return lib.put(url, null, { key }).toPromise(Promise).then((res) => {
101 expect(res).toEqual({ type: 'success', message: url });
102 expect(fetch).toHaveBeenCalledWith(url, {
103 method: 'PUT',
104 agent: null,
105 body: undefined,
106 headers: {
107 Authorization: `Token ${key}`,
108 'Content-Type': 'application/json; charset=UTF-8'
109 }
110 });
111 });
112 });
113
114 it('sends text', () => {
115 fetch.mockResponseOnce('hi');
116 return lib.put(url, 'hi', { type: 'text', key }).toPromise(Promise).then((res) => {
117 expect(res).toEqual({ type: 'success', message: url });
118 expect(fetch).toHaveBeenCalledWith(url, {
119 method: 'PUT',
120 agent: null,
121 body: 'hi',
122 headers: {
123 Authorization: `Token ${key}`,
124 'Content-Type': 'text/plain; charset=UTF-8'
125 }
126 });
127 });
128 });
129
130 it('uses https agent for ssl calls', () => {
131 fetch.mockResponseOnce(json);
132 return lib.put(url2, json, { key }).toPromise(Promise).then(() => {
133 expect(fetch.mock.calls[0][1].agent).not.toBeNull();
134 });
135 });
136
137 it('uses headers', () => {
138 fetch.mockResponseOnce(json);
139 return lib.put(url, json, { key, headers: { some_header: 'value' }}).toPromise(Promise).then(() => {
140 expect(fetch.mock.calls[0][1].headers).toEqual({
141 Authorization: `Token ${key}`,
142 'Content-Type': 'application/json; charset=UTF-8',
143 some_header: 'value'
144 });
145 });
146 });
147
148 it('returns stream of errors if PUT fails', () => {
149 fetch.mockResponseOnce('{}', { status: 500 });
150 return lib.put(url, json, { key }).toPromise(Promise).then((res) => {
151 expect(res).toEqual({ type: 'error', details: url, message: 'Internal Server Error' });
152 });
153 });
154 });
155
156 describe('query', () => {
157 const key = 'some api key',
158 json = {
159 index: 'pages',
160 body: {
161 query: {
162 match_all: {}
163 }
164 }
165 },
166 jsonString = JSON.stringify(json),
167 results = {
168 hits: {
169 total: 1,
170 hits: [{
171 _id: 'foo',
172 _source: {
173 uri: 'foo'
174 }
175 }]
176 }
177 },
178 resultsString = JSON.stringify(results),
179 noResults = {
180 hits: {
181 total: 0,
182 hits: []
183 }
184 },
185 noResultsString = JSON.stringify(noResults);
186
187 it('throws error if no api key specified', () => {
188 expect(() => lib.query(url, json)).toThrow('Please specify API key to do POST requests against Clay!');
189 });
190
191 it('returns error if elastic errors', () => {
192 fetch.mockResponseOnce('[parsing_exception] [prefix] malformed query, expected [END_OBJECT] but found [FIELD_NAME], with { line=1 & col=50 } :: {"path":"/pages/_doc/_search","query"...', { headers: { 'content-type': 'text/html; charset=utf-8' }});
193 return lib.query(url, json, { key }).toPromise(Promise).then((res) => {
194 expect(res).toEqual({ type: 'error', details: url, message: '[parsing_exception] [prefix] malformed query, expected [END_OBJECT] but found [FIELD_NAME], with { line=1 & col=50 }', url });
195 });
196 });
197
198 it('fetches results', () => {
199 fetch.mockResponseOnce(resultsString);
200 return lib.query(url, json, { key }).toPromise(Promise).then((res) => {
201 expect(res).toEqual({ type: 'success', details: url, message: '1 result', data: [{ _id: 'foo', uri: 'foo' }], total: 1 });
202 expect(fetch).toHaveBeenCalledWith(url, {
203 method: 'POST',
204 agent: null,
205 body: jsonString,
206 headers: {
207 Authorization: `Token ${key}`,
208 'Content-Type': 'application/json; charset=UTF-8'
209 }
210 });
211 });
212 });
213
214 it('fetches zero results', () => {
215 fetch.mockResponseOnce(noResultsString);
216 return lib.query(url, json, { key }).toPromise(Promise).then((res) => {
217 expect(res).toEqual({ type: 'error', details: url, message: 'No results', url });
218 expect(fetch).toHaveBeenCalledWith(url, {
219 method: 'POST',
220 agent: null,
221 body: jsonString,
222 headers: {
223 Authorization: `Token ${key}`,
224 'Content-Type': 'application/json; charset=UTF-8'
225 }
226 });
227 });
228 });
229
230 it('uses https agent for ssl calls', () => {
231 fetch.mockResponseOnce(resultsString);
232 return lib.query(url2, json, { key }).toPromise(Promise).then(() => {
233 expect(fetch.mock.calls[0][1].agent).not.toBeNull();
234 });
235 });
236
237 it('uses headers', () => {
238 fetch.mockResponseOnce(resultsString);
239 return lib.query(url, json, { key, headers: { some_header: 'value' }}).toPromise(Promise).then(() => {
240 expect(fetch.mock.calls[0][1].headers).toEqual({
241 Authorization: `Token ${key}`,
242 'Content-Type': 'application/json; charset=UTF-8',
243 some_header: 'value'
244 });
245 });
246 });
247
248 it('returns stream of errors if POST fails', () => {
249 fetch.mockResponseOnce('{}', { status: 500 });
250 return lib.query(url, json, { key }).toPromise(Promise).then((res) => {
251 expect(res).toEqual({ type: 'error', details: url, message: 'Internal Server Error' });
252 });
253 });
254 });
255
256 describe('findURI', () => {
257 it('finds page uri with one hop', () => {
258 fetch.mockResponseOnce('domain.com/_pages/foo');
259 return lib.findURI('http://domain.com/some-slug.html').toPromise(Promise).then((res) => {
260 expect(res).toEqual({ uri: 'domain.com/_pages/foo', prefix: 'http://domain.com'});
261 });
262 });
263
264 it('works with ssl', () => {
265 fetch.mockResponseOnce('domain.com/_pages/foo');
266 return lib.findURI('https://domain.com/some-slug.html').toPromise(Promise).then((res) => {
267 expect(res).toEqual({ uri: 'domain.com/_pages/foo', prefix: 'https://domain.com' });
268 });
269 });
270
271 it('finds page uri with two hops', () => {
272 fetch.mockResponseOnce('', { status: 404 });
273 fetch.mockResponseOnce('domain.com/_pages/foo');
274 return lib.findURI('http://domain.com/path/some-slug.html').toPromise(Promise).then((res) => {
275 expect(res).toEqual({ uri: 'domain.com/_pages/foo', prefix: 'http://domain.com' });
276 });
277 });
278
279 it('fails if no relevant api route', () => {
280 fetch.mockResponse('', { status: 404 });
281 return lib.findURI('http://domain.com/some-slug.html').toPromise(Promise).catch((e) => {
282 expect(e.message).toBe('Unable to find a Clay api for domain.com/some-slug.html');
283 });
284 });
285 });
286
287 describe('isElasticPrefix', () => {
288 it('returns true if _search endpoint exists at prefix', () => {
289 fetch.mockResponseOnce('{}');
290 return lib.isElasticPrefix('http://domain.com').toPromise(Promise).then((res) => {
291 expect(res).toBe(true);
292 });
293 });
294
295 it('returns false if _search endpoint does not exist at prefix', () => {
296 fetch.mockResponseOnce('{}', { status: 404 });
297 return lib.isElasticPrefix('http://domain.com').toPromise(Promise).then((res) => {
298 expect(res).toBe(false);
299 });
300 });
301
302 it('works for ssl', () => {
303 fetch.mockResponseOnce('{}');
304 return lib.isElasticPrefix('https://domain.com').toPromise(Promise).then(() => {
305 expect(fetch.mock.calls[0][1].agent).not.toBeNull();
306 });
307 });
308 });
309});