import { describe, it, expect } from 'vitest';
import { deleteManagedObjectTool } from '../../../src/tools/managedObjects/deleteManagedObject.js';
import { snapshotTest } from '../../helpers/snapshotTest.js';
import { setupTestEnvironment } from '../../helpers/testEnvironment.js';
import { server } from '../../setup.js';
import { http, HttpResponse } from 'msw';
describe('deleteManagedObject', () => {
const getSpy = setupTestEnvironment();
// ===== SNAPSHOT TEST =====
it('should match tool schema snapshot', async () => {
await snapshotTest('deleteManagedObject', deleteManagedObjectTool);
});
// ===== REQUEST CONSTRUCTION TESTS =====
describe('Request Construction', () => {
const requestCases = [
{
name: 'constructs URL with objectType and objectId',
input: { objectType: 'alpha_user', objectId: 'obj-123' },
assert: ({ url, scopes, options }: any) => {
expect(url).toBe('https://test.forgeblocks.com/openidm/managed/alpha_user/obj-123');
expect(scopes).toEqual(['fr:idm:*']);
expect(options).toEqual(expect.objectContaining({ method: 'DELETE' }));
}
},
{
name: 'uses DELETE method and scopes',
input: { objectType: 'alpha_user', objectId: 'obj-123' },
assert: ({ scopes, options }: any) => {
expect(scopes).toEqual(['fr:idm:*']);
expect(options).toEqual(expect.objectContaining({ method: 'DELETE' }));
}
}
];
it.each(requestCases)('$name', async ({ input, assert }) => {
await deleteManagedObjectTool.toolFunction(input as any);
const [url, scopes, options] = getSpy().mock.calls.at(-1)!;
assert({ url, scopes, options });
});
});
// ===== RESPONSE HANDLING TESTS =====
describe('Response Handling', () => {
it('should format successful response with deleted ID', async () => {
server.use(
http.delete('https://*/openidm/managed/:objectType/:objectId', ({ request, params }) => {
const authHeader = request.headers.get('Authorization');
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return new HttpResponse(JSON.stringify({ error: 'unauthorized' }), { status: 401 });
}
return HttpResponse.json({
_id: params.objectId as string,
_rev: '1'
});
})
);
const result = await deleteManagedObjectTool.toolFunction({
objectType: 'alpha_user',
objectId: 'obj-123'
});
expect(result.content[0].text).toContain('Deleted managed object');
expect(result.content[0].text).toContain('obj-123');
expect(result.content[0].text).toContain('alpha_user');
expect(result.content[0].type).toBe('text');
});
});
// ===== INPUT VALIDATION TESTS =====
describe('Input Validation', () => {
it('should reject empty objectType string', () => {
const schema = deleteManagedObjectTool.inputSchema.objectType;
expect(() => schema.parse('')).toThrow();
});
it('should accept standard object types', () => {
const schema = deleteManagedObjectTool.inputSchema.objectType;
expect(() => schema.parse('alpha_user')).not.toThrow();
expect(() => schema.parse('bravo_role')).not.toThrow();
});
it('should accept any non-empty object type string', () => {
const schema = deleteManagedObjectTool.inputSchema.objectType;
expect(() => schema.parse('alpha_device')).not.toThrow();
expect(() => schema.parse('custom_application')).not.toThrow();
});
it('should use safePathSegmentSchema for objectId', () => {
const schema = deleteManagedObjectTool.inputSchema.objectId;
expect(() => schema.parse('../etc/passwd')).toThrow(/path traversal/);
expect(() => schema.parse('')).toThrow(/cannot be empty/);
expect(() => schema.parse('ValidObjectId-123')).not.toThrow();
});
});
// ===== ERROR HANDLING TESTS =====
describe('Error Handling', () => {
it.each([
{
name: 'handles 401 Unauthorized error',
status: 401,
body: { error: 'unauthorized', message: 'Invalid token' },
matcher: /401|[Uu]nauthorized/
},
{
name: 'handles 404 Not Found error',
status: 404,
body: { error: 'not_found', message: 'Object does not exist' },
matcher: /404|[Nn]ot [Ff]ound/
},
{
name: 'handles 403 Forbidden error',
status: 403,
body: { error: 'forbidden', message: 'Insufficient permissions' },
matcher: /403|[Ff]orbidden/
}
])('$name', async ({ status, body, matcher }) => {
server.use(
http.delete('https://*/openidm/managed/:objectType/:objectId', () => {
return new HttpResponse(JSON.stringify(body), { status });
})
);
const result = await deleteManagedObjectTool.toolFunction({
objectType: 'alpha_user',
objectId: 'obj-123'
});
expect(result.content[0].text).toContain('Failed to delete managed object');
expect(result.content[0].text).toMatch(matcher);
});
});
});