Files
pleno-vue/tests/unit/edge-gateway-workspace.spec.js
T
Jeppe Bundgaard 6c4b9cb599 Add and improve e2e tests for Edge Gateway flows and configure pre-commit hooks:
- Introduced live smoke tests for Edge Gateways, verifying gateway routes and destructive-action prevention.
- Added e2e scenarios for deep-link navigation, unavailable gateway recovery, token rotation, and background page refresh.
- Refactored test helpers for streamlined functional validation in gateway scenarios.
- Updated `EdgeGatewayTerminal.vue` with test IDs for enhanced testability.
- Added and configured Husky pre-commit hooks for automated test file formatting and validation.
2026-04-16 10:52:56 +02:00

117 lines
6.7 KiB
JavaScript

import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
const workspaceSource = readFileSync(
join(process.cwd(), "src/components/displays/edgeGateway/EdgeGatewayWorkspace.vue"),
"utf8"
);
const routerSource = readFileSync(join(process.cwd(), "src/router.js"), "utf8");
const navSource = readFileSync(
join(process.cwd(), "src/views/dashboards/superUserDashboard/department/SuperUserDashboardDepartmentNavigation.vue"),
"utf8"
);
const edgeGatewaysViewSource = readFileSync(
join(process.cwd(), "src/views/dashboards/superUserDashboard/EdgeGateways.vue"),
"utf8"
);
const departmentGatewaysViewSource = readFileSync(
join(process.cwd(), "src/views/dashboards/superUserDashboard/department/DepartmentGateways.vue"),
"utf8"
);
describe("edge gateway workspace contract", () => {
it("renders the redesigned workflow sections and delegates root shell UI to the terminal component", () => {
expect(workspaceSource).toContain("Valgt gateway");
expect(workspaceSource).toContain("Overblik");
expect(workspaceSource).toContain("Installation");
expect(workspaceSource).toContain("Shelly-enheder");
expect(workspaceSource).toContain("Bindinger");
expect(workspaceSource).toContain("Opdateringer");
expect(workspaceSource).toContain("Historik");
expect(workspaceSource).toContain('import EdgeGatewayTerminal from "./EdgeGatewayTerminal.vue";');
expect(workspaceSource).toContain("<EdgeGatewayTerminal");
expect(workspaceSource).toContain('@session-approved="handleShellSessionApproved"');
});
it("renders queued discovery/update flows and the API polling control channel", () => {
expect(workspaceSource).toContain("Generér installer");
expect(workspaceSource).toContain('aria-label="Installer afdeling"');
expect(workspaceSource).toContain("Kør discovery");
expect(workspaceSource).toContain("Styringskanal");
expect(workspaceSource).toContain("Latens");
expect(workspaceSource).toContain("CPU");
expect(workspaceSource).toContain("RAM");
expect(workspaceSource).toContain("Disk");
expect(workspaceSource).toContain("getControlChannelMeta");
expect(workspaceSource).toContain("buildGatewayMetricView");
expect(workspaceSource).toContain("system_metrics");
expect(workspaceSource).toContain("startGatewayRefreshLoop");
expect(workspaceSource).toContain("stopGatewayRefreshLoop");
expect(workspaceSource).toContain("BACKGROUND_GATEWAY_REFRESH_INTERVAL_MS = 5_000");
expect(workspaceSource).toContain("startBackgroundGatewayRefreshLoop");
expect(workspaceSource).toContain("refreshWorkspaceDataInBackground");
expect(workspaceSource).toContain("Discovery er køet");
expect(workspaceSource).toContain("Opdatering er køet.");
expect(workspaceSource).toContain("resolveEdgeGatewayErrorMessage");
expect(workspaceSource).toContain("normalizeDisplayText");
expect(workspaceSource).toContain("decodeMojibakeText");
expect(workspaceSource).toContain(
"const displayErrorMessage = computed(() => decodeMojibakeText(normalizeDisplayText(errorMessage.value)));"
);
expect(workspaceSource).toContain("{{ displayErrorMessage }}");
expect(workspaceSource).toContain("Gateway-agenten er offline og kan ikke hente nye kommandoer lige nu.");
expect(workspaceSource).toContain("Gatewayen henter kommandoer og shell-events via API'et.");
expect(workspaceSource).toContain("Gem bindinger");
expect(workspaceSource).toContain("Planlæg opdatering");
expect(workspaceSource).toContain("Verificerer genstart");
expect(workspaceSource).toContain("Rullet tilbage");
expect(workspaceSource).toContain("Transporttilstand");
expect(workspaceSource).toContain("Break-glass adgang");
expect(workspaceSource).toContain("Gateway transport");
expect(workspaceSource).toContain("Afdelingens cutover");
expect(workspaceSource).toContain('data-testid="gateway-detail-header"');
expect(workspaceSource).toContain('data-testid="gateway-fleet-rail"');
expect(workspaceSource).toContain('data-testid="gateway-update-timeline"');
expect(workspaceSource).toContain('data-testid="gateway-rotation-confirmation"');
expect(workspaceSource).toContain('data-testid="gateway-rotation-result"');
expect(workspaceSource).toContain('data-testid="gateway-open-full-page"');
expect(workspaceSource).toContain("align-self: start;");
expect(workspaceSource).toContain(".edge-form-grid--installer");
});
it("builds richer binding device options and keeps stale selections editable", () => {
expect(workspaceSource).toContain("const inventoryDeviceOptions = computed(() =>");
expect(workspaceSource).toContain("const buildInventoryOptionLabel =");
expect(workspaceSource).toContain("const getBindingInventoryDevice = (binding) =>");
expect(workspaceSource).toContain("const getBindingDeviceOptions = (binding) =>");
expect(workspaceSource).toContain("Mangler i discovery");
expect(workspaceSource).toContain("{{ bindingHelperText }}");
expect(workspaceSource).toContain("{{ emptyBindingStateDescription }}");
expect(workspaceSource).toContain('binding.local_ip = device.local_ip ?? "";');
expect(workspaceSource).toContain("binding.channel = channelOptions[0];");
});
it("registers fleet, canonical detail, and department gateway routes in the router and navigation", () => {
expect(routerSource).toContain("path: '/superuser/gateways'");
expect(routerSource).toContain("name: 'edgegatewaydetail'");
expect(routerSource).toContain("path: '/superuser/gateways/:id'");
expect(routerSource).toContain("path: '/superuser/departments/:departmentId/gateways'");
expect(navSource).toContain("'/superuser/departments/' + departmentId.value + '/gateways'");
});
it("keeps route selection in the page layer and lets the department page deep-link into the canonical detail page", () => {
expect(workspaceSource).toContain("selectedGatewayId: {");
expect(workspaceSource).toContain('defineEmits(["open-gateway-page", "select-gateway"])');
expect(workspaceSource).toContain(
"const routeSelectedGatewayId = computed(() => normalizeGatewayId(props.selectedGatewayId));"
);
expect(workspaceSource).toContain('data-testid="gateway-unavailable-state"');
expect(edgeGatewaysViewSource).toContain('route.name === "edgegatewaydetail"');
expect(edgeGatewaysViewSource).toContain(':selected-gateway-id="selectedGatewayId"');
expect(edgeGatewaysViewSource).toContain('@select-gateway="handleGatewaySelection"');
expect(departmentGatewaysViewSource).toContain('@open-gateway-page="openGatewayPage"');
expect(departmentGatewaysViewSource).toContain('name: "edgegatewaydetail"');
});
});