test(line): improve logout scenario coverage

This commit is contained in:
Peter Steinberger
2026-02-22 11:28:09 +00:00
parent 5574eb6b35
commit 0a421d7409

View File

@@ -47,15 +47,50 @@ function createRuntime(): { runtime: PluginRuntime; mocks: LineRuntimeMocks } {
return { runtime, mocks: { writeConfigFile, resolveLineAccount } };
}
function createRuntimeEnv(): RuntimeEnv {
return {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn((code: number): never => {
throw new Error(`exit ${code}`);
}),
};
}
function resolveAccount(
resolveLineAccount: LineRuntimeMocks["resolveLineAccount"],
cfg: OpenClawConfig,
accountId: string,
): ResolvedLineAccount {
const resolver = resolveLineAccount as unknown as (params: {
cfg: OpenClawConfig;
accountId?: string;
}) => ResolvedLineAccount;
return resolver({ cfg, accountId });
}
async function runLogoutScenario(params: { cfg: OpenClawConfig; accountId: string }): Promise<{
result: Awaited<ReturnType<NonNullable<NonNullable<typeof linePlugin.gateway>["logoutAccount"]>>>;
mocks: LineRuntimeMocks;
}> {
const { runtime, mocks } = createRuntime();
setLineRuntime(runtime);
const account = resolveAccount(mocks.resolveLineAccount, params.cfg, params.accountId);
const result = await linePlugin.gateway!.logoutAccount!({
accountId: params.accountId,
cfg: params.cfg,
account,
runtime: createRuntimeEnv(),
});
return { result, mocks };
}
describe("linePlugin gateway.logoutAccount", () => {
beforeEach(() => {
setLineRuntime(createRuntime().runtime);
});
it("clears tokenFile/secretFile on default account logout", async () => {
const { runtime, mocks } = createRuntime();
setLineRuntime(runtime);
const cfg: OpenClawConfig = {
channels: {
line: {
@@ -64,38 +99,17 @@ describe("linePlugin gateway.logoutAccount", () => {
},
},
};
const runtimeEnv: RuntimeEnv = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn((code: number): never => {
throw new Error(`exit ${code}`);
}),
};
const resolveAccount = mocks.resolveLineAccount as unknown as (params: {
cfg: OpenClawConfig;
accountId?: string;
}) => ResolvedLineAccount;
const account = resolveAccount({
const { result, mocks } = await runLogoutScenario({
cfg,
accountId: DEFAULT_ACCOUNT_ID,
});
const result = await linePlugin.gateway!.logoutAccount!({
accountId: DEFAULT_ACCOUNT_ID,
cfg,
account,
runtime: runtimeEnv,
});
expect(result.cleared).toBe(true);
expect(result.loggedOut).toBe(true);
expect(mocks.writeConfigFile).toHaveBeenCalledWith({});
});
it("clears tokenFile/secretFile on account logout", async () => {
const { runtime, mocks } = createRuntime();
setLineRuntime(runtime);
const cfg: OpenClawConfig = {
channels: {
line: {
@@ -108,31 +122,35 @@ describe("linePlugin gateway.logoutAccount", () => {
},
},
};
const runtimeEnv: RuntimeEnv = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn((code: number): never => {
throw new Error(`exit ${code}`);
}),
};
const resolveAccount = mocks.resolveLineAccount as unknown as (params: {
cfg: OpenClawConfig;
accountId?: string;
}) => ResolvedLineAccount;
const account = resolveAccount({
const { result, mocks } = await runLogoutScenario({
cfg,
accountId: "primary",
});
const result = await linePlugin.gateway!.logoutAccount!({
accountId: "primary",
cfg,
account,
runtime: runtimeEnv,
});
expect(result.cleared).toBe(true);
expect(result.loggedOut).toBe(true);
expect(mocks.writeConfigFile).toHaveBeenCalledWith({});
});
it("does not write config when account has no token/secret fields", async () => {
const cfg: OpenClawConfig = {
channels: {
line: {
accounts: {
primary: {
name: "Primary",
},
},
},
},
};
const { result, mocks } = await runLogoutScenario({
cfg,
accountId: "primary",
});
expect(result.cleared).toBe(false);
expect(result.loggedOut).toBe(true);
expect(mocks.writeConfigFile).not.toHaveBeenCalled();
});
});