feat(editor): F4.5d the firewall in the device sheet
Measured first: SheetRun drives FILIUS' firewall dialog down to its table editor (Swing's own end of an edit). Java's table writes a cell into the rule before it checks it, so that the firewall holds "abc", a mask of 255.0.255.0 or port 0 while the table shows the old value, and reads a port that is no number as all ports. Here nothing the check refuses reaches the rule. - doc: the three switches, the default action, rules (new as Java's, cells by Java's checks: masks of ones then zeros, the directly connected marker as a source only, an empty port for all ports; protocol, action, moved up or down, removed) - editor: the firewall as a page of the router's and home router's sheet, with Java's explanations; the general tab named so (Java: "network interfaces") Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -348,6 +348,66 @@ test("keeps a home router's port forwarding on its own page, and shows its DHCP
|
||||
await expect(sheet(page).getByRole('tab', { name: 'LAN: 192.168.0.10' })).toHaveAttribute('aria-selected', 'true');
|
||||
});
|
||||
|
||||
test("sets up a router's firewall on its own page: the switches, the default, rules edited, moved and removed", async ({ page }) => {
|
||||
await openEditor(page, server.base, 'new');
|
||||
await page.locator('[data-palette="router"]').click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: '2', exact: true }).click();
|
||||
const id = (await drawing(page)).nodes[0]!.id;
|
||||
const firewall = async () => ((await sheetOf(page, id)) as RouterSheet).firewall;
|
||||
await sheet(page).getByRole('button', { name: 'Firewall einrichten' }).click();
|
||||
await expect(sheet(page).getByRole('heading')).toHaveText('Firewall einrichten');
|
||||
await expect(sheet(page).getByRole('tab')).toHaveText(['Allgemein', 'Firewall-Regeln']);
|
||||
await sheet(page).getByLabel('Firewall aktivieren').check();
|
||||
await sheet(page).getByLabel('nur SYN-Pakete verwerfen').uncheck();
|
||||
await expect.poll(firewall).toMatchObject({ isActive: true, filterSynSegmentsOnly: false });
|
||||
|
||||
await sheet(page).getByRole('tab', { name: 'Firewall-Regeln' }).click();
|
||||
await sheet(page).locator('select[name="defaultPolicy"]').selectOption('accept');
|
||||
await sheet(page).getByRole('button', { name: 'Neue Regel' }).click();
|
||||
const rows = sheet(page).locator('table[data-rows="firewall"] tbody tr');
|
||||
await expect(rows.first().locator('td')).toHaveText(['1', '', '', '', '', 'TCP', '', 'verwerfen']);
|
||||
await expect(sheet(page).getByRole('button', { name: 'rauf' })).toBeDisabled();
|
||||
await field(page, 'firewall-sourceIPAddress').fill('abc');
|
||||
await field(page, 'firewall-sourceIPAddress').press('Enter');
|
||||
await expect(sheet(page).getByRole('status')).toHaveText('Nicht übernommen – es gilt weiterhin (leer).');
|
||||
await field(page, 'firewall-sourceIPAddress').fill('10.0.0.0');
|
||||
await field(page, 'firewall-sourceIPAddress').press('Enter');
|
||||
await field(page, 'firewall-sourceSubnetMask').fill('255.0.255.0');
|
||||
await field(page, 'firewall-sourceSubnetMask').press('Enter');
|
||||
await expect(field(page, 'firewall-sourceSubnetMask')).toHaveAttribute('aria-invalid', 'true');
|
||||
await field(page, 'firewall-sourceSubnetMask').fill('255.0.0.0');
|
||||
await field(page, 'firewall-sourceSubnetMask').press('Enter');
|
||||
await field(page, 'firewall-port').fill('80');
|
||||
await field(page, 'firewall-port').press('Enter');
|
||||
await sheet(page).locator('select[name="firewall-protocol"]').selectOption('udp');
|
||||
await sheet(page).locator('select[name="firewall-action"]').selectOption('accept');
|
||||
await expect(rows.first().locator('td')).toHaveText(['1', '10.0.0.0', '255.0.0.0', '', '', 'UDP', '80', 'akzeptieren']);
|
||||
|
||||
await sheet(page).getByRole('button', { name: 'Neue Regel' }).click();
|
||||
await field(page, 'firewall-destinationIPAddress').fill('192.168.0.1');
|
||||
await field(page, 'firewall-destinationIPAddress').press('Enter');
|
||||
await expect(sheet(page).getByRole('button', { name: 'runter' })).toBeDisabled();
|
||||
await sheet(page).getByRole('button', { name: 'rauf' }).click();
|
||||
await expect.poll(async () => (await firewall()).rules.map((rule) => rule.destinationIPAddress)).toEqual(['192.168.0.1', '']);
|
||||
await expect(rows.first()).toHaveAttribute('aria-selected', 'true');
|
||||
await sheet(page).getByRole('button', { name: 'Regel löschen' }).click();
|
||||
await expect.poll(async () => (await firewall()).rules.map((rule) => rule.sourceIPAddress)).toEqual(['10.0.0.0']);
|
||||
// Java keeps a row chosen: the one that took the removed one's place.
|
||||
await expect(rows.first()).toHaveAttribute('aria-selected', 'true');
|
||||
await expect(field(page, 'firewall-sourceIPAddress')).toHaveValue('10.0.0.0');
|
||||
await expect(await firewall()).toMatchObject({ defaultPolicy: 'accept' });
|
||||
await sheet(page).getByRole('button', { name: 'Zurück' }).click();
|
||||
await expect(sheet(page).getByRole('heading')).toHaveText('Vermittlungsrechner');
|
||||
});
|
||||
|
||||
test("opens a home router's firewall from its general tab", async ({ page }) => {
|
||||
await openEditor(page, server.base, 'new');
|
||||
await page.locator('[data-palette="gateway"]').click();
|
||||
await sheet(page).getByRole('button', { name: 'Firewall einrichten' }).click();
|
||||
await expect(sheet(page).getByRole('heading')).toHaveText('Firewall einrichten');
|
||||
await expect(sheet(page).getByLabel('Firewall aktivieren')).not.toBeChecked();
|
||||
});
|
||||
|
||||
test.describe('on a phone', () => {
|
||||
test.use({ viewport: { width: 390, height: 844 }, hasTouch: true });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user