mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
additional tests for config pkg (#2237)
* add test config * add test for home creation * more checks * add test * skip peer platform * lint * fix windows
This commit is contained in:
parent
52b47868e3
commit
a54c18c02a
6 changed files with 292 additions and 101 deletions
|
@ -1,6 +1,5 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import Path from 'path';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import buildDebug from 'debug';
|
import buildDebug from 'debug';
|
||||||
|
|
||||||
|
@ -27,28 +26,34 @@ const debug = buildDebug('verdaccio:config');
|
||||||
* Find and get the first config file that match.
|
* Find and get the first config file that match.
|
||||||
* @return {String} the config file path
|
* @return {String} the config file path
|
||||||
*/
|
*/
|
||||||
function findConfigFile(configPath: string | undefined): string {
|
function findConfigFile(configPath?: string): string {
|
||||||
|
// console.log(process.env);
|
||||||
if (typeof configPath !== 'undefined') {
|
if (typeof configPath !== 'undefined') {
|
||||||
return Path.resolve(configPath);
|
return path.resolve(configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const configPaths: SetupDirectory[] = getConfigPaths();
|
const configPaths: SetupDirectory[] = getConfigPaths();
|
||||||
|
debug('%o posible locations found', configPaths.length);
|
||||||
if (_.isEmpty(configPaths)) {
|
if (_.isEmpty(configPaths)) {
|
||||||
|
// this should never happens
|
||||||
throw new Error('no configuration files can be processed');
|
throw new Error('no configuration files can be processed');
|
||||||
}
|
}
|
||||||
|
|
||||||
const primaryConf: any = _.find(configPaths, (configLocation: any) =>
|
// find the first location that already exist
|
||||||
|
const primaryConf: SetupDirectory | void = _.find(configPaths, (configLocation: SetupDirectory) =>
|
||||||
fileExists(configLocation.path)
|
fileExists(configLocation.path)
|
||||||
);
|
);
|
||||||
if (_.isNil(primaryConf) === false) {
|
|
||||||
|
if (typeof primaryConf !== 'undefined') {
|
||||||
|
debug('previous location exist already %s', primaryConf?.path);
|
||||||
return primaryConf.path;
|
return primaryConf.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
return createConfigFile(_.head(configPaths)).path;
|
return createConfigFile(_.head(configPaths)).path;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createConfigFile(configLocation: any): SetupDirectory {
|
function createConfigFile(configLocation: SetupDirectory): SetupDirectory {
|
||||||
createConfigFolder(configLocation);
|
createConfigFolder(configLocation);
|
||||||
|
|
||||||
const defaultConfig = updateStorageLinks(configLocation, readDefaultConfig());
|
const defaultConfig = updateStorageLinks(configLocation, readDefaultConfig());
|
||||||
|
@ -60,13 +65,18 @@ function createConfigFile(configLocation: any): SetupDirectory {
|
||||||
|
|
||||||
export function readDefaultConfig(): Buffer {
|
export function readDefaultConfig(): Buffer {
|
||||||
const pathDefaultConf: string = path.resolve(__dirname, 'conf/default.yaml');
|
const pathDefaultConf: string = path.resolve(__dirname, 'conf/default.yaml');
|
||||||
|
try {
|
||||||
|
debug('default configuration file %s', pathDefaultConf);
|
||||||
|
fs.accessSync(pathDefaultConf, fs.constants.R_OK);
|
||||||
|
} catch {
|
||||||
|
throw new TypeError('configuration file does not have enough permissions for reading');
|
||||||
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return fs.readFileSync(pathDefaultConf, CHARACTER_ENCODING.UTF8);
|
return fs.readFileSync(pathDefaultConf, CHARACTER_ENCODING.UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createConfigFolder(configLocation): void {
|
function createConfigFolder(configLocation): void {
|
||||||
fs.mkdirSync(Path.dirname(configLocation.path), { recursive: true });
|
fs.mkdirSync(path.dirname(configLocation.path), { recursive: true });
|
||||||
debug(`Creating default config file in %o`, configLocation?.path);
|
debug(`Creating default config file in %o`, configLocation?.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,64 +88,89 @@ function updateStorageLinks(configLocation, defaultConfig): string {
|
||||||
// $XDG_DATA_HOME defines the base directory relative to which user specific data
|
// $XDG_DATA_HOME defines the base directory relative to which user specific data
|
||||||
// files should be stored, If $XDG_DATA_HOME is either not set or empty, a default
|
// files should be stored, If $XDG_DATA_HOME is either not set or empty, a default
|
||||||
// equal to $HOME/.local/share should be used.
|
// equal to $HOME/.local/share should be used.
|
||||||
// $FlowFixMe
|
|
||||||
let dataDir =
|
let dataDir =
|
||||||
process.env.XDG_DATA_HOME || Path.join(process.env.HOME as string, '.local', 'share');
|
process.env.XDG_DATA_HOME || path.join(process.env.HOME as string, '.local', 'share');
|
||||||
if (folderExists(dataDir)) {
|
if (folderExists(dataDir)) {
|
||||||
dataDir = Path.resolve(Path.join(dataDir, pkgJSON.name, 'storage'));
|
debug(`previous storage located`);
|
||||||
|
debug(`update storage links to %s`, dataDir);
|
||||||
|
dataDir = path.resolve(path.join(dataDir, pkgJSON.name, 'storage'));
|
||||||
return defaultConfig.replace(/^storage: .\/storage$/m, `storage: ${dataDir}`);
|
return defaultConfig.replace(/^storage: .\/storage$/m, `storage: ${dataDir}`);
|
||||||
}
|
}
|
||||||
|
debug(`could not find a previous storage location, skip override`);
|
||||||
return defaultConfig;
|
return defaultConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of configuration locations by platform.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function getConfigPaths(): SetupDirectory[] {
|
function getConfigPaths(): SetupDirectory[] {
|
||||||
const listPaths: SetupDirectory[] = [
|
const listPaths: (SetupDirectory | void)[] = [
|
||||||
getXDGDirectory(),
|
getXDGDirectory(),
|
||||||
getWindowsDirectory(),
|
getWindowsDirectory(),
|
||||||
getRelativeDefaultDirectory(),
|
getRelativeDefaultDirectory(),
|
||||||
getOldDirectory(),
|
getOldDirectory(),
|
||||||
].reduce(function (acc, currentValue: any): SetupDirectory[] {
|
];
|
||||||
if (_.isUndefined(currentValue) === false) {
|
|
||||||
|
return listPaths.reduce(function (acc, currentValue: SetupDirectory | void): SetupDirectory[] {
|
||||||
|
if (typeof currentValue !== 'undefined') {
|
||||||
|
debug('directory detected path %s for type %s', currentValue?.path, currentValue.type);
|
||||||
acc.push(currentValue);
|
acc.push(currentValue);
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, [] as SetupDirectory[]);
|
}, [] as SetupDirectory[]);
|
||||||
|
|
||||||
return listPaths;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get XDG_CONFIG_HOME or HOME location (usually unix)
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const getXDGDirectory = (): SetupDirectory | void => {
|
const getXDGDirectory = (): SetupDirectory | void => {
|
||||||
const XDGConfig = getXDGHome() || (process.env.HOME && Path.join(process.env.HOME, '.config'));
|
const xDGConfigPath =
|
||||||
|
process.env.XDG_CONFIG_HOME || (process.env.HOME && path.join(process.env.HOME, '.config'));
|
||||||
if (XDGConfig && folderExists(XDGConfig)) {
|
if (xDGConfigPath && folderExists(xDGConfigPath)) {
|
||||||
|
debug('XDGConfig folder path %s', xDGConfigPath);
|
||||||
return {
|
return {
|
||||||
path: Path.join(XDGConfig, pkgJSON.name, CONFIG_FILE),
|
path: path.join(xDGConfigPath, pkgJSON.name, CONFIG_FILE),
|
||||||
type: XDG,
|
type: XDG,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getXDGHome = (): string | void => process.env.XDG_CONFIG_HOME;
|
/**
|
||||||
|
* Detect windows location, APPDATA
|
||||||
|
* usually something like C:\User\<Build User>\AppData\Local
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const getWindowsDirectory = (): SetupDirectory | void => {
|
const getWindowsDirectory = (): SetupDirectory | void => {
|
||||||
if (process.platform === WIN32 && process.env.APPDATA && folderExists(process.env.APPDATA)) {
|
if (process.platform === WIN32 && process.env.APPDATA && folderExists(process.env.APPDATA)) {
|
||||||
|
debug('is windows appdata: %s', process.env.APPDATA);
|
||||||
return {
|
return {
|
||||||
path: Path.resolve(Path.join(process.env.APPDATA, pkgJSON.name, CONFIG_FILE)),
|
path: path.resolve(path.join(process.env.APPDATA, pkgJSON.name, CONFIG_FILE)),
|
||||||
type: WIN,
|
type: WIN,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return relative directory, this is the default.
|
||||||
|
* It will cretate config in your {currentLocation/verdaccio/config.yaml}
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const getRelativeDefaultDirectory = (): SetupDirectory => {
|
const getRelativeDefaultDirectory = (): SetupDirectory => {
|
||||||
return {
|
return {
|
||||||
path: Path.resolve(Path.join('.', pkgJSON.name, CONFIG_FILE)),
|
path: path.resolve(path.join('.', pkgJSON.name, CONFIG_FILE)),
|
||||||
type: 'def',
|
type: 'def',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should never happens, consider it DEPRECATED
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const getOldDirectory = (): SetupDirectory => {
|
const getOldDirectory = (): SetupDirectory => {
|
||||||
return {
|
return {
|
||||||
path: Path.resolve(Path.join('.', CONFIG_FILE)),
|
path: path.resolve(path.join('.', CONFIG_FILE)),
|
||||||
type: 'old',
|
type: 'old',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -106,7 +106,7 @@ class Config implements AppConfig {
|
||||||
/**
|
/**
|
||||||
* Store or create whether receive a secret key
|
* Store or create whether receive a secret key
|
||||||
*/
|
*/
|
||||||
public checkSecretKey(secret: string): string {
|
public checkSecretKey(secret?: string): string {
|
||||||
debug('check secret key');
|
debug('check secret key');
|
||||||
if (_.isString(secret) && _.isEmpty(secret) === false) {
|
if (_.isString(secret) && _.isEmpty(secret) === false) {
|
||||||
this.secret = secret;
|
this.secret = secret;
|
||||||
|
|
105
packages/config/test/config.path.spec.ts
Normal file
105
packages/config/test/config.path.spec.ts
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
import os from 'os';
|
||||||
|
import { findConfigFile } from '../src/config-path';
|
||||||
|
|
||||||
|
const mockmkDir = jest.fn();
|
||||||
|
const mockaccessSync = jest.fn();
|
||||||
|
const mockwriteFile = jest.fn();
|
||||||
|
|
||||||
|
jest.mock('fs', () => {
|
||||||
|
const fsOri = jest.requireActual('fs');
|
||||||
|
return {
|
||||||
|
...fsOri,
|
||||||
|
statSync: (path) => ({
|
||||||
|
isDirectory: () => {
|
||||||
|
if (path.match(/fail/)) {
|
||||||
|
throw Error('file does not exist');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
accessSync: (a) => mockaccessSync(a),
|
||||||
|
mkdirSync: (a) => mockmkDir(a),
|
||||||
|
writeFileSync: (a) => mockwriteFile(a),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.mock('fs');
|
||||||
|
|
||||||
|
describe('config-path', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findConfigFile', () => {
|
||||||
|
if (os.platform() !== 'win32') {
|
||||||
|
describe('using defiled location from arguments', () => {
|
||||||
|
test('with custom location', () => {
|
||||||
|
expect(findConfigFile('/home/user/custom/location/config.yaml')).toEqual(
|
||||||
|
'/home/user/custom/location/config.yaml'
|
||||||
|
);
|
||||||
|
expect(mockwriteFile).not.toHaveBeenCalled();
|
||||||
|
expect(mockmkDir).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('whith env variables', () => {
|
||||||
|
test('with XDG_CONFIG_HOME if directory exist but config file is missing', () => {
|
||||||
|
process.env.XDG_CONFIG_HOME = '/home/user';
|
||||||
|
expect(findConfigFile()).toEqual('/home/user/verdaccio/config.yaml');
|
||||||
|
expect(mockwriteFile).toHaveBeenCalledWith('/home/user/verdaccio/config.yaml');
|
||||||
|
expect(mockmkDir).toHaveBeenCalledWith('/home/user/verdaccio');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('with HOME if directory exist but config file is missing', () => {
|
||||||
|
delete process.env.XDG_CONFIG_HOME;
|
||||||
|
process.env.HOME = '/home/user';
|
||||||
|
expect(findConfigFile()).toEqual('/home/user/.config/verdaccio/config.yaml');
|
||||||
|
expect(mockwriteFile).toHaveBeenCalledWith('/home/user/.config/verdaccio/config.yaml');
|
||||||
|
expect(mockmkDir).toHaveBeenCalledWith('/home/user/.config/verdaccio');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('error handling', () => {
|
||||||
|
test('XDG_CONFIG_HOME is not directory fallback to default', () => {
|
||||||
|
process.env.XDG_CONFIG_HOME = '/home/user/fail';
|
||||||
|
mockaccessSync.mockImplementation(() => {});
|
||||||
|
mockwriteFile.mockImplementation(() => {});
|
||||||
|
expect(findConfigFile()).toMatch('packages/config/verdaccio/config.yaml');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no permissions on read default config file', () => {
|
||||||
|
process.env.XDG_CONFIG_HOME = '/home/user';
|
||||||
|
mockaccessSync.mockImplementation(() => {
|
||||||
|
throw new Error('error on write file');
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(function () {
|
||||||
|
findConfigFile();
|
||||||
|
}).toThrow(/configuration file does not have enough permissions for reading/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with no env variables', () => {
|
||||||
|
test('with relative location', () => {
|
||||||
|
mockaccessSync.mockImplementation(() => {});
|
||||||
|
delete process.env.XDG_CONFIG_HOME;
|
||||||
|
delete process.env.HOME;
|
||||||
|
process.env.APPDATA = '/app/data/';
|
||||||
|
expect(findConfigFile()).toMatch('packages/config/verdaccio/config.yaml');
|
||||||
|
expect(mockwriteFile).toHaveBeenCalled();
|
||||||
|
expect(mockmkDir).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
test('with windows as directory exist but config file is missing', () => {
|
||||||
|
delete process.env.XDG_CONFIG_HOME;
|
||||||
|
delete process.env.HOME;
|
||||||
|
process.env.APPDATA = '/app/data/';
|
||||||
|
expect(findConfigFile()).toEqual('D:\\app\\data\\verdaccio\\config.yaml');
|
||||||
|
expect(mockwriteFile).toHaveBeenCalledWith('D:\\app\\data\\verdaccio\\config.yaml');
|
||||||
|
expect(mockmkDir).toHaveBeenCalledWith('D:\\app\\data\\verdaccio');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -9,6 +9,7 @@ import {
|
||||||
parseConfigFile,
|
parseConfigFile,
|
||||||
ROLES,
|
ROLES,
|
||||||
WEB_TITLE,
|
WEB_TITLE,
|
||||||
|
getMatchedPackagesSpec,
|
||||||
} from '../src';
|
} from '../src';
|
||||||
import { parseConfigurationFile } from './utils';
|
import { parseConfigurationFile } from './utils';
|
||||||
|
|
||||||
|
@ -23,56 +24,56 @@ const checkDefaultUplink = (config) => {
|
||||||
expect(config.uplinks[DEFAULT_UPLINK].url).toMatch(DEFAULT_REGISTRY);
|
expect(config.uplinks[DEFAULT_UPLINK].url).toMatch(DEFAULT_REGISTRY);
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkDefaultConfPackages = (config) => {
|
|
||||||
// auth
|
|
||||||
expect(_.isObject(config.auth)).toBeTruthy();
|
|
||||||
expect(_.isObject(config.auth.htpasswd)).toBeTruthy();
|
|
||||||
expect(config.auth.htpasswd.file).toMatch(/htpasswd/);
|
|
||||||
|
|
||||||
// web
|
|
||||||
expect(_.isObject(config.web)).toBeTruthy();
|
|
||||||
expect(config.web.title).toBe(WEB_TITLE);
|
|
||||||
expect(config.web.enable).toBeUndefined();
|
|
||||||
|
|
||||||
// packages
|
|
||||||
expect(_.isObject(config.packages)).toBeTruthy();
|
|
||||||
expect(Object.keys(config.packages).join('|')).toBe('@*/*|**');
|
|
||||||
expect(config.packages['@*/*'].access).toBeDefined();
|
|
||||||
expect(config.packages['@*/*'].access).toContainEqual(ROLES.$ALL);
|
|
||||||
expect(config.packages['@*/*'].publish).toBeDefined();
|
|
||||||
expect(config.packages['@*/*'].publish).toContainEqual(ROLES.$AUTH);
|
|
||||||
expect(config.packages['@*/*'].proxy).toBeDefined();
|
|
||||||
expect(config.packages['@*/*'].proxy).toContainEqual(DEFAULT_UPLINK);
|
|
||||||
expect(config.packages['**'].access).toBeDefined();
|
|
||||||
expect(config.packages['**'].access).toContainEqual(ROLES.$ALL);
|
|
||||||
expect(config.packages['**'].publish).toBeDefined();
|
|
||||||
expect(config.packages['**'].publish).toContainEqual(ROLES.$AUTH);
|
|
||||||
expect(config.packages['**'].proxy).toBeDefined();
|
|
||||||
expect(config.packages['**'].proxy).toContainEqual(DEFAULT_UPLINK);
|
|
||||||
// uplinks
|
|
||||||
expect(config.uplinks[DEFAULT_UPLINK]).toBeDefined();
|
|
||||||
expect(config.uplinks[DEFAULT_UPLINK].url).toEqual(DEFAULT_REGISTRY);
|
|
||||||
// audit
|
|
||||||
expect(config.middlewares).toBeDefined();
|
|
||||||
expect(config.middlewares.audit).toBeDefined();
|
|
||||||
expect(config.middlewares.audit.enabled).toBeTruthy();
|
|
||||||
// logs
|
|
||||||
expect(config.logs).toBeDefined();
|
|
||||||
expect(config.logs.type).toEqual('stdout');
|
|
||||||
expect(config.logs.format).toEqual('pretty');
|
|
||||||
expect(config.logs.level).toEqual('http');
|
|
||||||
// must not be enabled by default
|
|
||||||
expect(config.notify).toBeUndefined();
|
|
||||||
expect(config.store).toBeUndefined();
|
|
||||||
expect(config.publish).toBeUndefined();
|
|
||||||
expect(config.url_prefix).toBeUndefined();
|
|
||||||
expect(config.url_prefix).toBeUndefined();
|
|
||||||
|
|
||||||
expect(config.experiments).toBeUndefined();
|
|
||||||
expect(config.security).toEqual(defaultSecurity);
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('check basic content parsed file', () => {
|
describe('check basic content parsed file', () => {
|
||||||
|
const checkDefaultConfPackages = (config) => {
|
||||||
|
// auth
|
||||||
|
expect(_.isObject(config.auth)).toBeTruthy();
|
||||||
|
expect(_.isObject(config.auth.htpasswd)).toBeTruthy();
|
||||||
|
expect(config.auth.htpasswd.file).toMatch(/htpasswd/);
|
||||||
|
|
||||||
|
// web
|
||||||
|
expect(_.isObject(config.web)).toBeTruthy();
|
||||||
|
expect(config.web.title).toBe(WEB_TITLE);
|
||||||
|
expect(config.web.enable).toBeUndefined();
|
||||||
|
|
||||||
|
// packages
|
||||||
|
expect(_.isObject(config.packages)).toBeTruthy();
|
||||||
|
expect(Object.keys(config.packages).join('|')).toBe('@*/*|**');
|
||||||
|
expect(config.packages['@*/*'].access).toBeDefined();
|
||||||
|
expect(config.packages['@*/*'].access).toContainEqual(ROLES.$ALL);
|
||||||
|
expect(config.packages['@*/*'].publish).toBeDefined();
|
||||||
|
expect(config.packages['@*/*'].publish).toContainEqual(ROLES.$AUTH);
|
||||||
|
expect(config.packages['@*/*'].proxy).toBeDefined();
|
||||||
|
expect(config.packages['@*/*'].proxy).toContainEqual(DEFAULT_UPLINK);
|
||||||
|
expect(config.packages['**'].access).toBeDefined();
|
||||||
|
expect(config.packages['**'].access).toContainEqual(ROLES.$ALL);
|
||||||
|
expect(config.packages['**'].publish).toBeDefined();
|
||||||
|
expect(config.packages['**'].publish).toContainEqual(ROLES.$AUTH);
|
||||||
|
expect(config.packages['**'].proxy).toBeDefined();
|
||||||
|
expect(config.packages['**'].proxy).toContainEqual(DEFAULT_UPLINK);
|
||||||
|
// uplinks
|
||||||
|
expect(config.uplinks[DEFAULT_UPLINK]).toBeDefined();
|
||||||
|
expect(config.uplinks[DEFAULT_UPLINK].url).toEqual(DEFAULT_REGISTRY);
|
||||||
|
// audit
|
||||||
|
expect(config.middlewares).toBeDefined();
|
||||||
|
expect(config.middlewares.audit).toBeDefined();
|
||||||
|
expect(config.middlewares.audit.enabled).toBeTruthy();
|
||||||
|
// logs
|
||||||
|
expect(config.logs).toBeDefined();
|
||||||
|
expect(config.logs.type).toEqual('stdout');
|
||||||
|
expect(config.logs.format).toEqual('pretty');
|
||||||
|
expect(config.logs.level).toEqual('http');
|
||||||
|
// must not be enabled by default
|
||||||
|
expect(config.notify).toBeUndefined();
|
||||||
|
expect(config.store).toBeUndefined();
|
||||||
|
expect(config.publish).toBeUndefined();
|
||||||
|
expect(config.url_prefix).toBeUndefined();
|
||||||
|
expect(config.url_prefix).toBeUndefined();
|
||||||
|
|
||||||
|
expect(config.experiments).toBeUndefined();
|
||||||
|
expect(config.security).toEqual(defaultSecurity);
|
||||||
|
};
|
||||||
|
|
||||||
test('parse default.yaml', () => {
|
test('parse default.yaml', () => {
|
||||||
const config = new Config(parseConfigFile(resolveConf('default')));
|
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||||
checkDefaultUplink(config);
|
checkDefaultUplink(config);
|
||||||
|
@ -81,6 +82,57 @@ describe('check basic content parsed file', () => {
|
||||||
checkDefaultConfPackages(config);
|
checkDefaultConfPackages(config);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('parse docker.yaml', () => {
|
||||||
|
const config = new Config(parseConfigFile(resolveConf('docker')));
|
||||||
|
checkDefaultUplink(config);
|
||||||
|
expect(config.storage).toBe('/verdaccio/storage/data');
|
||||||
|
expect(config.auth.htpasswd.file).toBe('/verdaccio/storage/htpasswd');
|
||||||
|
checkDefaultConfPackages(config);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('checkSecretKey', () => {
|
||||||
|
test('with default.yaml and pre selected secret', () => {
|
||||||
|
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||||
|
expect(config.checkSecretKey('12345')).toEqual('12345');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('with default.yaml and void secret', () => {
|
||||||
|
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||||
|
expect(typeof config.checkSecretKey() === 'string').toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('with default.yaml and emtpy string secret', () => {
|
||||||
|
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||||
|
expect(typeof config.checkSecretKey('') === 'string').toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getMatchedPackagesSpec', () => {
|
||||||
|
test('should match with react as defined in config file', () => {
|
||||||
|
const configParsed = parseConfigFile(parseConfigurationFile('config-getMatchedPackagesSpec'));
|
||||||
|
const config = new Config(configParsed);
|
||||||
|
expect(config.getMatchedPackagesSpec('react')).toEqual({
|
||||||
|
access: ['admin'],
|
||||||
|
proxy: ['facebook'],
|
||||||
|
publish: ['admin'],
|
||||||
|
unpublish: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not match with react as defined in config file', () => {
|
||||||
|
const configParsed = parseConfigFile(parseConfigurationFile('config-getMatchedPackagesSpec'));
|
||||||
|
const config = new Config(configParsed);
|
||||||
|
expect(config.getMatchedPackagesSpec('somePackage')).toEqual({
|
||||||
|
access: [ROLES.$ALL],
|
||||||
|
proxy: ['npmjs'],
|
||||||
|
publish: [ROLES.$AUTH],
|
||||||
|
unpublish: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('VERDACCIO_STORAGE_PATH', () => {
|
||||||
test('should set storage to value set in VERDACCIO_STORAGE_PATH environment variable', () => {
|
test('should set storage to value set in VERDACCIO_STORAGE_PATH environment variable', () => {
|
||||||
const storageLocation = '/tmp/verdaccio';
|
const storageLocation = '/tmp/verdaccio';
|
||||||
process.env.VERDACCIO_STORAGE_PATH = storageLocation;
|
process.env.VERDACCIO_STORAGE_PATH = storageLocation;
|
||||||
|
@ -106,12 +158,4 @@ describe('check basic content parsed file', () => {
|
||||||
expect(config.storage).toBe(storageLocation);
|
expect(config.storage).toBe(storageLocation);
|
||||||
delete process.env.VERDACCIO_STORAGE_PATH;
|
delete process.env.VERDACCIO_STORAGE_PATH;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('parse docker.yaml', () => {
|
|
||||||
const config = new Config(parseConfigFile(resolveConf('docker')));
|
|
||||||
checkDefaultUplink(config);
|
|
||||||
expect(config.storage).toBe('/verdaccio/storage/data');
|
|
||||||
expect(config.auth.htpasswd.file).toBe('/verdaccio/storage/htpasswd');
|
|
||||||
checkDefaultConfPackages(config);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -88,26 +88,17 @@ describe('Package access utilities', () => {
|
||||||
() => {
|
() => {
|
||||||
const { packages } = parseConfigFile(parseConfigurationFile('deprecated-pkgs-basic'));
|
const { packages } = parseConfigFile(parseConfigurationFile('deprecated-pkgs-basic'));
|
||||||
const access = normalisePackageAccess(packages);
|
const access = normalisePackageAccess(packages);
|
||||||
|
|
||||||
expect(access).toBeDefined();
|
expect(access).toBeDefined();
|
||||||
|
|
||||||
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
||||||
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
||||||
const react = access['react-*'];
|
const react = access['react-*'];
|
||||||
|
|
||||||
expect(react).toBeDefined();
|
expect(react).toBeDefined();
|
||||||
expect(react.access).toBeDefined();
|
expect(react.access).toBeDefined();
|
||||||
|
|
||||||
// Intended checks, Typescript should catch this, we test the runtime part
|
|
||||||
// @ts-ignore
|
|
||||||
expect(react.access).toEqual([]);
|
expect(react.access).toEqual([]);
|
||||||
// @ts-ignore
|
|
||||||
expect(react.publish[0]).toBe('admin');
|
expect(react.publish[0]).toBe('admin');
|
||||||
expect(react.proxy).toBeDefined();
|
expect(react.proxy).toBeDefined();
|
||||||
// @ts-ignore
|
|
||||||
expect(react.proxy).toEqual([]);
|
expect(react.proxy).toEqual([]);
|
||||||
expect(react.storage).toBeDefined();
|
expect(react.storage).toBeDefined();
|
||||||
|
|
||||||
expect(react.storage).toBe('react-storage');
|
expect(react.storage).toBe('react-storage');
|
||||||
expect(scoped).toBeDefined();
|
expect(scoped).toBeDefined();
|
||||||
expect(scoped.storage).not.toBeDefined();
|
expect(scoped.storage).not.toBeDefined();
|
||||||
|
@ -126,7 +117,6 @@ describe('Package access utilities', () => {
|
||||||
|
|
||||||
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
||||||
expect(scoped).toBeUndefined();
|
expect(scoped).toBeUndefined();
|
||||||
|
|
||||||
// ** should be added by default **
|
// ** should be added by default **
|
||||||
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
||||||
expect(all).toBeDefined();
|
expect(all).toBeDefined();
|
||||||
|
@ -141,23 +131,23 @@ describe('Package access utilities', () => {
|
||||||
describe('getMatchedPackagesSpec', () => {
|
describe('getMatchedPackagesSpec', () => {
|
||||||
test('should test basic config', () => {
|
test('should test basic config', () => {
|
||||||
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-custom'));
|
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-custom'));
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
expect(getMatchedPackagesSpec('vue', packages).proxy).toMatch('npmjs');
|
expect(getMatchedPackagesSpec('vue', packages).proxy).toMatch('npmjs');
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
expect(getMatchedPackagesSpec('@scope/vue', packages).proxy).toMatch('npmjs');
|
expect(getMatchedPackagesSpec('@scope/vue', packages).proxy).toMatch('npmjs');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should test no ** wildcard on config', () => {
|
test('should test no ** wildcard on config', () => {
|
||||||
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-nosuper-wildcard-custom'));
|
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-nosuper-wildcard-custom'));
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
expect(getMatchedPackagesSpec('@fake/angular', packages).proxy).toMatch('npmjs');
|
expect(getMatchedPackagesSpec('@fake/angular', packages).proxy).toMatch('npmjs');
|
||||||
expect(getMatchedPackagesSpec('vue', packages)).toBeUndefined();
|
expect(getMatchedPackagesSpec('vue', packages)).toBeUndefined();
|
||||||
expect(getMatchedPackagesSpec('@scope/vue', packages)).toBeUndefined();
|
expect(getMatchedPackagesSpec('@scope/vue', packages)).toBeUndefined();
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
packages:
|
||||||
|
'react':
|
||||||
|
access: admin
|
||||||
|
publish: admin
|
||||||
|
proxy: facebook
|
||||||
|
'angular':
|
||||||
|
access: admin
|
||||||
|
publish: admin
|
||||||
|
proxy: google
|
||||||
|
'@*/*':
|
||||||
|
access: $all
|
||||||
|
publish: $authenticated
|
||||||
|
proxy: npmjs
|
||||||
|
'**':
|
||||||
|
access: $all
|
||||||
|
publish: $authenticated
|
||||||
|
proxy: npmjs
|
Loading…
Reference in a new issue