UNPKG

5.27 kBJavaScriptView Raw
1import HTTP, {defaultFetchConfig} from './http';
2
3describe('HTTP', () => {
4 const FAKE_TOKEN = 'fake-token';
5 let fakeAuth;
6 let http;
7 let fetchResult;
8
9 function mockFetch(httpInstance) {
10 sandbox.stub(httpInstance, '_fetch').resolves({
11 status: 200,
12 headers: new Headers({'content-type': 'application/json'}),
13 json: async () => fetchResult
14 });
15 }
16
17 beforeEach(function beforeEach() {
18 fakeAuth = {
19 constructor: {
20 shouldRefreshToken: sandbox.stub().returns(false)
21 },
22 requestToken: sandbox.stub().returns(FAKE_TOKEN),
23 forceTokenUpdate: sandbox.stub()
24 };
25
26 fetchResult = {
27 isResponseOk: true
28 };
29
30 http = new HTTP(fakeAuth);
31
32 mockFetch(http);
33 });
34
35 it('should export http service', () => http.should.exist);
36
37 it('should read token and perform authorized fetch', async () => {
38 await http.request('testurl', {foo: 'bar'});
39
40 fakeAuth.requestToken.should.have.been.called;
41
42 http._fetch.should.have.been.calledWith('testurl', {
43 foo: 'bar',
44 headers: {
45 ...defaultFetchConfig.headers,
46 Authorization: `Bearer ${FAKE_TOKEN}`
47 },
48 credentials: 'same-origin',
49 body: undefined
50 });
51 });
52
53 it('should perform unauthorized fetch', async () => {
54 await http.fetch('testurl', {foo: 'bar'});
55
56 fakeAuth.requestToken.should.not.have.been.called;
57
58 http._fetch.should.have.been.calledWith('testurl', {
59 foo: 'bar',
60 body: undefined
61 });
62 });
63
64 it('should perform request and return result', async () => {
65 const res = await http.request('testurl');
66 res.should.equal(fetchResult);
67 });
68
69 it('should perform request and return text result if no "application/json" header', async () => {
70 http._fetch.resolves({
71 status: 200,
72 headers: new Headers({'content-type': 'text/html'}),
73 json: async () => sandbox.spy(),
74 text: async () => 'some text'
75 });
76
77 const res = await http.request('testurl');
78 res.should.deep.equal({data: 'some text'});
79 });
80
81 it('should allow to get meta information of response', async () => {
82 const res = await http.request('testurl');
83
84 const meta = http.getMetaForResponse(res);
85 meta.status.should.equal(200); // eslint-disable-line no-magic-numbers
86 meta.headers.get('content-type').should.equal('application/json');
87 });
88
89 it('should allow to get meta information of string response', async () => {
90 http._fetch.resolves({
91 status: 200,
92 headers: new Headers({'content-type': 'text/html'}),
93 json: async () => sandbox.spy(),
94 text: async () => 'some text'
95 });
96 const res = await http.request('testurl');
97
98 const meta = http.getMetaForResponse(res);
99 meta.status.should.equal(200); // eslint-disable-line no-magic-numbers
100 meta.headers.get('content-type').should.equal('text/html');
101 });
102
103
104 it('should encode query params in url', async () => {
105 await http.request('http://testurl', {query: {
106 foo: 'bar',
107 test: ['a', 'b']
108 }});
109
110 http._fetch.should.have.been.
111 calledWith('http://testurl?foo=bar&test=a%2Cb', sinon.match(Object));
112 });
113
114 it('should support base url setting', async () => {
115 http.setBaseUrl('http://test');
116 await http.request('/foo');
117 http._fetch.should.have.been.calledWith('http://test/foo', sinon.match(Object));
118 });
119
120 it('should perform request convert "body" as object into string', async () => {
121 await http.request('testurl', {
122 method: 'POST',
123 body: {foo: 'bar'}
124 });
125
126 http._fetch.should.have.been.calledWithMatch('testurl', {
127 method: 'POST',
128 body: '{"foo":"bar"}'
129 });
130 });
131
132 it('should not refresh token if server responds OK', async () => {
133 await http.request('testurl');
134 fakeAuth.forceTokenUpdate.should.not.have.been.called;
135 });
136
137 it('should throw if response status is not OK', async () => {
138 http._fetch.resolves({
139 status: 405,
140 json: async () => fetchResult
141 });
142
143 const onError = sandbox.spy();
144 await http.request('testurl').catch(onError);
145
146 onError.should.have.been.called;
147 });
148
149 it('should refresh token and request again if invalid token error returned', async () => {
150 fakeAuth.constructor.shouldRefreshToken.returns(true);
151
152 http._fetch.
153 onFirstCall().resolves({
154 status: 405,
155 json: async () => ({error: 'invalid_token'}),
156 headers: new Headers({'content-type': 'application/json'})
157 }).
158 onSecondCall().resolves({
159 status: 200,
160 json: async () => fetchResult,
161 headers: new Headers({'content-type': 'application/json'})
162 });
163
164 const res = await http.request('testurl');
165
166 fakeAuth.forceTokenUpdate.should.have.been.called;
167
168 res.should.equal(fetchResult);
169 });
170
171 it('"get" method should call request with GET type', async () => {
172 sandbox.stub(http, 'request');
173 await http.get('testurl');
174
175 http.request.should.have.been.calledWith('testurl', {method: 'GET'});
176 });
177
178 it('"post" method should call request with POST type', async () => {
179 sandbox.stub(http, 'request');
180 await http.post('testurl', {body: {foo: 'bar'}});
181
182 http.request.should.have.been.calledWith('testurl', {method: 'POST', body: {foo: 'bar'}});
183 });
184});