0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-30 22:34:10 -05:00

fix: #3174 set correctly ui values to html render (#3248)

* 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:
Juan Picado 2022-06-24 22:09:46 +02:00 committed by GitHub
parent aa61d256de
commit a828a5f6c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 342 additions and 740 deletions

View 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

View file

@ -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

View file

@ -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",

View file

@ -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');
} }

View file

@ -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;

View 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

View file

@ -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);
});
}); });
}); });
}); });

View file

@ -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';

File diff suppressed because it is too large Load diff