mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
refactor(test): dedupe repeated fixture setup helpers
This commit is contained in:
@@ -64,6 +64,16 @@ function createRemoteRouteHarness(fetchMock?: ReturnType<typeof vi.fn>) {
|
|||||||
return { state, remote: ctx.forProfile("remote"), fetchMock: activeFetchMock };
|
return { state, remote: ctx.forProfile("remote"), fetchMock: activeFetchMock };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createSequentialPageLister<T>(responses: T[]) {
|
||||||
|
return vi.fn(async () => {
|
||||||
|
const next = responses.shift();
|
||||||
|
if (!next) {
|
||||||
|
throw new Error("no more responses");
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("browser server-context remote profile tab operations", () => {
|
describe("browser server-context remote profile tab operations", () => {
|
||||||
it("uses Playwright tab operations when available", async () => {
|
it("uses Playwright tab operations when available", async () => {
|
||||||
const listPagesViaPlaywright = vi.fn(async () => [
|
const listPagesViaPlaywright = vi.fn(async () => [
|
||||||
@@ -158,13 +168,7 @@ describe("browser server-context remote profile tab operations", () => {
|
|||||||
[{ targetId: "T1", title: "Tab 1", url: "https://example.com", type: "page" }],
|
[{ targetId: "T1", title: "Tab 1", url: "https://example.com", type: "page" }],
|
||||||
[{ targetId: "T1", title: "Tab 1", url: "https://example.com", type: "page" }],
|
[{ targetId: "T1", title: "Tab 1", url: "https://example.com", type: "page" }],
|
||||||
];
|
];
|
||||||
const listPagesViaPlaywright = vi.fn(async () => {
|
const listPagesViaPlaywright = createSequentialPageLister(responses);
|
||||||
const next = responses.shift();
|
|
||||||
if (!next) {
|
|
||||||
throw new Error("no more responses");
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.spyOn(pwAiModule, "getPwAiModule").mockResolvedValue({
|
vi.spyOn(pwAiModule, "getPwAiModule").mockResolvedValue({
|
||||||
listPagesViaPlaywright,
|
listPagesViaPlaywright,
|
||||||
@@ -186,13 +190,7 @@ describe("browser server-context remote profile tab operations", () => {
|
|||||||
{ targetId: "B", title: "B", url: "https://b.example", type: "page" },
|
{ targetId: "B", title: "B", url: "https://b.example", type: "page" },
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
const listPagesViaPlaywright = vi.fn(async () => {
|
const listPagesViaPlaywright = createSequentialPageLister(responses);
|
||||||
const next = responses.shift();
|
|
||||||
if (!next) {
|
|
||||||
throw new Error("no more responses");
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.spyOn(pwAiModule, "getPwAiModule").mockResolvedValue({
|
vi.spyOn(pwAiModule, "getPwAiModule").mockResolvedValue({
|
||||||
listPagesViaPlaywright,
|
listPagesViaPlaywright,
|
||||||
|
|||||||
@@ -167,6 +167,26 @@ function setupPluginInstallDirs() {
|
|||||||
return { tmpDir, pluginDir, extensionsDir };
|
return { tmpDir, pluginDir, extensionsDir };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupInstallPluginFromDirFixture(params?: { devDependencies?: Record<string, string> }) {
|
||||||
|
const workDir = makeTempDir();
|
||||||
|
const stateDir = makeTempDir();
|
||||||
|
const pluginDir = path.join(workDir, "plugin");
|
||||||
|
fs.mkdirSync(path.join(pluginDir, "dist"), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(pluginDir, "package.json"),
|
||||||
|
JSON.stringify({
|
||||||
|
name: "@openclaw/test-plugin",
|
||||||
|
version: "0.0.1",
|
||||||
|
openclaw: { extensions: ["./dist/index.js"] },
|
||||||
|
dependencies: { "left-pad": "1.3.0" },
|
||||||
|
...(params?.devDependencies ? { devDependencies: params.devDependencies } : {}),
|
||||||
|
}),
|
||||||
|
"utf-8",
|
||||||
|
);
|
||||||
|
fs.writeFileSync(path.join(pluginDir, "dist", "index.js"), "export {};", "utf-8");
|
||||||
|
return { pluginDir, extensionsDir: path.join(stateDir, "extensions") };
|
||||||
|
}
|
||||||
|
|
||||||
async function installFromDirWithWarnings(params: { pluginDir: string; extensionsDir: string }) {
|
async function installFromDirWithWarnings(params: { pluginDir: string; extensionsDir: string }) {
|
||||||
const warnings: string[] = [];
|
const warnings: string[] = [];
|
||||||
const result = await installPluginFromDir({
|
const result = await installPluginFromDir({
|
||||||
@@ -445,21 +465,7 @@ describe("installPluginFromArchive", () => {
|
|||||||
|
|
||||||
describe("installPluginFromDir", () => {
|
describe("installPluginFromDir", () => {
|
||||||
it("uses --ignore-scripts for dependency install", async () => {
|
it("uses --ignore-scripts for dependency install", async () => {
|
||||||
const workDir = makeTempDir();
|
const { pluginDir, extensionsDir } = setupInstallPluginFromDirFixture();
|
||||||
const stateDir = makeTempDir();
|
|
||||||
const pluginDir = path.join(workDir, "plugin");
|
|
||||||
fs.mkdirSync(path.join(pluginDir, "dist"), { recursive: true });
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.join(pluginDir, "package.json"),
|
|
||||||
JSON.stringify({
|
|
||||||
name: "@openclaw/test-plugin",
|
|
||||||
version: "0.0.1",
|
|
||||||
openclaw: { extensions: ["./dist/index.js"] },
|
|
||||||
dependencies: { "left-pad": "1.3.0" },
|
|
||||||
}),
|
|
||||||
"utf-8",
|
|
||||||
);
|
|
||||||
fs.writeFileSync(path.join(pluginDir, "dist", "index.js"), "export {};", "utf-8");
|
|
||||||
|
|
||||||
const run = vi.mocked(runCommandWithTimeout);
|
const run = vi.mocked(runCommandWithTimeout);
|
||||||
await expectInstallUsesIgnoreScripts({
|
await expectInstallUsesIgnoreScripts({
|
||||||
@@ -467,31 +473,18 @@ describe("installPluginFromDir", () => {
|
|||||||
install: async () =>
|
install: async () =>
|
||||||
await installPluginFromDir({
|
await installPluginFromDir({
|
||||||
dirPath: pluginDir,
|
dirPath: pluginDir,
|
||||||
extensionsDir: path.join(stateDir, "extensions"),
|
extensionsDir,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("strips workspace devDependencies before npm install", async () => {
|
it("strips workspace devDependencies before npm install", async () => {
|
||||||
const workDir = makeTempDir();
|
const { pluginDir, extensionsDir } = setupInstallPluginFromDirFixture({
|
||||||
const stateDir = makeTempDir();
|
devDependencies: {
|
||||||
const pluginDir = path.join(workDir, "plugin");
|
openclaw: "workspace:*",
|
||||||
fs.mkdirSync(path.join(pluginDir, "dist"), { recursive: true });
|
vitest: "^3.0.0",
|
||||||
fs.writeFileSync(
|
},
|
||||||
path.join(pluginDir, "package.json"),
|
});
|
||||||
JSON.stringify({
|
|
||||||
name: "@openclaw/test-plugin",
|
|
||||||
version: "0.0.1",
|
|
||||||
openclaw: { extensions: ["./dist/index.js"] },
|
|
||||||
dependencies: { "left-pad": "1.3.0" },
|
|
||||||
devDependencies: {
|
|
||||||
openclaw: "workspace:*",
|
|
||||||
vitest: "^3.0.0",
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
"utf-8",
|
|
||||||
);
|
|
||||||
fs.writeFileSync(path.join(pluginDir, "dist", "index.js"), "export {};", "utf-8");
|
|
||||||
|
|
||||||
const run = vi.mocked(runCommandWithTimeout);
|
const run = vi.mocked(runCommandWithTimeout);
|
||||||
run.mockResolvedValue({
|
run.mockResolvedValue({
|
||||||
@@ -505,7 +498,7 @@ describe("installPluginFromDir", () => {
|
|||||||
|
|
||||||
const res = await installPluginFromDir({
|
const res = await installPluginFromDir({
|
||||||
dirPath: pluginDir,
|
dirPath: pluginDir,
|
||||||
extensionsDir: path.join(stateDir, "extensions"),
|
extensionsDir,
|
||||||
});
|
});
|
||||||
expect(res.ok).toBe(true);
|
expect(res.ok).toBe(true);
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|||||||
@@ -46,6 +46,24 @@ async function createInstalledNpmPluginFixture(params: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UninstallResult = Awaited<ReturnType<typeof uninstallPlugin>>;
|
||||||
|
|
||||||
|
async function runDeleteInstalledNpmPluginFixture(baseDir: string): Promise<{
|
||||||
|
pluginDir: string;
|
||||||
|
result: UninstallResult;
|
||||||
|
}> {
|
||||||
|
const { pluginId, extensionsDir, pluginDir, config } = await createInstalledNpmPluginFixture({
|
||||||
|
baseDir,
|
||||||
|
});
|
||||||
|
const result = await uninstallPlugin({
|
||||||
|
config,
|
||||||
|
pluginId,
|
||||||
|
deleteFiles: true,
|
||||||
|
extensionsDir,
|
||||||
|
});
|
||||||
|
return { pluginDir, result };
|
||||||
|
}
|
||||||
|
|
||||||
function createSinglePluginEntries(pluginId = "my-plugin") {
|
function createSinglePluginEntries(pluginId = "my-plugin") {
|
||||||
return {
|
return {
|
||||||
[pluginId]: { enabled: true },
|
[pluginId]: { enabled: true },
|
||||||
@@ -61,6 +79,21 @@ function createSinglePluginWithEmptySlotsConfig(): OpenClawConfig {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createSingleNpmInstallConfig(installPath: string): OpenClawConfig {
|
||||||
|
return {
|
||||||
|
plugins: {
|
||||||
|
entries: createSinglePluginEntries(),
|
||||||
|
installs: {
|
||||||
|
"my-plugin": {
|
||||||
|
source: "npm",
|
||||||
|
spec: "my-plugin@1.0.0",
|
||||||
|
installPath,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function createPluginDirFixture(baseDir: string, pluginId = "my-plugin") {
|
async function createPluginDirFixture(baseDir: string, pluginId = "my-plugin") {
|
||||||
const pluginDir = path.join(baseDir, pluginId);
|
const pluginDir = path.join(baseDir, pluginId);
|
||||||
await fs.mkdir(pluginDir, { recursive: true });
|
await fs.mkdir(pluginDir, { recursive: true });
|
||||||
@@ -330,18 +363,9 @@ describe("uninstallPlugin", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("deletes directory when deleteFiles is true", async () => {
|
it("deletes directory when deleteFiles is true", async () => {
|
||||||
const { pluginId, extensionsDir, pluginDir, config } = await createInstalledNpmPluginFixture({
|
const { pluginDir, result } = await runDeleteInstalledNpmPluginFixture(tempDir);
|
||||||
baseDir: tempDir,
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await uninstallPlugin({
|
|
||||||
config,
|
|
||||||
pluginId,
|
|
||||||
deleteFiles: true,
|
|
||||||
extensionsDir,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.ok).toBe(true);
|
expect(result.ok).toBe(true);
|
||||||
if (result.ok) {
|
if (result.ok) {
|
||||||
expect(result.actions.directory).toBe(true);
|
expect(result.actions.directory).toBe(true);
|
||||||
@@ -389,18 +413,7 @@ describe("uninstallPlugin", () => {
|
|||||||
it("does not delete directory when deleteFiles is false", async () => {
|
it("does not delete directory when deleteFiles is false", async () => {
|
||||||
const pluginDir = await createPluginDirFixture(tempDir);
|
const pluginDir = await createPluginDirFixture(tempDir);
|
||||||
|
|
||||||
const config: OpenClawConfig = {
|
const config = createSingleNpmInstallConfig(pluginDir);
|
||||||
plugins: {
|
|
||||||
entries: createSinglePluginEntries(),
|
|
||||||
installs: {
|
|
||||||
"my-plugin": {
|
|
||||||
source: "npm",
|
|
||||||
spec: "my-plugin@1.0.0",
|
|
||||||
installPath: pluginDir,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await uninstallPlugin({
|
const result = await uninstallPlugin({
|
||||||
config,
|
config,
|
||||||
@@ -417,20 +430,7 @@ describe("uninstallPlugin", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("succeeds even if directory does not exist", async () => {
|
it("succeeds even if directory does not exist", async () => {
|
||||||
const config: OpenClawConfig = {
|
const config = createSingleNpmInstallConfig("/nonexistent/path");
|
||||||
plugins: {
|
|
||||||
entries: {
|
|
||||||
"my-plugin": { enabled: true },
|
|
||||||
},
|
|
||||||
installs: {
|
|
||||||
"my-plugin": {
|
|
||||||
source: "npm",
|
|
||||||
spec: "my-plugin@1.0.0",
|
|
||||||
installPath: "/nonexistent/path",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await uninstallPlugin({
|
const result = await uninstallPlugin({
|
||||||
config,
|
config,
|
||||||
@@ -447,18 +447,9 @@ describe("uninstallPlugin", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("returns a warning when directory deletion fails unexpectedly", async () => {
|
it("returns a warning when directory deletion fails unexpectedly", async () => {
|
||||||
const { pluginId, extensionsDir, config } = await createInstalledNpmPluginFixture({
|
|
||||||
baseDir: tempDir,
|
|
||||||
});
|
|
||||||
|
|
||||||
const rmSpy = vi.spyOn(fs, "rm").mockRejectedValueOnce(new Error("permission denied"));
|
const rmSpy = vi.spyOn(fs, "rm").mockRejectedValueOnce(new Error("permission denied"));
|
||||||
try {
|
try {
|
||||||
const result = await uninstallPlugin({
|
const { result } = await runDeleteInstalledNpmPluginFixture(tempDir);
|
||||||
config,
|
|
||||||
pluginId,
|
|
||||||
deleteFiles: true,
|
|
||||||
extensionsDir,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.ok).toBe(true);
|
expect(result.ok).toBe(true);
|
||||||
if (result.ok) {
|
if (result.ok) {
|
||||||
@@ -477,20 +468,7 @@ describe("uninstallPlugin", () => {
|
|||||||
await fs.mkdir(outsideDir, { recursive: true });
|
await fs.mkdir(outsideDir, { recursive: true });
|
||||||
await fs.writeFile(path.join(outsideDir, "index.js"), "// keep me");
|
await fs.writeFile(path.join(outsideDir, "index.js"), "// keep me");
|
||||||
|
|
||||||
const config: OpenClawConfig = {
|
const config = createSingleNpmInstallConfig(outsideDir);
|
||||||
plugins: {
|
|
||||||
entries: {
|
|
||||||
"my-plugin": { enabled: true },
|
|
||||||
},
|
|
||||||
installs: {
|
|
||||||
"my-plugin": {
|
|
||||||
source: "npm",
|
|
||||||
spec: "my-plugin@1.0.0",
|
|
||||||
installPath: outsideDir,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await uninstallPlugin({
|
const result = await uninstallPlugin({
|
||||||
config,
|
config,
|
||||||
|
|||||||
@@ -17,6 +17,13 @@ const SKIP_PATTERNS = [
|
|||||||
/[\\/][^\\/]*test-harness(?:\.[^\\/]+)?\.ts$/,
|
/[\\/][^\\/]*test-harness(?:\.[^\\/]+)?\.ts$/,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
type QuoteChar = "'" | '"' | "`";
|
||||||
|
|
||||||
|
type QuoteScanState = {
|
||||||
|
quote: QuoteChar | null;
|
||||||
|
escaped: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
function shouldSkip(relativePath: string): boolean {
|
function shouldSkip(relativePath: string): boolean {
|
||||||
return SKIP_PATTERNS.some((pattern) => pattern.test(relativePath));
|
return SKIP_PATTERNS.some((pattern) => pattern.test(relativePath));
|
||||||
}
|
}
|
||||||
@@ -27,26 +34,13 @@ function stripCommentsForScan(input: string): string {
|
|||||||
|
|
||||||
function findMatchingParen(source: string, openIndex: number): number {
|
function findMatchingParen(source: string, openIndex: number): number {
|
||||||
let depth = 1;
|
let depth = 1;
|
||||||
let quote: "'" | '"' | "`" | null = null;
|
const quoteState: QuoteScanState = { quote: null, escaped: false };
|
||||||
let escaped = false;
|
|
||||||
for (let i = openIndex + 1; i < source.length; i += 1) {
|
for (let i = openIndex + 1; i < source.length; i += 1) {
|
||||||
const ch = source[i];
|
const ch = source[i];
|
||||||
if (quote) {
|
if (consumeQuotedChar(quoteState, ch)) {
|
||||||
if (escaped) {
|
|
||||||
escaped = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ch === "\\") {
|
|
||||||
escaped = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ch === quote) {
|
|
||||||
quote = null;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ch === "'" || ch === '"' || ch === "`") {
|
if (beginQuotedSection(quoteState, ch)) {
|
||||||
quote = ch;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ch === "(") {
|
if (ch === "(") {
|
||||||
@@ -69,27 +63,15 @@ function splitTopLevelArguments(source: string): string[] {
|
|||||||
let parenDepth = 0;
|
let parenDepth = 0;
|
||||||
let bracketDepth = 0;
|
let bracketDepth = 0;
|
||||||
let braceDepth = 0;
|
let braceDepth = 0;
|
||||||
let quote: "'" | '"' | "`" | null = null;
|
const quoteState: QuoteScanState = { quote: null, escaped: false };
|
||||||
let escaped = false;
|
|
||||||
for (let i = 0; i < source.length; i += 1) {
|
for (let i = 0; i < source.length; i += 1) {
|
||||||
const ch = source[i];
|
const ch = source[i];
|
||||||
if (quote) {
|
if (quoteState.quote) {
|
||||||
current += ch;
|
current += ch;
|
||||||
if (escaped) {
|
consumeQuotedChar(quoteState, ch);
|
||||||
escaped = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ch === "\\") {
|
|
||||||
escaped = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ch === quote) {
|
|
||||||
quote = null;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ch === "'" || ch === '"' || ch === "`") {
|
if (beginQuotedSection(quoteState, ch)) {
|
||||||
quote = ch;
|
|
||||||
current += ch;
|
current += ch;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -142,6 +124,32 @@ function splitTopLevelArguments(source: string): string[] {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function beginQuotedSection(state: QuoteScanState, ch: string): boolean {
|
||||||
|
if (ch !== "'" && ch !== '"' && ch !== "`") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
state.quote = ch;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function consumeQuotedChar(state: QuoteScanState, ch: string): boolean {
|
||||||
|
if (!state.quote) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (state.escaped) {
|
||||||
|
state.escaped = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ch === "\\") {
|
||||||
|
state.escaped = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ch === state.quote) {
|
||||||
|
state.quote = null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function isOsTmpdirExpression(argument: string): boolean {
|
function isOsTmpdirExpression(argument: string): boolean {
|
||||||
return /^os\s*\.\s*tmpdir\s*\(\s*\)$/u.test(argument.trim());
|
return /^os\s*\.\s*tmpdir\s*\(\s*\)$/u.test(argument.trim());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,16 @@ function createThreadStarterRepliesClient(
|
|||||||
return { replies, client };
|
return { replies, client };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createListedChannelsContext(groupPolicy: "open" | "allowlist") {
|
||||||
|
return createSlackMonitorContext({
|
||||||
|
...baseParams(),
|
||||||
|
groupPolicy,
|
||||||
|
channelsConfig: {
|
||||||
|
C_LISTED: { requireMention: true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("normalizeSlackChannelType", () => {
|
describe("normalizeSlackChannelType", () => {
|
||||||
it("infers channel types from ids when missing", () => {
|
it("infers channel types from ids when missing", () => {
|
||||||
expect(normalizeSlackChannelType(undefined, "C123")).toBe("channel");
|
expect(normalizeSlackChannelType(undefined, "C123")).toBe("channel");
|
||||||
@@ -138,13 +148,7 @@ describe("isChannelAllowed with groupPolicy and channelsConfig", () => {
|
|||||||
it("allows unlisted channels when groupPolicy is open even with channelsConfig entries", () => {
|
it("allows unlisted channels when groupPolicy is open even with channelsConfig entries", () => {
|
||||||
// Bug fix: when groupPolicy="open" and channels has some entries,
|
// Bug fix: when groupPolicy="open" and channels has some entries,
|
||||||
// unlisted channels should still be allowed (not blocked)
|
// unlisted channels should still be allowed (not blocked)
|
||||||
const ctx = createSlackMonitorContext({
|
const ctx = createListedChannelsContext("open");
|
||||||
...baseParams(),
|
|
||||||
groupPolicy: "open",
|
|
||||||
channelsConfig: {
|
|
||||||
C_LISTED: { requireMention: true },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// Listed channel should be allowed
|
// Listed channel should be allowed
|
||||||
expect(ctx.isChannelAllowed({ channelId: "C_LISTED", channelType: "channel" })).toBe(true);
|
expect(ctx.isChannelAllowed({ channelId: "C_LISTED", channelType: "channel" })).toBe(true);
|
||||||
// Unlisted channel should ALSO be allowed when policy is "open"
|
// Unlisted channel should ALSO be allowed when policy is "open"
|
||||||
@@ -152,13 +156,7 @@ describe("isChannelAllowed with groupPolicy and channelsConfig", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("blocks unlisted channels when groupPolicy is allowlist", () => {
|
it("blocks unlisted channels when groupPolicy is allowlist", () => {
|
||||||
const ctx = createSlackMonitorContext({
|
const ctx = createListedChannelsContext("allowlist");
|
||||||
...baseParams(),
|
|
||||||
groupPolicy: "allowlist",
|
|
||||||
channelsConfig: {
|
|
||||||
C_LISTED: { requireMention: true },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// Listed channel should be allowed
|
// Listed channel should be allowed
|
||||||
expect(ctx.isChannelAllowed({ channelId: "C_LISTED", channelType: "channel" })).toBe(true);
|
expect(ctx.isChannelAllowed({ channelId: "C_LISTED", channelType: "channel" })).toBe(true);
|
||||||
// Unlisted channel should be blocked when policy is "allowlist"
|
// Unlisted channel should be blocked when policy is "allowlist"
|
||||||
|
|||||||
Reference in New Issue
Block a user