Files
english/.opencode/plugin/scout-block/tests/test-monorepo-scenarios.cjs
2026-04-12 01:06:31 +07:00

226 lines
6.7 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* test-monorepo-scenarios.cjs - Integration tests for monorepo patterns
*
* THIS IS THE CRITICAL TEST FILE FOR THE BUG FIX!
* Tests that subfolder blocked directories (node_modules, dist, etc.)
* are properly blocked in monorepo structures.
*/
const { execSync } = require('child_process');
const path = require('path');
const hookPath = path.join(__dirname, '..', '..', 'scout-block.cjs');
const scenarios = [
// === THE BUG CASES - These MUST be BLOCKED ===
{
input: { tool_name: 'Bash', tool_input: { command: 'ls packages/web/node_modules' } },
expected: 'BLOCKED',
desc: '[BUG FIX] ls subfolder node_modules'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'cd apps/api/node_modules' } },
expected: 'BLOCKED',
desc: '[BUG FIX] cd subfolder node_modules'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'cat packages/shared/node_modules/lodash/index.js' } },
expected: 'BLOCKED',
desc: '[BUG FIX] cat file in subfolder node_modules'
},
{
input: { tool_name: 'Read', tool_input: { file_path: 'packages/web/node_modules/react/package.json' } },
expected: 'BLOCKED',
desc: '[BUG FIX] Read subfolder node_modules'
},
{
input: { tool_name: 'Grep', tool_input: { pattern: 'export', path: 'packages/web/node_modules' } },
expected: 'BLOCKED',
desc: '[BUG FIX] Grep in subfolder node_modules'
},
{
input: { tool_name: 'Glob', tool_input: { pattern: 'packages/web/node_modules/**/*.js' } },
expected: 'BLOCKED',
desc: '[BUG FIX] Glob subfolder node_modules'
},
// === Deep nesting (also bug cases) ===
{
input: { tool_name: 'Read', tool_input: { file_path: 'a/b/c/d/node_modules/pkg/index.js' } },
expected: 'BLOCKED',
desc: '[BUG FIX] Deep nested node_modules'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'ls packages/web/dist' } },
expected: 'BLOCKED',
desc: '[BUG FIX] ls subfolder dist'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'cat apps/api/build/server.js' } },
expected: 'BLOCKED',
desc: '[BUG FIX] cat subfolder build'
},
// === Root level blocking (should still work) ===
{
input: { tool_name: 'Bash', tool_input: { command: 'ls node_modules' } },
expected: 'BLOCKED',
desc: 'ls root node_modules'
},
{
input: { tool_name: 'Read', tool_input: { file_path: 'node_modules/lodash/index.js' } },
expected: 'BLOCKED',
desc: 'Read root node_modules'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'cat .git/config' } },
expected: 'BLOCKED',
desc: 'cat .git file'
},
// === Build commands - MUST be ALLOWED ===
{
input: { tool_name: 'Bash', tool_input: { command: 'npm run build' } },
expected: 'ALLOWED',
desc: 'npm run build'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'pnpm build' } },
expected: 'ALLOWED',
desc: 'pnpm build'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'yarn build' } },
expected: 'ALLOWED',
desc: 'yarn build'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'npm test' } },
expected: 'ALLOWED',
desc: 'npm test'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'npm install' } },
expected: 'ALLOWED',
desc: 'npm install'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'pnpm --filter web run build' } },
expected: 'ALLOWED',
desc: 'pnpm filter build'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'npx tsc' } },
expected: 'ALLOWED',
desc: 'npx tsc'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'jest --coverage' } },
expected: 'ALLOWED',
desc: 'jest with flags'
},
// === Safe operations - MUST be ALLOWED ===
{
input: { tool_name: 'Read', tool_input: { file_path: 'packages/web/src/App.tsx' } },
expected: 'ALLOWED',
desc: 'Read safe path'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'ls packages/web/src' } },
expected: 'ALLOWED',
desc: 'ls safe path'
},
{
input: { tool_name: 'Grep', tool_input: { pattern: 'import', path: 'src' } },
expected: 'ALLOWED',
desc: 'Grep in src'
},
{
input: { tool_name: 'Glob', tool_input: { pattern: '**/*.ts' } },
expected: 'ALLOWED',
desc: 'Glob all .ts files'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'find packages -name "*.json" | head' } },
expected: 'ALLOWED',
desc: 'find without blocked dirs'
},
// === Edge cases - names containing blocked words but NOT the dirs ===
{
input: { tool_name: 'Read', tool_input: { file_path: 'my-node_modules-project/file.js' } },
expected: 'ALLOWED',
desc: 'node_modules in project name'
},
{
input: { tool_name: 'Bash', tool_input: { command: 'ls build-tools' } },
expected: 'ALLOWED',
desc: 'build- prefix directory'
},
];
console.log('Testing monorepo scenarios (scout-block integration)...\n');
console.log('Hook path:', hookPath, '\n');
let passed = 0;
let failed = 0;
for (const scenario of scenarios) {
try {
execSync(`node "${hookPath}"`, {
input: JSON.stringify(scenario.input),
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe']
});
// Exit 0 = ALLOWED
const actual = 'ALLOWED';
const success = actual === scenario.expected;
if (success) {
console.log(`\x1b[32m✓\x1b[0m ${scenario.desc}: ${actual}`);
passed++;
} else {
console.log(`\x1b[31m✗\x1b[0m ${scenario.desc}: expected ${scenario.expected}, got ${actual}`);
failed++;
}
} catch (error) {
// Exit 2 = BLOCKED
const actual = error.status === 2 ? 'BLOCKED' : `ERROR(${error.status})`;
const success = actual === scenario.expected;
if (success) {
console.log(`\x1b[32m✓\x1b[0m ${scenario.desc}: ${actual}`);
passed++;
} else {
console.log(`\x1b[31m✗\x1b[0m ${scenario.desc}: expected ${scenario.expected}, got ${actual}`);
if (error.stderr) {
console.log(` stderr: ${error.stderr.toString().trim().split('\n')[0]}`);
}
failed++;
}
}
}
console.log(`\nResults: ${passed} passed, ${failed} failed`);
// Highlight if any bug fix cases failed
const bugFixFailed = scenarios.filter(s => s.desc.includes('[BUG FIX]')).some(s => {
try {
execSync(`node "${hookPath}"`, {
input: JSON.stringify(s.input),
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe']
});
return s.expected === 'BLOCKED'; // Should have been blocked but wasn't
} catch (error) {
return error.status !== 2 && s.expected === 'BLOCKED';
}
});
if (bugFixFailed) {
console.log('\n\x1b[31mWARNING: Some bug fix test cases failed!\x1b[0m');
console.log('The subfolder blocking bug has NOT been fixed properly.');
}
process.exit(failed > 0 ? 1 : 0);