Skip to content

Commit 457c3cc

Browse files
feat(parity): 15 new MCP tools + CLI↔MCP e2e test harness
MCP parity (CLI↔MCP symmetry for PR 103's new commands): - cts_update_transport, cts_reassign_transport, cts_search_transports - stat_package, get_package - lookup_user - run_abap (creates temp class, POST /oo/classrun, deletes) - get_domain, get_data_element, get_structure (+source) - get_cds_ddl, get_cds_dcl (+source) - import_object, import_package, import_transport (wrap adt-cli ImportService; tmp dir in tests) - create_object / delete_object extended with DOMA, DTEL, TABL, STRUCT, DDLS, DCLS dispatch (DDIC/CDS creation via typed contracts, wrapper keys match schema: domain / wbobj / blueSource / source). - Mock routes (adt-fixtures) extended: object-root GET/POST/PUT/DELETE for CLAS/INTF/PROG/FUGR, every DDIC/CDS path (including source.main), oo/classrun POST, cts/transports?_action=FIND, useraction flows, searchconfiguration/metadata. adt-mcp/tests/integration.test.ts: 83/83 pass including smoke tests for every new tool. CLI↔MCP parity harness (packages/adt-cli/tests/e2e/): - harness.ts: startAdtHarness() boots the shared mock server, builds one AdtClient, wires both CLI (via __setTestAdtClient DI hook) and an in-memory MCP server at the same mock port. Commander program is built once per harness with exitOverride; runCliCommand captures stdout/stderr/exit. callMcpTool invokes via @modelcontextprotocol/sdk InMemoryTransport. assertParity runs both paths against the same fixtures and invokes a supplied expect() callback. - parity.cts.test.ts (10 tests): list/get/create/release/reassign/ delete/search/update transports. - parity.objects.test.ts (16 tests): CRUD for class, program, interface; package get/list/activate/delete/stat. - parity.ddic-cds.test.ts (16 tests): domain, dataelement, table, structure, DDL, DCL CRUD + source get. - parity.misc.test.ts (24 tests): check (single + package), osql, run_abap, user (current/exact/search), lock/unlock, source get/put, info, discovery. - smoke.test.ts (4 tests): harness self-test. Totals: 70 parity tests, 68 pass, 2 it.todo (documented reasons: cts tr set uses custom AdkContext bypassing global lockService; check_syntax MCP tool lacks packageName param). src/lib/utils/adt-client-v2.ts: adds __setTestAdtClient DI hook that short-circuits getAdtClientV2() in tests (bypasses disk auth + ADK init). Initialization is called once inside the harness. bun.lock: regenerated. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent d25885b commit 457c3cc

28 files changed

Lines changed: 3620 additions & 4 deletions

packages/adt-cli/src/lib/utils/adt-client-v2.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,32 @@ import {
5858
resetCaptured,
5959
} from '../shared/adt-client';
6060

61+
// =============================================================================
62+
// Test DI hook (internal, used by tests/e2e harness)
63+
// =============================================================================
64+
65+
let __testAdtClientOverride: AdtClient | null = null;
66+
67+
/**
68+
* @internal
69+
* Install or clear a test AdtClient instance. When set, `getAdtClientV2()` will
70+
* return this client instead of loading credentials from disk and constructing
71+
* a real client. Intended solely for e2e harness usage.
72+
*
73+
* Pass `null` to clear the override.
74+
*/
75+
export function __setTestAdtClient(client: AdtClient | null): void {
76+
__testAdtClientOverride = client;
77+
}
78+
79+
/**
80+
* @internal
81+
* Inspect the current test override (mostly for diagnostics / test cleanup).
82+
*/
83+
export function __getTestAdtClient(): AdtClient | null {
84+
return __testAdtClientOverride;
85+
}
86+
6187
// =============================================================================
6288
// Client Options
6389
// =============================================================================
@@ -162,6 +188,12 @@ async function tryAutoRefresh(
162188
export async function getAdtClientV2(
163189
options?: AdtClientV2Options,
164190
): Promise<AdtClient> {
191+
// Test DI hook: if a test harness has injected a client, return it.
192+
// Must short-circuit BEFORE touching disk-based auth / CLI context.
193+
if (__testAdtClientOverride) {
194+
return __testAdtClientOverride;
195+
}
196+
165197
// Merge with global CLI context (explicit options take precedence)
166198
const ctx = getCliContext();
167199
const effectiveOptions = {

0 commit comments

Comments
 (0)