TASKS-1823 WebManager module

This commit is contained in:
Igor Martyniuk
2026-08-28 08:35:58 +00:00
parent fdb2cf3837
commit c93d8c025b
654 changed files with 26232 additions and 6075 deletions
+61
View File
@@ -0,0 +1,61 @@
import { describe, expect, it } from 'vitest';
import { PAGE_BLOCK_REGISTRY } from '#web-runtime/blocks/registry';
import { normalizePage } from '#web-runtime/data/normalize';
import { PAGE_LAYOUT_REGISTRY } from '#web-runtime/layouts/registry';
/**
* The registries are how the renderer decides what to draw. A block type the backend can
* publish but the registry does not know renders as "unsupported", and a page type it does
* not know silently renders with the wrong layout — neither fails a build, so these are the
* checks that catch it.
*/
/** Every block type the backend can store — mirrors `BLOCK_TYPES` in the backend content types. */
const BACKEND_BLOCK_TYPES = ['content', 'faq', 'media-content', 'articles', 'banner', 'media'];
/** Every page type the backend can store — mirrors `PAGE_TYPES`. */
const BACKEND_PAGE_TYPES = ['landing', 'blog', 'blog-item'];
describe('block registry', () => {
it.each(BACKEND_BLOCK_TYPES)('renders the %s block the backend can publish', (type) => {
expect(PAGE_BLOCK_REGISTRY[type]).toBeTypeOf('function');
});
it('registers nothing the normalizer cannot produce', () => {
expect(Object.keys(PAGE_BLOCK_REGISTRY).sort()).toEqual([...BACKEND_BLOCK_TYPES].sort());
});
it('has no renderer for an unknown type, so it falls through to the unsupported block', () => {
expect(PAGE_BLOCK_REGISTRY['carousel']).toBeUndefined();
});
it('covers every block a normalized page can contain', () => {
const page = normalizePage(
{ title: 'x', blocks: BACKEND_BLOCK_TYPES.map((type) => ({ type })) },
{ locale: 'en', path: 'x' }
);
expect(page?.blocks).toHaveLength(BACKEND_BLOCK_TYPES.length);
for (const block of page?.blocks ?? []) {
expect(PAGE_BLOCK_REGISTRY[block.type]).toBeTypeOf('function');
}
});
});
describe('layout registry', () => {
it.each(BACKEND_PAGE_TYPES)('has a layout for the %s page type', (pageType) => {
expect(PAGE_LAYOUT_REGISTRY[pageType]).toBeTypeOf('function');
});
it('leaves an unknown layout to the standard fallback', () => {
expect(PAGE_LAYOUT_REGISTRY['microsite']).toBeUndefined();
expect(PAGE_LAYOUT_REGISTRY['landing']).toBeTypeOf('function');
});
it('resolves the layout a normalized page reports', () => {
const page = normalizePage({ title: 'x', pageType: 'blog-item' }, { locale: 'en', path: 'x' });
expect(page?.layout).toBe('blog-item');
expect(PAGE_LAYOUT_REGISTRY[page?.layout ?? '']).toBeTypeOf('function');
});
});