// The project the browser tests open for the web browser and web server // (browser/fixtures/web-pages.fls), made here with the document's commands: // a computer "Browser" (192.168.0.10) with a web browser, a computer // "Server" (192.168.0.20) whose web server runs with the pages below — links, // a mark in the page, a page in a folder, a GET and a POST form, an image // there and one missing, a script and a handler that must not run —, and a // router (192.168.0.1) for its pages, all on one switch. Compared on each run; // written anew with FILIUS_WRITE_FIXTURES=1. import { existsSync, readFileSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; import * as Y from 'yjs'; import { installationFiles, type VirtualFileSystem } from '@mdg-filius/core'; import { addDevice, connect, docArchive, emptyProject, fileEntry, readProject, ROOTS, setHostAddress, setInterfaceAddress, setSoftware, writeProject } from '@mdg-filius/doc'; import { openProjectArchive } from '@mdg-filius/fls'; const fixture = join(dirname(fileURLToPath(import.meta.url)), '../browser/fixtures/web-pages.fls'); /** The server's pages besides those its installation brings (index.html replaced). */ export const WEB_PAGES: Readonly> = { '/webserver/index.html': 'Seiten & Formulare' + '

Start

' + 'BildFehlt' + '

Zwei Unten Drei

' + '
' + '
' + '' + '
' + '

Unten

', '/webserver/zwei.html': 'ZweiStart', '/webserver/ziel.html': 'ZielZiel', '/webserver/ordner/drei.html': 'DreiVier', '/webserver/ordner/vier.html': 'Vier im OrdnerVier', }; function webPagesDoc(): Y.Doc { const doc = new Y.Doc(); writeProject(doc, emptyProject()); let ids = 0; const newId = () => `port-${++ids}`; addDevice(doc, { kind: 'pc', id: 'browser', name: 'Browser', x: 60, y: 60, newId }, 'me'); addDevice(doc, { kind: 'pc', id: 'server', name: 'Server', x: 360, y: 60, newId }, 'me'); addDevice(doc, { kind: 'router', id: 'router', name: 'Router', x: 210, y: 260, newId }, 'me'); addDevice(doc, { kind: 'networkSwitch', id: 'switch', name: 'Switch', x: 210, y: 140, newId }, 'me'); for (const [node, link] of [['browser', 'cable-1'], ['server', 'cable-2'], ['router', 'cable-3']] as const) connect(doc, { node }, { node: 'switch' }, link, 'me'); setHostAddress(doc, 'browser', 'ipAddress', '192.168.0.10', 'me'); setHostAddress(doc, 'server', 'ipAddress', '192.168.0.20', 'me'); // The router's second card, unplugged, away from the computers' network (its own address would be 192.168.0.10, the browser's). const routerPorts = (doc.getMap>(ROOTS.nodes).get('router')!.get('ports') as Y.Array>).map((port) => port.get('id') as string); setInterfaceAddress(doc, 'router', routerPorts[0]!, 'ipAddress', '192.168.0.1', 'me'); setInterfaceAddress(doc, 'router', routerPorts[1]!, 'ipAddress', '10.0.0.1', 'me'); setSoftware(doc, 'browser', { install: ['webBrowser'], remove: [] }, 'de', 'me'); setSoftware(doc, 'server', { install: ['webServer'], remove: [] }, 'de', 'me'); const server = doc.getMap>(ROOTS.nodes).get('server')!; (server.get('programs') as Y.Map>).get('webServer')!.set('active', true); const files = server.get('files') as Y.Map>; let order = files.size; files.set('/webserver/ordner', fileEntry(order++, { kind: 'directory' })); for (const [path, text] of Object.entries(WEB_PAGES)) { if (files.has(path)) (files.get(path)!.get('text') as Y.Text).delete(0, (files.get(path)!.get('text') as Y.Text).length); if (files.has(path)) (files.get(path)!.get('text') as Y.Text).insert(0, text); else files.set(path, fileEntry(order++, { kind: 'text', text })); } return doc; } /** A computer's files, text as it is, the rest by kind. */ function filesOf(files: VirtualFileSystem | undefined): Record { return Object.fromEntries((files?.allEntries() ?? []).map((entry) => [entry.path, entry.content.kind === 'text' ? entry.content.text : entry.content.kind])); } describe("the browser tests' project with web pages", () => { it('is made from the pages above', () => { const made = docArchive(webPagesDoc()).archive; if (process.env.FILIUS_WRITE_FIXTURES === '1' || !existsSync(fixture)) writeFileSync(fixture, made); let ids = 0; const open = (archive: Uint8Array) => openProjectArchive(archive, () => `id-${++ids}`); const [saved, fresh] = [open(new Uint8Array(readFileSync(fixture))), open(made)]; const server = (project: typeof saved) => project.graph.nodes.find((node) => node.displayName === 'Server')!.id; expect(filesOf(saved.virtualFileSystems.get(server(saved)))).toEqual(filesOf(fresh.virtualFileSystems.get(server(fresh)))); expect(filesOf(saved.virtualFileSystems.get(server(saved)))).toMatchObject(WEB_PAGES); expect(saved.activePrograms.get(server(saved))).toEqual(new Set(['webServer'])); expect(saved.graph.nodes.map((node) => node.displayName).sort()).toEqual(['Browser', 'Router', 'Server', 'Switch']); expect(saved.graph.links).toHaveLength(3); // The installation's picture is there for the start page's image. expect(installationFiles('webServer', 'de').map((file) => file.path)).toContain('/webserver/splashscreen-mini.png'); expect(readProject(webPagesDoc()).installedPrograms.get('browser')).toEqual(new Set(['webBrowser'])); }); });