parent
fe09beaf6a
commit
7855dd97a5
@ -0,0 +1,21 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { dirname, resolve } from 'path';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'jsdom',
|
||||||
|
setupFiles: ['./test/component/setup.js'],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': resolve(__dirname, '../src'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,100 @@
|
|||||||
|
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||||
|
import { mount } from "@vue/test-utils";
|
||||||
|
import MonitorList from "../../src/components/MonitorList.vue";
|
||||||
|
import MonitorListItem from "../../src/components/MonitorListItem.vue";
|
||||||
|
|
||||||
|
// Mock child components
|
||||||
|
vi.mock("../../src/components/MonitorListItem.vue", {
|
||||||
|
default: {
|
||||||
|
name: "MonitorListItem",
|
||||||
|
template: "<div class=\"monitor-list-item\"></div>"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("MonitorList.vue", () => {
|
||||||
|
let wrapper;
|
||||||
|
const mockMonitors = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Test Monitor 1",
|
||||||
|
type: "http",
|
||||||
|
status: "up",
|
||||||
|
url: "https://example.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Test Monitor 2",
|
||||||
|
type: "ping",
|
||||||
|
status: "down",
|
||||||
|
hostname: "example.org"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = mount(MonitorList, {
|
||||||
|
props: {
|
||||||
|
monitors: mockMonitors,
|
||||||
|
activeMonitor: null,
|
||||||
|
showTags: true,
|
||||||
|
showStatus: true,
|
||||||
|
showPing: true,
|
||||||
|
showAverage: true
|
||||||
|
},
|
||||||
|
global: {
|
||||||
|
stubs: {
|
||||||
|
MonitorListItem: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders monitor list items", () => {
|
||||||
|
const items = wrapper.findAllComponents(MonitorListItem);
|
||||||
|
expect(items).toHaveLength(mockMonitors.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("emits select-monitor event when monitor is clicked", async () => {
|
||||||
|
const items = wrapper.findAll(".monitor-list-item");
|
||||||
|
await items[0].trigger("click");
|
||||||
|
|
||||||
|
expect(wrapper.emitted("select-monitor")).toBeTruthy();
|
||||||
|
expect(wrapper.emitted("select-monitor")[0]).toEqual([mockMonitors[0]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("applies active class to selected monitor", async () => {
|
||||||
|
await wrapper.setProps({
|
||||||
|
activeMonitor: mockMonitors[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
const items = wrapper.findAll(".monitor-list-item");
|
||||||
|
expect(items[0].classes()).toContain("active");
|
||||||
|
expect(items[1].classes()).not.toContain("active");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("filters monitors based on search text", async () => {
|
||||||
|
const searchInput = wrapper.find("input[type=\"search\"]");
|
||||||
|
await searchInput.setValue("Test Monitor 1");
|
||||||
|
|
||||||
|
const items = wrapper.findAllComponents(MonitorListItem);
|
||||||
|
expect(items).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sorts monitors by status", async () => {
|
||||||
|
const sortButton = wrapper.find(".sort-status");
|
||||||
|
await sortButton.trigger("click");
|
||||||
|
|
||||||
|
const items = wrapper.findAllComponents(MonitorListItem);
|
||||||
|
const firstMonitorProps = items[0].props();
|
||||||
|
expect(firstMonitorProps.monitor.status).toBe("down");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("toggles visibility of columns", async () => {
|
||||||
|
await wrapper.setProps({
|
||||||
|
showPing: false,
|
||||||
|
showAverage: false
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.find(".ping-column").exists()).toBe(false);
|
||||||
|
expect(wrapper.find(".average-column").exists()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,114 @@
|
|||||||
|
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||||
|
import { mount } from "@vue/test-utils";
|
||||||
|
import PingChart from "../../src/components/PingChart.vue";
|
||||||
|
import { Line } from "vue-chartjs";
|
||||||
|
|
||||||
|
// Mock Chart.js components
|
||||||
|
vi.mock("vue-chartjs", () => ({
|
||||||
|
Line: {
|
||||||
|
name: "Line",
|
||||||
|
template: "<canvas></canvas>"
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("PingChart.vue", () => {
|
||||||
|
let wrapper;
|
||||||
|
const mockData = {
|
||||||
|
labels: ["12:00", "12:01", "12:02"],
|
||||||
|
datasets: [{
|
||||||
|
label: "Ping",
|
||||||
|
data: [100, 150, 120],
|
||||||
|
borderColor: "#42b983",
|
||||||
|
tension: 0.3
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockOptions = {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: "Response Time (ms)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = mount(PingChart, {
|
||||||
|
props: {
|
||||||
|
chartData: mockData,
|
||||||
|
options: mockOptions
|
||||||
|
},
|
||||||
|
global: {
|
||||||
|
stubs: {
|
||||||
|
Line: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders the chart component", () => {
|
||||||
|
expect(wrapper.findComponent(Line).exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes correct data to chart component", () => {
|
||||||
|
const chart = wrapper.findComponent(Line);
|
||||||
|
expect(chart.props("data")).toEqual(mockData);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes correct options to chart component", () => {
|
||||||
|
const chart = wrapper.findComponent(Line);
|
||||||
|
expect(chart.props("options")).toEqual(mockOptions);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("updates chart when data changes", async () => {
|
||||||
|
const newData = {
|
||||||
|
labels: ["12:03", "12:04"],
|
||||||
|
datasets: [{
|
||||||
|
label: "Ping",
|
||||||
|
data: [130, 140],
|
||||||
|
borderColor: "#42b983",
|
||||||
|
tension: 0.3
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
await wrapper.setProps({ chartData: newData });
|
||||||
|
const chart = wrapper.findComponent(Line);
|
||||||
|
expect(chart.props("data")).toEqual(newData);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles empty data gracefully", async () => {
|
||||||
|
const emptyData = {
|
||||||
|
labels: [],
|
||||||
|
datasets: [{
|
||||||
|
label: "Ping",
|
||||||
|
data: [],
|
||||||
|
borderColor: "#42b983",
|
||||||
|
tension: 0.3
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
await wrapper.setProps({ chartData: emptyData });
|
||||||
|
const chart = wrapper.findComponent(Line);
|
||||||
|
expect(chart.props("data")).toEqual(emptyData);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("applies custom styling options", async () => {
|
||||||
|
const customOptions = {
|
||||||
|
...mockOptions,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await wrapper.setProps({ options: customOptions });
|
||||||
|
const chart = wrapper.findComponent(Line);
|
||||||
|
expect(chart.props("options")).toEqual(customOptions);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,52 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { mount } from "@vue/test-utils";
|
||||||
|
import Status from "../../src/components/Status.vue";
|
||||||
|
import { UP, DOWN, PENDING, MAINTENANCE } from "../../src/util";
|
||||||
|
|
||||||
|
describe("Status.vue", () => {
|
||||||
|
const mountStatus = (status) => {
|
||||||
|
return mount(Status, {
|
||||||
|
props: {
|
||||||
|
status
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
it("renders UP status correctly", () => {
|
||||||
|
const wrapper = mountStatus(UP);
|
||||||
|
expect(wrapper.find(".badge").classes()).toContain("bg-success");
|
||||||
|
expect(wrapper.text()).toContain("UP");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders DOWN status correctly", () => {
|
||||||
|
const wrapper = mountStatus(DOWN);
|
||||||
|
expect(wrapper.find(".badge").classes()).toContain("bg-danger");
|
||||||
|
expect(wrapper.text()).toContain("DOWN");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders PENDING status correctly", () => {
|
||||||
|
const wrapper = mountStatus(PENDING);
|
||||||
|
expect(wrapper.find(".badge").classes()).toContain("bg-warning");
|
||||||
|
expect(wrapper.text()).toContain("PENDING");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders MAINTENANCE status correctly", () => {
|
||||||
|
const wrapper = mountStatus(MAINTENANCE);
|
||||||
|
expect(wrapper.find(".badge").classes()).toContain("bg-info");
|
||||||
|
expect(wrapper.text()).toContain("MAINTENANCE");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles unknown status gracefully", () => {
|
||||||
|
const wrapper = mountStatus("UNKNOWN");
|
||||||
|
expect(wrapper.find(".badge").classes()).toContain("bg-secondary");
|
||||||
|
expect(wrapper.text()).toContain("UNKNOWN");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("updates when status prop changes", async () => {
|
||||||
|
const wrapper = mountStatus(UP);
|
||||||
|
expect(wrapper.find(".badge").classes()).toContain("bg-success");
|
||||||
|
|
||||||
|
await wrapper.setProps({ status: DOWN });
|
||||||
|
expect(wrapper.find(".badge").classes()).toContain("bg-danger");
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,22 @@
|
|||||||
|
import { config } from "@vue/test-utils";
|
||||||
|
import { vi } from "vitest";
|
||||||
|
|
||||||
|
// Setup global mocks
|
||||||
|
vi.mock("vue-i18n", () => ({
|
||||||
|
useI18n: () => ({
|
||||||
|
t: (key) => key,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Global components mock
|
||||||
|
config.global.stubs = {
|
||||||
|
"font-awesome-icon": true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global mounting options
|
||||||
|
config.global.mocks = {
|
||||||
|
$t: (key) => key,
|
||||||
|
$filters: {
|
||||||
|
formatDateTime: vi.fn((date) => date.toString()),
|
||||||
|
},
|
||||||
|
};
|
Loading…
Reference in new issue