2017-12-19 01:58:43 -05:00
|
|
|
// @flow
|
2018-03-17 12:28:54 -05:00
|
|
|
import _ from 'lodash';
|
2018-06-19 14:21:25 -05:00
|
|
|
import ProxyStorage from '../../../src/lib/up-storage';
|
2018-06-17 06:34:59 -05:00
|
|
|
import AppConfig from '../../../src/lib/config';
|
2017-12-19 01:58:43 -05:00
|
|
|
// $FlowFixMe
|
2018-06-17 06:34:59 -05:00
|
|
|
import configExample from '../partials/config/index';
|
|
|
|
import {setup} from '../../../src/lib/logger';
|
2018-03-17 12:28:54 -05:00
|
|
|
|
2018-02-26 15:28:09 -05:00
|
|
|
import type {Config, UpLinkConf} from '@verdaccio/types';
|
2018-06-17 06:34:59 -05:00
|
|
|
import type {IProxy} from '../../../types/index';
|
2018-06-30 11:10:05 -05:00
|
|
|
import {API_ERROR, HTTP_STATUS} from "../../../src/lib/constants";
|
2018-06-24 15:39:09 -05:00
|
|
|
import {mockServer} from './mock';
|
|
|
|
import {DOMAIN_SERVERS} from '../../functional/config.functional';
|
2018-02-19 13:29:14 -05:00
|
|
|
|
2017-12-19 01:58:43 -05:00
|
|
|
setup([]);
|
|
|
|
|
|
|
|
describe('UpStorge', () => {
|
2018-06-24 15:39:09 -05:00
|
|
|
const mockServerPort: number = 55547;
|
|
|
|
let mockRegistry;
|
2018-02-24 05:41:36 -05:00
|
|
|
const uplinkDefault = {
|
2018-06-24 15:39:09 -05:00
|
|
|
url: `http://0.0.0.0:${mockServerPort}`
|
2017-12-19 01:58:43 -05:00
|
|
|
};
|
2018-02-24 10:35:14 -05:00
|
|
|
const generateProxy = (config: UpLinkConf = uplinkDefault) => {
|
2017-12-19 01:58:43 -05:00
|
|
|
const appConfig: Config = new AppConfig(configExample);
|
|
|
|
|
|
|
|
return new ProxyStorage(config, appConfig);
|
2018-02-24 05:41:36 -05:00
|
|
|
};
|
2017-12-19 01:58:43 -05:00
|
|
|
|
2018-06-24 15:39:09 -05:00
|
|
|
beforeAll(async () => {
|
|
|
|
mockRegistry = await mockServer(mockServerPort).init();
|
|
|
|
});
|
|
|
|
|
|
|
|
afterAll(function(done) {
|
|
|
|
mockRegistry[0].stop();
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
2017-12-19 01:58:43 -05:00
|
|
|
test('should be defined', () => {
|
|
|
|
const proxy = generateProxy();
|
2018-02-03 16:21:23 -05:00
|
|
|
|
2017-12-19 01:58:43 -05:00
|
|
|
expect(proxy).toBeDefined();
|
|
|
|
});
|
|
|
|
|
2017-12-19 03:56:40 -05:00
|
|
|
describe('UpStorge::getRemoteMetadata', () => {
|
|
|
|
test('should be get remote metadata', (done) => {
|
|
|
|
const proxy = generateProxy();
|
2018-02-03 16:21:23 -05:00
|
|
|
|
2017-12-19 03:56:40 -05:00
|
|
|
proxy.getRemoteMetadata('jquery', {}, (err, data, etag) => {
|
|
|
|
expect(err).toBeNull();
|
|
|
|
expect(_.isString(etag)).toBeTruthy();
|
|
|
|
expect(data.name).toBe('jquery');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should be get remote metadata with etag', (done) => {
|
|
|
|
const proxy = generateProxy();
|
2018-02-03 16:21:23 -05:00
|
|
|
|
2017-12-19 03:56:40 -05:00
|
|
|
proxy.getRemoteMetadata('jquery', {etag: '123456'}, (err, data, etag) => {
|
|
|
|
expect(err).toBeNull();
|
|
|
|
expect(_.isString(etag)).toBeTruthy();
|
|
|
|
expect(data.name).toBe('jquery');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should be get remote metadata package does not exist', (done) => {
|
|
|
|
const proxy = generateProxy();
|
2018-02-03 16:21:23 -05:00
|
|
|
|
|
|
|
proxy.getRemoteMetadata('@verdaccio/fake-package', {etag: '123456'}, (err) => {
|
2017-12-19 03:56:40 -05:00
|
|
|
expect(err).not.toBeNull();
|
|
|
|
expect(err.statusCode).toBe(404);
|
2018-06-24 03:11:52 -05:00
|
|
|
expect(err.message).toMatch(API_ERROR.NOT_PACKAGE_UPLINK);
|
2017-12-19 03:56:40 -05:00
|
|
|
done();
|
|
|
|
});
|
2017-12-19 01:58:43 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-12-19 03:56:40 -05:00
|
|
|
|
|
|
|
describe('UpStorge::fetchTarball', () => {
|
|
|
|
test('should fetch a tarball from uplink', (done) => {
|
|
|
|
const proxy = generateProxy();
|
2018-06-24 15:39:09 -05:00
|
|
|
const tarball:string = `http://${DOMAIN_SERVERS}:${mockServerPort}/jquery/-/jquery-1.5.1.tgz`;
|
2017-12-19 03:56:40 -05:00
|
|
|
const stream = proxy.fetchTarball(tarball);
|
|
|
|
|
|
|
|
stream.on('error', function(err) {
|
|
|
|
expect(err).toBeNull();
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
stream.on('content-length', function(contentLength) {
|
|
|
|
expect(contentLength).toBeDefined();
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
2018-02-03 16:21:23 -05:00
|
|
|
|
|
|
|
test('should throw a 404 on fetch a tarball from uplink', (done) => {
|
|
|
|
const proxy = generateProxy();
|
2018-06-24 15:39:09 -05:00
|
|
|
const tarball:string = `http://${DOMAIN_SERVERS}:${mockServerPort}/jquery/-/no-exist-1.5.1.tgz`;
|
2018-02-03 16:21:23 -05:00
|
|
|
const stream = proxy.fetchTarball(tarball);
|
|
|
|
|
|
|
|
stream.on('error', function(err) {
|
|
|
|
expect(err).not.toBeNull();
|
2018-06-30 11:10:05 -05:00
|
|
|
expect(err.statusCode).toBe(HTTP_STATUS.NOT_FOUND);
|
|
|
|
expect(err.message).toMatch(API_ERROR.NOT_FILE_UPLINK);
|
2018-02-03 16:21:23 -05:00
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
stream.on('content-length', function(contentLength) {
|
|
|
|
expect(contentLength).toBeDefined();
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should be offline uplink', (done) => {
|
|
|
|
const proxy = generateProxy();
|
|
|
|
const tarball:string = 'http://404.verdaccioo.com';
|
|
|
|
const stream = proxy.fetchTarball(tarball);
|
|
|
|
expect(proxy.failed_requests).toBe(0);
|
|
|
|
|
|
|
|
//to test a uplink is offline we have to be try 3 times
|
|
|
|
//the default failed request are set to 2
|
|
|
|
process.nextTick(function() {
|
|
|
|
stream.on('error', function(err) {
|
|
|
|
expect(err).not.toBeNull();
|
|
|
|
// expect(err.statusCode).toBe(404);
|
|
|
|
expect(proxy.failed_requests).toBe(1);
|
|
|
|
|
|
|
|
const streamSecondTry = proxy.fetchTarball(tarball);
|
|
|
|
streamSecondTry.on('error', function(err) {
|
|
|
|
expect(err).not.toBeNull();
|
|
|
|
/*
|
|
|
|
code: 'ENOTFOUND',
|
|
|
|
errno: 'ENOTFOUND',
|
|
|
|
*/
|
|
|
|
// expect(err.statusCode).toBe(404);
|
|
|
|
expect(proxy.failed_requests).toBe(2);
|
|
|
|
const streamThirdTry = proxy.fetchTarball(tarball);
|
|
|
|
streamThirdTry.on('error', function(err) {
|
|
|
|
expect(err).not.toBeNull();
|
2018-06-30 11:10:05 -05:00
|
|
|
expect(err.statusCode).toBe(HTTP_STATUS.INTERNAL_ERROR);
|
2018-02-03 16:21:23 -05:00
|
|
|
expect(proxy.failed_requests).toBe(2);
|
2018-06-30 11:10:05 -05:00
|
|
|
expect(err.message).toMatch(API_ERROR.UPLINK_OFFLINE);
|
2018-02-03 16:21:23 -05:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2017-12-19 03:56:40 -05:00
|
|
|
});
|
|
|
|
|
2018-02-24 05:41:36 -05:00
|
|
|
describe('UpStorge::isUplinkValid', () => {
|
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
describe('valid use cases', () => {
|
|
|
|
const validateUpLink = (
|
|
|
|
url: string,
|
|
|
|
tarBallUrl?: string = `${url}/artifactory/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz`) => {
|
|
|
|
const uplinkConf = { url };
|
|
|
|
const proxy: IProxy = generateProxy(uplinkConf);
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
return proxy.isUplinkValid(tarBallUrl);
|
|
|
|
}
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
test('should validate tarball path against uplink', () => {
|
|
|
|
expect(validateUpLink('https://artifactory.mydomain.com')).toBe(true);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
test('should validate tarball path against uplink case#2', () => {
|
|
|
|
expect(validateUpLink('https://artifactory.mydomain.com:443')).toBe(true);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
test('should validate tarball path against uplink case#3', () => {
|
|
|
|
expect(validateUpLink('http://localhost')).toBe(true);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
test('should validate tarball path against uplink case#4', () => {
|
|
|
|
expect(validateUpLink('http://my.domain.test')).toBe(true);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
test('should validate tarball path against uplink case#5', () => {
|
|
|
|
expect(validateUpLink('http://my.domain.test:3000')).toBe(true);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
// corner case https://github.com/verdaccio/verdaccio/issues/571
|
|
|
|
test('should validate tarball path against uplink case#6', () => {
|
|
|
|
// same protocol, same domain, port === 443 which is also the standard for https
|
|
|
|
expect(validateUpLink('https://my.domain.test',
|
|
|
|
`https://my.domain.test:443/artifactory/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz`)).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should validate tarball path against uplink case#7', () => {
|
|
|
|
expect(validateUpLink('https://artifactory.mydomain.com:5569')).toBe(true);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
test('should validate tarball path against uplink case#8', () => {
|
|
|
|
expect(validateUpLink('https://localhost:5539')).toBe(true);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
});
|
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
describe('invalid use cases', () => {
|
|
|
|
test('should fails on validate tarball path against uplink', () => {
|
|
|
|
const url: string = 'https://artifactory.mydomain.com';
|
|
|
|
const tarBallUrl: string = 'https://localhost/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
|
|
|
const uplinkConf = { url };
|
|
|
|
const proxy: IProxy = generateProxy(uplinkConf);
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
test('should fails on validate tarball path against uplink case#2', () => {
|
|
|
|
// different domain same, same port, same protocol
|
|
|
|
const url = 'https://domain';
|
|
|
|
const tarBallUrl = 'https://localhost/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
|
|
|
const uplinkConf = { url };
|
|
|
|
const proxy: IProxy = generateProxy(uplinkConf);
|
2018-02-24 05:41:36 -05:00
|
|
|
|
2018-02-24 10:35:14 -05:00
|
|
|
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should fails on validate tarball path against uplink case#3', () => {
|
|
|
|
// same domain, diferent protocol, diferent port
|
|
|
|
const url = 'http://localhost:5001';
|
|
|
|
const tarBallUrl = 'https://localhost:4000/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
|
|
|
const uplinkConf = { url };
|
|
|
|
const proxy: IProxy = generateProxy(uplinkConf);
|
|
|
|
|
|
|
|
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should fails on validate tarball path against uplink case#4', () => {
|
|
|
|
// same domain, same protocol, different port
|
|
|
|
const url = 'https://subdomain.domain:5001';
|
|
|
|
const tarBallUrl = 'https://subdomain.domain:4000/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
|
|
|
const uplinkConf = { url };
|
|
|
|
const proxy: IProxy = generateProxy(uplinkConf);
|
|
|
|
|
|
|
|
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should fails on validate tarball path against uplink case#5', () => {
|
|
|
|
// different protocol, different domain, different port
|
|
|
|
const url = 'https://subdomain.my:5001';
|
|
|
|
const tarBallUrl = 'http://subdomain.domain:4000/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
|
|
|
const uplinkConf = { url };
|
|
|
|
const proxy: IProxy = generateProxy(uplinkConf);
|
|
|
|
|
|
|
|
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
|
|
|
});
|
2018-02-24 05:41:36 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-12-19 01:58:43 -05:00
|
|
|
});
|