Files
openobserve/web/src/lib/core/RefreshButton/ORefreshButton.spec.ts
T
Bhargavandgithub-actions[bot] af4bad4167 feat(overview): org-scoped overview endpoint and Home Overview v2 page (#15931)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-11-04 12:21:32 +00:00

228 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { mount } from "@vue/test-utils";
import { createI18n } from "vue-i18n";
import enLocale from "@/locales/languages/en-US.json";
import ORefreshButton from "./ORefreshButton.vue";
import { raw } from "@/types/i18n";
// The component calls useI18n() in setup, so an i18n instance must be installed
// or vue-i18n throws "Need to install with app.use function". Source the real
// en.json so refreshButton.* labels resolve as they do in the app.
const i18n = createI18n({
locale: "en",
legacy: false,
messages: { en: enLocale },
});
// OTooltip is stubbed so the forwarded shortcut id can be asserted without mounting reka-ui.
const stubs = {
OButton: { template: '<button v-bind="$attrs"><slot /></button>' },
OTooltip: {
props: ["content", "shortcutId"],
template: '<span data-stub-tooltip :data-shortcut="shortcutId">{{ content }}</span>',
},
};
const globalConfig = { stubs, plugins: [i18n] };
describe("ORefreshButton", () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
// --- Default rendering ---
it("renders the refresh button", () => {
const wrapper = mount(ORefreshButton, { global: globalConfig });
expect(wrapper.find('[data-test="refresh-button"]').exists()).toBe(true);
});
it("does not render a timestamp span when lastRunAt is not provided", () => {
const wrapper = mount(ORefreshButton, { global: globalConfig });
expect(wrapper.find("span.tabular-nums").exists()).toBe(false);
});
it("renders a timestamp span when lastRunAt is provided", () => {
const ts = Date.now() - 10_000;
const wrapper = mount(ORefreshButton, {
props: { lastRunAt: ts },
global: globalConfig,
});
expect(wrapper.find("span.tabular-nums").exists()).toBe(true);
});
// --- dot color classes ---
it("uses idle dot color when no lastRunAt", () => {
const wrapper = mount(ORefreshButton, { global: globalConfig });
const dot = wrapper.find(".rounded-full");
expect(dot.classes()).toContain("bg-refresh-dot-idle");
});
it("uses fresh dot color when lastRunAt < 30s ago", () => {
const wrapper = mount(ORefreshButton, {
props: { lastRunAt: Date.now() - 5_000 },
global: globalConfig,
});
const dot = wrapper.find(".rounded-full");
expect(dot.classes()).toContain("bg-refresh-dot-fresh");
});
it("uses stale dot color when lastRunAt is 30s–5min ago", () => {
const wrapper = mount(ORefreshButton, {
props: { lastRunAt: Date.now() - 60_000 },
global: globalConfig,
});
const dot = wrapper.find(".rounded-full");
expect(dot.classes()).toContain("bg-refresh-dot-stale");
});
it("uses critical dot color when lastRunAt > 5min ago", () => {
const wrapper = mount(ORefreshButton, {
props: { lastRunAt: Date.now() - 400_000 },
global: globalConfig,
});
const dot = wrapper.find(".rounded-full");
expect(dot.classes()).toContain("bg-refresh-dot-critical");
});
it("uses idle dot color when loading=true regardless of lastRunAt", () => {
const wrapper = mount(ORefreshButton, {
props: { lastRunAt: Date.now() - 5_000, loading: true },
global: globalConfig,
});
const dot = wrapper.find(".rounded-full");
expect(dot.classes()).toContain("bg-refresh-dot-idle");
});
// --- emits ---
it("emits click when button is clicked", async () => {
const wrapper = mount(ORefreshButton, { global: globalConfig });
await wrapper.find('[data-test="refresh-button"]').trigger("click");
expect(wrapper.emitted("click")).toHaveLength(1);
});
it("does not emit click when loading=true", async () => {
const wrapper = mount(ORefreshButton, {
props: { loading: true },
global: globalConfig,
});
await wrapper.find('[data-test="refresh-button"]').trigger("click");
expect(wrapper.emitted("click")).toBeUndefined();
});
it("does not emit click when disabled=true", async () => {
const wrapper = mount(ORefreshButton, {
props: { disabled: true },
global: globalConfig,
});
await wrapper.find('[data-test="refresh-button"]').trigger("click");
expect(wrapper.emitted("click")).toBeUndefined();
});
// --- accessible name ---
it("names the button Refresh, with the age once it has run", () => {
const never = mount(ORefreshButton, { global: globalConfig });
expect(never.find("button").attributes("aria-label")).toBe("Refresh");
const ran = mount(ORefreshButton, {
props: { layout: "inline", lastRunAt: Date.now() - 57_000 },
global: globalConfig,
});
expect(ran.find("button").attributes("aria-label")).toBe("Refresh, last refreshed 57s ago");
});
it("shows a passed tooltip instead of the last-refreshed time", () => {
const wrapper = mount(ORefreshButton, {
props: { lastRunAt: Date.now() - 3_000, tooltip: raw("Data as of 16:19") },
global: globalConfig,
});
const tips = wrapper.findAll("[data-stub-tooltip]").map((tip) => tip.text());
expect(tips).toContain("Data as of 16:19");
expect(tips.some((tip) => tip.startsWith("Last refreshed"))).toBe(false);
});
// --- layout="inline" ---
describe("size", () => {
const button = (props = {}) =>
mount(ORefreshButton, { props, global: globalConfig }).find('[data-test="refresh-button"]');
it("uses the toolbar icon size by default", () => {
expect(button().attributes("size")).toBe("icon-toolbar");
expect(button().classes()).not.toContain("size-5.5!");
});
it("inset renders the icon size with size-5.5", () => {
const inset = button({ size: "inset" });
expect(inset.attributes("size")).toBe("icon");
expect(inset.classes()).toContain("size-5.5!");
});
});
describe("layout=inline", () => {
const inline = (props: Record<string, unknown> = {}) =>
mount(ORefreshButton, {
props: { layout: "inline", ...props },
global: globalConfig,
});
it("renders no staleness dot", () => {
const wrapper = inline({ lastRunAt: Date.now() - 5_000 });
expect(wrapper.find(".rounded-full").exists()).toBe(false);
});
it("puts the age inside the button with a divider and a reserved width", () => {
const wrapper = inline({ lastRunAt: Date.now() - 10_000 });
const button = wrapper.find("button");
expect(button.find("span.w-px").exists()).toBe(true);
const age = button.find("span.tabular-nums");
expect(age.exists()).toBe(true);
expect(age.classes()).toContain("min-w-12");
expect(age.text()).toBe("10s ago");
});
it("renders neither divider nor age when lastRunAt is null", () => {
const wrapper = inline({ lastRunAt: null });
expect(wrapper.find("button").exists()).toBe(true);
expect(wrapper.find("span.w-px").exists()).toBe(false);
expect(wrapper.find("span.tabular-nums").exists()).toBe(false);
});
it("treats a zero timestamp as never fetched", () => {
const wrapper = inline({ lastRunAt: 0 });
expect(wrapper.find("span.tabular-nums").exists()).toBe(false);
expect(wrapper.find("[data-stub-tooltip]").text()).toBe("Not yet refreshed");
});
it("forwards dataTest onto the button", () => {
const wrapper = inline({ dataTest: "pipeline-list-refresh-btn" });
expect(wrapper.find('[data-test="pipeline-list-refresh-btn"]').exists()).toBe(true);
expect(wrapper.find('[data-test="refresh-button"]').exists()).toBe(false);
});
it("forwards shortcutId and the exact time to the tooltip", () => {
const ts = Date.now() - 3_000;
const wrapper = inline({ lastRunAt: ts, shortcutId: "pipelinesRefresh" });
const tip = wrapper.find("[data-stub-tooltip]");
expect(tip.attributes("data-shortcut")).toBe("pipelinesRefresh");
expect(tip.text()).toBe(`Last refreshed: ${new Date(ts).toLocaleTimeString()}`);
});
it("emits click, and not while loading", async () => {
const live = inline({ dataTest: "x-refresh" });
await live.find('[data-test="x-refresh"]').trigger("click");
expect(live.emitted("click")).toHaveLength(1);
const busy = inline({ dataTest: "x-refresh", loading: true });
await busy.find('[data-test="x-refresh"]').trigger("click");
expect(busy.emitted("click")).toBeUndefined();
});
});
});