From 391040b5acea063be148a52f7b6cec9477bf2c13 Mon Sep 17 00:00:00 2001 From: robbond Date: Wed, 25 Mar 2026 11:08:52 +0000 Subject: [PATCH] test(phase7): lock downloadBlob file-client delegation --- memory-bank/change-log.md | 37 +++++++++++++++++++++++++ tests/phase7/service-behaviour.test.cjs | 30 ++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/memory-bank/change-log.md b/memory-bank/change-log.md index 66e0c7fe..267cca9c 100644 --- a/memory-bank/change-log.md +++ b/memory-bank/change-log.md @@ -2346,3 +2346,40 @@ Validation: Follow-ups: - Optional next bounded slice: add a focused phase6/phase7 behavioural assertion for `documentDirectService.downloadBlob` to explicitly lock the `downloadFileBlob` delegation contract. + +--- + +### CL-067: TASK22260 next slice — phase7 downloadBlob delegation behavioural lock + +date: 2026-03-25 +author: Cline +scope: `tests/phase7/service-behaviour.test.cjs` +type: change +rationale: Execute the queued follow-up by adding explicit phase7 behavioural coverage for `documentDirectService.downloadBlob` so file-client delegation and blob request config remain contract-stable. +impact: Increases regression confidence for document download helper behaviour after `fileClient` extraction, without runtime code changes. +status: completed + +Summary: + +- Added new phase7 behavioural test: + - `document/downloadBlob delegates blob request config via file client helper` +- The test asserts: + - `downloadBlob` lower-cases container in URL composition + - request is issued through config-style request path (`axios.request` in harness) + - request method is `get` + - `responseType` is `blob` + - returned payload contract is preserved from request helper data. + +Validation: + +- `node tests/phase7/service-behaviour.test.cjs` -> pass (13/13) +- `node tests/phase22/index.test.cjs` -> pass + - core-token: 2/2 + - client-utils: 5/5 + - file-client: 3/3 + - phase22 combined: pass +- `npm run lint` -> warnings only (pre-existing `react-hooks/exhaustive-deps`; no new lint errors) + +Follow-ups: + +- Optional next bounded slice: evaluate adding equivalent focused behavioural coverage in phase6 if download helper behavior becomes part of that suite’s scope. diff --git a/tests/phase7/service-behaviour.test.cjs b/tests/phase7/service-behaviour.test.cjs index d456b7e8..fb008ae4 100644 --- a/tests/phase7/service-behaviour.test.cjs +++ b/tests/phase7/service-behaviour.test.cjs @@ -215,6 +215,36 @@ test("document delete blob flows use signer hash", async () => { ); }); +test("document/downloadBlob delegates blob request config via file client helper", async () => { + const axios = createAxiosMock(); + const logger = createLoggerMock(); + + axios.requestHandler = async (config) => { + return { data: { type: "blob", url: config.url } }; + }; + + const document = loadServiceModule("documentDirectService.js", { + axios, + BASE_URL: "http://example.local", + consoleLogger: logger.consoleLogger, + hashAPIPath: () => "" + }); + + const result = await document.downloadBlob( + "MyContainer", + "folder/file.pdf" + ); + + assert.deepStrictEqual(normalize(result), { + type: "blob", + url: "http://example.local/api/file/downloadblob?container=mycontainer&blobname=folder/file.pdf" + }); + assert.strictEqual(axios.calls.length, 1); + assert.strictEqual(axios.calls[0].type, "request"); + assert.strictEqual(axios.calls[0].config.method, "get"); + assert.strictEqual(axios.calls[0].config.responseType, "blob"); +}); + test("account/getPortalLogin appends hash and returns res.data", async () => { const axios = createAxiosMock(); const logger = createLoggerMock();