Skip to content

Commit 0c7f7b4

Browse files
committed
Copy rest/packages/client => accounts/packages/rest-client
1 parent 72e55ef commit 0c7f7b4

File tree

10 files changed

+644
-0
lines changed

10 files changed

+644
-0
lines changed

packages/rest-client/.npmignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__tests__
2+
src/
3+
coverage/
4+
node_modules
5+
.npmignore
6+
tsconfig.json
7+
yarn.lock

packages/rest-client/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# @accounts/rest-client
2+
3+
[![npm](https://img.shields.io/npm/v/@accounts/rest-client.svg?maxAge=2592000)](https://www.npmjs.com/package/@accounts/rest-client)
4+
[![CircleCI](https://circleci.com/gh/accounts-js/rest.svg?style=shield)](https://circleci.com/gh/accounts-js/rest)
5+
[![codecov](https://codecov.io/gh/accounts-js/rest/branch/master/graph/badge.svg)](https://codecov.io/gh/accounts-js/rest)
6+
![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)
7+
8+
## Install
9+
10+
```
11+
yarn add @accounts/rest-client
12+
```
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import fetch from 'node-fetch';
2+
import { authFetch } from '../src/auth-fetch';
3+
4+
window.fetch = jest.fn().mockImplementation(() => ({
5+
status: 200,
6+
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
7+
}));
8+
9+
describe('authFetch', () => {
10+
beforeEach(() => {
11+
jest.clearAllMocks();
12+
});
13+
14+
it('should call fetch', async () => {
15+
const accounts = {
16+
refreshSession: jest.fn(() => Promise.resolve()),
17+
tokens: jest.fn(() => Promise.resolve({})),
18+
};
19+
await authFetch(accounts, 'path', {});
20+
expect(accounts.refreshSession).toBeCalled();
21+
expect(accounts.tokens).toBeCalled();
22+
});
23+
24+
it('should set access token header', async () => {
25+
const accounts = {
26+
refreshSession: jest.fn(() => Promise.resolve()),
27+
tokens: jest.fn(() => Promise.resolve({ accessToken: 'accessToken' })),
28+
};
29+
await authFetch(accounts, 'path', {});
30+
expect(accounts.refreshSession).toBeCalled();
31+
expect(accounts.tokens).toBeCalled();
32+
expect(window.fetch.mock.calls[0][1].headers['accounts-access-token']).toBe(
33+
'accessToken'
34+
);
35+
});
36+
37+
it('should pass other headers', async () => {
38+
const accounts = {
39+
refreshSession: jest.fn(() => Promise.resolve()),
40+
tokens: jest.fn(() => Promise.resolve({ accessToken: 'accessToken' })),
41+
};
42+
await authFetch(accounts, 'path', {
43+
headers: {
44+
toto: 'toto',
45+
},
46+
});
47+
expect(accounts.refreshSession).toBeCalled();
48+
expect(accounts.tokens).toBeCalled();
49+
expect(window.fetch.mock.calls[0][1].headers.toto).toBe('toto');
50+
});
51+
});
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
import fetch from 'node-fetch';
2+
import { RestClient } from '../src/rest-client';
3+
4+
window.fetch = jest.fn().mockImplementation(() => ({
5+
status: 200,
6+
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
7+
}));
8+
9+
window.Headers = fetch.Headers;
10+
11+
describe('RestClient', () => {
12+
beforeEach(() => {
13+
jest.clearAllMocks();
14+
});
15+
16+
it('should have a way to configure api host address and root path', () => {
17+
const client = new RestClient({
18+
apiHost: 'http://localhost:3000/',
19+
rootPath: 'accounts',
20+
});
21+
22+
expect(client.options.apiHost).toBe('http://localhost:3000/');
23+
expect(client.options.rootPath).toBe('accounts');
24+
25+
return client.fetch('try').then(() => {
26+
expect(window.fetch.mock.calls[0][0]).toBe(
27+
'http://localhost:3000/accounts/try'
28+
);
29+
});
30+
});
31+
32+
describe('fetch', () => {
33+
const client = new RestClient({
34+
apiHost: 'http://localhost:3000/',
35+
rootPath: 'accounts',
36+
});
37+
38+
it('should enable custom headers', () =>
39+
client
40+
.fetch('route', {}, { origin: 'localhost:3000' })
41+
.then(() =>
42+
expect(window.fetch.mock.calls[0][1].headers.origin).toBe(
43+
'localhost:3000'
44+
)
45+
));
46+
47+
it('should throw error', async () => {
48+
window.fetch = jest.fn().mockImplementation(() => ({
49+
status: 400,
50+
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
51+
}));
52+
53+
try {
54+
await client.fetch('route', {}, { origin: 'localhost:3000' });
55+
throw new Error();
56+
} catch (err) {
57+
expect(window.fetch.mock.calls[0][1].headers.origin).toBe(
58+
'localhost:3000'
59+
);
60+
}
61+
window.fetch = jest.fn().mockImplementation(() => ({
62+
status: 200,
63+
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
64+
}));
65+
});
66+
67+
it('should throw if server did not return a response', async () => {
68+
window.fetch = jest.fn().mockImplementation(() => null);
69+
70+
try {
71+
await client.fetch('route', {}, { origin: 'localhost:3000' });
72+
throw new Error();
73+
} catch (err) {
74+
expect(window.fetch.mock.calls[0][1].headers.origin).toBe(
75+
'localhost:3000'
76+
);
77+
expect(err.message).toBe('Server did not return a response');
78+
}
79+
window.fetch = jest.fn().mockImplementation(() => ({
80+
status: 200,
81+
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
82+
}));
83+
});
84+
});
85+
86+
describe('loginWithService', () => {
87+
const client = new RestClient({
88+
apiHost: 'http://localhost:3000',
89+
rootPath: '/accounts',
90+
});
91+
92+
it('should call fetch with authenticate path', async () => {
93+
await client.loginWithService('password', {
94+
user: {
95+
username: 'toto',
96+
},
97+
password: 'password',
98+
});
99+
expect(window.fetch.mock.calls[0][0]).toBe(
100+
'http://localhost:3000/accounts/password/authenticate'
101+
);
102+
expect(window.fetch.mock.calls[0][1].body).toBe(
103+
'{"user":{"username":"toto"},"password":"password"}'
104+
);
105+
});
106+
});
107+
108+
describe('impersonate', () => {
109+
const client = new RestClient({
110+
apiHost: 'http://localhost:3000',
111+
rootPath: '/accounts',
112+
});
113+
114+
it('should call fetch with impersonate path', () =>
115+
client
116+
.impersonate('token', 'user')
117+
.then(() =>
118+
expect(window.fetch.mock.calls[0][0]).toBe(
119+
'http://localhost:3000/accounts/impersonate'
120+
)
121+
));
122+
});
123+
124+
describe('refreshTokens', () => {
125+
const client = new RestClient({
126+
apiHost: 'http://localhost:3000',
127+
rootPath: '/accounts',
128+
});
129+
130+
it('should call fetch with refreshTokens path', () =>
131+
client
132+
.refreshTokens('accessToken', 'refreshToken')
133+
.then(() =>
134+
expect(window.fetch.mock.calls[0][0]).toBe(
135+
'http://localhost:3000/accounts/refreshTokens'
136+
)
137+
));
138+
});
139+
140+
describe('logout', () => {
141+
const client = new RestClient({
142+
apiHost: 'http://localhost:3000',
143+
rootPath: '/accounts',
144+
});
145+
146+
it('should call fetch with logout path', () =>
147+
client
148+
.logout('accessToken')
149+
.then(() =>
150+
expect(window.fetch.mock.calls[0][0]).toBe(
151+
'http://localhost:3000/accounts/logout'
152+
)
153+
));
154+
});
155+
156+
describe('getUser', () => {
157+
const client = new RestClient({
158+
apiHost: 'http://localhost:3000',
159+
rootPath: '/accounts',
160+
});
161+
162+
it('should call fetch with user path', () =>
163+
client
164+
.getUser('accessToken')
165+
.then(() =>
166+
expect(window.fetch.mock.calls[0][0]).toBe(
167+
'http://localhost:3000/accounts/user'
168+
)
169+
));
170+
});
171+
172+
describe('createUser', () => {
173+
const client = new RestClient({
174+
apiHost: 'http://localhost:3000',
175+
rootPath: '/accounts',
176+
});
177+
178+
it('should call fetch with register path', () =>
179+
client
180+
.createUser('user')
181+
.then(() =>
182+
expect(window.fetch.mock.calls[0][0]).toBe(
183+
'http://localhost:3000/accounts/password/register'
184+
)
185+
));
186+
});
187+
188+
describe('resetPassword', () => {
189+
const client = new RestClient({
190+
apiHost: 'http://localhost:3000',
191+
rootPath: '/accounts',
192+
});
193+
194+
it('should call fetch with resetPassword path', () =>
195+
client
196+
.resetPassword('token', 'resetPassword')
197+
.then(() =>
198+
expect(window.fetch.mock.calls[0][0]).toBe(
199+
'http://localhost:3000/accounts/password/resetPassword'
200+
)
201+
));
202+
});
203+
204+
describe('verifyEmail', () => {
205+
const client = new RestClient({
206+
apiHost: 'http://localhost:3000',
207+
rootPath: '/accounts',
208+
});
209+
210+
it('should call fetch with verifyEmail path', () =>
211+
client
212+
.verifyEmail('token')
213+
.then(() =>
214+
expect(window.fetch.mock.calls[0][0]).toBe(
215+
'http://localhost:3000/accounts/password/verifyEmail'
216+
)
217+
));
218+
});
219+
220+
describe('sendVerificationEmail', () => {
221+
const client = new RestClient({
222+
apiHost: 'http://localhost:3000',
223+
rootPath: '/accounts',
224+
});
225+
226+
it('should call fetch with verifyEmail path', () =>
227+
client
228+
.sendVerificationEmail('email')
229+
.then(() =>
230+
expect(window.fetch.mock.calls[0][0]).toBe(
231+
'http://localhost:3000/accounts/password/sendVerificationEmail'
232+
)
233+
));
234+
});
235+
236+
describe('sendResetPasswordEmail', () => {
237+
const client = new RestClient({
238+
apiHost: 'http://localhost:3000',
239+
rootPath: '/accounts',
240+
});
241+
242+
it('should call fetch with verifyEmail path', () =>
243+
client
244+
.sendResetPasswordEmail('email')
245+
.then(() =>
246+
expect(window.fetch.mock.calls[0][0]).toBe(
247+
'http://localhost:3000/accounts/password/sendResetPasswordEmail'
248+
)
249+
));
250+
});
251+
});

packages/rest-client/package.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"name": "@accounts/rest-client",
3+
"version": "0.1.0-beta.2",
4+
"description": "REST client for accounts",
5+
"main": "lib/index",
6+
"typings": "lib/index",
7+
"publishConfig": {
8+
"access": "public"
9+
},
10+
"scripts": {
11+
"start": "tsc --watch",
12+
"precompile": "rimraf ./lib",
13+
"compile": "tsc",
14+
"prepublish": "npm run compile",
15+
"test": "npm run testonly",
16+
"testonly": "jest",
17+
"coverage": "npm run testonly -- --coverage",
18+
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
19+
},
20+
"jest": {
21+
"testEnvironment": "jsdom",
22+
"transform": {
23+
".(ts|tsx)": "<rootDir>/../../node_modules/ts-jest/preprocessor.js"
24+
},
25+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx)$",
26+
"moduleFileExtensions": [
27+
"ts",
28+
"js"
29+
],
30+
"mapCoverage": true
31+
},
32+
"repository": {
33+
"type": "git",
34+
"url": "https://github.com/js-accounts/rest/tree/master/packages/rest-client"
35+
},
36+
"keywords": [
37+
"rest",
38+
"graphql",
39+
"grant",
40+
"auth",
41+
"authentication",
42+
"accounts",
43+
"users",
44+
"oauth"
45+
],
46+
"author": "Tim Mikeladze",
47+
"license": "MIT",
48+
"devDependencies": {
49+
"@accounts/client": "0.1.0-beta.3",
50+
"@accounts/common": "0.1.0-beta.3",
51+
"@types/lodash": "4.14.104",
52+
"node-fetch": "2.1.1"
53+
},
54+
"peerDependencies": {
55+
"@accounts/client": "^0.1.0-beta.0",
56+
"@accounts/common": "^0.1.0-beta.0"
57+
},
58+
"dependencies": {
59+
"lodash": "^4.17.4"
60+
}
61+
}

0 commit comments

Comments
 (0)