1 |
|
2 |
|
3 |
|
4 | var chai = require('chai')
|
5 | var expect = chai.expect
|
6 | chai.use(require('chai-as-promised'))
|
7 | var httpism = require('../..')
|
8 | require('es6-promise').polyfill()
|
9 | var serverSide = require('karma-server-side')
|
10 | var FakeXMLHttpRequest = require('fake-xml-http-request')
|
11 |
|
12 | var server = 'http://' + window.location.hostname + ':12345'
|
13 | var badServer = 'http://' + window.location.hostname + ':12346'
|
14 |
|
15 | describe('httpism', function () {
|
16 | before(function () {
|
17 | return serverSide.run(function () {
|
18 | if (this.server) {
|
19 | this.server.destroy()
|
20 | }
|
21 |
|
22 | var app = serverRequire('./test/browser/app')
|
23 | var serverDestroy = serverRequire('server-destroy')
|
24 |
|
25 | this.server = app.listen(12345)
|
26 | serverDestroy(this.server)
|
27 | })
|
28 | })
|
29 |
|
30 | describe('get', function () {
|
31 | it('can make a JSON GET request', function () {
|
32 | return httpism.get('/', {response: true}).then(function (response) {
|
33 | expect(response.body.method).to.equal('GET')
|
34 | expect(response.body.url).to.equal('/')
|
35 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
36 | expect(response.url).to.equal('/')
|
37 | })
|
38 | })
|
39 |
|
40 | it('can GET with query string', function () {
|
41 | return httpism.get('/', {response: true, params: {a: 'b', b: 'c', c: 'd'}}).then(function (response) {
|
42 | expect(response.body.method).to.equal('GET')
|
43 | expect(response.body.query).to.eql({a: 'b', b: 'c', c: 'd'})
|
44 | expect(response.body.url).to.equal('/?a=b&b=c&c=d')
|
45 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
46 | expect(response.url).to.equal('/?a=b&b=c&c=d')
|
47 | })
|
48 | })
|
49 |
|
50 | it('can make a string GET request', function () {
|
51 | return httpism.get('/text?text=asdf').then(function (body) {
|
52 | expect(body).to.equal('asdf')
|
53 | })
|
54 | })
|
55 |
|
56 | it('throws if receives 404', function () {
|
57 | return httpism.get('/status/404').then(function () {
|
58 | throw new Error('expected to throw exception')
|
59 | }, function (response) {
|
60 | expect(response.message).to.eql('GET /status/404 => 404 Not Found')
|
61 | expect(response.body.method).to.eql('GET')
|
62 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
63 | expect(response.url).to.equal('/status/404')
|
64 | })
|
65 | })
|
66 | })
|
67 |
|
68 | describe('jsonp', function () {
|
69 | it('can call JSONP', function () {
|
70 | return httpism.get(server + '/jsonp', {jsonp: 'callback'}).then(function (body) {
|
71 | expect(body).to.eql({blah: 'blah'})
|
72 | })
|
73 | })
|
74 |
|
75 | it('throws exception if there is an error', function () {
|
76 | return expect(httpism.get(server + '/404', {jsonp: 'callback'})).to.be.rejectedWith(server + '/404')
|
77 | })
|
78 | })
|
79 | describe('cookies', function () {
|
80 | it('can send and receive cookies', function () {
|
81 | return httpism.get('/cookies', {params: {a: 'b'}}).then(function () {
|
82 | expect(document.cookie).to.include('a=b')
|
83 | return httpism.get('/').then(function (body) {
|
84 | expect(body.cookies.a).to.equal('b')
|
85 | })
|
86 | })
|
87 | })
|
88 |
|
89 | describe('cross-domain', function () {
|
90 | beforeEach(function () {
|
91 | return httpism.get(server + '/cookies', {params: {a: ''}, withCredentials: true})
|
92 | })
|
93 |
|
94 | it("by default, doesn't send cookies cross-domain", function () {
|
95 | return httpism.get(server + '/cookies', {params: {a: 'b'}, withCredentials: true}).then(function () {
|
96 | return httpism.get(server + '/').then(function (body) {
|
97 | expect(body.cookies.a).to.equal(undefined)
|
98 | })
|
99 | })
|
100 | })
|
101 |
|
102 | it('withCredentials = true, sends cookies cross-domain', function () {
|
103 | return httpism.get(server + '/cookies', {params: {a: 'b'}, withCredentials: true}).then(function () {
|
104 | return httpism.get(server + '/', {withCredentials: true}).then(function (body) {
|
105 | expect(body.cookies.a).to.equal('b')
|
106 | })
|
107 | })
|
108 | })
|
109 |
|
110 | it("doesn't send x-requested-with if cross-domain", function () {
|
111 | return httpism.get(server + '/').then(function (body) {
|
112 | expect(body.xhr).to.equal(false)
|
113 | })
|
114 | })
|
115 |
|
116 | it('throws when it cannot connect to the remote server', function () {
|
117 | return httpism.get(badServer + '/').then(function () {
|
118 | throw new Error('expected to be rejected')
|
119 | }, function () {
|
120 | })
|
121 | })
|
122 | })
|
123 | })
|
124 |
|
125 | describe('post', function () {
|
126 | it('can make a json post request', function () {
|
127 | return httpism.post('/', {data: 'hehey'}, {response: true}).then(function (response) {
|
128 | expect(response.body.body).to.eql({data: 'hehey'})
|
129 | expect(response.body.headers['content-type']).to.equal('application/json')
|
130 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
131 | expect(response.url).to.equal('/')
|
132 | })
|
133 | })
|
134 |
|
135 | it('can make a cross-origin json post request', function () {
|
136 | return httpism.post(server + '/', {data: 'hehey'}, {response: true}).then(function (response) {
|
137 | expect(response.body.body).to.eql({data: 'hehey'})
|
138 | expect(response.body.headers['content-type']).to.equal('application/json')
|
139 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
140 | expect(response.url).to.equal(server + '/')
|
141 | })
|
142 | })
|
143 |
|
144 | it('can make a text post request', function () {
|
145 | return httpism.post('/', 'hehey', {response: true}).then(function (response) {
|
146 | expect(response.body.body).to.eql('hehey')
|
147 | expect(response.body.headers['content-type']).to.equal('text/plain;charset=UTF-8')
|
148 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
149 | expect(response.url).to.equal('/')
|
150 | })
|
151 | })
|
152 |
|
153 | it('can make a form post request', function () {
|
154 | return httpism.post('/', {message: 'hehey', to: 'bob'}, {response: true, form: true}).then(function (response) {
|
155 | expect(response.body.body).to.eql({message: 'hehey', to: 'bob'})
|
156 | expect(response.body.headers['content-type']).to.equal('application/x-www-form-urlencoded')
|
157 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
158 | expect(response.url).to.equal('/')
|
159 | })
|
160 | })
|
161 |
|
162 | it('can make a FormData request', function () {
|
163 | var data = new FormData()
|
164 | data.append('name', 'joe')
|
165 | data.append('file', new File(['file content'], 'file.txt', {type: 'text/plain'}))
|
166 | return httpism.post('/form', data).then(function (body) {
|
167 | expect(body).to.eql({
|
168 | name: 'joe',
|
169 | file: {
|
170 | contents: 'file content',
|
171 | headers: {
|
172 | 'content-disposition': 'form-data; name="file"; filename="file.txt"',
|
173 | 'content-type': 'text/plain'
|
174 | }
|
175 | }
|
176 | })
|
177 | })
|
178 | })
|
179 | })
|
180 |
|
181 | describe('put', function () {
|
182 | it('can make a json put request', function () {
|
183 | return httpism.put('/', {data: 'hehey'}, {response: true}).then(function (response) {
|
184 | expect(response.body.body).to.eql({data: 'hehey'})
|
185 | expect(response.body.headers['content-type']).to.equal('application/json')
|
186 | expect(response.headers['content-type']).to.equal('application/json; charset=utf-8')
|
187 | expect(response.url).to.equal('/')
|
188 | })
|
189 | })
|
190 | })
|
191 |
|
192 | describe('abort', function () {
|
193 | it('can abort a request', function () {
|
194 | var request = httpism.get('/')
|
195 | request.abort()
|
196 | return new Promise(function (resolve, reject) {
|
197 | request.then(function (response) {
|
198 | reject(new Error("didn't expect response"))
|
199 | }, function (error) {
|
200 | if (error.aborted !== true) {
|
201 | reject(error)
|
202 | } else {
|
203 | resolve()
|
204 | }
|
205 | })
|
206 | })
|
207 | })
|
208 |
|
209 | it('can abort a request even with user middleware', function () {
|
210 | var middlewareRequest, middlewareResponse
|
211 |
|
212 | var http = httpism.client([
|
213 | function (request, next) {
|
214 | middlewareRequest = true
|
215 | return next().then(function (response) {
|
216 | middlewareResponse = true
|
217 | return response
|
218 | })
|
219 | }
|
220 | ])
|
221 |
|
222 | var request = http.get('/')
|
223 | request.abort()
|
224 | return new Promise(function (resolve, reject) {
|
225 | request.then(function (response) {
|
226 | reject(new Error("didn't expect response"))
|
227 | }, function (error) {
|
228 | if (error.aborted !== true) {
|
229 | reject(error)
|
230 | } else {
|
231 | resolve()
|
232 | }
|
233 | })
|
234 | }).then(function () {
|
235 | expect(middlewareRequest).to.equal(true)
|
236 | expect(middlewareResponse).to.equal(undefined)
|
237 | })
|
238 | })
|
239 | })
|
240 |
|
241 | describe('x-requested-with header', function () {
|
242 | it('sends the x-requested-with header', function () {
|
243 | return httpism.get('/').then(function (body) {
|
244 | expect(body.xhr).to.equal(true)
|
245 | })
|
246 | })
|
247 | })
|
248 |
|
249 | describe('delete', function () {
|
250 | it('can respond with 204 and empty body', function () {
|
251 | return httpism.delete('/delete', {response: true}).then(function (response) {
|
252 | expect(response.statusCode).to.equal(204)
|
253 | expect(response.body).to.equal(undefined)
|
254 | })
|
255 | })
|
256 | })
|
257 |
|
258 | describe('jsonReviver', function () {
|
259 | it('uses the JSON reviver to decode JSON values', function () {
|
260 | return httpism.post('/', {
|
261 | greeting: 'hi'
|
262 | }, {
|
263 | jsonReviver: function (key, value) {
|
264 | if (key !== 'greeting') return value
|
265 | return value + '!'
|
266 | }
|
267 | }).then(function (body) {
|
268 | expect(body.body.greeting).to.equal('hi!')
|
269 | })
|
270 | })
|
271 | })
|
272 |
|
273 | describe('xhr option', function () {
|
274 | it('can override the XHR used in the request', function () {
|
275 | FakeXMLHttpRequest.prototype.onSend = function (xhr) {
|
276 | xhr.respond(200, {'Content-Type': 'text/plain'}, 'faked response')
|
277 | }
|
278 | return httpism.get('/', {xhr: FakeXMLHttpRequest}).then(function (body) {
|
279 | expect(body).to.equal('faked response')
|
280 | })
|
281 | })
|
282 | })
|
283 |
|
284 | describe('basic auth', function () {
|
285 | it('can specify basic authentication', function () {
|
286 | return httpism.get('/private', {basicAuth: {username: 'user', password: 'good'}}).then(function (body) {
|
287 | expect(body).to.equal('private')
|
288 | })
|
289 | })
|
290 |
|
291 | it('returns 401 when unauthorized', function () {
|
292 | return httpism.get('/private', {basicAuth: {username: 'user', password: 'bad'}, response: true, exceptions: false}).then(function (response) {
|
293 | expect(response.statusCode).to.equal(401)
|
294 | })
|
295 | })
|
296 | })
|
297 | })
|