Files
sentryagent-idp/tests/unit/services/MarketplaceService.test.ts
SentryAgent.ai Developer 5e580b51dd fix(tests): resolve 4 failing test suites and patch lodash vulnerability
Test fixes (type mismatches introduced by V&V resolution changes):
- HealthDetailedController.test.ts: replace pool/makePool with dbProbe/makeDbProbe
  to match refactored HealthDetailedDeps interface (Pool → DbProbe abstraction)
- EventPublisher.test.ts: pass all 4 required constructor args to WebhookDeliveryWorker
  mock (pool, vaultClient, redisClient, redisUrl) — was passing only 1
- MarketplaceService.test.ts: IAgent.did/didCreatedAt are string|undefined (not null);
  fix makeAgent defaults and makeAgent({did:null}) call; fix type assertion to unknown first
- OIDCTrustPolicyService.test.ts: ICreateTrustPolicyRequest.branch is string|undefined
  (not nullable); replace all branch:null with branch:undefined

Security fix:
- npm audit fix: lodash ≤4.17.23 (HIGH) → patched; 0 vulnerabilities remaining

Result: 50/50 test suites pass, 722/722 tests pass, 0 vulnerabilities

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 08:40:23 +00:00

118 lines
4.1 KiB
TypeScript

/**
* Unit tests for src/services/MarketplaceService.ts
*/
import { MarketplaceService } from '../../../src/services/MarketplaceService';
import { AgentRepository } from '../../../src/repositories/AgentRepository';
import { AgentNotFoundError } from '../../../src/utils/errors';
import { IAgent, IMarketplaceFilters } from '../../../src/types/index';
jest.mock('../../../src/repositories/AgentRepository');
const MockAgentRepo = AgentRepository as jest.MockedClass<typeof AgentRepository>;
const BASE_FILTERS: IMarketplaceFilters = { page: 1, limit: 10 };
function makeAgent(overrides: Partial<IAgent> = {}): IAgent {
return {
agentId: 'agent-001',
organizationId: 'org-001',
email: 'agent@example.com',
agentType: 'screener',
version: 'v1.0.0',
capabilities: ['resume:read'],
owner: 'test-team',
deploymentEnv: 'production',
status: 'active',
isPublic: true,
createdAt: new Date('2026-01-01'),
updatedAt: new Date('2026-01-02'),
did: undefined,
didCreatedAt: undefined,
...overrides,
};
}
describe('MarketplaceService', () => {
let service: MarketplaceService;
let agentRepo: jest.Mocked<AgentRepository>;
beforeEach(() => {
jest.clearAllMocks();
agentRepo = new MockAgentRepo({} as never) as jest.Mocked<AgentRepository>;
service = new MarketplaceService(agentRepo);
});
describe('listPublicAgents()', () => {
it('should return mapped agent cards', async () => {
const agent = makeAgent();
agentRepo.findPublicAgents = jest.fn().mockResolvedValue({ agents: [agent], total: 1 });
const result = await service.listPublicAgents(BASE_FILTERS);
expect(result.data).toHaveLength(1);
expect(result.data[0].agentId).toBe('agent-001');
expect(result.total).toBe(1);
expect(result.page).toBe(1);
expect(result.limit).toBe(10);
});
it('should strip private fields (email, organizationId) from cards', async () => {
const agent = makeAgent();
agentRepo.findPublicAgents = jest.fn().mockResolvedValue({ agents: [agent], total: 1 });
const result = await service.listPublicAgents(BASE_FILTERS);
const card = result.data[0] as unknown as Record<string, unknown>;
expect(card['email']).toBeUndefined();
expect(card['organizationId']).toBeUndefined();
});
it('should include a minimal DID document when agent has a DID', async () => {
const agent = makeAgent({ did: 'did:web:sentryagent.ai:agents:agent-001' });
agentRepo.findPublicAgents = jest.fn().mockResolvedValue({ agents: [agent], total: 1 });
const result = await service.listPublicAgents(BASE_FILTERS);
expect(result.data[0].didDocument).not.toBeNull();
expect(result.data[0].didDocument?.id).toBe('did:web:sentryagent.ai:agents:agent-001');
});
it('should return null DID document when agent has no DID', async () => {
const agent = makeAgent({ did: undefined });
agentRepo.findPublicAgents = jest.fn().mockResolvedValue({ agents: [agent], total: 1 });
const result = await service.listPublicAgents(BASE_FILTERS);
expect(result.data[0].didDocument).toBeNull();
});
it('should return empty data array when no public agents exist', async () => {
agentRepo.findPublicAgents = jest.fn().mockResolvedValue({ agents: [], total: 0 });
const result = await service.listPublicAgents(BASE_FILTERS);
expect(result.data).toHaveLength(0);
expect(result.total).toBe(0);
});
});
describe('getPublicAgent()', () => {
it('should return a card for a public agent', async () => {
const agent = makeAgent();
agentRepo.findPublicById = jest.fn().mockResolvedValue(agent);
const card = await service.getPublicAgent('agent-001');
expect(card.agentId).toBe('agent-001');
expect(card.owner).toBe('test-team');
});
it('should throw AgentNotFoundError when agent is not found', async () => {
agentRepo.findPublicById = jest.fn().mockResolvedValue(null);
await expect(service.getPublicAgent('nonexistent')).rejects.toThrow(AgentNotFoundError);
});
});
});