113 lines
4.1 KiB
JavaScript
113 lines
4.1 KiB
JavaScript
// @vitest-environment jsdom
|
|
|
|
import { mount } from "@vue/test-utils";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import ReleaseContextBar from "@/components/release/ReleaseContextBar.vue";
|
|
import { normalizeReleasePanel, routeSlugForReleaseChannel } from "@/components/release/useReleaseManagerContext.js";
|
|
import { releaseEntityFacts, releaseEntityTooltipText } from "@/components/release/releaseEntityFacts.js";
|
|
|
|
const global = {
|
|
stubs: {
|
|
"b-button": {
|
|
props: ["disabled", "loading"],
|
|
emits: ["click"],
|
|
template: "<button :disabled='disabled' @click='$emit(\"click\", $event)'><slot /></button>",
|
|
},
|
|
"b-tag": {
|
|
template: "<span><slot /></span>",
|
|
},
|
|
"b-tooltip": {
|
|
template: "<span><slot name='content' /><slot /></span>",
|
|
},
|
|
},
|
|
};
|
|
|
|
describe("release manager workspace primitives", () => {
|
|
it("normalizes route panels and stable channel route slugs", () => {
|
|
expect(normalizeReleasePanel("bundles")).toBe("deployments");
|
|
expect(normalizeReleasePanel("replay")).toBe("operations");
|
|
expect(normalizeReleasePanel("failover")).toBe("data-services");
|
|
expect(normalizeReleasePanel("missing")).toBe("overview");
|
|
expect(routeSlugForReleaseChannel({ slug: "stable" })).toBe("master");
|
|
expect(routeSlugForReleaseChannel({ slug: "canary" })).toBe("canary");
|
|
});
|
|
|
|
it("builds concrete data-service tooltip facts", () => {
|
|
const facts = releaseEntityFacts({
|
|
type: "data service",
|
|
entity: {
|
|
kind: "database",
|
|
mode: "production_shared",
|
|
target: {
|
|
instance_label: "node-3",
|
|
deployment_status: "running",
|
|
version: "10.11",
|
|
replication: {
|
|
label: "mariadb-primary",
|
|
host: "db-1.truckwash.internal",
|
|
port: 3306,
|
|
status: "ok",
|
|
role: "primary",
|
|
lag_seconds: 0,
|
|
last_checked_at: "2026-05-21T10:00:00Z",
|
|
uptime_seconds: 86400,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const text = releaseEntityTooltipText(facts);
|
|
|
|
expect(text).toContain("Node: node-3");
|
|
expect(text).toContain("Online state: running");
|
|
expect(text).toContain("Hostname: db-1.truckwash.internal");
|
|
expect(text).toContain("Port: 3306");
|
|
expect(text).toContain("Replication role: primary");
|
|
expect(text).toContain("Last check: 2026-05-21T10:00:00Z");
|
|
});
|
|
|
|
it("emits global context changes and endpoint actions", async () => {
|
|
const wrapper = mount(ReleaseContextBar, {
|
|
props: {
|
|
channels: [
|
|
{ id: 1, slug: "stable", name: "Stable", default_channel: true },
|
|
{ id: 2, slug: "canary", name: "Canary" },
|
|
],
|
|
selectedChannelSlug: "stable",
|
|
selectedApp: "all",
|
|
selectedBranch: "master",
|
|
branchOptions: ["master", "canary"],
|
|
branchStatus: { frontend: { state: "available" }, api: { state: "available" } },
|
|
canDeploy: true,
|
|
},
|
|
global,
|
|
});
|
|
|
|
await wrapper.get('[data-testid="release-context-channel"]').setValue("canary");
|
|
await wrapper.get('[data-testid="release-context-app"]').setValue("api");
|
|
await wrapper.get('[data-testid="release-context-branch"]').setValue("canary");
|
|
await wrapper.get('[data-testid="release-context-test"]').trigger("click");
|
|
|
|
expect(wrapper.emitted("update:channel")?.[0]).toEqual(["canary"]);
|
|
expect(wrapper.emitted("update:app")?.[0]).toEqual(["api"]);
|
|
expect(wrapper.emitted("update:branch")?.[0]).toEqual(["canary"]);
|
|
expect(wrapper.emitted("test")).toHaveLength(1);
|
|
expect(wrapper.text()).toContain("/master/api");
|
|
});
|
|
|
|
it("shows missing branch context as a warning", () => {
|
|
const wrapper = mount(ReleaseContextBar, {
|
|
props: {
|
|
channels: [{ id: 3, slug: "internal", name: "Internal" }],
|
|
selectedChannelSlug: "internal",
|
|
selectedApp: "frontend",
|
|
selectedBranch: "internal",
|
|
branchStatus: { frontend: { state: "missing" } },
|
|
},
|
|
global,
|
|
});
|
|
|
|
expect(wrapper.get('[data-testid="release-context-branch-warning"]').text()).toContain("internal is missing");
|
|
});
|
|
});
|