mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-30 22:34:10 -05:00
* chore: enable tests * Update ci.yml * fix: #3174 set correctly ui values to html render * Update ci.yml * fix hex validator
This commit is contained in:
parent
aa61d256de
commit
a828a5f6c0
9 changed files with 342 additions and 740 deletions
7
.changeset/healthy-pants-smash.md
Normal file
7
.changeset/healthy-pants-smash.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
'@verdaccio/ui-theme': patch
|
||||||
|
'@verdaccio/test-helper': patch
|
||||||
|
'@verdaccio/web': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: #3174 set correctly ui values to html render
|
|
@ -5,6 +5,7 @@ import path from 'path';
|
||||||
|
|
||||||
import { Auth, IAuth } from '@verdaccio/auth';
|
import { Auth, IAuth } from '@verdaccio/auth';
|
||||||
import { Config } from '@verdaccio/config';
|
import { Config } from '@verdaccio/config';
|
||||||
|
import { API_ERROR, errorUtils } from '@verdaccio/core';
|
||||||
import { errorReportingMiddleware, final, handleError } from '@verdaccio/middleware';
|
import { errorReportingMiddleware, final, handleError } from '@verdaccio/middleware';
|
||||||
import { generateRandomHexString } from '@verdaccio/utils';
|
import { generateRandomHexString } from '@verdaccio/utils';
|
||||||
|
|
||||||
|
@ -27,6 +28,12 @@ export async function initializeServer(
|
||||||
routesMiddleware.map((route: any) => {
|
routesMiddleware.map((route: any) => {
|
||||||
app.use(route(config, auth, storage));
|
app.use(route(config, auth, storage));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// catch 404
|
||||||
|
app.get('/*', function (req, res, next) {
|
||||||
|
next(errorUtils.getNotFound(API_ERROR.FILE_NOT_FOUND));
|
||||||
|
});
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
app.use(handleError);
|
app.use(handleError);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -50,13 +50,14 @@
|
||||||
"node-html-parser": "4.1.5",
|
"node-html-parser": "4.1.5",
|
||||||
"supertest": "6.2.2",
|
"supertest": "6.2.2",
|
||||||
"nock": "13.2.2",
|
"nock": "13.2.2",
|
||||||
|
"jsdom": "20.0.0",
|
||||||
"undici": "4.15.0",
|
"undici": "4.15.0",
|
||||||
"verdaccio-auth-memory": "workspace:11.0.0-6-next.8",
|
"verdaccio-auth-memory": "workspace:11.0.0-6-next.8",
|
||||||
"verdaccio-memory": "workspace:11.0.0-6-next.10"
|
"verdaccio-memory": "workspace:11.0.0-6-next.10"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rimraf ./build",
|
"clean": "rimraf ./build",
|
||||||
"test": "cross-env NODE_ENV=test DEBUG=verdaccido* jest -u",
|
"test": "jest",
|
||||||
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
||||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||||
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
||||||
|
|
|
@ -40,7 +40,17 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
||||||
...config.flags,
|
...config.flags,
|
||||||
};
|
};
|
||||||
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
|
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
|
||||||
const { scriptsBodyAfter, metaScripts, scriptsbodyBefore } = Object.assign(
|
const {
|
||||||
|
scriptsBodyAfter,
|
||||||
|
metaScripts,
|
||||||
|
scriptsbodyBefore,
|
||||||
|
showInfo,
|
||||||
|
showSettings,
|
||||||
|
showThemeSwitch,
|
||||||
|
showFooter,
|
||||||
|
showSearch,
|
||||||
|
showDownloadTarball,
|
||||||
|
} = Object.assign(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
scriptsBodyAfter: [],
|
scriptsBodyAfter: [],
|
||||||
|
@ -50,6 +60,12 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
||||||
config?.web
|
config?.web
|
||||||
);
|
);
|
||||||
const options: TemplateUIOptions = {
|
const options: TemplateUIOptions = {
|
||||||
|
showInfo,
|
||||||
|
showSettings,
|
||||||
|
showThemeSwitch,
|
||||||
|
showFooter,
|
||||||
|
showSearch,
|
||||||
|
showDownloadTarball,
|
||||||
darkMode,
|
darkMode,
|
||||||
url_prefix,
|
url_prefix,
|
||||||
basename,
|
basename,
|
||||||
|
@ -69,10 +85,7 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
webPage = cache.get('template');
|
webPage = cache.get('template');
|
||||||
|
|
||||||
if (!webPage) {
|
if (!webPage) {
|
||||||
debug('web options %o', options);
|
|
||||||
debug('web manifestFiles %o', manifestFiles);
|
|
||||||
webPage = renderTemplate(
|
webPage = renderTemplate(
|
||||||
{
|
{
|
||||||
manifest: manifestFiles ?? defaultManifestFiles,
|
manifest: manifestFiles ?? defaultManifestFiles,
|
||||||
|
@ -83,7 +96,6 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
||||||
},
|
},
|
||||||
manifest
|
manifest
|
||||||
);
|
);
|
||||||
debug('template :: %o', webPage);
|
|
||||||
if (needHtmlCache) {
|
if (needHtmlCache) {
|
||||||
cache.set('template', webPage);
|
cache.set('template', webPage);
|
||||||
debug('set template cache');
|
debug('set template cache');
|
||||||
|
@ -96,5 +108,5 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
||||||
}
|
}
|
||||||
res.setHeader('Content-Type', HEADERS.TEXT_HTML);
|
res.setHeader('Content-Type', HEADERS.TEXT_HTML);
|
||||||
res.send(webPage);
|
res.send(webPage);
|
||||||
debug('render web');
|
debug('web rendered');
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ export type AuthorAvatar = Author & { avatar?: string };
|
||||||
const debug = buildDebug('verdaccio:web:utils');
|
const debug = buildDebug('verdaccio:web:utils');
|
||||||
|
|
||||||
export function validatePrimaryColor(primaryColor) {
|
export function validatePrimaryColor(primaryColor) {
|
||||||
const isHex = /^#+([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/i.test(primaryColor);
|
const isHex = /^#([0-9A-F]{3}){1,2}$/i.test(primaryColor);
|
||||||
if (!isHex) {
|
if (!isHex) {
|
||||||
debug('invalid primary color %o', primaryColor);
|
debug('invalid primary color %o', primaryColor);
|
||||||
return;
|
return;
|
||||||
|
|
46
packages/web/test/config/web.yaml
Normal file
46
packages/web/test/config/web.yaml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
auth:
|
||||||
|
auth-memory:
|
||||||
|
users:
|
||||||
|
test:
|
||||||
|
name: test
|
||||||
|
password: test
|
||||||
|
|
||||||
|
web:
|
||||||
|
title: verdaccio web
|
||||||
|
login: true
|
||||||
|
scope: '@scope'
|
||||||
|
pkgManagers:
|
||||||
|
- pnpm
|
||||||
|
- yarn
|
||||||
|
showInfo: true
|
||||||
|
showSettings: true
|
||||||
|
showSearch: true
|
||||||
|
showFooter: true
|
||||||
|
showThemeSwitch: true
|
||||||
|
showDownloadTarball: true
|
||||||
|
showRaw: true
|
||||||
|
primary_color: '#ffffff'
|
||||||
|
logoURI: 'http://logo.org/logo.png'
|
||||||
|
flags:
|
||||||
|
- something: false
|
||||||
|
|
||||||
|
url_prefix: /prefix
|
||||||
|
|
||||||
|
publish:
|
||||||
|
allow_offline: false
|
||||||
|
|
||||||
|
uplinks:
|
||||||
|
|
||||||
|
log: { type: stdout, format: pretty, level: trace }
|
||||||
|
|
||||||
|
packages:
|
||||||
|
'@*/*':
|
||||||
|
access: $anonymous
|
||||||
|
publish: $anonymous
|
||||||
|
'**':
|
||||||
|
access: $anonymous
|
||||||
|
publish: $anonymous
|
||||||
|
_debug: true
|
||||||
|
|
||||||
|
flags:
|
||||||
|
changePassword: true
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { JSDOM } from 'jsdom';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import supertest from 'supertest';
|
import supertest from 'supertest';
|
||||||
|
|
||||||
|
@ -28,34 +29,80 @@ describe('test web server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('render', () => {
|
describe('render', () => {
|
||||||
test('should return the root', async () => {
|
describe('output', () => {
|
||||||
return supertest(await initializeServer('default-test.yaml'))
|
const render = async (config = 'default-test.yaml') => {
|
||||||
.get('/')
|
const response = await supertest(await initializeServer(config))
|
||||||
.set('Accept', HEADERS.TEXT_HTML)
|
.get('/')
|
||||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
.set('Accept', HEADERS.TEXT_HTML)
|
||||||
.expect(HTTP_STATUS.OK);
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
return new JSDOM(response.text, { runScripts: 'dangerously' });
|
||||||
|
};
|
||||||
|
|
||||||
|
test('should match render set ui properties', async () => {
|
||||||
|
const {
|
||||||
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
||||||
|
} = await render('web.yaml');
|
||||||
|
expect(__VERDACCIO_BASENAME_UI_OPTIONS).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
showInfo: true,
|
||||||
|
showSettings: true,
|
||||||
|
showThemeSwitch: true,
|
||||||
|
showFooter: true,
|
||||||
|
showSearch: true,
|
||||||
|
showDownloadTarball: true,
|
||||||
|
darkMode: false,
|
||||||
|
url_prefix: '/prefix',
|
||||||
|
basename: '/prefix/',
|
||||||
|
primaryColor: '#ffffff',
|
||||||
|
// FIXME: mock these values, avoid random
|
||||||
|
// base: 'http://127.0.0.1:60864/prefix/',
|
||||||
|
// version: '6.0.0-6-next.28',
|
||||||
|
logoURI: '',
|
||||||
|
flags: { searchRemote: true },
|
||||||
|
login: true,
|
||||||
|
pkgManagers: ['pnpm', 'yarn'],
|
||||||
|
title: 'verdaccio web',
|
||||||
|
scope: '@scope',
|
||||||
|
language: 'es-US',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.todo('test default title');
|
||||||
|
test.todo('test need html cache');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return the body for a package detail page', async () => {
|
describe('status', () => {
|
||||||
return supertest(await initializeServer('default-test.yaml'))
|
test('should return the http status 200 for root', async () => {
|
||||||
.get('/-/web/section/some-package')
|
return supertest(await initializeServer('default-test.yaml'))
|
||||||
.set('Accept', HEADERS.TEXT_HTML)
|
.get('/')
|
||||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
.set('Accept', HEADERS.TEXT_HTML)
|
||||||
.expect(HTTP_STATUS.OK);
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
||||||
});
|
.expect(HTTP_STATUS.OK);
|
||||||
|
});
|
||||||
|
|
||||||
test.skip('should static file not found', async () => {
|
test('should return the body for a package detail page', async () => {
|
||||||
return supertest(await initializeServer('default-test.yaml'))
|
return supertest(await initializeServer('default-test.yaml'))
|
||||||
.get('/-/static/not-found.js')
|
.get('/-/web/section/some-package')
|
||||||
.set('Accept', HEADERS.TEXT_HTML)
|
.set('Accept', HEADERS.TEXT_HTML)
|
||||||
.expect(HTTP_STATUS.NOT_FOUND);
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
||||||
});
|
.expect(HTTP_STATUS.OK);
|
||||||
|
});
|
||||||
|
|
||||||
test('should static file found', async () => {
|
test('should static file not found', async () => {
|
||||||
return supertest(await initializeServer('default-test.yaml'))
|
return supertest(await initializeServer('default-test.yaml'))
|
||||||
.get('/-/static/main.js')
|
.get('/-/static/not-found.js')
|
||||||
.set('Accept', HEADERS.TEXT_HTML)
|
.set('Accept', HEADERS.TEXT_HTML)
|
||||||
.expect(HTTP_STATUS.OK);
|
.expect(HTTP_STATUS.NOT_FOUND);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should static file found', async () => {
|
||||||
|
return supertest(await initializeServer('default-test.yaml'))
|
||||||
|
.get('/-/static/main.js')
|
||||||
|
.set('Accept', HEADERS.TEXT_HTML)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,22 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import { parseReadme } from '../src/utils/web-utils';
|
import { parseReadme, validatePrimaryColor } from '../src/utils/web-utils';
|
||||||
|
|
||||||
const readmeFile = (fileName = 'markdown.md') => {
|
const readmeFile = (fileName = 'markdown.md') => {
|
||||||
return fs.readFileSync(path.join(__dirname, `./partials/readme/${fileName}`));
|
return fs.readFileSync(path.join(__dirname, `./partials/readme/${fileName}`));
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Utilities', () => {
|
describe('Utilities', () => {
|
||||||
|
describe('validatePrimaryColor', () => {
|
||||||
|
test('is valid', () => {
|
||||||
|
expect(validatePrimaryColor('#222222')).toEqual('#222222');
|
||||||
|
expect(validatePrimaryColor('#222fff')).toEqual('#222fff');
|
||||||
|
});
|
||||||
|
test('is invalid', () => {
|
||||||
|
expect(validatePrimaryColor('fff')).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
describe('parseReadme', () => {
|
describe('parseReadme', () => {
|
||||||
test('should parse makrdown text to html template', () => {
|
test('should parse makrdown text to html template', () => {
|
||||||
const markdown = '# markdown';
|
const markdown = '# markdown';
|
||||||
|
|
887
pnpm-lock.yaml
887
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue