mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-07 08:26:11 +00:00
Some checks are pending
CodeQL / Analyze (python) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Publish / Classify release event (push) Waiting to run
Publish / RC guard (marker + release-PR skip) (push) Blocked by required conditions
Publish / Publish to npm (push) Blocked by required conditions
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
Publish / ci (push) Blocked by required conditions
Publish / Build & Push RC Docker images (push) Blocked by required conditions
Scorecard / Scorecard analysis (push) Waiting to run
124 lines
3.9 KiB
TypeScript
124 lines
3.9 KiB
TypeScript
/**
|
|
* P0 Unit Tests: Security Hardening
|
|
*
|
|
* Tests security-related utility helpers in isolation:
|
|
* - Relation type allowlist
|
|
* - Path traversal detection
|
|
* - isTestFilePath patterns
|
|
*/
|
|
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
VALID_RELATION_TYPES,
|
|
VALID_NODE_LABELS,
|
|
isTestFilePath,
|
|
} from '../../src/mcp/local/local-backend.js';
|
|
|
|
// ─── Relation type allowlist ──────────────────────────────────────────
|
|
|
|
describe('VALID_RELATION_TYPES', () => {
|
|
it('contains all expected relation types', () => {
|
|
expect(VALID_RELATION_TYPES.size).toBe(15);
|
|
for (const t of [
|
|
'CALLS',
|
|
'IMPORTS',
|
|
'EXTENDS',
|
|
'IMPLEMENTS',
|
|
'HAS_METHOD',
|
|
'HAS_PROPERTY',
|
|
'METHOD_OVERRIDES',
|
|
'OVERRIDES',
|
|
'METHOD_IMPLEMENTS',
|
|
'ACCESSES',
|
|
'HANDLES_ROUTE',
|
|
'FETCHES',
|
|
'HANDLES_TOOL',
|
|
'ENTRY_POINT_OF',
|
|
'WRAPS',
|
|
]) {
|
|
expect(VALID_RELATION_TYPES.has(t)).toBe(true);
|
|
}
|
|
});
|
|
|
|
it('rejects invalid relation types', () => {
|
|
expect(VALID_RELATION_TYPES.has('CONTAINS')).toBe(false);
|
|
expect(VALID_RELATION_TYPES.has('USES')).toBe(false);
|
|
expect(VALID_RELATION_TYPES.has('calls')).toBe(false); // case-sensitive
|
|
expect(VALID_RELATION_TYPES.has('DROP_TABLE')).toBe(false);
|
|
});
|
|
});
|
|
|
|
// ─── Valid node labels ───────────────────────────────────────────────
|
|
|
|
describe('VALID_NODE_LABELS', () => {
|
|
it('contains core node types', () => {
|
|
for (const label of [
|
|
'File',
|
|
'Folder',
|
|
'Function',
|
|
'Class',
|
|
'Interface',
|
|
'Method',
|
|
'CodeElement',
|
|
]) {
|
|
expect(VALID_NODE_LABELS.has(label)).toBe(true);
|
|
}
|
|
});
|
|
|
|
it('contains meta node types', () => {
|
|
for (const label of ['Community', 'Process']) {
|
|
expect(VALID_NODE_LABELS.has(label)).toBe(true);
|
|
}
|
|
});
|
|
|
|
it('contains multi-language node types', () => {
|
|
for (const label of ['Struct', 'Enum', 'Macro', 'Trait', 'Impl', 'Namespace']) {
|
|
expect(VALID_NODE_LABELS.has(label)).toBe(true);
|
|
}
|
|
});
|
|
|
|
it('rejects invalid labels', () => {
|
|
expect(VALID_NODE_LABELS.has('InvalidType')).toBe(false);
|
|
expect(VALID_NODE_LABELS.has('function')).toBe(false); // case-sensitive
|
|
});
|
|
});
|
|
|
|
// ─── Path traversal detection ────────────────────────────────────────
|
|
|
|
describe('path traversal (isTestFilePath as proxy for path handling)', () => {
|
|
it('isTestFilePath matches .test. files', () => {
|
|
expect(isTestFilePath('src/foo.test.ts')).toBe(true);
|
|
expect(isTestFilePath('src/foo.spec.ts')).toBe(true);
|
|
});
|
|
|
|
it('isTestFilePath matches __tests__ directory', () => {
|
|
expect(isTestFilePath('src/__tests__/foo.ts')).toBe(true);
|
|
});
|
|
|
|
it('isTestFilePath matches /test/ directory', () => {
|
|
expect(isTestFilePath('src/test/foo.ts')).toBe(true);
|
|
});
|
|
|
|
it('isTestFilePath handles Windows backslash paths', () => {
|
|
expect(isTestFilePath('src\\test\\foo.ts')).toBe(true);
|
|
expect(isTestFilePath('src\\__tests__\\bar.ts')).toBe(true);
|
|
});
|
|
|
|
it('isTestFilePath is case-insensitive', () => {
|
|
expect(isTestFilePath('SRC/TEST/Foo.ts')).toBe(true);
|
|
expect(isTestFilePath('SRC/Foo.Test.ts')).toBe(true);
|
|
});
|
|
|
|
it('isTestFilePath matches Go test files', () => {
|
|
expect(isTestFilePath('pkg/handler_test.go')).toBe(true);
|
|
});
|
|
|
|
it('isTestFilePath matches Python test files', () => {
|
|
expect(isTestFilePath('tests/test_handler.py')).toBe(true);
|
|
expect(isTestFilePath('pkg/handler_test.py')).toBe(true);
|
|
});
|
|
|
|
it('isTestFilePath returns false for non-test files', () => {
|
|
expect(isTestFilePath('src/main.ts')).toBe(false);
|
|
expect(isTestFilePath('src/utils/helper.ts')).toBe(false);
|
|
});
|
|
});
|