Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  setup-surface.test.ts

  Sprache: JAVA
 

import { describe, expect, it, vi } from "vitest";
import {
  createPluginSetupWizardConfigure,
  createTestWizardPrompter,
  runSetupWizardConfigure,
} from "../../../test/helpers/plugins/setup-wizard.js";
import type { OpenClawConfig } from "../runtime-api.js";
import "./zalo-js.test-mocks.js";
import { zalouserSetupWizard } from "./setup-surface.js";
import { zalouserSetupPlugin } from "./setup-test-helpers.js";

const zalouserConfigure = createPluginSetupWizardConfigure(zalouserSetupPlugin);

async function runSetup(params: {
  cfg?: OpenClawConfig;
  prompter: ReturnType<typeof createTestWizardPrompter>;
  options?: Record<string, unknown>;
  forceAllowFrom?: boolean;
}) {
  return await runSetupWizardConfigure({
    configure: zalouserConfigure,
    cfg: params.cfg,
    prompter: params.prompter,
    options: params.options,
    forceAllowFrom: params.forceAllowFrom,
  });
}

describe("zalouser setup wizard", () => {
  function expectEnabledDefaultSetup(
    result: Awaited<ReturnType<typeof runSetup>>,
    dmPolicy?: "pairing" | "allowlist",
  ) {
    expect(result.accountId).toBe("default");
    expect(result.cfg.channels?.zalouser?.enabled).toBe(true);
    expect(result.cfg.plugins?.entries?.zalouser?.enabled).toBe(true);
    if (dmPolicy) {
      expect(result.cfg.channels?.zalouser?.dmPolicy).toBe(dmPolicy);
    }
  }

  function createQuickstartPrompter(params?: {
    note?: ReturnType<typeof createTestWizardPrompter>["note"];
    seen?: string[];
    dmPolicy?: "pairing" | "allowlist";
    groupAccess?: boolean;
    groupPolicy?: "allowlist";
    textByMessage?: Record<string, string>;
  }) {
    const select = vi.fn(
      async ({ message, options }: { message: string; options: Array<{ value: string }> }) => {
        const first = options[0];
        if (!first) {
          throw new Error("no options");
        }
        params?.seen?.push(message);
        if (message === "Zalo Personal DM policy" && params?.dmPolicy) {
          return params.dmPolicy;
        }
        if (message === "Zalo groups access" && params?.groupPolicy) {
          return params.groupPolicy;
        }
        return first.value;
      },
    ) as ReturnType<typeof createTestWizardPrompter>["select"];
    const text = vi.fn(
      async ({ message }: { message: string }) => params?.textByMessage?.[message] ?? "",
    ) as ReturnType<typeof createTestWizardPrompter>["text"];
    return createTestWizardPrompter({
      ...(params?.note ? { note: params.note } : {}),
      confirm: vi.fn(async ({ message }: { message: string }) => {
        params?.seen?.push(message);
        if (message === "Login via QR code now?") {
          return false;
        }
        if (message === "Configure Zalo groups access?") {
          return params?.groupAccess ?? false;
        }
        return false;
      }),
      select,
      text,
    });
  }

  it("enables the account without forcing QR login", async () => {
    const prompter = createTestWizardPrompter({
      confirm: vi.fn(async ({ message }: { message: string }) => {
        if (message === "Login via QR code now?") {
          return false;
        }
        if (message === "Configure Zalo groups access?") {
          return false;
        }
        return false;
      }),
    });

    const result = await runSetup({ prompter });

    expect(result.accountId).toBe("default");
    expect(result.cfg.channels?.zalouser?.enabled).toBe(true);
    expect(result.cfg.plugins?.entries?.zalouser?.enabled).toBe(true);
  });

  it("prompts DM policy before group access in quickstart", async () => {
    const seen: string[] = [];
    const prompter = createQuickstartPrompter({ seen, dmPolicy: "pairing" });

    const result = await runSetup({
      prompter,
      options: { quickstartDefaults: true },
    });

    expectEnabledDefaultSetup(result, "pairing");
    expect(seen.indexOf("Zalo Personal DM policy")).toBeGreaterThanOrEqual(0);
    expect(seen.indexOf("Configure Zalo groups access?")).toBeGreaterThanOrEqual(0);
    expect(seen.indexOf("Zalo Personal DM policy")).toBeLessThan(
      seen.indexOf("Configure Zalo groups access?"),
    );
  });

  it("allows an empty quickstart DM allowlist with a warning", async () => {
    const note = vi.fn(async (_message: string, _title?: string) => {});
    const prompter = createQuickstartPrompter({
      note,
      dmPolicy: "allowlist",
      textByMessage: {
        "Zalouser allowFrom (name or user id)""",
      },
    });

    const result = await runSetup({
      prompter,
      options: { quickstartDefaults: true },
    });

    expectEnabledDefaultSetup(result, "allowlist");
    expect(result.cfg.channels?.zalouser?.allowFrom).toEqual([]);
    expect(
      note.mock.calls.some(([message]) => message.includes("No DM allowlist entries added yet.")),
    ).toBe(true);
  });

  it("allows an empty group allowlist with a warning", async () => {
    const note = vi.fn(async (_message: string, _title?: string) => {});
    const prompter = createQuickstartPrompter({
      note,
      groupAccess: true,
      groupPolicy: "allowlist",
      textByMessage: {
        "Zalo groups allowlist (comma-separated)""",
      },
    });

    const result = await runSetup({ prompter });

    expect(result.cfg.channels?.zalouser?.groupPolicy).toBe("allowlist");
    expect(result.cfg.channels?.zalouser?.groups).toEqual({});
    expect(
      note.mock.calls.some(([message]) =>
        message.includes("No group allowlist entries added yet."),
      ),
    ).toBe(true);
  });

  it("writes canonical enabled entries for configured groups", async () => {
    const prompter = createQuickstartPrompter({
      groupAccess: true,
      groupPolicy: "allowlist",
      textByMessage: {
        "Zalo groups allowlist (comma-separated)""Family, Work",
      },
    });

    const result = await runSetup({ prompter });

    expect(result.cfg.channels?.zalouser?.groups).toEqual({
      Family: { enabled: true, requireMention: true },
      Work: { enabled: true, requireMention: true },
    });
  });

  it("preserves non-quickstart forceAllowFrom behavior", async () => {
    const note = vi.fn(async (_message: string, _title?: string) => {});
    const seen: string[] = [];
    const prompter = createTestWizardPrompter({
      note,
      confirm: vi.fn(async ({ message }: { message: string }) => {
        seen.push(message);
        if (message === "Login via QR code now?") {
          return false;
        }
        if (message === "Configure Zalo groups access?") {
          return false;
        }
        return false;
      }),
      text: vi.fn(async ({ message }: { message: string }) => {
        seen.push(message);
        if (message === "Zalouser allowFrom (name or user id)") {
          return "";
        }
        return "";
      }) as ReturnType<typeof createTestWizardPrompter>["text"],
    });

    const result = await runSetup({ prompter, forceAllowFrom: true });

    expect(result.cfg.channels?.zalouser?.dmPolicy).toBe("allowlist");
    expect(result.cfg.channels?.zalouser?.allowFrom).toEqual([]);
    expect(seen).not.toContain("Zalo Personal DM policy");
    expect(seen).toContain("Zalouser allowFrom (name or user id)");
    expect(
      note.mock.calls.some(([message]) => message.includes("No DM allowlist entries added yet.")),
    ).toBe(true);
  });

  it("allowlists the plugin when a plugin allowlist already exists", async () => {
    const prompter = createTestWizardPrompter({
      confirm: vi.fn(async ({ message }: { message: string }) => {
        if (message === "Login via QR code now?") {
          return false;
        }
        if (message === "Configure Zalo groups access?") {
          return false;
        }
        return false;
      }),
    });

    const result = await runSetup({
      cfg: {
        plugins: {
          allow: ["telegram"],
        },
      } as OpenClawConfig,
      prompter,
    });

    expect(result.cfg.plugins?.entries?.zalouser?.enabled).toBe(true);
    expect(result.cfg.plugins?.allow).toEqual(["telegram""zalouser"]);
  });

  it("reads the named-account DM policy instead of the channel root", () => {
    expect(
      zalouserSetupWizard.dmPolicy?.getCurrent(
        {
          channels: {
            zalouser: {
              dmPolicy: "disabled",
              accounts: {
                work: {
                  profile: "work",
                  dmPolicy: "allowlist",
                },
              },
            },
          },
        } as OpenClawConfig,
        "work",
      ),
    ).toBe("allowlist");
  });

  it("reports account-scoped config keys for named accounts", () => {
    expect(zalouserSetupWizard.dmPolicy?.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual(
      {
        policyKey: "channels.zalouser.accounts.work.dmPolicy",
        allowFromKey: "channels.zalouser.accounts.work.allowFrom",
      },
    );
  });

  it("uses configured defaultAccount for omitted DM policy account context", () => {
    const cfg = {
      channels: {
        zalouser: {
          defaultAccount: "work",
          dmPolicy: "disabled",
          allowFrom: ["123456789"],
          accounts: {
            work: {
              dmPolicy: "allowlist",
              profile: "work-profile",
            },
          },
        },
      },
    } as OpenClawConfig;

    expect(zalouserSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist");
    expect(zalouserSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({
      policyKey: "channels.zalouser.accounts.work.dmPolicy",
      allowFromKey: "channels.zalouser.accounts.work.allowFrom",
    });

    const next = zalouserSetupWizard.dmPolicy?.setPolicy(cfg, "open");
    expect(next?.channels?.zalouser?.dmPolicy).toBe("disabled");
    const workAccount = next?.channels?.zalouser?.accounts?.work as
      | { dmPolicy?: string; allowFrom?: Array<string | number> }
      | undefined;
    expect(workAccount?.dmPolicy).toBe("open");
  });

  it('writes open policy state to the named account and preserves inherited allowFrom with "*"', () => {
    const next = zalouserSetupWizard.dmPolicy?.setPolicy(
      {
        channels: {
          zalouser: {
            allowFrom: ["123456789"],
            accounts: {
              work: {
                profile: "work",
              },
            },
          },
        },
      } as OpenClawConfig,
      "open",
      "work",
    );

    expect(next?.channels?.zalouser?.dmPolicy).toBeUndefined();
    const workAccount = next?.channels?.zalouser?.accounts?.work as
      | { dmPolicy?: string; allowFrom?: Array<string | number> }
      | undefined;
    expect(workAccount?.dmPolicy).toBe("open");
    expect(workAccount?.allowFrom).toEqual(["123456789""*"]);
  });

  it("shows the account-scoped current DM policy in quickstart notes", async () => {
    const note = vi.fn(async (_message: string, _title?: string) => {});
    const prompter = createQuickstartPrompter({ note, dmPolicy: "pairing" });

    await runSetupWizardConfigure({
      configure: zalouserConfigure,
      cfg: {
        channels: {
          zalouser: {
            dmPolicy: "disabled",
            accounts: {
              work: {
                profile: "work",
                dmPolicy: "allowlist",
                allowFrom: ["123456789"],
              },
            },
          },
        },
      } as OpenClawConfig,
      prompter,
      options: { quickstartDefaults: true },
      accountOverrides: { zalouser: "work" },
    });

    expect(
      note.mock.calls.some(([message]) =>
        message.includes("Current: dmPolicy=allowlist, allowFrom=123456789"),
      ),
    ).toBe(true);
  });
});

Messung V0.5 in Prozent
C=100 H=96 G=97

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge