Some checks failed
CI / test-backend (push) Successful in 32s
CI / lint (push) Failing after 2m12s
CI / build-frontend (pull_request) Successful in 1m38s
Build and Publish Docker Image / build (pull_request) Has been skipped
CI / test-backend (pull_request) Successful in 24s
OSV-Scanner PR Scan / scan-pr (pull_request) Successful in 53s
CI / test-lang (pull_request) Successful in 1m15s
CI / lint (pull_request) Failing after 5m8s
CI / build-frontend (push) Successful in 9m46s
CI / test-lang (push) Successful in 9m48s
Tests / test (push) Successful in 13m32s
Tests / test (pull_request) Successful in 11m23s
Build Test / Build and Test (push) Successful in 15m56s
Build and Publish Docker Image / build-dev (pull_request) Successful in 13m42s
Build Test / Build and Test (pull_request) Successful in 16m9s
- Introduced new test files for telemetry functionality, including integration, fuzzing, and extended tests to ensure robustness and performance. - Added tests for parsing LXMF display names and telemetry data, addressing potential bugs and ensuring correct handling of various input formats. - Implemented performance tests for the InterfacesPage component, validating rendering efficiency with a large number of discovered interfaces. - Enhanced existing tests for markdown rendering and link utilities to cover additional edge cases and improve stability.
147 lines
4.7 KiB
JavaScript
147 lines
4.7 KiB
JavaScript
import { mount } from "@vue/test-utils";
|
|
import { describe, it, expect, vi } from "vitest";
|
|
import InterfacesPage from "../../meshchatx/src/frontend/components/interfaces/InterfacesPage.vue";
|
|
|
|
// Mock dependencies
|
|
vi.mock("../../meshchatx/src/frontend/js/GlobalState", () => ({
|
|
default: {
|
|
config: { theme: "light" },
|
|
hasPendingInterfaceChanges: false,
|
|
modifiedInterfaceNames: new Set(),
|
|
},
|
|
}));
|
|
|
|
vi.mock("../../meshchatx/src/frontend/js/Utils", () => ({
|
|
default: {
|
|
formatBytes: (b) => `${b} B`,
|
|
isInterfaceEnabled: () => true,
|
|
},
|
|
}));
|
|
|
|
vi.mock("../../meshchatx/src/frontend/js/ToastUtils", () => ({
|
|
default: {
|
|
success: vi.fn(),
|
|
error: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
vi.mock("../../meshchatx/src/frontend/js/ElectronUtils", () => ({
|
|
default: {
|
|
relaunch: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
// Mock axios
|
|
global.axios = {
|
|
get: vi.fn((url) => {
|
|
if (url.includes("/api/v1/reticulum/interfaces")) {
|
|
return Promise.resolve({ data: { interfaces: {} } });
|
|
}
|
|
if (url.includes("/api/v1/app/info")) {
|
|
return Promise.resolve({ data: { app_info: { is_reticulum_running: true } } });
|
|
}
|
|
if (url.includes("/api/v1/interface-stats")) {
|
|
return Promise.resolve({ data: { interface_stats: { interfaces: [] } } });
|
|
}
|
|
if (url.includes("/api/v1/reticulum/discovery")) {
|
|
return Promise.resolve({ data: { discovery: { discover_interfaces: true } } });
|
|
}
|
|
if (url.includes("/api/v1/reticulum/discovered-interfaces")) {
|
|
return Promise.resolve({ data: { interfaces: [], active: [] } });
|
|
}
|
|
return Promise.resolve({ data: {} });
|
|
}),
|
|
post: vi.fn(() => Promise.resolve({ data: {} })),
|
|
patch: vi.fn(() => Promise.resolve({ data: {} })),
|
|
};
|
|
window.axios = global.axios;
|
|
|
|
// Mock MaterialDesignIcon
|
|
const MaterialDesignIcon = {
|
|
template: '<div class="mdi"></div>',
|
|
props: ["iconName"],
|
|
};
|
|
|
|
describe("InterfacesPage Performance", () => {
|
|
it("renders InterfacesPage with 1000 disconnected discovered interfaces", async () => {
|
|
const numDiscovered = 1000;
|
|
const discoveredInterfaces = Array.from({ length: numDiscovered }, (_, i) => ({
|
|
name: `Discovered ${i}`,
|
|
type: "UDPInterface",
|
|
reachable_on: `192.168.1.${i}`,
|
|
port: 4242,
|
|
discovery_hash: `hash_${i}`,
|
|
}));
|
|
|
|
const start = performance.now();
|
|
const wrapper = mount(InterfacesPage, {
|
|
global: {
|
|
components: {
|
|
MaterialDesignIcon,
|
|
Toggle: { template: "<div></div>" },
|
|
ImportInterfacesModal: {
|
|
template: "<div></div>",
|
|
methods: { show: vi.fn() },
|
|
},
|
|
Interface: { template: "<div></div>" },
|
|
},
|
|
mocks: {
|
|
$t: (key) => key,
|
|
$router: { push: vi.fn() },
|
|
},
|
|
},
|
|
});
|
|
|
|
await wrapper.setData({
|
|
discoveredInterfaces,
|
|
activeTab: "overview", // This is where discovered interfaces are shown in the template I saw
|
|
});
|
|
|
|
const end = performance.now();
|
|
console.log(`Rendered ${numDiscovered} discovered interfaces in ${(end - start).toFixed(2)}ms`);
|
|
|
|
// Check if animations are present
|
|
const pulsingElements = wrapper.findAll(".animate-pulse");
|
|
expect(pulsingElements.length).toBe(numDiscovered);
|
|
|
|
expect(end - start).toBeLessThan(5000);
|
|
});
|
|
|
|
it("stops pulsing animations after 30 seconds", async () => {
|
|
const iface = {
|
|
name: "Discovered 1",
|
|
type: "UDPInterface",
|
|
reachable_on: "192.168.1.1",
|
|
port: 4242,
|
|
discovery_hash: "hash_1",
|
|
disconnected_at: Date.now() - 31000, // 31 seconds ago
|
|
};
|
|
|
|
const wrapper = mount(InterfacesPage, {
|
|
global: {
|
|
components: {
|
|
MaterialDesignIcon,
|
|
Toggle: { template: "<div></div>" },
|
|
ImportInterfacesModal: {
|
|
template: "<div></div>",
|
|
methods: { show: vi.fn() },
|
|
},
|
|
Interface: { template: "<div></div>" },
|
|
},
|
|
mocks: {
|
|
$t: (key) => key,
|
|
$router: { push: vi.fn() },
|
|
},
|
|
},
|
|
});
|
|
|
|
await wrapper.setData({
|
|
discoveredInterfaces: [iface],
|
|
activeTab: "overview",
|
|
});
|
|
|
|
const pulsingElements = wrapper.findAll(".animate-pulse");
|
|
expect(pulsingElements.length).toBe(0);
|
|
});
|
|
});
|