mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-01-20 22:52:46 -05:00
refactor: unit tests and api service
refactor: fixes login api success call refactor: fixes login respose for success case
This commit is contained in:
parent
f4a4f02c9b
commit
5c95551e8f
9 changed files with 72 additions and 46 deletions
|
@ -44,7 +44,7 @@ export default class Header extends React.Component {
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
API.request('logo')
|
API.request('logo')
|
||||||
.then((response) => response.text().then((logo) => this.setState({logo})))
|
.then((logo) => this.setState({logo}))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
});
|
});
|
||||||
|
@ -66,13 +66,13 @@ export default class Header extends React.Component {
|
||||||
username: this.state.username,
|
username: this.state.username,
|
||||||
password: this.state.password
|
password: this.state.password
|
||||||
};
|
};
|
||||||
let resp = await API.request(`login`, 'POST', {
|
const resp = await API.request(`login`, 'POST', {
|
||||||
body: JSON.stringify(credentials),
|
body: JSON.stringify(credentials),
|
||||||
headers: {
|
headers: {
|
||||||
Accept: HEADERS.JSON,
|
Accept: HEADERS.JSON,
|
||||||
'Content-Type': HEADERS.JSON
|
'Content-Type': HEADERS.JSON
|
||||||
}
|
}
|
||||||
}).then((response) => response.json());
|
});
|
||||||
|
|
||||||
storage.setItem('token', resp.token);
|
storage.setItem('token', resp.token);
|
||||||
storage.setItem('username', resp.username);
|
storage.setItem('username', resp.username);
|
||||||
|
@ -80,9 +80,9 @@ export default class Header extends React.Component {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const errorObj = {
|
const errorObj = {
|
||||||
title: 'Unable to login',
|
title: 'Unable to login',
|
||||||
type: 'error'
|
type: 'error',
|
||||||
|
description: e.error
|
||||||
};
|
};
|
||||||
errorObj.description = e.message;
|
|
||||||
this.setState({loginError: errorObj});
|
this.setState({loginError: errorObj});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,7 @@ export default class PackageSidebar extends React.Component {
|
||||||
let packageMeta;
|
let packageMeta;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
packageMeta = await API.request(`sidebar/${packageName}`, 'GET').then(function(response) {
|
packageMeta = await API.request(`sidebar/${packageName}`, 'GET');
|
||||||
return response.json();
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setState({
|
this.setState({
|
||||||
failed: true
|
failed: true
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default class Detail extends React.Component {
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await API.request(`package/readme/${packageName}`, 'GET').then((response) => response.text());
|
const resp = await API.request(`package/readme/${packageName}`, 'GET');
|
||||||
this.setState({
|
this.setState({
|
||||||
readMe: resp
|
readMe: resp
|
||||||
});
|
});
|
||||||
|
|
|
@ -51,7 +51,7 @@ export default class Home extends React.Component {
|
||||||
|
|
||||||
async loadPackages() {
|
async loadPackages() {
|
||||||
try {
|
try {
|
||||||
this.req = await API.request('packages', 'GET').then((response) => response.json());
|
this.req = await API.request('packages', 'GET');
|
||||||
|
|
||||||
if (this.state.query === '') {
|
if (this.state.query === '') {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -70,7 +70,7 @@ export default class Home extends React.Component {
|
||||||
|
|
||||||
async searchPackage(query) {
|
async searchPackage(query) {
|
||||||
try {
|
try {
|
||||||
this.req = await API.request(`/search/${query}`, 'GET').then((response) => response.json());
|
this.req = await API.request(`/search/${query}`, 'GET');
|
||||||
|
|
||||||
// Implement cancel feature later
|
// Implement cancel feature later
|
||||||
if (this.state.query === query) {
|
if (this.state.query === query) {
|
||||||
|
|
|
@ -17,18 +17,42 @@ class API {
|
||||||
url = window.VERDACCIO_API_URL + url;
|
url = window.VERDACCIO_API_URL + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleErrors(response) {
|
/**
|
||||||
if (!response.ok) {
|
* Handles response according to content type
|
||||||
throw Error(response.statusText);
|
* @param {object} response
|
||||||
|
* @returns {promise}
|
||||||
|
*/
|
||||||
|
function handleResponseType(response) {
|
||||||
|
if (response.headers) {
|
||||||
|
const contentType = response.headers.get('Content-Type');
|
||||||
|
if (contentType.includes('application/pdf')) {
|
||||||
|
return Promise.all([response.ok, response.blob()]);
|
||||||
|
}
|
||||||
|
if (contentType.includes('application/json')) {
|
||||||
|
return Promise.all([response.ok, response.json()]);
|
||||||
|
}
|
||||||
|
// it includes all text types
|
||||||
|
if (contentType.includes('text/')) {
|
||||||
|
return Promise.all([response.ok, response.text()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch(url, {
|
return new Promise((resolve, reject) => {
|
||||||
|
fetch(url, {
|
||||||
method,
|
method,
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
...options
|
...options
|
||||||
}).then(handleErrors);
|
})
|
||||||
|
.then(handleResponseType)
|
||||||
|
.then(([responseOk, body]) => {
|
||||||
|
if (responseOk) {
|
||||||
|
resolve(body);
|
||||||
|
} else {
|
||||||
|
reject(body);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,7 @@ const register = (url, method = 'get', options = {}) => {
|
||||||
|
|
||||||
if (url === 'sidebar/verdaccio' && method.toLocaleLowerCase() === 'get') {
|
if (url === 'sidebar/verdaccio' && method.toLocaleLowerCase() === 'get') {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
resolve({
|
resolve(packageMeta);
|
||||||
json: function() {
|
|
||||||
return packageMeta;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ describe('<Header /> component shallow', () => {
|
||||||
|
|
||||||
it('handleSubmit - should give error for blank username and password', () => {
|
it('handleSubmit - should give error for blank username and password', () => {
|
||||||
const HeaderWrapper = wrapper.find(Header).dive();
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
const handleSubmit = HeaderWrapper.instance().handleSubmit;
|
const {handleSubmit} = HeaderWrapper.instance();
|
||||||
const error = {
|
const error = {
|
||||||
description: "Username or password can't be empty!",
|
description: "Username or password can't be empty!",
|
||||||
title: 'Unable to login',
|
title: 'Unable to login',
|
||||||
|
@ -67,11 +67,14 @@ describe('<Header /> component shallow', () => {
|
||||||
|
|
||||||
it('handleSubmit - should login successfully', () => {
|
it('handleSubmit - should login successfully', () => {
|
||||||
const HeaderWrapper = wrapper.find(Header).dive();
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
const handleSubmit = HeaderWrapper.instance().handleSubmit;
|
const {handleSubmit} = HeaderWrapper.instance();
|
||||||
|
const event = {preventDefault: () => {}}
|
||||||
|
const spy = jest.spyOn(event, 'preventDefault');
|
||||||
|
|
||||||
HeaderWrapper.setState({ username: 'sam', password: '1234' });
|
HeaderWrapper.setState({ username: 'sam', password: '1234' });
|
||||||
|
|
||||||
handleSubmit().then(() => {
|
handleSubmit(event).then(() => {
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
expect(storage.getItem('token')).toEqual('TEST_TOKEN');
|
expect(storage.getItem('token')).toEqual('TEST_TOKEN');
|
||||||
expect(storage.getItem('username')).toEqual('sam');
|
expect(storage.getItem('username')).toEqual('sam');
|
||||||
});
|
});
|
||||||
|
@ -79,30 +82,37 @@ describe('<Header /> component shallow', () => {
|
||||||
|
|
||||||
it('handleSubmit - login should failed with 401', () => {
|
it('handleSubmit - login should failed with 401', () => {
|
||||||
const HeaderWrapper = wrapper.find(Header).dive();
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
const handleSubmit = HeaderWrapper.instance().handleSubmit;
|
const {handleSubmit} = HeaderWrapper.instance();
|
||||||
const errorObject = {
|
const errorObject = {
|
||||||
title: 'Unable to login',
|
title: 'Unable to login',
|
||||||
type: 'error',
|
type: 'error',
|
||||||
description: 'Unauthorized'
|
description: 'bad username/password, access denied'
|
||||||
};
|
};
|
||||||
|
const event = { preventDefault: () => { } }
|
||||||
|
const spy = jest.spyOn(event, 'preventDefault');
|
||||||
HeaderWrapper.setState({ username: 'sam', password: '12345' });
|
HeaderWrapper.setState({ username: 'sam', password: '12345' });
|
||||||
|
|
||||||
handleSubmit().catch((error) => {
|
handleSubmit(event).then(() => {
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
expect(HeaderWrapper.state('loginError')).toEqual(errorObject);
|
expect(HeaderWrapper.state('loginError')).toEqual(errorObject);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handleSubmit - login should failed with when no data is sent', () => {
|
it('handleSubmit - login should failed with when no data is sent', () => {
|
||||||
const HeaderWrapper = wrapper.find(Header).dive();
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
const handleSubmit = HeaderWrapper.instance().handleSubmit;
|
const {handleSubmit} = HeaderWrapper.instance();
|
||||||
const error = {
|
const error = {
|
||||||
title: 'Unable to login',
|
title: 'Unable to login',
|
||||||
type: 'error',
|
type: 'error',
|
||||||
description: "Username or password can't be empty!"
|
description: "Username or password can't be empty!"
|
||||||
};
|
};
|
||||||
|
const event = { preventDefault: () => { } }
|
||||||
|
const spy = jest.spyOn(event, 'preventDefault');
|
||||||
|
|
||||||
HeaderWrapper.setState({});
|
HeaderWrapper.setState({});
|
||||||
|
|
||||||
handleSubmit().then(() => {
|
handleSubmit(event).then(() => {
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
expect(HeaderWrapper.state('loginError')).toEqual(error);
|
expect(HeaderWrapper.state('loginError')).toEqual(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,21 +4,17 @@
|
||||||
* @returns {promise}
|
* @returns {promise}
|
||||||
*/
|
*/
|
||||||
export default function(config) {
|
export default function(config) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise((resolve, reject) => {
|
||||||
const body = JSON.parse(config.body);
|
const body = JSON.parse(config.body);
|
||||||
if (body.username === 'sam' && body.password === '1234') {
|
if (body.username === 'sam' && body.password === '1234') {
|
||||||
return new Promise(function(resolve) {
|
|
||||||
resolve({
|
resolve({
|
||||||
json: function() {
|
|
||||||
return {
|
|
||||||
username: 'sam',
|
username: 'sam',
|
||||||
token: 'TEST_TOKEN'
|
token: 'TEST_TOKEN'
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw Error('Unauthorized');
|
reject({
|
||||||
|
error: 'bad username/password, access denied'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
/**
|
/**
|
||||||
* Mock response for login api
|
* Mock response for logo api
|
||||||
* @returns {promise}
|
* @returns {promise}
|
||||||
*/
|
*/
|
||||||
export default function() {
|
export default function() {
|
||||||
const response = {
|
const response = {
|
||||||
url: 'http://xyz.com/image.jpg'
|
text(){
|
||||||
|
return 'http://xyz.com/image.jpg';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return Promise.resolve(response);
|
return Promise.resolve(response);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue