@streetjs/storage 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/drivers/local.d.ts +8 -0
- package/dist/drivers/local.d.ts.map +1 -1
- package/dist/drivers/local.js +18 -3
- package/dist/drivers/local.js.map +1 -1
- package/dist/tests/contract.d.ts +19 -0
- package/dist/tests/contract.d.ts.map +1 -1
- package/dist/tests/contract.js +28 -0
- package/dist/tests/contract.js.map +1 -1
- package/package.json +10 -6
- package/dist/tests/access.test.d.ts +0 -2
- package/dist/tests/access.test.d.ts.map +0 -1
- package/dist/tests/access.test.js +0 -270
- package/dist/tests/access.test.js.map +0 -1
- package/dist/tests/azure-driver.test.d.ts +0 -2
- package/dist/tests/azure-driver.test.d.ts.map +0 -1
- package/dist/tests/azure-driver.test.js +0 -183
- package/dist/tests/azure-driver.test.js.map +0 -1
- package/dist/tests/backblaze-driver.test.d.ts +0 -2
- package/dist/tests/backblaze-driver.test.d.ts.map +0 -1
- package/dist/tests/backblaze-driver.test.js +0 -185
- package/dist/tests/backblaze-driver.test.js.map +0 -1
- package/dist/tests/bridge-degradation.test.d.ts +0 -2
- package/dist/tests/bridge-degradation.test.d.ts.map +0 -1
- package/dist/tests/bridge-degradation.test.js +0 -138
- package/dist/tests/bridge-degradation.test.js.map +0 -1
- package/dist/tests/cli.test.d.ts +0 -2
- package/dist/tests/cli.test.d.ts.map +0 -1
- package/dist/tests/cli.test.js +0 -127
- package/dist/tests/cli.test.js.map +0 -1
- package/dist/tests/contract.test.d.ts +0 -2
- package/dist/tests/contract.test.d.ts.map +0 -1
- package/dist/tests/contract.test.js +0 -110
- package/dist/tests/contract.test.js.map +0 -1
- package/dist/tests/directory.test.d.ts +0 -2
- package/dist/tests/directory.test.d.ts.map +0 -1
- package/dist/tests/directory.test.js +0 -125
- package/dist/tests/directory.test.js.map +0 -1
- package/dist/tests/errors.test.d.ts +0 -2
- package/dist/tests/errors.test.d.ts.map +0 -1
- package/dist/tests/errors.test.js +0 -93
- package/dist/tests/errors.test.js.map +0 -1
- package/dist/tests/events-bridge.test.d.ts +0 -2
- package/dist/tests/events-bridge.test.d.ts.map +0 -1
- package/dist/tests/events-bridge.test.js +0 -228
- package/dist/tests/events-bridge.test.js.map +0 -1
- package/dist/tests/example-smoke.test.d.ts +0 -2
- package/dist/tests/example-smoke.test.d.ts.map +0 -1
- package/dist/tests/example-smoke.test.js +0 -34
- package/dist/tests/example-smoke.test.js.map +0 -1
- package/dist/tests/gcs-driver.test.d.ts +0 -2
- package/dist/tests/gcs-driver.test.d.ts.map +0 -1
- package/dist/tests/gcs-driver.test.js +0 -197
- package/dist/tests/gcs-driver.test.js.map +0 -1
- package/dist/tests/image.test.d.ts +0 -2
- package/dist/tests/image.test.d.ts.map +0 -1
- package/dist/tests/image.test.js +0 -102
- package/dist/tests/image.test.js.map +0 -1
- package/dist/tests/lifecycle.test.d.ts +0 -2
- package/dist/tests/lifecycle.test.d.ts.map +0 -1
- package/dist/tests/lifecycle.test.js +0 -171
- package/dist/tests/lifecycle.test.js.map +0 -1
- package/dist/tests/local-driver.test.d.ts +0 -2
- package/dist/tests/local-driver.test.d.ts.map +0 -1
- package/dist/tests/local-driver.test.js +0 -153
- package/dist/tests/local-driver.test.js.map +0 -1
- package/dist/tests/local-streaming.test.d.ts +0 -2
- package/dist/tests/local-streaming.test.d.ts.map +0 -1
- package/dist/tests/local-streaming.test.js +0 -121
- package/dist/tests/local-streaming.test.js.map +0 -1
- package/dist/tests/memory-driver.test.d.ts +0 -2
- package/dist/tests/memory-driver.test.d.ts.map +0 -1
- package/dist/tests/memory-driver.test.js +0 -180
- package/dist/tests/memory-driver.test.js.map +0 -1
- package/dist/tests/memory-streaming.test.d.ts +0 -2
- package/dist/tests/memory-streaming.test.d.ts.map +0 -1
- package/dist/tests/memory-streaming.test.js +0 -92
- package/dist/tests/memory-streaming.test.js.map +0 -1
- package/dist/tests/minio-driver.test.d.ts +0 -2
- package/dist/tests/minio-driver.test.d.ts.map +0 -1
- package/dist/tests/minio-driver.test.js +0 -146
- package/dist/tests/minio-driver.test.js.map +0 -1
- package/dist/tests/non-s3-integration.test.d.ts +0 -2
- package/dist/tests/non-s3-integration.test.d.ts.map +0 -1
- package/dist/tests/non-s3-integration.test.js +0 -201
- package/dist/tests/non-s3-integration.test.js.map +0 -1
- package/dist/tests/observability.registration.test.d.ts +0 -2
- package/dist/tests/observability.registration.test.d.ts.map +0 -1
- package/dist/tests/observability.registration.test.js +0 -103
- package/dist/tests/observability.registration.test.js.map +0 -1
- package/dist/tests/observability.test.d.ts +0 -2
- package/dist/tests/observability.test.d.ts.map +0 -1
- package/dist/tests/observability.test.js +0 -240
- package/dist/tests/observability.test.js.map +0 -1
- package/dist/tests/plugin.test.d.ts +0 -2
- package/dist/tests/plugin.test.d.ts.map +0 -1
- package/dist/tests/plugin.test.js +0 -112
- package/dist/tests/plugin.test.js.map +0 -1
- package/dist/tests/prop-concurrent.test.d.ts +0 -2
- package/dist/tests/prop-concurrent.test.d.ts.map +0 -1
- package/dist/tests/prop-concurrent.test.js +0 -59
- package/dist/tests/prop-concurrent.test.js.map +0 -1
- package/dist/tests/prop-copy.test.d.ts +0 -2
- package/dist/tests/prop-copy.test.d.ts.map +0 -1
- package/dist/tests/prop-copy.test.js +0 -63
- package/dist/tests/prop-copy.test.js.map +0 -1
- package/dist/tests/prop-delete.test.d.ts +0 -2
- package/dist/tests/prop-delete.test.d.ts.map +0 -1
- package/dist/tests/prop-delete.test.js +0 -35
- package/dist/tests/prop-delete.test.js.map +0 -1
- package/dist/tests/prop-directory.test.d.ts +0 -2
- package/dist/tests/prop-directory.test.d.ts.map +0 -1
- package/dist/tests/prop-directory.test.js +0 -118
- package/dist/tests/prop-directory.test.js.map +0 -1
- package/dist/tests/prop-driver-conformance.test.d.ts +0 -2
- package/dist/tests/prop-driver-conformance.test.d.ts.map +0 -1
- package/dist/tests/prop-driver-conformance.test.js +0 -110
- package/dist/tests/prop-driver-conformance.test.js.map +0 -1
- package/dist/tests/prop-driver-equivalence.test.d.ts +0 -2
- package/dist/tests/prop-driver-equivalence.test.d.ts.map +0 -1
- package/dist/tests/prop-driver-equivalence.test.js +0 -163
- package/dist/tests/prop-driver-equivalence.test.js.map +0 -1
- package/dist/tests/prop-lifecycle.test.d.ts +0 -2
- package/dist/tests/prop-lifecycle.test.d.ts.map +0 -1
- package/dist/tests/prop-lifecycle.test.js +0 -83
- package/dist/tests/prop-lifecycle.test.js.map +0 -1
- package/dist/tests/prop-list.test.d.ts +0 -2
- package/dist/tests/prop-list.test.d.ts.map +0 -1
- package/dist/tests/prop-list.test.js +0 -53
- package/dist/tests/prop-list.test.js.map +0 -1
- package/dist/tests/prop-metadata.test.d.ts +0 -2
- package/dist/tests/prop-metadata.test.d.ts.map +0 -1
- package/dist/tests/prop-metadata.test.js +0 -87
- package/dist/tests/prop-metadata.test.js.map +0 -1
- package/dist/tests/prop-move.test.d.ts +0 -2
- package/dist/tests/prop-move.test.d.ts.map +0 -1
- package/dist/tests/prop-move.test.js +0 -67
- package/dist/tests/prop-move.test.js.map +0 -1
- package/dist/tests/prop-multipart-abort.test.d.ts +0 -2
- package/dist/tests/prop-multipart-abort.test.d.ts.map +0 -1
- package/dist/tests/prop-multipart-abort.test.js +0 -48
- package/dist/tests/prop-multipart-abort.test.js.map +0 -1
- package/dist/tests/prop-multipart.test.d.ts +0 -2
- package/dist/tests/prop-multipart.test.d.ts.map +0 -1
- package/dist/tests/prop-multipart.test.js +0 -65
- package/dist/tests/prop-multipart.test.js.map +0 -1
- package/dist/tests/prop-resumable.test.d.ts +0 -2
- package/dist/tests/prop-resumable.test.d.ts.map +0 -1
- package/dist/tests/prop-resumable.test.js +0 -78
- package/dist/tests/prop-resumable.test.js.map +0 -1
- package/dist/tests/prop-search.test.d.ts +0 -2
- package/dist/tests/prop-search.test.d.ts.map +0 -1
- package/dist/tests/prop-search.test.js +0 -120
- package/dist/tests/prop-search.test.js.map +0 -1
- package/dist/tests/prop-signed-url.test.d.ts +0 -2
- package/dist/tests/prop-signed-url.test.d.ts.map +0 -1
- package/dist/tests/prop-signed-url.test.js +0 -74
- package/dist/tests/prop-signed-url.test.js.map +0 -1
- package/dist/tests/prop-streaming.test.d.ts +0 -2
- package/dist/tests/prop-streaming.test.d.ts.map +0 -1
- package/dist/tests/prop-streaming.test.js +0 -34
- package/dist/tests/prop-streaming.test.js.map +0 -1
- package/dist/tests/prop-upload-download.test.d.ts +0 -2
- package/dist/tests/prop-upload-download.test.d.ts.map +0 -1
- package/dist/tests/prop-upload-download.test.js +0 -30
- package/dist/tests/prop-upload-download.test.js.map +0 -1
- package/dist/tests/prop-validation.test.d.ts +0 -2
- package/dist/tests/prop-validation.test.d.ts.map +0 -1
- package/dist/tests/prop-validation.test.js +0 -50
- package/dist/tests/prop-validation.test.js.map +0 -1
- package/dist/tests/prop-versioning.test.d.ts +0 -2
- package/dist/tests/prop-versioning.test.d.ts.map +0 -1
- package/dist/tests/prop-versioning.test.js +0 -74
- package/dist/tests/prop-versioning.test.js.map +0 -1
- package/dist/tests/queue-bridge.test.d.ts +0 -2
- package/dist/tests/queue-bridge.test.d.ts.map +0 -1
- package/dist/tests/queue-bridge.test.js +0 -111
- package/dist/tests/queue-bridge.test.js.map +0 -1
- package/dist/tests/r2-driver.test.d.ts +0 -2
- package/dist/tests/r2-driver.test.d.ts.map +0 -1
- package/dist/tests/r2-driver.test.js +0 -143
- package/dist/tests/r2-driver.test.js.map +0 -1
- package/dist/tests/realtime-bridge.test.d.ts +0 -2
- package/dist/tests/realtime-bridge.test.d.ts.map +0 -1
- package/dist/tests/realtime-bridge.test.js +0 -106
- package/dist/tests/realtime-bridge.test.js.map +0 -1
- package/dist/tests/resumable.test.d.ts +0 -2
- package/dist/tests/resumable.test.d.ts.map +0 -1
- package/dist/tests/resumable.test.js +0 -104
- package/dist/tests/resumable.test.js.map +0 -1
- package/dist/tests/s3-base.test.d.ts +0 -2
- package/dist/tests/s3-base.test.d.ts.map +0 -1
- package/dist/tests/s3-base.test.js +0 -289
- package/dist/tests/s3-base.test.js.map +0 -1
- package/dist/tests/s3-integration.test.d.ts +0 -2
- package/dist/tests/s3-integration.test.d.ts.map +0 -1
- package/dist/tests/s3-integration.test.js +0 -270
- package/dist/tests/s3-integration.test.js.map +0 -1
- package/dist/tests/s3.test.d.ts +0 -2
- package/dist/tests/s3.test.d.ts.map +0 -1
- package/dist/tests/s3.test.js +0 -203
- package/dist/tests/s3.test.js.map +0 -1
- package/dist/tests/scaffold.test.d.ts +0 -2
- package/dist/tests/scaffold.test.d.ts.map +0 -1
- package/dist/tests/scaffold.test.js +0 -13
- package/dist/tests/scaffold.test.js.map +0 -1
- package/dist/tests/search.test.d.ts +0 -2
- package/dist/tests/search.test.d.ts.map +0 -1
- package/dist/tests/search.test.js +0 -106
- package/dist/tests/search.test.js.map +0 -1
- package/dist/tests/supabase-driver.test.d.ts +0 -2
- package/dist/tests/supabase-driver.test.d.ts.map +0 -1
- package/dist/tests/supabase-driver.test.js +0 -196
- package/dist/tests/supabase-driver.test.js.map +0 -1
- package/dist/tests/testing-utilities.test.d.ts +0 -2
- package/dist/tests/testing-utilities.test.d.ts.map +0 -1
- package/dist/tests/testing-utilities.test.js +0 -138
- package/dist/tests/testing-utilities.test.js.map +0 -1
- package/dist/tests/validation.test.d.ts +0 -2
- package/dist/tests/validation.test.d.ts.map +0 -1
- package/dist/tests/validation.test.js +0 -135
- package/dist/tests/validation.test.js.map +0 -1
- package/dist/tests/versioning.test.d.ts +0 -2
- package/dist/tests/versioning.test.d.ts.map +0 -1
- package/dist/tests/versioning.test.js +0 -128
- package/dist/tests/versioning.test.js.map +0 -1
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
// Unit tests for the Events integration bridge wired into the storage facade
|
|
2
|
-
// (task 21.1).
|
|
3
|
-
//
|
|
4
|
-
// Verifies the Requirement 18 / 13.4 semantics over the zero-dependency
|
|
5
|
-
// `memory` provider:
|
|
6
|
-
//
|
|
7
|
-
// - object mutations publish the corresponding typed event through the
|
|
8
|
-
// structural EventsLike bridge: put(new) → storage.uploaded, put(existing) →
|
|
9
|
-
// storage.updated, delete → storage.deleted, move/rename → storage.moved,
|
|
10
|
-
// restoreVersion → storage.restored (18.1).
|
|
11
|
-
// - each payload carries the affected key and (when available) metadata (18.2).
|
|
12
|
-
// - applied lifecycle actions publish through the same bridge (13.4).
|
|
13
|
-
// - a failing events layer never throws into the storage operation path.
|
|
14
|
-
// - with no events bridge configured, publication is a complete no-op.
|
|
15
|
-
// - bridgeStorageEvents is a standalone, never-throwing publisher.
|
|
16
|
-
//
|
|
17
|
-
// Uses the Node.js built-in test runner (node:test); executed via
|
|
18
|
-
// `node --test dist/tests/*.test.js`.
|
|
19
|
-
//
|
|
20
|
-
// Requirements: 13.4, 18.1, 18.2, 18.3, 28.3
|
|
21
|
-
import test from "node:test";
|
|
22
|
-
import assert from "node:assert/strict";
|
|
23
|
-
import { createStorage, bridgeStorageEvents } from "../index.js";
|
|
24
|
-
const DAY = 24 * 60 * 60 * 1000;
|
|
25
|
-
const T0 = 1_700_000_000_000;
|
|
26
|
-
/** A recording EventsLike double capturing every published (event, payload). */
|
|
27
|
-
function recordingEvents() {
|
|
28
|
-
const published = [];
|
|
29
|
-
return {
|
|
30
|
-
published,
|
|
31
|
-
publish(event, payload) {
|
|
32
|
-
published.push({ event, payload: payload });
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
test("put on a new key publishes storage.uploaded with key + metadata (Req 18.1, 18.2)", async () => {
|
|
37
|
-
const events = recordingEvents();
|
|
38
|
-
const storage = createStorage({ provider: "memory", bridges: { events } });
|
|
39
|
-
await storage.put("photo.png", "bytes", { contentType: "image/png" });
|
|
40
|
-
assert.equal(events.published.length, 1);
|
|
41
|
-
const { event, payload } = events.published[0];
|
|
42
|
-
assert.equal(event, "storage.uploaded");
|
|
43
|
-
assert.equal(payload.key, "photo.png");
|
|
44
|
-
assert.ok(payload.metadata);
|
|
45
|
-
assert.equal(payload.metadata.key, "photo.png");
|
|
46
|
-
assert.equal(payload.metadata.contentType, "image/png");
|
|
47
|
-
});
|
|
48
|
-
test("put overwriting an existing key publishes storage.updated (Req 18.1)", async () => {
|
|
49
|
-
const events = recordingEvents();
|
|
50
|
-
const storage = createStorage({ provider: "memory", bridges: { events } });
|
|
51
|
-
await storage.put("doc.txt", "v1");
|
|
52
|
-
await storage.put("doc.txt", "v2");
|
|
53
|
-
assert.deepEqual(events.published.map((e) => e.event), ["storage.uploaded", "storage.updated"]);
|
|
54
|
-
assert.equal(events.published[1].payload.key, "doc.txt");
|
|
55
|
-
assert.ok(events.published[1].payload.metadata);
|
|
56
|
-
});
|
|
57
|
-
test("delete publishes storage.deleted with the key (Req 18.1, 18.2)", async () => {
|
|
58
|
-
const events = recordingEvents();
|
|
59
|
-
const storage = createStorage({ provider: "memory", bridges: { events } });
|
|
60
|
-
await storage.put("gone.txt", "x");
|
|
61
|
-
events.published.length = 0; // ignore the upload event
|
|
62
|
-
await storage.delete("gone.txt");
|
|
63
|
-
assert.equal(events.published.length, 1);
|
|
64
|
-
assert.equal(events.published[0].event, "storage.deleted");
|
|
65
|
-
assert.equal(events.published[0].payload.key, "gone.txt");
|
|
66
|
-
});
|
|
67
|
-
test("move publishes storage.moved for the destination (Req 18.1)", async () => {
|
|
68
|
-
const events = recordingEvents();
|
|
69
|
-
const storage = createStorage({ provider: "memory", bridges: { events } });
|
|
70
|
-
await storage.put("a.txt", "content");
|
|
71
|
-
events.published.length = 0;
|
|
72
|
-
await storage.move("a.txt", "b.txt");
|
|
73
|
-
assert.equal(events.published.length, 1);
|
|
74
|
-
assert.equal(events.published[0].event, "storage.moved");
|
|
75
|
-
assert.equal(events.published[0].payload.key, "b.txt");
|
|
76
|
-
assert.ok(events.published[0].payload.metadata);
|
|
77
|
-
});
|
|
78
|
-
test("rename publishes storage.moved (delegates to move) (Req 18.1)", async () => {
|
|
79
|
-
const events = recordingEvents();
|
|
80
|
-
const storage = createStorage({ provider: "memory", bridges: { events } });
|
|
81
|
-
await storage.put("old", "content");
|
|
82
|
-
events.published.length = 0;
|
|
83
|
-
await storage.rename("old", "new");
|
|
84
|
-
assert.deepEqual(events.published.map((e) => e.event), ["storage.moved"]);
|
|
85
|
-
assert.equal(events.published[0].payload.key, "new");
|
|
86
|
-
});
|
|
87
|
-
test("move of a missing source publishes nothing", async () => {
|
|
88
|
-
const events = recordingEvents();
|
|
89
|
-
const storage = createStorage({ provider: "memory", bridges: { events } });
|
|
90
|
-
const result = await storage.move("missing", "dest");
|
|
91
|
-
assert.equal(result.moved, false);
|
|
92
|
-
assert.deepEqual(events.published, []);
|
|
93
|
-
});
|
|
94
|
-
test("restoreVersion publishes storage.restored (Req 18.1)", async () => {
|
|
95
|
-
const events = recordingEvents();
|
|
96
|
-
const storage = createStorage({
|
|
97
|
-
provider: "memory",
|
|
98
|
-
versioning: true,
|
|
99
|
-
bridges: { events },
|
|
100
|
-
});
|
|
101
|
-
await storage.put("k", "v1");
|
|
102
|
-
await storage.put("k", "v2"); // snapshots v1 as a version
|
|
103
|
-
const versions = await storage.listVersions("k");
|
|
104
|
-
assert.equal(versions.length, 1);
|
|
105
|
-
events.published.length = 0;
|
|
106
|
-
await storage.restoreVersion("k", versions[0].versionId);
|
|
107
|
-
assert.equal(events.published.length, 1);
|
|
108
|
-
assert.equal(events.published[0].event, "storage.restored");
|
|
109
|
-
assert.equal(events.published[0].payload.key, "k");
|
|
110
|
-
assert.ok(events.published[0].payload.metadata);
|
|
111
|
-
});
|
|
112
|
-
test("applyLifecycle publishes lifecycle events through the bridge (Req 13.4)", async () => {
|
|
113
|
-
const events = recordingEvents();
|
|
114
|
-
let now = T0;
|
|
115
|
-
const clock = () => now;
|
|
116
|
-
const storage = createStorage({ provider: "memory", clock, bridges: { events } });
|
|
117
|
-
await storage.put("old", "a");
|
|
118
|
-
now = T0 + 10 * DAY;
|
|
119
|
-
events.published.length = 0;
|
|
120
|
-
const outcomes = await storage.applyLifecycle({ type: "delete-after-days", days: 5 });
|
|
121
|
-
assert.deepEqual(outcomes, [{ key: "old", action: "deleted" }]);
|
|
122
|
-
assert.equal(events.published.length, 1);
|
|
123
|
-
assert.equal(events.published[0].event, "storage.deleted");
|
|
124
|
-
assert.equal(events.published[0].payload.key, "old");
|
|
125
|
-
assert.equal(events.published[0].payload.action, "deleted");
|
|
126
|
-
});
|
|
127
|
-
test("expire-temp-uploads publishes storage.expired (Req 13.4)", async () => {
|
|
128
|
-
const events = recordingEvents();
|
|
129
|
-
let now = T0;
|
|
130
|
-
const clock = () => now;
|
|
131
|
-
const storage = createStorage({ provider: "memory", clock, bridges: { events } });
|
|
132
|
-
const uploadId = await storage.createMultipartUpload("big", { contentType: "text/plain" });
|
|
133
|
-
await storage.uploadPart(uploadId, 1, new TextEncoder().encode("part-1"));
|
|
134
|
-
now = T0 + 60_000;
|
|
135
|
-
events.published.length = 0;
|
|
136
|
-
const outcomes = await storage.applyLifecycle({ type: "expire-temp-uploads", afterMs: 30_000 });
|
|
137
|
-
assert.equal(outcomes.length, 1);
|
|
138
|
-
assert.equal(events.published.length, 1);
|
|
139
|
-
assert.equal(events.published[0].event, "storage.expired");
|
|
140
|
-
assert.equal(events.published[0].payload.action, "expired");
|
|
141
|
-
});
|
|
142
|
-
test("archive-after-months publishes storage.moved with action=archived (Req 13.4)", async () => {
|
|
143
|
-
const events = recordingEvents();
|
|
144
|
-
let now = T0;
|
|
145
|
-
const clock = () => now;
|
|
146
|
-
const storage = createStorage({ provider: "memory", clock, bridges: { events } });
|
|
147
|
-
await storage.put("report", "payload");
|
|
148
|
-
now = T0 + 90 * DAY;
|
|
149
|
-
events.published.length = 0;
|
|
150
|
-
const outcomes = await storage.applyLifecycle({ type: "archive-after-months", months: 2 });
|
|
151
|
-
assert.deepEqual(outcomes, [{ key: "report", action: "archived" }]);
|
|
152
|
-
assert.equal(events.published.length, 1);
|
|
153
|
-
assert.equal(events.published[0].event, "storage.moved");
|
|
154
|
-
assert.equal(events.published[0].payload.action, "archived");
|
|
155
|
-
});
|
|
156
|
-
test("a synchronous publish failure never breaks the storage operation", async () => {
|
|
157
|
-
const throwingEvents = {
|
|
158
|
-
publish() {
|
|
159
|
-
throw new Error("event bus down");
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
const storage = createStorage({ provider: "memory", bridges: { events: throwingEvents } });
|
|
163
|
-
// The put must still succeed and return metadata despite the publish throwing.
|
|
164
|
-
const metadata = await storage.put("k", "v");
|
|
165
|
-
assert.equal(metadata.key, "k");
|
|
166
|
-
assert.equal(await storage.exists("k"), true);
|
|
167
|
-
// delete must likewise succeed.
|
|
168
|
-
await storage.delete("k");
|
|
169
|
-
assert.equal(await storage.exists("k"), false);
|
|
170
|
-
});
|
|
171
|
-
test("an asynchronous publish rejection never breaks the storage operation", async () => {
|
|
172
|
-
const rejectingEvents = {
|
|
173
|
-
publish() {
|
|
174
|
-
return Promise.reject(new Error("async bus down"));
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
const storage = createStorage({ provider: "memory", bridges: { events: rejectingEvents } });
|
|
178
|
-
const metadata = await storage.put("k", "v");
|
|
179
|
-
assert.equal(metadata.key, "k");
|
|
180
|
-
const result = await storage.get("k");
|
|
181
|
-
assert.equal(result.found, true);
|
|
182
|
-
});
|
|
183
|
-
test("with no events bridge configured, operations proceed with no publication", async () => {
|
|
184
|
-
const storage = createStorage({ provider: "memory" });
|
|
185
|
-
const metadata = await storage.put("k", "v");
|
|
186
|
-
assert.equal(metadata.key, "k");
|
|
187
|
-
await storage.delete("k");
|
|
188
|
-
assert.equal(await storage.exists("k"), false);
|
|
189
|
-
});
|
|
190
|
-
test("bridgeStorageEvents is a standalone never-throwing publisher", () => {
|
|
191
|
-
const events = recordingEvents();
|
|
192
|
-
const publisher = bridgeStorageEvents(events);
|
|
193
|
-
const metadata = {
|
|
194
|
-
key: "k",
|
|
195
|
-
size: 1,
|
|
196
|
-
contentType: "text/plain",
|
|
197
|
-
etag: "e",
|
|
198
|
-
checksum: "c",
|
|
199
|
-
accessLevel: "private",
|
|
200
|
-
createdAt: T0,
|
|
201
|
-
updatedAt: T0,
|
|
202
|
-
custom: {},
|
|
203
|
-
};
|
|
204
|
-
publisher.uploaded(metadata);
|
|
205
|
-
publisher.updated(metadata);
|
|
206
|
-
publisher.deleted("k");
|
|
207
|
-
publisher.moved(metadata);
|
|
208
|
-
publisher.restored(metadata);
|
|
209
|
-
publisher.expired("k");
|
|
210
|
-
publisher.lifecycle({ key: "k", action: "moved" });
|
|
211
|
-
assert.deepEqual(events.published.map((e) => e.event), [
|
|
212
|
-
"storage.uploaded",
|
|
213
|
-
"storage.updated",
|
|
214
|
-
"storage.deleted",
|
|
215
|
-
"storage.moved",
|
|
216
|
-
"storage.restored",
|
|
217
|
-
"storage.expired",
|
|
218
|
-
"storage.moved",
|
|
219
|
-
]);
|
|
220
|
-
// A throwing bus is fully isolated.
|
|
221
|
-
const badPublisher = bridgeStorageEvents({
|
|
222
|
-
publish() {
|
|
223
|
-
throw new Error("down");
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
assert.doesNotThrow(() => badPublisher.uploaded(metadata));
|
|
227
|
-
});
|
|
228
|
-
//# sourceMappingURL=events-bridge.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"events-bridge.test.js","sourceRoot":"","sources":["../../src/tests/events-bridge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"example-smoke.test.d.ts","sourceRoot":"","sources":["../../src/tests/example-smoke.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// Smoke test for the runnable end-to-end example (task 31.2).
|
|
2
|
-
//
|
|
3
|
-
// This test imports `runStorageDemo` from the example application and executes
|
|
4
|
-
// it end to end against the zero-dependency in-memory driver — no external
|
|
5
|
-
// services, no network, no real image library. It passes a no-op log sink to
|
|
6
|
-
// keep test output quiet and asserts on the returned summary to prove the
|
|
7
|
-
// demonstrated operations (upload, download, replace, list, delete, signed URL,
|
|
8
|
-
// streaming progress, resize, thumbnail, metadata) all succeeded.
|
|
9
|
-
//
|
|
10
|
-
// Requirements: 25.3, 27.1
|
|
11
|
-
import test from "node:test";
|
|
12
|
-
import assert from "node:assert/strict";
|
|
13
|
-
import { runStorageDemo } from "../examples/storage-demo.js";
|
|
14
|
-
/** A no-op log sink so the demo runs quietly under the test runner. */
|
|
15
|
-
const quietLog = (_line) => { };
|
|
16
|
-
test("runStorageDemo runs end to end on the zero-dependency driver", async () => {
|
|
17
|
-
const summary = await runStorageDemo(quietLog);
|
|
18
|
-
// Download round-tripped and matched the upload.
|
|
19
|
-
assert.equal(summary.downloaded, "ok");
|
|
20
|
-
// Listing returned at least one stored object.
|
|
21
|
-
assert.ok(Array.isArray(summary.listedKeys));
|
|
22
|
-
assert.ok(summary.listedKeys.length > 0, "expected at least one listed key");
|
|
23
|
-
// A signed URL was produced.
|
|
24
|
-
assert.equal(typeof summary.signedUrl, "string");
|
|
25
|
-
assert.ok(summary.signedUrl.length > 0, "expected a non-empty signed URL");
|
|
26
|
-
// Streaming upload surfaced byte-level progress.
|
|
27
|
-
assert.ok(summary.progressUpdates > 0, "expected at least one progress update");
|
|
28
|
-
// Image processing produced resized and thumbnail variants.
|
|
29
|
-
assert.ok(typeof summary.resizedKey === "string" && summary.resizedKey.length > 0, "expected a resized variant key");
|
|
30
|
-
assert.ok(typeof summary.thumbnailKey === "string" && summary.thumbnailKey.length > 0, "expected a thumbnail variant key");
|
|
31
|
-
// Metadata inspection reported a positive object size.
|
|
32
|
-
assert.ok(summary.avatarSize > 0, "expected a positive avatar size");
|
|
33
|
-
});
|
|
34
|
-
//# sourceMappingURL=example-smoke.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"example-smoke.test.js","sourceRoot":"","sources":["../../src/tests/example-smoke.test.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,0EAA0E;AAC1E,gFAAgF;AAChF,kEAAkE;AAClE,EAAE;AACF,2BAA2B;AAE3B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,uEAAuE;AACvE,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAQ,EAAE,GAAE,CAAC,CAAC;AAE7C,IAAI,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;IAC9E,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE/C,iDAAiD;IACjD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAEvC,+CAA+C;IAC/C,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,kCAAkC,CAAC,CAAC;IAE7E,6BAA6B;IAC7B,MAAM,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,iCAAiC,CAAC,CAAC;IAE3E,iDAAiD;IACjD,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,GAAG,CAAC,EAAE,uCAAuC,CAAC,CAAC;IAEhF,4DAA4D;IAC5D,MAAM,CAAC,EAAE,CACP,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EACvE,gCAAgC,CACjC,CAAC;IACF,MAAM,CAAC,EAAE,CACP,OAAO,OAAO,CAAC,YAAY,KAAK,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAC3E,kCAAkC,CACnC,CAAC;IAEF,uDAAuD;IACvD,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,EAAE,iCAAiC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gcs-driver.test.d.ts","sourceRoot":"","sources":["../../src/tests/gcs-driver.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
// Unit tests for the Google Cloud Storage driver submodule (task 29.2). Unlike
|
|
2
|
-
// the S3-compatible providers, GCS uses a bucket/file object model, so the
|
|
3
|
-
// driver maps the StorageDriver contract directly onto a purpose-built
|
|
4
|
-
// structural GcsClientLike (not the shared S3 base). These tests exercise the
|
|
5
|
-
// injected-client path with an in-memory GcsClientLike double (no
|
|
6
|
-
// `@google-cloud/storage` SDK, no external service), the StorageConfigError
|
|
7
|
-
// guard when no client is injected, the connect() guard when the SDK is absent,
|
|
8
|
-
// and the shared driver contract-conformance suite.
|
|
9
|
-
//
|
|
10
|
-
// Requirements: 2.1, 2.3, 3.3
|
|
11
|
-
import test from "node:test";
|
|
12
|
-
import assert from "node:assert/strict";
|
|
13
|
-
import { createGoogleCloudStorageDriver, connectGoogleCloudStorageDriver, } from "../drivers/gcs.js";
|
|
14
|
-
import { StorageConfigError } from "../errors.js";
|
|
15
|
-
import { registerStorageDriverContractTests } from "./contract.js";
|
|
16
|
-
const FIXED_NOW = 1_700_000_000_000;
|
|
17
|
-
const fixedClock = () => FIXED_NOW;
|
|
18
|
-
function bytes(str) {
|
|
19
|
-
return new TextEncoder().encode(str);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* A minimal in-memory GcsClientLike double. It stores the raw bytes plus the
|
|
23
|
-
* content type and custom-metadata map exactly as the real GCS object model
|
|
24
|
-
* would, and returns `null` (never throws) for a missing object so the driver's
|
|
25
|
-
* not-found mapping is exercised.
|
|
26
|
-
*/
|
|
27
|
-
function makeFakeClient() {
|
|
28
|
-
const objects = new Map(); // name -> { bytes, contentType, metadata }
|
|
29
|
-
return {
|
|
30
|
-
async save(name, data, options) {
|
|
31
|
-
objects.set(name, {
|
|
32
|
-
bytes: data.slice(),
|
|
33
|
-
contentType: options?.contentType,
|
|
34
|
-
metadata: options?.metadata ? { ...options.metadata } : undefined,
|
|
35
|
-
});
|
|
36
|
-
},
|
|
37
|
-
async download(name) {
|
|
38
|
-
const obj = objects.get(name);
|
|
39
|
-
return obj === undefined ? null : obj.bytes.slice();
|
|
40
|
-
},
|
|
41
|
-
async delete(name) {
|
|
42
|
-
objects.delete(name);
|
|
43
|
-
},
|
|
44
|
-
async exists(name) {
|
|
45
|
-
return objects.has(name);
|
|
46
|
-
},
|
|
47
|
-
async getMetadata(name) {
|
|
48
|
-
const obj = objects.get(name);
|
|
49
|
-
if (obj === undefined)
|
|
50
|
-
return null;
|
|
51
|
-
return {
|
|
52
|
-
size: String(obj.bytes.byteLength),
|
|
53
|
-
contentType: obj.contentType,
|
|
54
|
-
etag: `${name}-etag`,
|
|
55
|
-
updated: new Date(FIXED_NOW).toISOString(),
|
|
56
|
-
timeCreated: new Date(FIXED_NOW).toISOString(),
|
|
57
|
-
metadata: obj.metadata,
|
|
58
|
-
};
|
|
59
|
-
},
|
|
60
|
-
async getFiles({ prefix }) {
|
|
61
|
-
return [...objects.entries()]
|
|
62
|
-
.filter(([name]) => name.startsWith(prefix))
|
|
63
|
-
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
64
|
-
.map(([name, obj]) => ({
|
|
65
|
-
name,
|
|
66
|
-
attributes: {
|
|
67
|
-
size: String(obj.bytes.byteLength),
|
|
68
|
-
updated: new Date(FIXED_NOW).toISOString(),
|
|
69
|
-
},
|
|
70
|
-
}));
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function makeDriver() {
|
|
75
|
-
return createGoogleCloudStorageDriver(makeFakeClient(), { clock: fixedClock });
|
|
76
|
-
}
|
|
77
|
-
// ── name ──────────────────────────────────────────────────────────────────────
|
|
78
|
-
test("driver name is fixed to gcs", () => {
|
|
79
|
-
assert.equal(makeDriver().name, "gcs");
|
|
80
|
-
});
|
|
81
|
-
// ── injected-client primitives round-trip ─────────────────────────────────────
|
|
82
|
-
test("put/get round-trips bytes and typed metadata over the injected client", async () => {
|
|
83
|
-
const driver = makeDriver();
|
|
84
|
-
const content = bytes("gcs object payload");
|
|
85
|
-
await driver.put("bucketed/key.txt", content, {
|
|
86
|
-
contentType: "text/plain",
|
|
87
|
-
owner: "user-7",
|
|
88
|
-
tenant: "tenant-q",
|
|
89
|
-
accessLevel: "public",
|
|
90
|
-
custom: { label: "report" },
|
|
91
|
-
});
|
|
92
|
-
const result = await driver.get("bucketed/key.txt");
|
|
93
|
-
assert.equal(result.found, true);
|
|
94
|
-
assert.deepEqual(result.bytes, content);
|
|
95
|
-
assert.equal(result.metadata.contentType, "text/plain");
|
|
96
|
-
assert.equal(result.metadata.owner, "user-7");
|
|
97
|
-
assert.equal(result.metadata.tenant, "tenant-q");
|
|
98
|
-
assert.equal(result.metadata.accessLevel, "public");
|
|
99
|
-
assert.deepEqual(result.metadata.custom, { label: "report" });
|
|
100
|
-
assert.equal(result.metadata.size, content.byteLength);
|
|
101
|
-
});
|
|
102
|
-
test("createdAt is preserved across overwrite while updatedAt advances", async () => {
|
|
103
|
-
let now = 1000;
|
|
104
|
-
const driver = createGoogleCloudStorageDriver(makeFakeClient(), { clock: () => now });
|
|
105
|
-
const first = await driver.put("k.txt", bytes("v1"), {});
|
|
106
|
-
now = 5000;
|
|
107
|
-
const second = await driver.put("k.txt", bytes("v2-longer"), {});
|
|
108
|
-
assert.equal(second.createdAt, first.createdAt);
|
|
109
|
-
assert.equal(second.updatedAt, 5000);
|
|
110
|
-
assert.equal(second.size, bytes("v2-longer").byteLength);
|
|
111
|
-
});
|
|
112
|
-
test("exists/delete/stat/list behave consistently", async () => {
|
|
113
|
-
const driver = makeDriver();
|
|
114
|
-
await driver.put("d/a.txt", bytes("a"), {});
|
|
115
|
-
await driver.put("d/b.txt", bytes("bb"), {});
|
|
116
|
-
assert.equal(await driver.exists("d/a.txt"), true);
|
|
117
|
-
assert.equal(await driver.exists("d/missing.txt"), false);
|
|
118
|
-
const stat = await driver.stat("d/b.txt");
|
|
119
|
-
assert.ok(stat);
|
|
120
|
-
assert.equal(stat.size, 2);
|
|
121
|
-
assert.equal(await driver.stat("d/missing.txt"), null);
|
|
122
|
-
const items = await driver.list("d/");
|
|
123
|
-
assert.deepEqual(items.map((i) => i.key), ["d/a.txt", "d/b.txt"]);
|
|
124
|
-
await driver.delete("d/a.txt");
|
|
125
|
-
assert.equal(await driver.exists("d/a.txt"), false);
|
|
126
|
-
});
|
|
127
|
-
test("list honors cursor and limit", async () => {
|
|
128
|
-
const driver = makeDriver();
|
|
129
|
-
await driver.put("p/1", bytes("1"), {});
|
|
130
|
-
await driver.put("p/2", bytes("2"), {});
|
|
131
|
-
await driver.put("p/3", bytes("3"), {});
|
|
132
|
-
const limited = await driver.list("p/", { limit: 2 });
|
|
133
|
-
assert.deepEqual(limited.map((i) => i.key), ["p/1", "p/2"]);
|
|
134
|
-
const afterCursor = await driver.list("p/", { cursor: "p/1" });
|
|
135
|
-
assert.deepEqual(afterCursor.map((i) => i.key), ["p/2", "p/3"]);
|
|
136
|
-
});
|
|
137
|
-
test("get on a missing key reports found:false", async () => {
|
|
138
|
-
const driver = makeDriver();
|
|
139
|
-
const result = await driver.get("nope");
|
|
140
|
-
assert.equal(result.found, false);
|
|
141
|
-
});
|
|
142
|
-
// ── streaming ──────────────────────────────────────────────────────────────────
|
|
143
|
-
test("putStream/getStream round-trip through the injected client", async () => {
|
|
144
|
-
const { Readable } = await import("node:stream");
|
|
145
|
-
const driver = makeDriver();
|
|
146
|
-
const payload = bytes("streamed gcs payload");
|
|
147
|
-
await driver.putStream("s/obj.bin", Readable.from([Buffer.from(payload)]), {
|
|
148
|
-
contentType: "application/octet-stream",
|
|
149
|
-
});
|
|
150
|
-
const stream = await driver.getStream("s/obj.bin");
|
|
151
|
-
const chunks = [];
|
|
152
|
-
for await (const chunk of stream)
|
|
153
|
-
chunks.push(Buffer.from(chunk));
|
|
154
|
-
assert.deepEqual(new Uint8Array(Buffer.concat(chunks)), payload);
|
|
155
|
-
});
|
|
156
|
-
test("getStream throws NotFoundError for a missing key", async () => {
|
|
157
|
-
const driver = makeDriver();
|
|
158
|
-
await assert.rejects(() => driver.getStream("absent"), (err) => {
|
|
159
|
-
assert.ok(err instanceof Error);
|
|
160
|
-
assert.equal(err.name, "NotFoundError");
|
|
161
|
-
return true;
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
// ── advanced capabilities are left undefined for facade simulation ─────────────
|
|
165
|
-
test("advanced capabilities are undefined (simulated by the facade)", () => {
|
|
166
|
-
const driver = makeDriver();
|
|
167
|
-
assert.equal(driver.multipart, undefined);
|
|
168
|
-
assert.equal(driver.resumable, undefined);
|
|
169
|
-
assert.equal(driver.versioning, undefined);
|
|
170
|
-
assert.equal(driver.signedUrl, undefined);
|
|
171
|
-
assert.equal(driver.lifecycle, undefined);
|
|
172
|
-
});
|
|
173
|
-
// ── configuration guards ──────────────────────────────────────────────────────
|
|
174
|
-
test("createGoogleCloudStorageDriver throws StorageConfigError when no client is injected", () => {
|
|
175
|
-
assert.throws(() => createGoogleCloudStorageDriver(undefined), (err) => {
|
|
176
|
-
assert.ok(err instanceof StorageConfigError);
|
|
177
|
-
assert.equal(err.provider, "gcs");
|
|
178
|
-
return true;
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
test("connectGoogleCloudStorageDriver throws StorageConfigError when the GCS SDK is absent", async () => {
|
|
182
|
-
await assert.rejects(() => connectGoogleCloudStorageDriver({ bucket: "b" }), (err) => {
|
|
183
|
-
assert.ok(err instanceof StorageConfigError);
|
|
184
|
-
assert.equal(err.provider, "gcs");
|
|
185
|
-
return true;
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
test("connectGoogleCloudStorageDriver throws StorageConfigError when bucket is missing", async () => {
|
|
189
|
-
await assert.rejects(() => connectGoogleCloudStorageDriver({ bucket: "" }), (err) => {
|
|
190
|
-
assert.ok(err instanceof StorageConfigError);
|
|
191
|
-
assert.equal(err.provider, "gcs");
|
|
192
|
-
return true;
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
// ── shared contract-conformance suite ─────────────────────────────────────────
|
|
196
|
-
registerStorageDriverContractTests("gcs", () => createGoogleCloudStorageDriver(makeFakeClient(), { clock: fixedClock }), test);
|
|
197
|
-
//# sourceMappingURL=gcs-driver.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gcs-driver.test.js","sourceRoot":"","sources":["../../src/tests/gcs-driver.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"image.test.d.ts","sourceRoot":"","sources":["../../src/tests/image.test.ts"],"names":[],"mappings":""}
|
package/dist/tests/image.test.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
// Unit tests for the image processor's error handling and caching (task 19.2).
|
|
2
|
-
//
|
|
3
|
-
// Verifies the Requirement 14 semantics that guard and cache image
|
|
4
|
-
// transformations over the zero-dependency `memory` provider, driving the
|
|
5
|
-
// processor through the public `storage.images.transform(key, operations)`
|
|
6
|
-
// surface with a structural fake `imageCodec`:
|
|
7
|
-
//
|
|
8
|
-
// - unsupported-format error: transforming a non-image source (e.g. a
|
|
9
|
-
// `text/plain` object) throws `UnsupportedImageError` and leaves the source
|
|
10
|
-
// Object completely unmodified — its bytes and its metadata are intact,
|
|
11
|
-
// regardless of whether processing would otherwise succeed (Requirement 14.4).
|
|
12
|
-
// - cache-hit reuse: two identical transform requests on the same unchanged
|
|
13
|
-
// source invoke the injected codec only ONCE (the second request is served
|
|
14
|
-
// from the cache) and produce the same variant (Requirement 14.3).
|
|
15
|
-
//
|
|
16
|
-
// Uses the Node.js built-in test runner (node:test); executed via
|
|
17
|
-
// `node --test dist/tests/*.test.js`.
|
|
18
|
-
//
|
|
19
|
-
// Requirements: 14.3, 14.4
|
|
20
|
-
import test from "node:test";
|
|
21
|
-
import assert from "node:assert/strict";
|
|
22
|
-
import { createStorage } from "../facade.js";
|
|
23
|
-
import { UnsupportedImageError } from "../errors.js";
|
|
24
|
-
const fixedClock = () => 1_700_000_000_000;
|
|
25
|
-
/**
|
|
26
|
-
* Build a structural fake `ImageCodec` whose `transform` returns deterministic
|
|
27
|
-
* bytes and counts how many times it was invoked, so a test can assert the
|
|
28
|
-
* processor cache prevents re-invocation for identical requests.
|
|
29
|
-
*/
|
|
30
|
-
function makeFakeCodec() {
|
|
31
|
-
const codec = {
|
|
32
|
-
calls: 0,
|
|
33
|
-
transform(bytes, operation) {
|
|
34
|
-
codec.calls += 1;
|
|
35
|
-
// Deterministic output derived only from the requested output format, so
|
|
36
|
-
// identical requests would (absent caching) produce identical bytes.
|
|
37
|
-
const marker = `variant:${operation.format ?? "png"}`;
|
|
38
|
-
return new TextEncoder().encode(marker);
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
return codec;
|
|
42
|
-
}
|
|
43
|
-
test("transforming a non-image source throws UnsupportedImageError (Req 14.4)", async () => {
|
|
44
|
-
const codec = makeFakeCodec();
|
|
45
|
-
const storage = createStorage({ provider: "memory", imageCodec: codec, clock: fixedClock });
|
|
46
|
-
await storage.put("notes.txt", "just some text", { contentType: "text/plain" });
|
|
47
|
-
await assert.rejects(() => storage.images.transform("notes.txt", { resize: { width: 10, height: 10 } }), UnsupportedImageError);
|
|
48
|
-
// The guard must run before any codec call.
|
|
49
|
-
assert.equal(codec.calls, 0);
|
|
50
|
-
});
|
|
51
|
-
test("a rejected non-image transform leaves the source Object unmodified (Req 14.4)", async () => {
|
|
52
|
-
const codec = makeFakeCodec();
|
|
53
|
-
const storage = createStorage({ provider: "memory", imageCodec: codec, clock: fixedClock });
|
|
54
|
-
await storage.put("notes.txt", "just some text", { contentType: "text/plain" });
|
|
55
|
-
const before = await storage.get("notes.txt");
|
|
56
|
-
const beforeBytes = Buffer.from(before.bytes);
|
|
57
|
-
const beforeMeta = before.metadata;
|
|
58
|
-
assert.ok(beforeMeta);
|
|
59
|
-
await assert.rejects(() => storage.images.transform("notes.txt", { format: "png", resize: { width: 4 } }), UnsupportedImageError);
|
|
60
|
-
const after = await storage.get("notes.txt");
|
|
61
|
-
assert.ok(after.metadata);
|
|
62
|
-
// Bytes are byte-for-byte intact.
|
|
63
|
-
assert.ok(beforeBytes.equals(Buffer.from(after.bytes)));
|
|
64
|
-
assert.equal(Buffer.from(after.bytes).toString(), "just some text");
|
|
65
|
-
// Metadata is intact: identity, size, content type, and checksum unchanged.
|
|
66
|
-
assert.equal(after.metadata.key, beforeMeta.key);
|
|
67
|
-
assert.equal(after.metadata.size, beforeMeta.size);
|
|
68
|
-
assert.equal(after.metadata.contentType, "text/plain");
|
|
69
|
-
assert.equal(after.metadata.checksum, beforeMeta.checksum);
|
|
70
|
-
assert.equal(after.metadata.etag, beforeMeta.etag);
|
|
71
|
-
assert.equal(after.metadata.updatedAt, beforeMeta.updatedAt);
|
|
72
|
-
});
|
|
73
|
-
test("identical transform requests invoke the codec only once (Req 14.3)", async () => {
|
|
74
|
-
const codec = makeFakeCodec();
|
|
75
|
-
const storage = createStorage({ provider: "memory", imageCodec: codec, clock: fixedClock });
|
|
76
|
-
const pngBytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 1, 2, 3, 4]);
|
|
77
|
-
await storage.put("photo.png", pngBytes, { contentType: "image/png" });
|
|
78
|
-
const operations = { resize: { width: 100, height: 100 }, format: "webp" };
|
|
79
|
-
const first = await storage.images.transform("photo.png", operations);
|
|
80
|
-
const second = await storage.images.transform("photo.png", operations);
|
|
81
|
-
// The codec performed the pixel work exactly once; the second request was a
|
|
82
|
-
// cache hit (Requirement 14.3).
|
|
83
|
-
assert.equal(codec.calls, 1);
|
|
84
|
-
// Both requests produced the same variant.
|
|
85
|
-
assert.equal(second.key, first.key);
|
|
86
|
-
assert.equal(second.checksum, first.checksum);
|
|
87
|
-
assert.equal(second.etag, first.etag);
|
|
88
|
-
assert.equal(second.size, first.size);
|
|
89
|
-
assert.equal(second.contentType, first.contentType);
|
|
90
|
-
assert.equal(first.contentType, "image/webp");
|
|
91
|
-
});
|
|
92
|
-
test("distinct transform parameters are not served from the cache (Req 14.3)", async () => {
|
|
93
|
-
const codec = makeFakeCodec();
|
|
94
|
-
const storage = createStorage({ provider: "memory", imageCodec: codec, clock: fixedClock });
|
|
95
|
-
const pngBytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 5, 6, 7, 8]);
|
|
96
|
-
await storage.put("photo.png", pngBytes, { contentType: "image/png" });
|
|
97
|
-
await storage.images.transform("photo.png", { resize: { width: 50 }, format: "png" });
|
|
98
|
-
await storage.images.transform("photo.png", { resize: { width: 60 }, format: "png" });
|
|
99
|
-
// Different parameters are a cache miss, so the codec runs for each.
|
|
100
|
-
assert.equal(codec.calls, 2);
|
|
101
|
-
});
|
|
102
|
-
//# sourceMappingURL=image.test.js.map
|