fix(sep-2243): collapse check IDs to one-per-requirement (#287)
The sep-2243 scenario check IDs drifted from the requirement-traceability yaml in #259 — the code emitted one ID per test case while the yaml declares one per normative requirement, so the IDs no longer matched. Rename the emitted IDs so a check ID maps to a single MUST/SHOULD and is emitted once per case (the per-case detail moves to name/description), matching the repo's existing 'same id, vary status/message' convention: - mcp-method-header-* / mcp-name-header-* -> client-includes-standard-headers - reject-invalid-tool-* / keep-valid-tool -> client-reject-invalid-tool - server-accepts-{lower,upper}case-name -> header-name-case-insensitive - server reject status checks (mismatch/missing/case x method/name) -> server-reject-invalid-headers - their error-code variants -> server-reject-error-code Merge the yaml's server-reject-mismatch + server-reject-status into one server-reject-invalid-headers MUST (HTTP 400 on a header-validation failure); keep server-reject-error-code as the SHOULD. Base64/custom-header rejection checks keep their own param-validation IDs (out of scope here). Gates and the whitespace-acceptance check keep their scenario-matching names. No behavior change — only check IDs, descriptions, and the yaml.
This commit is contained in:
parent
5c1b815cd1
commit
70f7ba0004
3 changed files with 48 additions and 23 deletions
|
|
@ -626,7 +626,7 @@ export class HttpInvalidToolHeadersScenario extends BaseHttpScenario {
|
|||
// Check that valid_tool WAS called — proves client kept valid tools
|
||||
const validToolCalled = this.calledTools.has('valid_tool');
|
||||
this.checks.push({
|
||||
id: 'sep-2243-keep-valid-tool',
|
||||
id: 'sep-2243-client-reject-invalid-tool',
|
||||
name: 'ClientKeepsValidTool',
|
||||
description: 'Client MUST keep valid tools while excluding invalid ones',
|
||||
status: validToolCalled ? 'SUCCESS' : 'FAILURE',
|
||||
|
|
@ -654,7 +654,7 @@ export class HttpInvalidToolHeadersScenario extends BaseHttpScenario {
|
|||
for (const toolName of invalidTools) {
|
||||
const called = this.calledTools.has(toolName);
|
||||
this.checks.push({
|
||||
id: `sep-2243-reject-invalid-tool-${toolName.replace(/_/g, '-')}`,
|
||||
id: 'sep-2243-client-reject-invalid-tool',
|
||||
name: `ClientRejectsInvalidTool_${toolName}`,
|
||||
description: `Client MUST NOT call tool '${toolName}' with invalid x-mcp-header`,
|
||||
status: called ? 'FAILURE' : 'SUCCESS',
|
||||
|
|
|
|||
|
|
@ -31,14 +31,19 @@ describe('HttpStandardHeadersScenario (SEP-2243) — negative', () => {
|
|||
});
|
||||
}
|
||||
|
||||
it('FAILs sep-2243-mcp-method-header-initialize when Mcp-Method is missing', async () => {
|
||||
// The coarse check id is emitted once per method/name case, so we narrow to
|
||||
// the initialize Mcp-Method emission via its (case-specific) name.
|
||||
const COARSE_ID = 'sep-2243-client-includes-standard-headers';
|
||||
const INIT_METHOD_NAME = 'ClientMcpMethodHeader_initialize';
|
||||
|
||||
it('FAILs the initialize Mcp-Method emission when Mcp-Method is missing', async () => {
|
||||
const scenario = new HttpStandardHeadersScenario();
|
||||
const { serverUrl } = await scenario.start();
|
||||
try {
|
||||
await postInitialize(serverUrl, {}); // no Mcp-Method header
|
||||
const checks = scenario.getChecks();
|
||||
const check = checks.find(
|
||||
(c) => c.id === 'sep-2243-mcp-method-header-initialize'
|
||||
(c) => c.id === COARSE_ID && c.name === INIT_METHOD_NAME
|
||||
);
|
||||
expect(check?.status).toBe('FAILURE');
|
||||
} finally {
|
||||
|
|
@ -46,14 +51,14 @@ describe('HttpStandardHeadersScenario (SEP-2243) — negative', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('SUCCEEDs sep-2243-mcp-method-header-initialize when Mcp-Method matches', async () => {
|
||||
it('SUCCEEDs the initialize Mcp-Method emission when Mcp-Method matches', async () => {
|
||||
const scenario = new HttpStandardHeadersScenario();
|
||||
const { serverUrl } = await scenario.start();
|
||||
try {
|
||||
await postInitialize(serverUrl, { 'Mcp-Method': 'initialize' });
|
||||
const checks = scenario.getChecks();
|
||||
const check = checks.find(
|
||||
(c) => c.id === 'sep-2243-mcp-method-header-initialize'
|
||||
(c) => c.id === COARSE_ID && c.name === INIT_METHOD_NAME
|
||||
);
|
||||
expect(check?.status).toBe('SUCCESS');
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export class HttpStandardHeadersScenario extends BaseHttpScenario {
|
|||
for (const method of expectedMethods) {
|
||||
if (!this.methodHeaderChecks.has(method)) {
|
||||
result.push({
|
||||
id: `sep-2243-mcp-method-header-${method.replace(/\//g, '-')}`,
|
||||
id: 'sep-2243-client-includes-standard-headers',
|
||||
name: `ClientMcpMethodHeader_${method.replace(/\//g, '_')}`,
|
||||
description: `Client sends correct Mcp-Method header on ${method} request`,
|
||||
status: 'SKIPPED',
|
||||
|
|
@ -68,7 +68,7 @@ export class HttpStandardHeadersScenario extends BaseHttpScenario {
|
|||
for (const method of expectedNameMethods) {
|
||||
if (!this.nameHeaderChecks.has(method)) {
|
||||
result.push({
|
||||
id: `sep-2243-mcp-name-header-${method.replace(/\//g, '-')}`,
|
||||
id: 'sep-2243-client-includes-standard-headers',
|
||||
name: `ClientMcpNameHeader_${method.replace(/\//g, '_')}`,
|
||||
description: `Client sends correct Mcp-Name header on ${method} request`,
|
||||
status: 'SKIPPED',
|
||||
|
|
@ -141,7 +141,7 @@ export class HttpStandardHeadersScenario extends BaseHttpScenario {
|
|||
this.methodHeaderChecks.set(method, errors.length === 0);
|
||||
|
||||
this.checks.push({
|
||||
id: `sep-2243-mcp-method-header-${method.replace(/\//g, '-')}`,
|
||||
id: 'sep-2243-client-includes-standard-headers',
|
||||
name: `ClientMcpMethodHeader_${method.replace(/\//g, '_')}`,
|
||||
description: `Client sends correct Mcp-Method header on ${method} request`,
|
||||
status: errors.length === 0 ? 'SUCCESS' : 'FAILURE',
|
||||
|
|
@ -186,7 +186,7 @@ export class HttpStandardHeadersScenario extends BaseHttpScenario {
|
|||
this.nameHeaderChecks.set(method, errors.length === 0);
|
||||
|
||||
this.checks.push({
|
||||
id: `sep-2243-mcp-name-header-${method.replace(/\//g, '-')}`,
|
||||
id: 'sep-2243-client-includes-standard-headers',
|
||||
name: `ClientMcpNameHeader_${method.replace(/\//g, '_')}`,
|
||||
description: `Client sends correct Mcp-Name header on ${method} request`,
|
||||
status: errors.length === 0 ? 'SUCCESS' : 'FAILURE',
|
||||
|
|
|
|||
Loading…
Reference in a new issue