import * as fc from "fast-check";
/**
* Feature: mcp-debugger-tool, Property 20: Response format consistency
* Validates: Requirements 9.1, 9.2
*
* For any debugging operation, the MCP Server should return a structured JSON response
* containing an operation status field and either a results object or an error object
* with code, message, and context.
*/
describe("MCP ACS Debugger Server - Response Format Consistency", () => {
/**
* Helper to validate response structure
*/
function validateResponseStructure(response: any): boolean {
// Must have a status field
if (!response.status) {
return false;
}
// If status is 'success', should have result fields
if (response.status === "success") {
return true; // Success responses can have various result fields
}
// If status is 'error', must have code and message
if (response.status === "error") {
return (
typeof response.code === "string" &&
typeof response.message === "string"
);
}
return false;
}
it("should validate success response structure", () => {
const successResponse = {
status: "success",
sessionId: "test-session-id",
state: "paused",
};
expect(validateResponseStructure(successResponse)).toBe(true);
});
it("should validate error response structure", () => {
const errorResponse = {
status: "error",
code: "SESSION_NOT_FOUND",
message: "Session not found",
};
expect(validateResponseStructure(errorResponse)).toBe(true);
});
it("should reject invalid response structure without status", () => {
const invalidResponse = {
sessionId: "test-session-id",
};
expect(validateResponseStructure(invalidResponse)).toBe(false);
});
it("should reject error response without code", () => {
const invalidErrorResponse = {
status: "error",
message: "Error message",
};
expect(validateResponseStructure(invalidErrorResponse)).toBe(false);
});
it("should reject error response without message", () => {
const invalidErrorResponse = {
status: "error",
code: "ERROR_CODE",
};
expect(validateResponseStructure(invalidErrorResponse)).toBe(false);
});
/**
* Property test: All response structures should be consistent
* This tests various response formats to ensure they follow the spec
*/
it("property: all success responses have status field", () => {
fc.assert(
fc.property(
fc.record({
status: fc.constant("success"),
sessionId: fc.string(),
state: fc.constantFrom("paused", "running", "terminated"),
}),
(response: any) => {
expect(validateResponseStructure(response)).toBe(true);
expect(response.status).toBe("success");
}
),
{ numRuns: 100 }
);
});
/**
* Property test: All error responses have required fields
*/
it("property: all error responses have code and message", () => {
fc.assert(
fc.property(
fc.record({
status: fc.constant("error"),
code: fc.constantFrom(
"SESSION_NOT_FOUND",
"BREAKPOINT_SET_FAILED",
"CONTINUE_FAILED",
"STEP_OVER_FAILED",
"INSPECT_FAILED",
"GET_STACK_FAILED",
"HANG_DETECTION_FAILED"
),
message: fc.string({ minLength: 1 }),
}),
(response: any) => {
expect(validateResponseStructure(response)).toBe(true);
expect(response.status).toBe("error");
expect(typeof response.code).toBe("string");
expect(typeof response.message).toBe("string");
expect(response.message.length).toBeGreaterThan(0);
}
),
{ numRuns: 100 }
);
});
/**
* Property test: Response format is consistent across different tool responses
*/
it("property: response format is consistent for all tool types", () => {
fc.assert(
fc.property(
fc.oneof(
// Success responses
fc.record({
status: fc.constant("success"),
sessionId: fc.string(),
state: fc.string(),
}),
fc.record({
status: fc.constant("success"),
breakpointId: fc.string(),
file: fc.string(),
line: fc.integer({ min: 1 }),
}),
fc.record({
status: fc.constant("success"),
state: fc.string(),
location: fc.record({
file: fc.string(),
line: fc.integer({ min: 1 }),
}),
}),
// Error responses
fc.record({
status: fc.constant("error"),
code: fc.string({ minLength: 1 }),
message: fc.string({ minLength: 1 }),
})
),
(response: any) => {
expect(validateResponseStructure(response)).toBe(true);
}
),
{ numRuns: 100 }
);
});
});