Refactor and enhance tests for call graph extractors and connection management
- Updated JavaScriptCallGraphExtractorTests to improve naming conventions and test cases for Azure Functions, CLI commands, and socket handling. - Modified NodeCallGraphExtractorTests to correctly assert exceptions for null inputs. - Enhanced WitnessModalComponent tests in Angular to use Jasmine spies and improved assertions for path visualization and signature verification. - Added ConnectionState property for tracking connection establishment time in Router.Common. - Implemented validation for HelloPayload in ConnectionManager to ensure required fields are present. - Introduced RabbitMqContainerFixture method for restarting RabbitMQ container during tests. - Added integration tests for RabbitMq to verify connection recovery after broker restarts. - Created new BinaryCallGraphExtractorTests, GoCallGraphExtractorTests, and PythonCallGraphExtractorTests for comprehensive coverage of binary, Go, and Python call graph extraction functionalities. - Developed ConnectionManagerTests to validate connection handling, including rejection of invalid hello messages and proper cleanup on client disconnects.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { signal } from '@angular/core';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { WitnessModalComponent } from './witness-modal.component';
|
||||
import {
|
||||
@@ -19,7 +20,7 @@ import { WitnessMockClient } from '../../core/api/witness.client';
|
||||
describe('WitnessModalComponent', () => {
|
||||
let component: WitnessModalComponent;
|
||||
let fixture: ComponentFixture<WitnessModalComponent>;
|
||||
let mockWitnessClient: jest.Mocked<WitnessMockClient>;
|
||||
let mockWitnessClient: jasmine.SpyObj<WitnessMockClient>;
|
||||
|
||||
const mockWitness: ReachabilityWitness = {
|
||||
witnessId: 'witness-001',
|
||||
@@ -64,24 +65,24 @@ describe('WitnessModalComponent', () => {
|
||||
evidence: {
|
||||
callGraphHash: 'blake3:a1b2c3d4e5f6',
|
||||
surfaceHash: 'sha256:9f8e7d6c5b4a',
|
||||
analysisMethod: 'static',
|
||||
},
|
||||
signature: {
|
||||
keyId: 'attestor-stellaops-ed25519',
|
||||
algorithm: 'ed25519',
|
||||
signatureValue: 'base64-signature-value',
|
||||
signedAt: '2025-12-18T10:30:00Z',
|
||||
signature: 'base64-signature-value',
|
||||
},
|
||||
observedAt: '2025-12-18T10:30:00Z',
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
mockWitnessClient = {
|
||||
verifySignature: jest.fn(),
|
||||
getWitnessById: jest.fn(),
|
||||
getWitnessForVulnerability: jest.fn(),
|
||||
listWitnessesByScan: jest.fn(),
|
||||
exportWitness: jest.fn(),
|
||||
} as unknown as jest.Mocked<WitnessMockClient>;
|
||||
mockWitnessClient = jasmine.createSpyObj('WitnessMockClient', [
|
||||
'verifyWitness',
|
||||
'getWitness',
|
||||
'getWitnessesForVuln',
|
||||
'listWitnesses',
|
||||
'downloadWitnessJson',
|
||||
]);
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [WitnessModalComponent],
|
||||
@@ -120,7 +121,7 @@ describe('WitnessModalComponent', () => {
|
||||
|
||||
it('should show path visualization for reachable vulns', () => {
|
||||
expect(component.pathData()).toBeDefined();
|
||||
expect(component.pathData()?.steps.length).toBeGreaterThan(0);
|
||||
expect(component.pathData()?.callPath.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -159,28 +160,30 @@ describe('WitnessModalComponent', () => {
|
||||
|
||||
it('should verify signature on button click', async () => {
|
||||
const mockResult: WitnessVerificationResult = {
|
||||
witnessId: 'witness-001',
|
||||
verified: true,
|
||||
keyId: 'attestor-stellaops-ed25519',
|
||||
algorithm: 'ed25519',
|
||||
message: 'Signature valid',
|
||||
verifiedAt: '2025-12-18T10:30:00Z',
|
||||
};
|
||||
mockWitnessClient.verifySignature.mockReturnValue(Promise.resolve(mockResult));
|
||||
mockWitnessClient.verifyWitness.and.returnValue(of(mockResult));
|
||||
|
||||
await component.verifySignature();
|
||||
|
||||
expect(mockWitnessClient.verifySignature).toHaveBeenCalledWith(mockWitness);
|
||||
expect(mockWitnessClient.verifyWitness).toHaveBeenCalled();
|
||||
expect(component.verificationResult()).toEqual(mockResult);
|
||||
});
|
||||
|
||||
it('should handle verification failure', async () => {
|
||||
const failedResult: WitnessVerificationResult = {
|
||||
witnessId: 'witness-001',
|
||||
verified: false,
|
||||
keyId: 'attestor-stellaops-ed25519',
|
||||
algorithm: 'ed25519',
|
||||
message: 'Invalid signature',
|
||||
verifiedAt: '2025-12-18T10:30:00Z',
|
||||
error: 'Signature mismatch',
|
||||
};
|
||||
mockWitnessClient.verifySignature.mockReturnValue(Promise.resolve(failedResult));
|
||||
mockWitnessClient.verifyWitness.and.returnValue(of(failedResult));
|
||||
|
||||
await component.verifySignature();
|
||||
|
||||
@@ -199,15 +202,15 @@ describe('WitnessModalComponent', () => {
|
||||
it('should generate JSON download', () => {
|
||||
// Mock URL.createObjectURL and document.createElement
|
||||
const mockUrl = 'blob:mock-url';
|
||||
global.URL.createObjectURL = jest.fn().mockReturnValue(mockUrl);
|
||||
global.URL.revokeObjectURL = jest.fn();
|
||||
spyOn(URL, 'createObjectURL').and.returnValue(mockUrl);
|
||||
spyOn(URL, 'revokeObjectURL');
|
||||
|
||||
const mockAnchor = {
|
||||
href: '',
|
||||
download: '',
|
||||
click: jest.fn(),
|
||||
click: jasmine.createSpy('click'),
|
||||
};
|
||||
jest.spyOn(document, 'createElement').mockReturnValue(mockAnchor as unknown as HTMLAnchorElement);
|
||||
spyOn(document, 'createElement').and.returnValue(mockAnchor as unknown as HTMLAnchorElement);
|
||||
|
||||
component.downloadJson();
|
||||
|
||||
@@ -225,20 +228,18 @@ describe('WitnessModalComponent', () => {
|
||||
});
|
||||
|
||||
it('should copy witness ID to clipboard', async () => {
|
||||
const mockClipboard = {
|
||||
writeText: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
Object.assign(navigator, { clipboard: mockClipboard });
|
||||
const writeTextSpy = jasmine.createSpy('writeText').and.returnValue(Promise.resolve(undefined));
|
||||
Object.assign(navigator, { clipboard: { writeText: writeTextSpy } });
|
||||
|
||||
await component.copyWitnessId();
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledWith('witness-001');
|
||||
expect(writeTextSpy).toHaveBeenCalledWith('witness-001');
|
||||
});
|
||||
});
|
||||
|
||||
describe('modal behavior', () => {
|
||||
it('should emit close event on backdrop click', () => {
|
||||
const closeSpy = jest.fn();
|
||||
const closeSpy = jasmine.createSpy('close');
|
||||
component.close.subscribe(closeSpy);
|
||||
|
||||
fixture.componentRef.setInput('witness', mockWitness);
|
||||
@@ -252,7 +253,7 @@ describe('WitnessModalComponent', () => {
|
||||
});
|
||||
|
||||
it('should not emit close when clicking modal content', () => {
|
||||
const closeSpy = jest.fn();
|
||||
const closeSpy = jasmine.createSpy('close');
|
||||
component.close.subscribe(closeSpy);
|
||||
|
||||
fixture.componentRef.setInput('witness', mockWitness);
|
||||
@@ -278,7 +279,7 @@ describe('WitnessModalComponent', () => {
|
||||
expect(pathData?.entrypoint).toBeDefined();
|
||||
expect(pathData?.entrypoint?.symbol).toBe('UserController.getUser');
|
||||
expect(pathData?.sink?.symbol).toBe('JsonParser.parse');
|
||||
expect(pathData?.steps.length).toBe(3);
|
||||
expect(pathData?.callPath.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should include gates in path data', () => {
|
||||
|
||||
Reference in New Issue
Block a user