




















@@ -1,10 +1,13 @@
1-import { describe, expect, it } from "vitest";
1+import { render } from "lit";
2+import { describe, expect, it, vi } from "vitest";
3+import type { WhatsAppStatus } from "../types.ts";
24import {
35channelEnabled,
46resolveChannelConfigured,
57resolveChannelDisplayState,
68} from "./channels.shared.ts";
79import type { ChannelsProps } from "./channels.types.ts";
10+import { renderWhatsAppCard } from "./channels.whatsapp.ts";
811912function createProps(snapshot: ChannelsProps["snapshot"]): ChannelsProps {
1013return {
@@ -41,6 +44,45 @@ function createProps(snapshot: ChannelsProps["snapshot"]): ChannelsProps {
4144};
4245}
434647+function createWhatsAppStatus(overrides: Partial<WhatsAppStatus> = {}): WhatsAppStatus {
48+return {
49+configured: true,
50+linked: false,
51+running: false,
52+connected: false,
53+reconnectAttempts: 0,
54+ ...overrides,
55+};
56+}
57+58+function renderWhatsAppButtons(params: {
59+linked?: boolean;
60+qrDataUrl?: string | null;
61+onWhatsAppStart?: ChannelsProps["onWhatsAppStart"];
62+}) {
63+const whatsapp = createWhatsAppStatus({ linked: params.linked === true });
64+const props = createProps({
65+ts: Date.now(),
66+channelOrder: ["whatsapp"],
67+channelLabels: { whatsapp: "WhatsApp" },
68+channels: { whatsapp },
69+channelAccounts: {},
70+channelDefaultAccountId: {},
71+});
72+props.whatsappQrDataUrl = params.qrDataUrl ?? null;
73+if (params.onWhatsAppStart) {
74+props.onWhatsAppStart = params.onWhatsAppStart;
75+}
76+77+const container = document.createElement("div");
78+render(renderWhatsAppCard({ props, whatsapp, accountCountLabel: null }), container);
79+const buttons = Array.from(container.querySelectorAll("button"));
80+return {
81+ buttons,
82+labels: buttons.map((button) => button.textContent?.trim()),
83+};
84+}
85+4486describe("channel display selectors", () => {
4587it("returns the channel summary configured flag when present", () => {
4688const props = createProps({
@@ -118,3 +160,44 @@ describe("channel display selectors", () => {
118160expect(channelEnabled("quietchat", props)).toBe(false);
119161});
120162});
163+164+describe("WhatsApp card actions", () => {
165+it("shows QR as the primary action before WhatsApp is linked", () => {
166+const onWhatsAppStart = vi.fn();
167+const { buttons, labels } = renderWhatsAppButtons({
168+linked: false,
169+ onWhatsAppStart,
170+});
171+172+expect(labels).toContain("Show QR");
173+expect(labels).not.toContain("Relink");
174+expect(labels).not.toContain("Wait for scan");
175+176+buttons.find((button) => button.textContent?.trim() === "Show QR")?.click();
177+expect(onWhatsAppStart).toHaveBeenCalledWith(false);
178+});
179+180+it("uses relink as the explicit action after WhatsApp is linked", () => {
181+const onWhatsAppStart = vi.fn();
182+const { buttons, labels } = renderWhatsAppButtons({
183+linked: true,
184+ onWhatsAppStart,
185+});
186+187+expect(labels).toContain("Relink");
188+expect(labels).not.toContain("Show QR");
189+190+buttons.find((button) => button.textContent?.trim() === "Relink")?.click();
191+expect(onWhatsAppStart).toHaveBeenCalledWith(true);
192+});
193+194+it("shows wait for scan only while a QR is displayed", () => {
195+const { labels } = renderWhatsAppButtons({
196+linked: false,
197+qrDataUrl: "data:image/png;base64,current-qr",
198+});
199+200+expect(labels).toContain("Show QR");
201+expect(labels).toContain("Wait for scan");
202+});
203+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。