1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-02-21 07:29:37 +01:00

Merge branch 'master' into chore/remove-obsolete-travis-ci-code

This commit is contained in:
Juan Picado @jotadeveloper 2018-06-30 19:48:36 +02:00 committed by GitHub
commit ee1c50e835
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 89 additions and 61 deletions

@ -32,7 +32,7 @@ aliases:
restore_cache: restore_cache:
keys: keys:
- *repo_key - *repo_key
- &ignore_branches - &ignore_non_dev_branches
filters: filters:
tags: tags:
only: /.*/ only: /.*/
@ -41,6 +41,13 @@ aliases:
- gh-pages - gh-pages
- l10n_master - l10n_master
- /release\/.*/ - /release\/.*/
- &execute_on_release
filters:
tags:
only: /(v)?[0-9]+(\.[0-9]+)*/
branches:
ignore:
- /.*/
jobs: jobs:
prepare: prepare:
@ -187,27 +194,27 @@ workflows:
workflow: workflow:
jobs: jobs:
- prepare: - prepare:
<<: *ignore_branches <<: *ignore_non_dev_branches
- test_node6: - test_node6:
requires: requires:
- prepare - prepare
<<: *ignore_branches <<: *ignore_non_dev_branches
- test_node8: - test_node8:
requires: requires:
- prepare - prepare
<<: *ignore_branches <<: *ignore_non_dev_branches
- test_node9: - test_node9:
requires: requires:
- prepare - prepare
<<: *ignore_branches <<: *ignore_non_dev_branches
- test_node10: - test_node10:
requires: requires:
- prepare - prepare
<<: *ignore_branches <<: *ignore_non_dev_branches
- test_e2e: - test_e2e:
requires: requires:
- prepare - prepare
<<: *ignore_branches <<: *ignore_non_dev_branches
- coverage: - coverage:
requires: requires:
- test_node6 - test_node6
@ -215,7 +222,7 @@ workflows:
- test_node9 - test_node9
- test_node10 - test_node10
- test_e2e - test_e2e
<<: *ignore_branches <<: *ignore_non_dev_branches
- publish_gh_pages: - publish_gh_pages:
requires: requires:
- test_node6 - test_node6
@ -223,14 +230,9 @@ workflows:
- test_node9 - test_node9
- test_node10 - test_node10
- test_e2e - test_e2e
<<: *ignore_branches <<: *execute_on_release
- publish_package: - publish_package:
requires: requires:
- coverage - coverage
- publish_gh_pages - publish_gh_pages
filters: <<: *execute_on_release
tags:
only: /(v)?[0-9]+(\.[0-9]+)*/
branches:
ignore:
- /.*/

@ -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) => {
method, fetch(url, {
credentials: 'same-origin', method,
...options credentials: 'same-origin',
}).then(handleErrors); ...options
})
.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() { username: 'sam',
return { token: 'TEST_TOKEN'
username: 'sam',
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);
} }