mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-11-13 03:35:52 +01:00
313 lines
12 KiB
TypeScript
313 lines
12 KiB
TypeScript
import path from 'path';
|
|
import _ from 'lodash';
|
|
import {spliceURL} from '../../../../src/utils/string';
|
|
import {parseConfigFile} from '../../../../src/lib/utils';
|
|
import {
|
|
getMatchedPackagesSpec,
|
|
hasProxyTo,
|
|
normalisePackageAccess, sanityCheckUplinksProps,
|
|
uplinkSanityCheck
|
|
} from '../../../../src/lib/config-utils';
|
|
import {PACKAGE_ACCESS, ROLES} from '../../../../src/lib/constants';
|
|
|
|
describe('Config Utilities', () => {
|
|
|
|
const parseConfigurationFile = (conf) => {
|
|
const { name, ext } = path.parse(conf);
|
|
const format = ext.startsWith('.') ? ext.substring(1) : 'yaml';
|
|
|
|
return path.join(__dirname, `../../partials/config/${format}/${name}.${format}`);
|
|
};
|
|
|
|
describe('uplinkSanityCheck', () => {
|
|
test('should test basic conversion', ()=> {
|
|
const uplinks = uplinkSanityCheck(parseConfigFile(parseConfigurationFile('uplink-basic')).uplinks);
|
|
expect(Object.keys(uplinks)).toContain('server1');
|
|
expect(Object.keys(uplinks)).toContain('server2');
|
|
});
|
|
|
|
test('should throw error on blacklisted uplink name', ()=> {
|
|
const {uplinks} = parseConfigFile(parseConfigurationFile('uplink-wrong'));
|
|
|
|
expect(() => {
|
|
uplinkSanityCheck(uplinks)
|
|
}).toThrow('CONFIG: reserved uplink name: anonymous');
|
|
});
|
|
});
|
|
|
|
describe('sanityCheckUplinksProps', () => {
|
|
test('should fails if url prop is missing', ()=> {
|
|
const {uplinks} = parseConfigFile(parseConfigurationFile('uplink-wrong'));
|
|
expect(() => {
|
|
sanityCheckUplinksProps(uplinks)
|
|
}).toThrow('CONFIG: no url for uplink: none-url');
|
|
});
|
|
|
|
test('should bypass an empty uplink list', ()=> {
|
|
// @ts-ignore
|
|
expect(sanityCheckUplinksProps([])).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('normalisePackageAccess', () => {
|
|
test('should test basic conversion', ()=> {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('pkgs-basic'));
|
|
const access = normalisePackageAccess(packages);
|
|
|
|
expect(access).toBeDefined();
|
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
|
|
|
expect(scoped).toBeDefined();
|
|
expect(all).toBeDefined();
|
|
});
|
|
|
|
test('should define an empty publish array even if is not defined in packages', ()=> {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('pkgs-basic-no-publish'));
|
|
const access = normalisePackageAccess(packages);
|
|
|
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
|
// publish must defined
|
|
expect(scoped.publish).toBeDefined();
|
|
expect(scoped.publish).toHaveLength(0);
|
|
expect(all.publish).toBeDefined();
|
|
expect(all.publish).toHaveLength(0);
|
|
});
|
|
|
|
test('should define an empty access array even if is not defined in packages', ()=> {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('pkgs-basic-no-access'));
|
|
const access = normalisePackageAccess(packages);
|
|
|
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
|
// publish must defined
|
|
expect(scoped.access).toBeDefined();
|
|
expect(scoped.access).toHaveLength(0);
|
|
expect(all.access).toBeDefined();
|
|
expect(all.access).toHaveLength(0);
|
|
});
|
|
|
|
test('should define an empty proxy array even if is not defined in package', ()=> {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('pkgs-basic-no-proxy'));
|
|
const access = normalisePackageAccess(packages);
|
|
|
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
|
// publish must defined
|
|
expect(scoped.proxy).toBeDefined();
|
|
expect(scoped.proxy).toHaveLength(0);
|
|
expect(all.proxy).toBeDefined();
|
|
expect(all.proxy).toHaveLength(0);
|
|
});
|
|
|
|
test('should test multi user group definition', ()=> {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('pkgs-multi-group'));
|
|
const access = normalisePackageAccess(packages);
|
|
|
|
expect(access).toBeDefined();
|
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
|
|
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
|
|
|
expect(scoped).toBeDefined();
|
|
expect(scoped.access).toContain('$all');
|
|
expect(scoped.publish).toHaveLength(2);
|
|
expect(scoped.publish).toContain('admin');
|
|
expect(scoped.publish).toContain('superadmin');
|
|
|
|
expect(all).toBeDefined();
|
|
expect(all.access).toHaveLength(3);
|
|
expect(all.access).toContain('$all');
|
|
expect(all.publish).toHaveLength(1);
|
|
expect(all.publish).toContain('admin');
|
|
|
|
});
|
|
|
|
|
|
test('should normalize deprecated packages into the new ones (backward props compatible)', ()=> {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('deprecated-pkgs-basic'));
|
|
const access = normalisePackageAccess(packages);
|
|
|
|
expect(access).toBeDefined();
|
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
|
const react = access['react-*'];
|
|
|
|
expect(react).toBeDefined();
|
|
expect(react.access).toBeDefined();
|
|
|
|
// Intended checks, Typescript should catch this, we test the runtime part
|
|
// @ts-ignore
|
|
expect(react.access[0]).toBe(ROLES.$ALL);
|
|
expect(react.publish).toBeDefined();
|
|
// @ts-ignore
|
|
expect(react.publish[0]).toBe('admin');
|
|
expect(react.proxy).toBeDefined();
|
|
// @ts-ignore
|
|
expect(react.proxy[0]).toBe('uplink2');
|
|
expect(react.storage).toBeDefined();
|
|
|
|
expect(react.storage).toBe('react-storage');
|
|
expect(scoped).toBeDefined();
|
|
expect(scoped.storage).not.toBeDefined();
|
|
expect(all).toBeDefined();
|
|
expect(all.access).toBeDefined();
|
|
expect(all.storage).not.toBeDefined();
|
|
expect(all.publish).toBeDefined();
|
|
expect(all.proxy).toBeDefined();
|
|
expect(all.allow_access).toBeUndefined();
|
|
expect(all.allow_publish).toBeUndefined();
|
|
expect(all.proxy_access).toBeUndefined();
|
|
});
|
|
|
|
test('should check not default packages access', ()=> {
|
|
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-empty'));
|
|
const access = normalisePackageAccess(packages);
|
|
expect(access).toBeDefined();
|
|
|
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
|
expect(scoped).toBeUndefined();
|
|
|
|
// ** should be added by default **
|
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
|
expect(all).toBeDefined();
|
|
|
|
expect(all.access).toBeDefined();
|
|
expect(_.isArray(all.access)).toBeTruthy();
|
|
expect(all.publish).toBeDefined();
|
|
expect(_.isArray(all.publish)).toBeTruthy();
|
|
|
|
});
|
|
});
|
|
|
|
describe('getMatchedPackagesSpec', () => {
|
|
test('should test basic config', () => {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('pkgs-custom'));
|
|
// @ts-ignore
|
|
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
|
// @ts-ignore
|
|
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
|
// @ts-ignore
|
|
expect(getMatchedPackagesSpec('vue', packages).proxy).toMatch('npmjs');
|
|
// @ts-ignore
|
|
expect(getMatchedPackagesSpec('@scope/vue', packages).proxy).toMatch('npmjs');
|
|
});
|
|
|
|
test('should test no ** wildcard on config', () => {
|
|
const {packages} = parseConfigFile(parseConfigurationFile('pkgs-nosuper-wildcard-custom'));
|
|
// @ts-ignore
|
|
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
|
// @ts-ignore
|
|
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
|
// @ts-ignore
|
|
expect(getMatchedPackagesSpec('@fake/angular', packages).proxy).toMatch('npmjs');
|
|
expect(getMatchedPackagesSpec('vue', packages)).toBeUndefined();
|
|
expect(getMatchedPackagesSpec('@scope/vue', packages)).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('hasProxyTo', () => {
|
|
test('should test basic config', () => {
|
|
const packages = normalisePackageAccess(parseConfigFile(parseConfigurationFile('pkgs-basic')).packages);
|
|
// react
|
|
expect(hasProxyTo('react', 'facebook', packages)).toBeFalsy();
|
|
expect(hasProxyTo('react', 'google', packages)).toBeFalsy();
|
|
// vue
|
|
expect(hasProxyTo('vue', 'google', packages)).toBeFalsy();
|
|
expect(hasProxyTo('vue', 'fake', packages)).toBeFalsy();
|
|
expect(hasProxyTo('vue', 'npmjs', packages)).toBeTruthy();
|
|
// angular
|
|
expect(hasProxyTo('angular', 'google', packages)).toBeFalsy();
|
|
expect(hasProxyTo('angular', 'facebook', packages)).toBeFalsy();
|
|
expect(hasProxyTo('angular', 'npmjs', packages)).toBeTruthy();
|
|
});
|
|
|
|
test('should test resolve based on custom package access', () => {
|
|
const packages = normalisePackageAccess(parseConfigFile(parseConfigurationFile('pkgs-custom')).packages);
|
|
// react
|
|
expect(hasProxyTo('react', 'facebook', packages)).toBeTruthy();
|
|
expect(hasProxyTo('react', 'google', packages)).toBeFalsy();
|
|
// vue
|
|
expect(hasProxyTo('vue', 'google', packages)).toBeFalsy();
|
|
expect(hasProxyTo('vue', 'fake', packages)).toBeFalsy();
|
|
expect(hasProxyTo('vue', 'npmjs', packages)).toBeTruthy();
|
|
// angular
|
|
expect(hasProxyTo('angular', 'google', packages)).toBeTruthy();
|
|
expect(hasProxyTo('angular', 'facebook', packages)).toBeFalsy();
|
|
expect(hasProxyTo('angular', 'npmjs', packages)).toBeFalsy();
|
|
});
|
|
|
|
test('should not resolve any proxy', () => {
|
|
const packages = normalisePackageAccess(parseConfigFile(parseConfigurationFile('pkgs-empty')).packages);
|
|
// react
|
|
expect(hasProxyTo('react', 'npmjs', packages)).toBeFalsy();
|
|
expect(hasProxyTo('react', 'npmjs', packages)).toBeFalsy();
|
|
// vue
|
|
expect(hasProxyTo('vue', 'npmjs', packages)).toBeFalsy();
|
|
expect(hasProxyTo('vue', 'npmjs', packages)).toBeFalsy();
|
|
expect(hasProxyTo('vue', 'npmjs', packages)).toBeFalsy();
|
|
// angular
|
|
expect(hasProxyTo('angular', 'npmjs', packages)).toBeFalsy();
|
|
expect(hasProxyTo('angular', 'npmjs', packages)).toBeFalsy();
|
|
expect(hasProxyTo('angular', 'npmjs', packages)).toBeFalsy();
|
|
// private
|
|
expect(hasProxyTo('private', 'fake', packages)).toBeFalsy();
|
|
});
|
|
});
|
|
|
|
describe('spliceURL', () => {
|
|
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');
|
|
});
|
|
});
|
|
|
|
describe('JSON', () => {
|
|
test('parse default.json', () => {
|
|
const config = parseConfigFile(parseConfigurationFile('default.json'));
|
|
|
|
expect(config.storage).toBeDefined();
|
|
});
|
|
|
|
test('parse invalid.json', () => {
|
|
expect(function ( ) {
|
|
parseConfigFile(parseConfigurationFile('invalid.json'));
|
|
}).toThrow(/Error/);
|
|
});
|
|
|
|
test('parse not-exists.json', () => {
|
|
expect(function ( ) {
|
|
parseConfigFile(parseConfigurationFile('not-exists.json'));
|
|
}).toThrow(/Error/);
|
|
});
|
|
});
|
|
|
|
describe('JavaScript', () => {
|
|
test('parse default.js', () => {
|
|
const config = parseConfigFile(parseConfigurationFile('default.js'));
|
|
|
|
expect(config.storage).toBeDefined();
|
|
});
|
|
|
|
test('parse invalid.js', () => {
|
|
expect(function ( ) {
|
|
parseConfigFile(parseConfigurationFile('invalid.js'));
|
|
}).toThrow(/Error/);
|
|
});
|
|
|
|
test('parse not-exists.js', () => {
|
|
expect(function ( ) {
|
|
parseConfigFile(parseConfigurationFile('not-exists.js'));
|
|
}).toThrow(/Error/);
|
|
});
|
|
});
|
|
});
|