mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
refactor(extensions): reuse shared helper primitives
This commit is contained in:
@@ -51,14 +51,10 @@ describe("checkTwitchAccessControl", () => {
|
||||
|
||||
describe("when no restrictions are configured", () => {
|
||||
it("allows messages that mention the bot (default requireMention)", () => {
|
||||
const message: TwitchChatMessage = {
|
||||
...mockMessage,
|
||||
message: "@testbot hello",
|
||||
};
|
||||
const result = checkTwitchAccessControl({
|
||||
message,
|
||||
account: mockAccount,
|
||||
botUsername: "testbot",
|
||||
const result = runAccessCheck({
|
||||
message: {
|
||||
message: "@testbot hello",
|
||||
},
|
||||
});
|
||||
expect(result.allowed).toBe(true);
|
||||
});
|
||||
@@ -66,30 +62,20 @@ describe("checkTwitchAccessControl", () => {
|
||||
|
||||
describe("requireMention default", () => {
|
||||
it("defaults to true when undefined", () => {
|
||||
const message: TwitchChatMessage = {
|
||||
...mockMessage,
|
||||
message: "hello bot",
|
||||
};
|
||||
|
||||
const result = checkTwitchAccessControl({
|
||||
message,
|
||||
account: mockAccount,
|
||||
botUsername: "testbot",
|
||||
const result = runAccessCheck({
|
||||
message: {
|
||||
message: "hello bot",
|
||||
},
|
||||
});
|
||||
expect(result.allowed).toBe(false);
|
||||
expect(result.reason).toContain("does not mention the bot");
|
||||
});
|
||||
|
||||
it("allows mention when requireMention is undefined", () => {
|
||||
const message: TwitchChatMessage = {
|
||||
...mockMessage,
|
||||
message: "@testbot hello",
|
||||
};
|
||||
|
||||
const result = checkTwitchAccessControl({
|
||||
message,
|
||||
account: mockAccount,
|
||||
botUsername: "testbot",
|
||||
const result = runAccessCheck({
|
||||
message: {
|
||||
message: "@testbot hello",
|
||||
},
|
||||
});
|
||||
expect(result.allowed).toBe(true);
|
||||
});
|
||||
@@ -97,52 +83,25 @@ describe("checkTwitchAccessControl", () => {
|
||||
|
||||
describe("requireMention", () => {
|
||||
it("allows messages that mention the bot", () => {
|
||||
const account: TwitchAccountConfig = {
|
||||
...mockAccount,
|
||||
requireMention: true,
|
||||
};
|
||||
const message: TwitchChatMessage = {
|
||||
...mockMessage,
|
||||
message: "@testbot hello",
|
||||
};
|
||||
|
||||
const result = checkTwitchAccessControl({
|
||||
message,
|
||||
account,
|
||||
botUsername: "testbot",
|
||||
const result = runAccessCheck({
|
||||
account: { requireMention: true },
|
||||
message: { message: "@testbot hello" },
|
||||
});
|
||||
expect(result.allowed).toBe(true);
|
||||
});
|
||||
|
||||
it("blocks messages that don't mention the bot", () => {
|
||||
const account: TwitchAccountConfig = {
|
||||
...mockAccount,
|
||||
requireMention: true,
|
||||
};
|
||||
|
||||
const result = checkTwitchAccessControl({
|
||||
message: mockMessage,
|
||||
account,
|
||||
botUsername: "testbot",
|
||||
const result = runAccessCheck({
|
||||
account: { requireMention: true },
|
||||
});
|
||||
expect(result.allowed).toBe(false);
|
||||
expect(result.reason).toContain("does not mention the bot");
|
||||
});
|
||||
|
||||
it("is case-insensitive for bot username", () => {
|
||||
const account: TwitchAccountConfig = {
|
||||
...mockAccount,
|
||||
requireMention: true,
|
||||
};
|
||||
const message: TwitchChatMessage = {
|
||||
...mockMessage,
|
||||
message: "@TestBot hello",
|
||||
};
|
||||
|
||||
const result = checkTwitchAccessControl({
|
||||
message,
|
||||
account,
|
||||
botUsername: "testbot",
|
||||
const result = runAccessCheck({
|
||||
account: { requireMention: true },
|
||||
message: { message: "@TestBot hello" },
|
||||
});
|
||||
expect(result.allowed).toBe(true);
|
||||
});
|
||||
|
||||
@@ -14,17 +14,28 @@ import { describe, expect, it } from "vitest";
|
||||
import { collectTwitchStatusIssues } from "./status.js";
|
||||
import type { ChannelAccountSnapshot } from "./types.js";
|
||||
|
||||
function createSnapshot(overrides: Partial<ChannelAccountSnapshot> = {}): ChannelAccountSnapshot {
|
||||
return {
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function createSimpleTwitchConfig(overrides: Record<string, unknown>) {
|
||||
return {
|
||||
channels: {
|
||||
twitch: overrides,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("status", () => {
|
||||
describe("collectTwitchStatusIssues", () => {
|
||||
it("should detect unconfigured accounts", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: false,
|
||||
enabled: true,
|
||||
running: false,
|
||||
},
|
||||
];
|
||||
const snapshots: ChannelAccountSnapshot[] = [createSnapshot({ configured: false })];
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots);
|
||||
|
||||
@@ -34,14 +45,7 @@ describe("status", () => {
|
||||
});
|
||||
|
||||
it("should detect disabled accounts", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: false,
|
||||
running: false,
|
||||
},
|
||||
];
|
||||
const snapshots: ChannelAccountSnapshot[] = [createSnapshot({ enabled: false })];
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots);
|
||||
|
||||
@@ -51,24 +55,12 @@ describe("status", () => {
|
||||
});
|
||||
|
||||
it("should detect missing clientId when account configured (simplified config)", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
},
|
||||
];
|
||||
|
||||
const mockCfg = {
|
||||
channels: {
|
||||
twitch: {
|
||||
username: "testbot",
|
||||
accessToken: "oauth:test123",
|
||||
// clientId missing
|
||||
},
|
||||
},
|
||||
};
|
||||
const snapshots: ChannelAccountSnapshot[] = [createSnapshot()];
|
||||
const mockCfg = createSimpleTwitchConfig({
|
||||
username: "testbot",
|
||||
accessToken: "oauth:test123",
|
||||
// clientId missing
|
||||
});
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never);
|
||||
|
||||
@@ -77,24 +69,12 @@ describe("status", () => {
|
||||
});
|
||||
|
||||
it("should warn about oauth: prefix in token (simplified config)", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
},
|
||||
];
|
||||
|
||||
const mockCfg = {
|
||||
channels: {
|
||||
twitch: {
|
||||
username: "testbot",
|
||||
accessToken: "oauth:test123", // has prefix
|
||||
clientId: "test-id",
|
||||
},
|
||||
},
|
||||
};
|
||||
const snapshots: ChannelAccountSnapshot[] = [createSnapshot()];
|
||||
const mockCfg = createSimpleTwitchConfig({
|
||||
username: "testbot",
|
||||
accessToken: "oauth:test123", // has prefix
|
||||
clientId: "test-id",
|
||||
});
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never);
|
||||
|
||||
@@ -104,26 +84,14 @@ describe("status", () => {
|
||||
});
|
||||
|
||||
it("should detect clientSecret without refreshToken (simplified config)", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
},
|
||||
];
|
||||
|
||||
const mockCfg = {
|
||||
channels: {
|
||||
twitch: {
|
||||
username: "testbot",
|
||||
accessToken: "oauth:test123",
|
||||
clientId: "test-id",
|
||||
clientSecret: "secret123",
|
||||
// refreshToken missing
|
||||
},
|
||||
},
|
||||
};
|
||||
const snapshots: ChannelAccountSnapshot[] = [createSnapshot()];
|
||||
const mockCfg = createSimpleTwitchConfig({
|
||||
username: "testbot",
|
||||
accessToken: "oauth:test123",
|
||||
clientId: "test-id",
|
||||
clientSecret: "secret123",
|
||||
// refreshToken missing
|
||||
});
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never);
|
||||
|
||||
@@ -132,25 +100,13 @@ describe("status", () => {
|
||||
});
|
||||
|
||||
it("should detect empty allowFrom array (simplified config)", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
},
|
||||
];
|
||||
|
||||
const mockCfg = {
|
||||
channels: {
|
||||
twitch: {
|
||||
username: "testbot",
|
||||
accessToken: "test123",
|
||||
clientId: "test-id",
|
||||
allowFrom: [], // empty array
|
||||
},
|
||||
},
|
||||
};
|
||||
const snapshots: ChannelAccountSnapshot[] = [createSnapshot()];
|
||||
const mockCfg = createSimpleTwitchConfig({
|
||||
username: "testbot",
|
||||
accessToken: "test123",
|
||||
clientId: "test-id",
|
||||
allowFrom: [], // empty array
|
||||
});
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never);
|
||||
|
||||
@@ -159,26 +115,14 @@ describe("status", () => {
|
||||
});
|
||||
|
||||
it("should detect allowedRoles 'all' with allowFrom conflict (simplified config)", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
},
|
||||
];
|
||||
|
||||
const mockCfg = {
|
||||
channels: {
|
||||
twitch: {
|
||||
username: "testbot",
|
||||
accessToken: "test123",
|
||||
clientId: "test-id",
|
||||
allowedRoles: ["all"],
|
||||
allowFrom: ["123456"], // conflict!
|
||||
},
|
||||
},
|
||||
};
|
||||
const snapshots: ChannelAccountSnapshot[] = [createSnapshot()];
|
||||
const mockCfg = createSimpleTwitchConfig({
|
||||
username: "testbot",
|
||||
accessToken: "test123",
|
||||
clientId: "test-id",
|
||||
allowedRoles: ["all"],
|
||||
allowFrom: ["123456"], // conflict!
|
||||
});
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never);
|
||||
|
||||
@@ -189,13 +133,7 @@ describe("status", () => {
|
||||
|
||||
it("should detect runtime errors", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
lastError: "Connection timeout",
|
||||
},
|
||||
createSnapshot({ lastError: "Connection timeout" }),
|
||||
];
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots);
|
||||
@@ -207,15 +145,11 @@ describe("status", () => {
|
||||
|
||||
it("should detect accounts that never connected", () => {
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
running: false,
|
||||
createSnapshot({
|
||||
lastStartAt: undefined,
|
||||
lastInboundAt: undefined,
|
||||
lastOutboundAt: undefined,
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots);
|
||||
@@ -230,13 +164,10 @@ describe("status", () => {
|
||||
const oldDate = Date.now() - 8 * 24 * 60 * 60 * 1000; // 8 days ago
|
||||
|
||||
const snapshots: ChannelAccountSnapshot[] = [
|
||||
{
|
||||
accountId: "default",
|
||||
configured: true,
|
||||
enabled: true,
|
||||
createSnapshot({
|
||||
running: true,
|
||||
lastStartAt: oldDate,
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
const issues = collectTwitchStatusIssues(snapshots);
|
||||
|
||||
Reference in New Issue
Block a user