Skip to content

Commit

Permalink
Copy rest/packages/client => accounts/packages/rest-client
Browse files Browse the repository at this point in the history
  • Loading branch information
Aetherall committed Mar 11, 2018
1 parent 72e55ef commit 0c7f7b4
Show file tree
Hide file tree
Showing 10 changed files with 644 additions and 0 deletions.
7 changes: 7 additions & 0 deletions packages/rest-client/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
__tests__
src/
coverage/
node_modules
.npmignore
tsconfig.json
yarn.lock
12 changes: 12 additions & 0 deletions packages/rest-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# @accounts/rest-client

[![npm](https://img.shields.io/npm/v/@accounts/rest-client.svg?maxAge=2592000)](https://www.npmjs.com/package/@accounts/rest-client)
[![CircleCI](https://circleci.com/gh/accounts-js/rest.svg?style=shield)](https://circleci.com/gh/accounts-js/rest)
[![codecov](https://codecov.io/gh/accounts-js/rest/branch/master/graph/badge.svg)](https://codecov.io/gh/accounts-js/rest)
![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)

## Install

```
yarn add @accounts/rest-client
```
51 changes: 51 additions & 0 deletions packages/rest-client/__tests__/auth-fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import fetch from 'node-fetch';
import { authFetch } from '../src/auth-fetch';

window.fetch = jest.fn().mockImplementation(() => ({
status: 200,
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
}));

describe('authFetch', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should call fetch', async () => {
const accounts = {
refreshSession: jest.fn(() => Promise.resolve()),
tokens: jest.fn(() => Promise.resolve({})),
};
await authFetch(accounts, 'path', {});
expect(accounts.refreshSession).toBeCalled();
expect(accounts.tokens).toBeCalled();
});

it('should set access token header', async () => {
const accounts = {
refreshSession: jest.fn(() => Promise.resolve()),
tokens: jest.fn(() => Promise.resolve({ accessToken: 'accessToken' })),
};
await authFetch(accounts, 'path', {});
expect(accounts.refreshSession).toBeCalled();
expect(accounts.tokens).toBeCalled();
expect(window.fetch.mock.calls[0][1].headers['accounts-access-token']).toBe(
'accessToken'
);
});

it('should pass other headers', async () => {
const accounts = {
refreshSession: jest.fn(() => Promise.resolve()),
tokens: jest.fn(() => Promise.resolve({ accessToken: 'accessToken' })),
};
await authFetch(accounts, 'path', {
headers: {
toto: 'toto',
},
});
expect(accounts.refreshSession).toBeCalled();
expect(accounts.tokens).toBeCalled();
expect(window.fetch.mock.calls[0][1].headers.toto).toBe('toto');
});
});
251 changes: 251 additions & 0 deletions packages/rest-client/__tests__/rest-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import fetch from 'node-fetch';
import { RestClient } from '../src/rest-client';

window.fetch = jest.fn().mockImplementation(() => ({
status: 200,
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
}));

window.Headers = fetch.Headers;

describe('RestClient', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should have a way to configure api host address and root path', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000/',
rootPath: 'accounts',
});

expect(client.options.apiHost).toBe('http://localhost:3000/');
expect(client.options.rootPath).toBe('accounts');

return client.fetch('try').then(() => {
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/try'
);
});
});

describe('fetch', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000/',
rootPath: 'accounts',
});

it('should enable custom headers', () =>
client
.fetch('route', {}, { origin: 'localhost:3000' })
.then(() =>
expect(window.fetch.mock.calls[0][1].headers.origin).toBe(
'localhost:3000'
)
));

it('should throw error', async () => {
window.fetch = jest.fn().mockImplementation(() => ({
status: 400,
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
}));

try {
await client.fetch('route', {}, { origin: 'localhost:3000' });
throw new Error();
} catch (err) {
expect(window.fetch.mock.calls[0][1].headers.origin).toBe(
'localhost:3000'
);
}
window.fetch = jest.fn().mockImplementation(() => ({
status: 200,
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
}));
});

it('should throw if server did not return a response', async () => {
window.fetch = jest.fn().mockImplementation(() => null);

try {
await client.fetch('route', {}, { origin: 'localhost:3000' });
throw new Error();
} catch (err) {
expect(window.fetch.mock.calls[0][1].headers.origin).toBe(
'localhost:3000'
);
expect(err.message).toBe('Server did not return a response');
}
window.fetch = jest.fn().mockImplementation(() => ({
status: 200,
json: jest.fn().mockImplementation(() => ({ test: 'test' })),
}));
});
});

describe('loginWithService', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with authenticate path', async () => {
await client.loginWithService('password', {
user: {
username: 'toto',
},
password: 'password',
});
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/password/authenticate'
);
expect(window.fetch.mock.calls[0][1].body).toBe(
'{"user":{"username":"toto"},"password":"password"}'
);
});
});

describe('impersonate', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with impersonate path', () =>
client
.impersonate('token', 'user')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/impersonate'
)
));
});

describe('refreshTokens', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with refreshTokens path', () =>
client
.refreshTokens('accessToken', 'refreshToken')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/refreshTokens'
)
));
});

describe('logout', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with logout path', () =>
client
.logout('accessToken')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/logout'
)
));
});

describe('getUser', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with user path', () =>
client
.getUser('accessToken')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/user'
)
));
});

describe('createUser', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with register path', () =>
client
.createUser('user')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/password/register'
)
));
});

describe('resetPassword', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with resetPassword path', () =>
client
.resetPassword('token', 'resetPassword')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/password/resetPassword'
)
));
});

describe('verifyEmail', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with verifyEmail path', () =>
client
.verifyEmail('token')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/password/verifyEmail'
)
));
});

describe('sendVerificationEmail', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with verifyEmail path', () =>
client
.sendVerificationEmail('email')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/password/sendVerificationEmail'
)
));
});

describe('sendResetPasswordEmail', () => {
const client = new RestClient({
apiHost: 'http://localhost:3000',
rootPath: '/accounts',
});

it('should call fetch with verifyEmail path', () =>
client
.sendResetPasswordEmail('email')
.then(() =>
expect(window.fetch.mock.calls[0][0]).toBe(
'http://localhost:3000/accounts/password/sendResetPasswordEmail'
)
));
});
});
61 changes: 61 additions & 0 deletions packages/rest-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "@accounts/rest-client",
"version": "0.1.0-beta.2",
"description": "REST client for accounts",
"main": "lib/index",
"typings": "lib/index",
"publishConfig": {
"access": "public"
},
"scripts": {
"start": "tsc --watch",
"precompile": "rimraf ./lib",
"compile": "tsc",
"prepublish": "npm run compile",
"test": "npm run testonly",
"testonly": "jest",
"coverage": "npm run testonly -- --coverage",
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
},
"jest": {
"testEnvironment": "jsdom",
"transform": {
".(ts|tsx)": "<rootDir>/../../node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx)$",
"moduleFileExtensions": [
"ts",
"js"
],
"mapCoverage": true
},
"repository": {
"type": "git",
"url": "https://github.com/js-accounts/rest/tree/master/packages/rest-client"
},
"keywords": [
"rest",
"graphql",
"grant",
"auth",
"authentication",
"accounts",
"users",
"oauth"
],
"author": "Tim Mikeladze",
"license": "MIT",
"devDependencies": {
"@accounts/client": "0.1.0-beta.3",
"@accounts/common": "0.1.0-beta.3",
"@types/lodash": "4.14.104",
"node-fetch": "2.1.1"
},
"peerDependencies": {
"@accounts/client": "^0.1.0-beta.0",
"@accounts/common": "^0.1.0-beta.0"
},
"dependencies": {
"lodash": "^4.17.4"
}
}
Loading

0 comments on commit 0c7f7b4

Please sign in to comment.