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