Advertisement

← ubon

src/__tests__/framework-scanner.test.ts

1.8 KB Download file
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { FrameworkScanner } from '../scanners/framework-scanner';

/**
 * Smoke tests for the framework rule pack. We don't try to cover every rule
 * exhaustively — `framework-rules.test.ts` does that for static analysis;
 * here we verify the scanner reaches into a real on-disk fixture.
 */
describe('FrameworkScanner integration', () => {
  let dir: string;

  beforeEach(() => {
    dir = mkdtempSync(join(tmpdir(), 'ubon-fw-'));
  });

  afterEach(() => {
    rmSync(dir, { recursive: true, force: true });
  });

  const writeFile = (rel: string, content: string) => {
    const full = join(dir, rel);
    mkdirSync(join(full, '..'), { recursive: true });
    writeFileSync(full, content);
  };

  it('flags a Server Action with no auth (NEXT212)', async () => {
    writeFile(
      'app/actions.ts',
      `'use server';

export async function deleteUser(formData: FormData) {
  const id = formData.get('id');
  // ... db.users.delete({ where: { id } })
}
`
    );
    const scanner = new FrameworkScanner();
    const results = await scanner.scan({ directory: dir, verbose: false } as any);
    expect(results.some((r) => r.ruleId === 'NEXT212')).toBe(true);
  });

  it('flags Edge runtime + Node API misuse (EDGE001)', async () => {
    writeFile(
      'app/api/edge/route.ts',
      `import fs from 'fs';

export const runtime = 'edge';

export async function GET() {
  const data = fs.readFileSync('/tmp/foo');
  return new Response(data);
}
`
    );
    const scanner = new FrameworkScanner();
    const results = await scanner.scan({ directory: dir, verbose: false } as any);
    expect(results.some((r) => r.ruleId === 'EDGE001')).toBe(true);
  });
});