diff --git a/src/webui/src/components/Header/index.js b/src/webui/src/components/Header/index.js
index 3426805c1..19d0d95ad 100644
--- a/src/webui/src/components/Header/index.js
+++ b/src/webui/src/components/Header/index.js
@@ -44,7 +44,7 @@ export default class Header extends React.Component {
componentWillMount() {
API.request('logo')
- .then((response) => response.text().then((logo) => this.setState({logo})))
+ .then((logo) => this.setState({logo}))
.catch((error) => {
throw new Error(error);
});
@@ -66,13 +66,13 @@ export default class Header extends React.Component {
username: this.state.username,
password: this.state.password
};
- let resp = await API.request(`login`, 'POST', {
+ const resp = await API.request(`login`, 'POST', {
body: JSON.stringify(credentials),
headers: {
Accept: HEADERS.JSON,
'Content-Type': HEADERS.JSON
}
- }).then((response) => response.json());
+ });
storage.setItem('token', resp.token);
storage.setItem('username', resp.username);
@@ -80,9 +80,9 @@ export default class Header extends React.Component {
} catch (e) {
const errorObj = {
title: 'Unable to login',
- type: 'error'
+ type: 'error',
+ description: e.error
};
- errorObj.description = e.message;
this.setState({loginError: errorObj});
}
}
diff --git a/src/webui/src/components/PackageSidebar/index.jsx b/src/webui/src/components/PackageSidebar/index.jsx
index 82f535dcb..deed61706 100644
--- a/src/webui/src/components/PackageSidebar/index.jsx
+++ b/src/webui/src/components/PackageSidebar/index.jsx
@@ -33,9 +33,7 @@ export default class PackageSidebar extends React.Component {
let packageMeta;
try {
- packageMeta = await API.request(`sidebar/${packageName}`, 'GET').then(function(response) {
- return response.json();
- });
+ packageMeta = await API.request(`sidebar/${packageName}`, 'GET');
} catch (err) {
this.setState({
failed: true
diff --git a/src/webui/src/modules/detail/index.jsx b/src/webui/src/modules/detail/index.jsx
index acd93be16..0c305426c 100644
--- a/src/webui/src/modules/detail/index.jsx
+++ b/src/webui/src/modules/detail/index.jsx
@@ -47,7 +47,7 @@ export default class Detail extends React.Component {
});
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({
readMe: resp
});
diff --git a/src/webui/src/modules/home/index.js b/src/webui/src/modules/home/index.js
index 8160d79f8..72a19879f 100644
--- a/src/webui/src/modules/home/index.js
+++ b/src/webui/src/modules/home/index.js
@@ -51,7 +51,7 @@ export default class Home extends React.Component {
async loadPackages() {
try {
- this.req = await API.request('packages', 'GET').then((response) => response.json());
+ this.req = await API.request('packages', 'GET');
if (this.state.query === '') {
this.setState({
@@ -70,7 +70,7 @@ export default class Home extends React.Component {
async searchPackage(query) {
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
if (this.state.query === query) {
diff --git a/src/webui/utils/api.js b/src/webui/utils/api.js
index c76ffe3e2..fa0436ca4 100644
--- a/src/webui/utils/api.js
+++ b/src/webui/utils/api.js
@@ -17,18 +17,42 @@ class API {
url = window.VERDACCIO_API_URL + url;
}
- function handleErrors(response) {
- if (!response.ok) {
- throw Error(response.statusText);
+ /**
+ * Handles response according to content type
+ * @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, {
- method,
- credentials: 'same-origin',
- ...options
- }).then(handleErrors);
+ return new Promise((resolve, reject) => {
+ fetch(url, {
+ method,
+ credentials: 'same-origin',
+ ...options
+ })
+ .then(handleResponseType)
+ .then(([responseOk, body]) => {
+ if (responseOk) {
+ resolve(body);
+ } else {
+ reject(body);
+ }
+ });
+ });
}
}
diff --git a/test/unit/webui/components/__mocks__/api.js b/test/unit/webui/components/__mocks__/api.js
index 2c8e2cf3e..afd8eeb44 100644
--- a/test/unit/webui/components/__mocks__/api.js
+++ b/test/unit/webui/components/__mocks__/api.js
@@ -22,11 +22,7 @@ const register = (url, method = 'get', options = {}) => {
if (url === 'sidebar/verdaccio' && method.toLocaleLowerCase() === 'get') {
return new Promise(function(resolve) {
- resolve({
- json: function() {
- return packageMeta;
- }
- });
+ resolve(packageMeta);
});
}
diff --git a/test/unit/webui/components/header.spec.js b/test/unit/webui/components/header.spec.js
index 2bb42f3ae..a0718d5be 100644
--- a/test/unit/webui/components/header.spec.js
+++ b/test/unit/webui/components/header.spec.js
@@ -55,7 +55,7 @@ describe(' component shallow', () => {
it('handleSubmit - should give error for blank username and password', () => {
const HeaderWrapper = wrapper.find(Header).dive();
- const handleSubmit = HeaderWrapper.instance().handleSubmit;
+ const {handleSubmit} = HeaderWrapper.instance();
const error = {
description: "Username or password can't be empty!",
title: 'Unable to login',
@@ -67,11 +67,14 @@ describe(' component shallow', () => {
it('handleSubmit - should login successfully', () => {
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' });
- handleSubmit().then(() => {
+ handleSubmit(event).then(() => {
+ expect(spy).toHaveBeenCalled();
expect(storage.getItem('token')).toEqual('TEST_TOKEN');
expect(storage.getItem('username')).toEqual('sam');
});
@@ -79,30 +82,37 @@ describe(' component shallow', () => {
it('handleSubmit - login should failed with 401', () => {
const HeaderWrapper = wrapper.find(Header).dive();
- const handleSubmit = HeaderWrapper.instance().handleSubmit;
+ const {handleSubmit} = HeaderWrapper.instance();
const errorObject = {
title: 'Unable to login',
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' });
- handleSubmit().catch((error) => {
+ handleSubmit(event).then(() => {
+ expect(spy).toHaveBeenCalled();
expect(HeaderWrapper.state('loginError')).toEqual(errorObject);
});
});
it('handleSubmit - login should failed with when no data is sent', () => {
const HeaderWrapper = wrapper.find(Header).dive();
- const handleSubmit = HeaderWrapper.instance().handleSubmit;
+ const {handleSubmit} = HeaderWrapper.instance();
const error = {
title: 'Unable to login',
type: 'error',
description: "Username or password can't be empty!"
};
+ const event = { preventDefault: () => { } }
+ const spy = jest.spyOn(event, 'preventDefault');
+
HeaderWrapper.setState({});
- handleSubmit().then(() => {
+ handleSubmit(event).then(() => {
+ expect(spy).toHaveBeenCalled();
expect(HeaderWrapper.state('loginError')).toEqual(error);
});
});
diff --git a/test/unit/webui/components/store/login.js b/test/unit/webui/components/store/login.js
index 35f6897fc..bbe89e9e1 100644
--- a/test/unit/webui/components/store/login.js
+++ b/test/unit/webui/components/store/login.js
@@ -4,21 +4,17 @@
* @returns {promise}
*/
export default function(config) {
- return new Promise(function(resolve, reject) {
+ return new Promise((resolve, reject) => {
const body = JSON.parse(config.body);
if (body.username === 'sam' && body.password === '1234') {
- return new Promise(function(resolve) {
resolve({
- json: function() {
- return {
- username: 'sam',
- token: 'TEST_TOKEN'
- }
- }
+ username: 'sam',
+ token: 'TEST_TOKEN'
});
- });
} else {
- throw Error('Unauthorized');
+ reject({
+ error: 'bad username/password, access denied'
+ });
}
});
}
diff --git a/test/unit/webui/components/store/logo.js b/test/unit/webui/components/store/logo.js
index 74162df22..11c4e9a3b 100644
--- a/test/unit/webui/components/store/logo.js
+++ b/test/unit/webui/components/store/logo.js
@@ -1,10 +1,12 @@
/**
- * Mock response for login api
+ * Mock response for logo api
* @returns {promise}
*/
export default function() {
const response = {
- url: 'http://xyz.com/image.jpg'
+ text(){
+ return 'http://xyz.com/image.jpg';
+ }
};
return Promise.resolve(response);
}