diff --git a/src/api/web/endpoint/user.js b/src/api/web/endpoint/user.js
index 857d9dc3f..bf459306d 100644
--- a/src/api/web/endpoint/user.js
+++ b/src/api/web/endpoint/user.js
@@ -4,7 +4,7 @@ import HTTPError from 'http-errors';
import type {Config} from '@verdaccio/types';
import type {Router} from 'express';
import type {IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer} from '../../../../types';
-import {combineBaseUrl, getWebProtocol} from '../../../lib/utils';
+// import {combineBaseUrl, getWebProtocol} from '../../../lib/utils';
function addUserAuthApi(route: Router, auth: IAuth, config: Config) {
route.post('/login', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
@@ -22,12 +22,13 @@ function addUserAuthApi(route: Router, auth: IAuth, config: Config) {
});
});
- route.post('/-/logout', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
- const base = combineBaseUrl(getWebProtocol(req), req.get('host'), config.url_prefix);
+ // FIXME: this will be re-implemented
+ // route.post('/-/logout', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
+ // const base = combineBaseUrl(getWebProtocol(req), req.get('host'), config.url_prefix);
- res.cookies.set('token', '');
- res.redirect(base);
- });
+ // res.cookies.set('token', '');
+ // res.redirect(base);
+ // });
}
export default addUserAuthApi;
diff --git a/src/utils/user.js b/src/utils/user.js
index 5eae16b7d..d3ca87c0f 100644
--- a/src/utils/user.js
+++ b/src/utils/user.js
@@ -1,6 +1,8 @@
// @flow
import {stringToMD5} from './string';
+
+export const GRAVATAR_DEFAULT = 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mm';
/**
* Generate gravatar url from email address
*/
@@ -11,6 +13,6 @@ export function generateGravatarUrl(email?: string): string {
return `https://www.gravatar.com/avatar/${emailMD5}`;
} else {
- return 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mm';
+ return GRAVATAR_DEFAULT;
}
}
diff --git a/test/unit/api.spec.js b/test/unit/api.spec.js
index 881a1679c..512b39be6 100644
--- a/test/unit/api.spec.js
+++ b/test/unit/api.spec.js
@@ -5,18 +5,21 @@ import rimraf from 'rimraf';
import configDefault from './partials/config';
import publishMetadata from './partials/publish-api';
+import forbiddenPlace from './partials/forbidden-place';
import Config from '../../src/lib/config';
import Storage from '../../src/lib/storage';
import Auth from '../../src/lib/auth';
import indexAPI from '../../src/api/index';
require('../../src/lib/logger').setup([]);
+const credentials = { name: 'Jota', password: 'secretPass' };
describe('endpoint unit test', () => {
let config;
let storage;
let auth;
let app;
+ jest.setTimeout(10000);
beforeAll(function(done) {
const store = path.join(__dirname, './partials/store/test-storage');
@@ -36,445 +39,596 @@ describe('endpoint unit test', () => {
});
});
- describe('should test ping api', () => {
- test('should test endpoint /-/ping', (done) => {
- request(app)
- .get('/-/ping')
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- done();
- });
+ describe('Registry API Endpoints', () => {
+
+ describe('should test ping api', () => {
+ test('should test endpoint /-/ping', (done) => {
+ request(app)
+ .get('/-/ping')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ done();
+ });
+ });
+ });
+
+ describe('should test whoami api', () => {
+ test('should test /-/whoami endpoint', (done) => {
+ request(app)
+ .get('/-/whoami')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ done();
+ });
+ });
+
+ test('should test /whoami endpoint', (done) => {
+ request(app)
+ .get('/-/whoami')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ done();
+ });
+ });
+ });
+
+ describe('should test user api', () => {
+ test('should test add a new user', (done) => {
+ request(app)
+ .put('/-/user/org.couchdb.user:jota')
+ .send(credentials)
+ .expect('Content-Type', /json/)
+ .expect(201)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body.ok).toBeDefined();
+ expect(res.body.ok).toMatch(`user '${credentials.name}' created`);
+ done();
+ });
+ });
+
+ test('should test fails add a new user with missing name', (done) => {
+
+ const credentialsShort = _.clone(credentials);
+ delete credentialsShort.name;
+
+ request(app)
+ .put('/-/user/org.couchdb.user:jota')
+ .send(credentialsShort)
+ .expect('Content-Type', /json/)
+ .expect(400)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body.error).toBeDefined();
+ expect(res.body.error).toMatch(/username and password is required/);
+ done();
+ });
+ });
+
+ test('should test fails add a new user with missing password', (done) => {
+
+ const credentialsShort = _.clone(credentials);
+ delete credentialsShort.password;
+
+ request(app)
+ .put('/-/user/org.couchdb.user:jota')
+ .send(credentialsShort)
+ .expect('Content-Type', /json/)
+ .expect(400)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body.error).toBeDefined();
+ //FIXME: message is not 100% accurate
+ expect(res.body.error).toMatch(/username and password is required/);
+ done();
+ });
+ });
+
+ test('should test add a new user with login', (done) => {
+
+ request(app)
+ .put('/-/user/org.couchdb.user:jota')
+ .send(credentials)
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ expect(res.body).toBeTruthy();
+ done();
+ });
+ });
+
+ test('should test fails add a new user with wrong password', (done) => {
+
+ const credentialsShort = _.clone(credentials);
+ credentialsShort.password = 'failPassword';
+
+ request(app)
+ .put('/-/user/org.couchdb.user:jota')
+ .send(credentialsShort)
+ .expect('Content-Type', /json/)
+ .expect(401)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body.error).toBeDefined();
+ expect(res.body.error).toMatch(/unauthorized/);
+ done();
+ });
+ });
+
+ });
+
+ describe('should test package api', () => {
+
+ test('should fetch jquery package from remote uplink', (done) => {
+
+ request(app)
+ .get('/jquery')
+ .set('content-type', 'application/json; charset=utf-8')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body).toBeDefined();
+ expect(res.body.name).toMatch(/jquery/);
+ done();
+ });
+ });
+
+ test('should fetch jquery specific version package from remote uplink', (done) => {
+
+ request(app)
+ .get('/jquery/1.5.1')
+ .set('content-type', 'application/json; charset=utf-8')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body).toBeDefined();
+ expect(res.body.name).toMatch(/jquery/);
+ done();
+ });
+ });
+
+ test('should fetch jquery specific tag package from remote uplink', (done) => {
+
+ request(app)
+ .get('/jquery/latest')
+ .set('content-type', 'application/json; charset=utf-8')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body).toBeDefined();
+ expect(res.body.name).toMatch(/jquery/);
+ done();
+ });
+ });
+
+ test('should fails on fetch jquery specific tag package from remote uplink', (done) => {
+
+ request(app)
+ .get('/jquery/never-will-exist-this-tag')
+ .set('content-type', 'application/json; charset=utf-8')
+ .expect('Content-Type', /json/)
+ .expect(404)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ done();
+ });
+ });
+
+ test('should not found a unexisting remote package under scope', (done) => {
+
+ request(app)
+ .get('/@verdaccio/not-found')
+ .set('content-type', 'application/json; charset=utf-8')
+ .expect('Content-Type', /json/)
+ .expect(404)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ done();
+ });
+ });
+
+ test('should forbid access to remote package', (done) => {
+
+ request(app)
+ .get('/forbidden-place')
+ .set('content-type', 'application/json; charset=utf-8')
+ .expect('Content-Type', /json/)
+ .expect(403)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ done();
+ });
+ });
+
+ test('should fetch a tarball from remote uplink', (done) => {
+
+ request(app)
+ .get('/jquery/-/jquery-1.5.1.tgz')
+ .expect('Content-Type', /application\/octet-stream/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body).toBeDefined();
+ done();
+ });
+ });
+
+ test('should fails fetch a tarball from remote uplink', (done) => {
+
+ request(app)
+ .get('/jquery/-/jquery-0.0.1.tgz')
+ .expect('Content-Type', /application\/octet-stream/)
+ .expect(404)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ done();
+ });
+ });
+
+ });
+
+ describe('should test dist-tag api', () => {
+ const jqueryVersion = '2.1.2';
+ const jqueryUpdatedVersion = {
+ 'beta': '3.0.0',
+ 'jota': '1.6.3'
+ };
+
+ test('should set a new tag on jquery', (done) => {
+
+ request(app)
+ .put('/jquery/verdaccio-tag')
+ .send(JSON.stringify(jqueryVersion))
+ .set('accept', 'gzip')
+ .set('accept-encoding', 'application/json')
+ .set('content-type', 'application/json')
+ .expect(201)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body.ok).toBeDefined();
+ expect(res.body.ok).toMatch(/package tagged/);
+ done();
+ });
+ });
+
+ test('should fetch all tag for jquery', (done) => {
+
+ request(app)
+ .get('/-/package/jquery/dist-tags')
+ .set('accept-encoding', 'application/json')
+ .set('content-type', 'application/json')
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body).toBeDefined();
+ expect(res.body['verdaccio-tag']).toMatch(jqueryVersion);
+ done();
+ });
+ });
+
+ test('should update a new tag on jquery', (done) => {
+
+ request(app)
+ .post('/-/package/jquery/dist-tags')
+ .send(JSON.stringify(jqueryUpdatedVersion))
+ .set('content-type', 'application/json')
+ .expect(201)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body.ok).toBeDefined();
+ expect(res.body.ok).toMatch(/tags updated/);
+ done();
+ });
+ });
+
+ test('should fetch all tags for jquery and ccheck previous update', (done) => {
+
+ request(app)
+ .get('/-/package/jquery/dist-tags')
+ .set('accept-encoding', 'application/json')
+ .set('content-type', 'application/json')
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body).toBeDefined();
+ expect(res.body['beta']).toMatch(jqueryUpdatedVersion['beta']);
+ done();
+ });
+ });
+
+ test('should set a remove a tag on jquery', (done) => {
+
+ request(app)
+ .del('/-/package/jquery/dist-tags/verdaccio-tag')
+ .set('accept-encoding', 'application/json')
+ .set('content-type', 'application/json')
+ //.expect('Content-Type', /json/)
+ .expect(201)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ expect(res.body.ok).toBeDefined();
+ expect(res.body.ok).toMatch(/tag removed/);
+ done();
+ });
+ });
+
+ });
+
+ describe('should test search api', () => {
+ test('should perform a search', (done) => {
+ const now = Date.now()
+ const cacheTime = now - 6000000;
+ request(app)
+ .get('/-/all/since?stale=update_after&startkey=' + cacheTime)
+ // .set('accept-encoding', 'application/json')
+ // .set('content-type', 'application/json')
+ //.expect('Content-Type', /json/)
+ .expect(200)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ //TODO: we have to catch the stream check whether it returns something
+ // we should not spend much time on this api since is deprecated somehow.
+ done();
+ });
+ });
+
+ });
+
+ describe('should test publish api', () => {
+ test('should publish a new package', (done) => {
+ request(app)
+ .put('/@scope%2fpk1-test')
+ .set('content-type', 'application/json')
+ .send(JSON.stringify(publishMetadata))
+ .expect(201)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ expect(res.body.ok).toBeDefined();
+ expect(res.body.success).toBeDefined();
+ expect(res.body.success).toBeTruthy();
+ expect(res.body.ok).toMatch(/created new package/);
+ done();
+ });
+ });
+
+ test('should unpublish a new package', (done) => {
+ //FUTURE: for some reason it does not remove the scope folder
+ request(app)
+ .del('/@scope%2fpk1-test/-rev/4-6abcdb4efd41a576')
+ .set('content-type', 'application/json')
+ .expect(201)
+ .end(function(err, res) {
+ if (err) {
+ return done(err);
+ }
+ expect(res.body.ok).toBeDefined();
+ expect(res.body.ok).toMatch(/package removed/);
+ done();
+ });
+ });
});
});
- describe('should test whoami api', () => {
- test('should test /-/whoami endpoint', (done) => {
- request(app)
- .get('/-/whoami')
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- done();
- });
+ describe('Registry WebUI endpoints', () => {
+ beforeAll(async function() {
+ await request(app)
+ .put('/@scope%2fpk1-test')
+ .set('content-type', 'application/json')
+ .send(JSON.stringify(publishMetadata))
+ .expect(201);
+
+ await request(app)
+ .put('/forbidden-place')
+ .set('content-type', 'application/json')
+ .send(JSON.stringify(forbiddenPlace))
+ .expect(201);
});
- test('should test /whoami endpoint', (done) => {
- request(app)
- .get('/-/whoami')
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- done();
+ describe('Packages', () => {
+
+ test('should display all packages', (done) => {
+ request(app)
+ .get('/-/verdaccio/packages' )
+ .expect(200)
+ .end(function(err, res) {
+ expect(res.body).toHaveLength(1);
+ done();
+ });
+ });
+
+ test('should display scoped readme', (done) => {
+ request(app)
+ .get('/-/verdaccio/package/readme/@scope/pk1-test')
+ .expect(200)
+ .expect('Content-Type', 'text/plain; charset=utf-8')
+ .end(function(err, res) {
+ expect(res.text).toMatch('
test
\n');
+ done();
+ });
+ });
+
+ test('should display scoped readme 404', (done) => {
+ request(app)
+ .get('/-/verdaccio/package/readme/@scope/404')
+ .expect(200)
+ .expect('Content-Type', 'text/plain; charset=utf-8')
+ .end(function(err, res) {
+ expect(res.body.error).toMatch('no such package available');
+ done();
+ });
+ });
+
+ test('should display sidebar info', (done) => {
+ request(app)
+ .get('/-/verdaccio/sidebar/@scope/pk1-test')
+ .expect(200)
+ .expect('Content-Type', /json/)
+ .end(function(err, res) {
+ const sideBarInfo = res.body;
+ const latestVersion = publishMetadata.versions[publishMetadata['dist-tags'].latest];
+
+ expect(sideBarInfo.name).toBe(latestVersion.name);
+ expect(sideBarInfo.latest.author).toBeDefined();
+ expect(sideBarInfo.latest.author.avatar).toMatch(/www.gravatar.com/);
+ expect(sideBarInfo.latest.author.name).toBe(latestVersion.author.name);
+ expect(sideBarInfo.latest.author.email).toBe(latestVersion.author.email);
+ done();
+ });
+ });
+
+ test('should display sidebar info 404', (done) => {
+ request(app)
+ .get('/-/verdaccio/sidebar/@scope/404')
+ .expect(404)
+ .expect('Content-Type', /json/)
+ .end(function(err, res) {
+ done();
+ });
+ });
+ });
+
+ describe('Search', () => {
+
+ test('should search pk1-test', (done) => {
+ request(app)
+ .get('/-/verdaccio/search/scope')
+ .expect(200)
+ .end(function(err, res) {
+ expect(res.body).toHaveLength(1);
+ done();
+ });
+ });
+
+ test('should search with 404', (done) => {
+ request(app)
+ .get('/-/verdaccio/search/@')
+ .expect(200)
+ .end(function(err, res) {
+ // in a normal world, the output would be 1
+ // https://github.com/verdaccio/verdaccio/issues/345
+ // should fix this
+ expect(res.body).toHaveLength(0);
+ done();
+ });
+ });
+
+ test('should not find forbidden-place', (done) => {
+ request(app)
+ .get('/-/verdaccio/search/forbidden-place')
+ .expect(200)
+ .end(function(err, res) {
+ //this is expected since we are not logged
+ // and forbidden-place is allow_access: 'nobody'
+ expect(res.body).toHaveLength(0);
+ done();
+ });
+ });
+ });
+
+ describe('User', () => {
+ describe('login webui', () => {
+ test('should log a user jota', (done) => {
+ request(app)
+ .post('/-/verdaccio/login')
+ .send({
+ username: credentials.name,
+ password: credentials.password
+ })
+ .expect(200)
+ .end(function(err, res) {
+ expect(res.body.error).toBeUndefined();
+ expect(res.body.token).toBeDefined();
+ expect(res.body.token).toBeTruthy();
+ expect(res.body.username).toMatch(credentials.name);
+ done();
+ });
});
+
+ test('should fails on log unvalid user', (done) => {
+ request(app)
+ .post('/-/verdaccio/login')
+ .send(JSON.stringify({
+ username: 'fake',
+ password: 'fake'
+ }))
+ //FIXME: there should be 401
+ .expect(200)
+ .end(function(err, res) {
+ expect(res.body.error).toMatch(/bad username\/password, access denied/);
+ done();
+ });
+ });
+ });
});
});
-
- describe('should test user api', () => {
- const credentials = { name: 'Jota', password: 'secretPass' };
-
- test('should test add a new user', (done) => {
-
-
- request(app)
- .put('/-/user/org.couchdb.user:jota')
- .send(credentials)
- .expect('Content-Type', /json/)
- .expect(201)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body.ok).toBeDefined();
- expect(res.body.ok).toMatch(`user '${credentials.name}' created`);
- done();
- });
- });
-
- test('should test fails add a new user with missing name', (done) => {
-
- const credentialsShort = _.clone(credentials);
- delete credentialsShort.name;
-
- request(app)
- .put('/-/user/org.couchdb.user:jota')
- .send(credentialsShort)
- .expect('Content-Type', /json/)
- .expect(400)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body.error).toBeDefined();
- expect(res.body.error).toMatch(/username and password is required/);
- done();
- });
- });
-
- test('should test fails add a new user with missing password', (done) => {
-
- const credentialsShort = _.clone(credentials);
- delete credentialsShort.password;
-
- request(app)
- .put('/-/user/org.couchdb.user:jota')
- .send(credentialsShort)
- .expect('Content-Type', /json/)
- .expect(400)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body.error).toBeDefined();
- //FIXME: message is not 100% accurate
- expect(res.body.error).toMatch(/username and password is required/);
- done();
- });
- });
-
- test('should test add a new user with login', (done) => {
-
- request(app)
- .put('/-/user/org.couchdb.user:jota')
- .send(credentials)
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- expect(res.body).toBeTruthy();
- done();
- });
- });
-
- test('should test fails add a new user with wrong password', (done) => {
-
- const credentialsShort = _.clone(credentials);
- credentialsShort.password = 'failPassword';
-
- request(app)
- .put('/-/user/org.couchdb.user:jota')
- .send(credentialsShort)
- .expect('Content-Type', /json/)
- .expect(401)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body.error).toBeDefined();
- expect(res.body.error).toMatch(/unauthorized/);
- done();
- });
- });
-
- });
-
- describe('should test package api', () => {
-
- test('should fetch jquery package from remote uplink', (done) => {
-
- request(app)
- .get('/jquery')
- .set('content-type', 'application/json; charset=utf-8')
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body).toBeDefined();
- expect(res.body.name).toMatch(/jquery/);
- done();
- });
- });
-
- test('should fetch jquery specific version package from remote uplink', (done) => {
-
- request(app)
- .get('/jquery/1.5.1')
- .set('content-type', 'application/json; charset=utf-8')
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body).toBeDefined();
- expect(res.body.name).toMatch(/jquery/);
- done();
- });
- });
-
- test('should fetch jquery specific tag package from remote uplink', (done) => {
-
- request(app)
- .get('/jquery/latest')
- .set('content-type', 'application/json; charset=utf-8')
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body).toBeDefined();
- expect(res.body.name).toMatch(/jquery/);
- done();
- });
- });
-
- test('should fails on fetch jquery specific tag package from remote uplink', (done) => {
-
- request(app)
- .get('/jquery/never-will-exist-this-tag')
- .set('content-type', 'application/json; charset=utf-8')
- .expect('Content-Type', /json/)
- .expect(404)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- done();
- });
- });
-
- test('should not found a unexisting remote package under scope', (done) => {
-
- request(app)
- .get('/@verdaccio/not-found')
- .set('content-type', 'application/json; charset=utf-8')
- .expect('Content-Type', /json/)
- .expect(404)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- done();
- });
- });
-
- test('should forbid access to remote package', (done) => {
-
- request(app)
- .get('/forbidden-place')
- .set('content-type', 'application/json; charset=utf-8')
- .expect('Content-Type', /json/)
- .expect(403)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- done();
- });
- });
-
- test('should fetch a tarball from remote uplink', (done) => {
-
- request(app)
- .get('/jquery/-/jquery-1.5.1.tgz')
- .expect('Content-Type', /application\/octet-stream/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body).toBeDefined();
- done();
- });
- });
-
- test('should fails fetch a tarball from remote uplink', (done) => {
-
- request(app)
- .get('/jquery/-/jquery-0.0.1.tgz')
- .expect('Content-Type', /application\/octet-stream/)
- .expect(404)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- done();
- });
- });
-
- });
-
- describe('should test dist-tag api', () => {
- const jqueryVersion = '2.1.2';
- const jqueryUpdatedVersion = {
- 'beta': '3.0.0',
- 'jota': '1.6.3'
- };
-
- test('should set a new tag on jquery', (done) => {
-
- request(app)
- .put('/jquery/verdaccio-tag')
- .send(JSON.stringify(jqueryVersion))
- .set('accept', 'gzip')
- .set('accept-encoding', 'application/json')
- .set('content-type', 'application/json')
- .expect(201)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body.ok).toBeDefined();
- expect(res.body.ok).toMatch(/package tagged/);
- done();
- });
- });
-
- test('should fetch all tag for jquery', (done) => {
-
- request(app)
- .get('/-/package/jquery/dist-tags')
- .set('accept-encoding', 'application/json')
- .set('content-type', 'application/json')
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body).toBeDefined();
- expect(res.body['verdaccio-tag']).toMatch(jqueryVersion);
- done();
- });
- });
-
- test('should update a new tag on jquery', (done) => {
-
- request(app)
- .post('/-/package/jquery/dist-tags')
- .send(JSON.stringify(jqueryUpdatedVersion))
- .set('content-type', 'application/json')
- .expect(201)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body.ok).toBeDefined();
- expect(res.body.ok).toMatch(/tags updated/);
- done();
- });
- });
-
- test('should fetch all tags for jquery and ccheck previous update', (done) => {
-
- request(app)
- .get('/-/package/jquery/dist-tags')
- .set('accept-encoding', 'application/json')
- .set('content-type', 'application/json')
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body).toBeDefined();
- expect(res.body['beta']).toMatch(jqueryUpdatedVersion['beta']);
- done();
- });
- });
-
- test('should set a remove a tag on jquery', (done) => {
-
- request(app)
- .del('/-/package/jquery/dist-tags/verdaccio-tag')
- .set('accept-encoding', 'application/json')
- .set('content-type', 'application/json')
- //.expect('Content-Type', /json/)
- .expect(201)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
-
- expect(res.body.ok).toBeDefined();
- expect(res.body.ok).toMatch(/tag removed/);
- done();
- });
- });
-
- });
-
- describe('should test search api', () => {
- test('should perform a search', (done) => {
- const now = Date.now()
- const cacheTime = now - 6000000;
- request(app)
- .get('/-/all/since?stale=update_after&startkey=' + cacheTime)
- // .set('accept-encoding', 'application/json')
- // .set('content-type', 'application/json')
- //.expect('Content-Type', /json/)
- .expect(200)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- //TODO: we have to catch the stream check whether it returns something
- // we should not spend much time on this api since is deprecated somehow.
- done();
- });
- });
-
- });
-
- describe('should test publish api', () => {
- test('should publish a new package', (done) => {
- request(app)
- .put('/@scope%2fpk1-test')
- .set('content-type', 'application/json')
- .send(JSON.stringify(publishMetadata))
- .expect(201)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- expect(res.body.ok).toBeDefined();
- expect(res.body.success).toBeDefined();
- expect(res.body.success).toBeTruthy();
- expect(res.body.ok).toMatch(/created new package/);
- done();
- });
- });
-
- test('should unpublish a new package', (done) => {
- //FUTURE: for some reason it does not remove the scope folder
- request(app)
- .del('/@scope%2fpk1-test/-rev/4-6abcdb4efd41a576')
- .set('content-type', 'application/json')
- .expect(201)
- .end(function(err, res) {
- if (err) {
- return done(err);
- }
- expect(res.body.ok).toBeDefined();
- expect(res.body.ok).toMatch(/package removed/);
- done();
- });
- });
- });
-
});
diff --git a/test/unit/partials/config.js b/test/unit/partials/config.js
index 722dae174..92d044625 100644
--- a/test/unit/partials/config.js
+++ b/test/unit/partials/config.js
@@ -14,7 +14,7 @@ const config = {
'forbidden-place': {
allow_access: 'nobody',
- allow_publish: 'nobody'
+ allow_publish: '$all'
},
'react': {
diff --git a/test/unit/partials/forbidden-place.js b/test/unit/partials/forbidden-place.js
new file mode 100644
index 000000000..da6f078b0
--- /dev/null
+++ b/test/unit/partials/forbidden-place.js
@@ -0,0 +1,53 @@
+const json = {
+ "_id": "forbidden-place",
+ "name": "forbidden-place",
+ "description": "",
+ "dist-tags": {
+ "latest": "1.0.6"
+ },
+ "versions": {
+ "1.0.6": {
+ "name": "forbidden-place",
+ "version": "1.0.6",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [
+
+ ],
+ "author": {
+ "name": "Juan Picado",
+ "email": "juan@jotadeveloper.com"
+ },
+ "license": "ISC",
+ "dependencies": {
+ "verdaccio": "^2.7.2"
+ },
+ "readme": "# test",
+ "readmeFilename": "README.md",
+ "_id": "forbidden-place@1.0.6",
+ "_npmVersion": "5.5.1",
+ "_nodeVersion": "8.7.0",
+ "_npmUser": {
+
+ },
+ "dist": {
+ "integrity": "sha512-6gHiERpiDgtb3hjqpQH5\/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==",
+ "shasum": "2c03764f651a9f016ca0b7620421457b619151b9",
+ "tarball": "http:\/\/localhost:5555\/forbidden-place\/-\/forbidden-place-1.0.6.tgz"
+ }
+ }
+ },
+ "readme": "# test",
+ "_attachments": {
+ "forbidden-place-1.0.6.tgz": {
+ "content_type": "application\/octet-stream",
+ "data": "H4sIAAAAAAAAE+2W32vbMBDH85y\/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo\/\/79KPeQsnIw5KUDX\/9IOvurLuz\/DHSjK\/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF\/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI\/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS\/pLQe+D+FIv\/agIWI6GX66kFuIhT+1gDjrp\/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0\/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi\/IHpU9fz3\/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6\/f88f\/Pu47zomiPk2Lv\/dOv8h+P\/34\/D\/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=",
+ "length": 512
+ }
+ }
+}
+
+module.exports = json;
diff --git a/test/unit/up-storage.spec.js b/test/unit/up-storage.spec.js
index ed946fbab..035079d36 100644
--- a/test/unit/up-storage.spec.js
+++ b/test/unit/up-storage.spec.js
@@ -1,10 +1,11 @@
// @flow
+import _ from 'lodash';
import ProxyStorage from '../../src/lib/up-storage';
import AppConfig from '../../src/lib/config';
-import _ from 'lodash';
// $FlowFixMe
import configExample from './partials/config';
import {setup} from '../../src/lib/logger';
+
import type {Config, UpLinkConf} from '@verdaccio/types';
import type {IProxy} from '../../types';
diff --git a/test/unit/utils.spec.js b/test/unit/utils.spec.js
index 8d1a54bb6..4dce407d5 100644
--- a/test/unit/utils.spec.js
+++ b/test/unit/utils.spec.js
@@ -1,42 +1,78 @@
-let assert = require('assert');
-let validate = require('../../src/lib/utils').validate_name;
+// @flow
-describe('Validate', () => {
- test('good ones', () => {
- assert( validate('verdaccio') );
- assert( validate('some.weird.package-zzz') );
- assert( validate('old-package@0.1.2.tgz') );
+import assert from 'assert';
+import {validate_name as validate} from '../../src/lib/utils';
+import {generateGravatarUrl, GRAVATAR_DEFAULT} from '../../src/utils/user';
+import {spliceURL} from '../../src/utils/string';
+
+describe('Utilities', () => {
+
+ describe('String utilities', () => {
+ test('should splice two strings and generate a url', () => {
+ const url: string = spliceURL('http://domain.com', '/-/static/logo.png');
+
+ expect(url).toMatch('http://domain.com/-/static/logo.png');
+ });
+
+ test('should splice a empty strings and generate a url', () => {
+ const url: string = spliceURL('', '/-/static/logo.png');
+
+ expect(url).toMatch('/-/static/logo.png');
+ });
});
- test('uppercase', () => {
- assert( validate('EVE') );
- assert( validate('JSONStream') );
+ describe('User utilities', () => {
+ test('should generate gravatar url with email', () => {
+ const gravatarUrl: string = generateGravatarUrl('user@verdaccio.org');
+
+ expect(gravatarUrl).toMatch('https://www.gravatar.com/avatar/');
+ expect(gravatarUrl).not.toMatch('000000000');
+ });
+
+ test('should generate generic gravatar url', () => {
+ const gravatarUrl: string = generateGravatarUrl();
+
+ expect(gravatarUrl).toMatch(GRAVATAR_DEFAULT);
+ });
});
- test('no package.json', () => {
- assert( !validate('package.json') );
- });
+ describe('Validations', () => {
+ test('good ones', () => {
+ assert( validate('verdaccio') );
+ assert( validate('some.weird.package-zzz') );
+ assert( validate('old-package@0.1.2.tgz') );
+ });
- test('no path seps', () => {
- assert( !validate('some/thing') );
- assert( !validate('some\\thing') );
- });
+ test('uppercase', () => {
+ assert( validate('EVE') );
+ assert( validate('JSONStream') );
+ });
- test('no hidden', () => {
- assert( !validate('.bin') );
- });
+ test('no package.json', () => {
+ assert( !validate('package.json') );
+ });
- test('no reserved', () => {
- assert( !validate('favicon.ico') );
- assert( !validate('node_modules') );
- assert( !validate('__proto__') );
- });
+ test('no path seps', () => {
+ assert( !validate('some/thing') );
+ assert( !validate('some\\thing') );
+ });
- test('other', () => {
- assert( !validate('pk g') );
- assert( !validate('pk\tg') );
- assert( !validate('pk%20g') );
- assert( !validate('pk+g') );
- assert( !validate('pk:g') );
+ test('no hidden', () => {
+ assert( !validate('.bin') );
+ });
+
+ test('no reserved', () => {
+ assert( !validate('favicon.ico') );
+ assert( !validate('node_modules') );
+ assert( !validate('__proto__') );
+ });
+
+ test('other', () => {
+ assert( !validate('pk g') );
+ assert( !validate('pk\tg') );
+ assert( !validate('pk%20g') );
+ assert( !validate('pk+g') );
+ assert( !validate('pk:g') );
+ });
});
});