mirror of
https://github.com/jackwener/OpenCLI.git
synced 2026-09-14 18:25:42 +08:00
61ea05bff7
Security: - Fix URL injection in fetch.ts and bilibili.ts (JSON.stringify instead of string interpolation) - Fix unused scroll() amount parameter TypeScript: - Enable strictNullChecks in tsconfig - Change CliCommand.func signature to IPage (non-null) for browser adapters - Fix 93 compile errors across all adapters Build: - Remove || true from build-manifest (report failures instead of silencing) - Replace Unix shell commands with Node.js scripts for cross-platform builds Code quality: - Remove error-object special detection from pipeline executor - Unify error handling to throw pattern Tests: - New interceptor.test.ts (11 tests) - New executor.test.ts (13 tests) - Rewrite output.test.ts with comprehensive coverage (10 tests)
95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
/**
|
|
* Tests for interceptor.ts: JavaScript code generators for XHR/Fetch interception.
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import { generateInterceptorJs, generateReadInterceptedJs, generateTapInterceptorJs } from './interceptor.js';
|
|
|
|
describe('generateInterceptorJs', () => {
|
|
it('generates valid JavaScript function source', () => {
|
|
const js = generateInterceptorJs('"api/search"');
|
|
expect(js).toContain('window.fetch');
|
|
expect(js).toContain('XMLHttpRequest');
|
|
expect(js).toContain('"api/search"');
|
|
// Should be a function expression wrapping
|
|
expect(js.trim()).toMatch(/^\(\)\s*=>/);
|
|
});
|
|
|
|
it('uses default array name and patch guard', () => {
|
|
const js = generateInterceptorJs('"test"');
|
|
expect(js).toContain('__opencli_intercepted');
|
|
expect(js).toContain('__opencli_interceptor_patched');
|
|
});
|
|
|
|
it('uses custom array name and patch guard', () => {
|
|
const js = generateInterceptorJs('"test"', {
|
|
arrayName: '__my_data',
|
|
patchGuard: '__my_guard',
|
|
});
|
|
expect(js).toContain('__my_data');
|
|
expect(js).toContain('__my_guard');
|
|
expect(js).not.toContain('__opencli_intercepted');
|
|
});
|
|
|
|
it('includes fetch clone and json parsing', () => {
|
|
const js = generateInterceptorJs('"api"');
|
|
expect(js).toContain('response.clone()');
|
|
expect(js).toContain('clone.json()');
|
|
});
|
|
|
|
it('includes XHR open and send patching', () => {
|
|
const js = generateInterceptorJs('"api"');
|
|
expect(js).toContain('XMLHttpRequest.prototype');
|
|
expect(js).toContain('__origOpen');
|
|
expect(js).toContain('__origSend');
|
|
});
|
|
});
|
|
|
|
describe('generateReadInterceptedJs', () => {
|
|
it('generates valid JavaScript to read and clear data', () => {
|
|
const js = generateReadInterceptedJs();
|
|
expect(js).toContain('__opencli_intercepted');
|
|
// Should clear the array after reading
|
|
expect(js).toContain('= []');
|
|
});
|
|
|
|
it('uses custom array name', () => {
|
|
const js = generateReadInterceptedJs('__custom_arr');
|
|
expect(js).toContain('__custom_arr');
|
|
expect(js).not.toContain('__opencli_intercepted');
|
|
});
|
|
});
|
|
|
|
describe('generateTapInterceptorJs', () => {
|
|
it('returns all required fields', () => {
|
|
const tap = generateTapInterceptorJs('"api/data"');
|
|
|
|
expect(tap.setupVar).toBeDefined();
|
|
expect(tap.capturedVar).toBe('captured');
|
|
expect(tap.promiseVar).toBe('capturePromise');
|
|
expect(tap.resolveVar).toBe('captureResolve');
|
|
expect(tap.fetchPatch).toBeDefined();
|
|
expect(tap.xhrPatch).toBeDefined();
|
|
expect(tap.restorePatch).toBeDefined();
|
|
});
|
|
|
|
it('contains the capture pattern in setup', () => {
|
|
const tap = generateTapInterceptorJs('"my-pattern"');
|
|
expect(tap.setupVar).toContain('"my-pattern"');
|
|
});
|
|
|
|
it('restores original fetch and XHR in restorePatch', () => {
|
|
const tap = generateTapInterceptorJs('"test"');
|
|
expect(tap.restorePatch).toContain('origFetch');
|
|
expect(tap.restorePatch).toContain('origXhrOpen');
|
|
expect(tap.restorePatch).toContain('origXhrSend');
|
|
});
|
|
|
|
it('uses first-match capture (only first response)', () => {
|
|
const tap = generateTapInterceptorJs('"test"');
|
|
// Both fetch and xhr patches should check !captured before storing
|
|
expect(tap.fetchPatch).toContain('!captured');
|
|
expect(tap.xhrPatch).toContain('!captured');
|
|
});
|
|
});
|