@stratal/testing 0.0.1
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/LICENSE +21 -0
- package/dist/core/env/index.d.ts +2 -0
- package/dist/core/env/index.d.ts.map +1 -0
- package/dist/core/env/index.js +2 -0
- package/dist/core/env/index.js.map +1 -0
- package/dist/core/env/test-env.d.ts +9 -0
- package/dist/core/env/test-env.d.ts.map +1 -0
- package/dist/core/env/test-env.js +14 -0
- package/dist/core/env/test-env.js.map +1 -0
- package/dist/core/http/fetch-mock.d.ts +236 -0
- package/dist/core/http/fetch-mock.d.ts.map +1 -0
- package/dist/core/http/fetch-mock.js +290 -0
- package/dist/core/http/fetch-mock.js.map +1 -0
- package/dist/core/http/fetch-mock.types.d.ts +48 -0
- package/dist/core/http/fetch-mock.types.d.ts.map +1 -0
- package/dist/core/http/fetch-mock.types.js +2 -0
- package/dist/core/http/fetch-mock.types.js.map +1 -0
- package/dist/core/http/index.d.ts +6 -0
- package/dist/core/http/index.d.ts.map +1 -0
- package/dist/core/http/index.js +5 -0
- package/dist/core/http/index.js.map +1 -0
- package/dist/core/http/test-http-client.d.ts +54 -0
- package/dist/core/http/test-http-client.d.ts.map +1 -0
- package/dist/core/http/test-http-client.js +75 -0
- package/dist/core/http/test-http-client.js.map +1 -0
- package/dist/core/http/test-http-request.d.ts +44 -0
- package/dist/core/http/test-http-request.d.ts.map +1 -0
- package/dist/core/http/test-http-request.js +75 -0
- package/dist/core/http/test-http-request.js.map +1 -0
- package/dist/core/http/test-response.d.ts +161 -0
- package/dist/core/http/test-response.d.ts.map +1 -0
- package/dist/core/http/test-response.js +309 -0
- package/dist/core/http/test-response.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/override/index.d.ts +2 -0
- package/dist/core/override/index.d.ts.map +1 -0
- package/dist/core/override/index.js +2 -0
- package/dist/core/override/index.js.map +1 -0
- package/dist/core/override/provider-override-builder.d.ts +77 -0
- package/dist/core/override/provider-override-builder.d.ts.map +1 -0
- package/dist/core/override/provider-override-builder.js +94 -0
- package/dist/core/override/provider-override-builder.js.map +1 -0
- package/dist/core/test.d.ts +48 -0
- package/dist/core/test.d.ts.map +1 -0
- package/dist/core/test.js +53 -0
- package/dist/core/test.js.map +1 -0
- package/dist/core/testing-module-builder.d.ts +98 -0
- package/dist/core/testing-module-builder.d.ts.map +1 -0
- package/dist/core/testing-module-builder.js +154 -0
- package/dist/core/testing-module-builder.js.map +1 -0
- package/dist/core/testing-module.d.ts +77 -0
- package/dist/core/testing-module.d.ts.map +1 -0
- package/dist/core/testing-module.js +99 -0
- package/dist/core/testing-module.js.map +1 -0
- package/dist/errors/index.d.ts +3 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +3 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/setup-error.d.ts +9 -0
- package/dist/errors/setup-error.d.ts.map +1 -0
- package/dist/errors/setup-error.js +11 -0
- package/dist/errors/setup-error.js.map +1 -0
- package/dist/errors/test-error.d.ts +9 -0
- package/dist/errors/test-error.d.ts.map +1 -0
- package/dist/errors/test-error.js +15 -0
- package/dist/errors/test-error.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/mocks/index.d.ts +4 -0
- package/dist/mocks/index.d.ts.map +1 -0
- package/dist/mocks/index.js +4 -0
- package/dist/mocks/index.js.map +1 -0
- package/dist/mocks/nodemailer.d.ts +10 -0
- package/dist/mocks/nodemailer.d.ts.map +1 -0
- package/dist/mocks/nodemailer.js +9 -0
- package/dist/mocks/nodemailer.js.map +1 -0
- package/dist/storage/fake-storage.service.d.ts +114 -0
- package/dist/storage/fake-storage.service.d.ts.map +1 -0
- package/dist/storage/fake-storage.service.js +233 -0
- package/dist/storage/fake-storage.service.js.map +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { StorageManagerService, StorageService, StreamingBlobPayloadInputTypes, type DownloadResult, type PresignedUrlResult, type StorageConfig, type UploadOptions, type UploadResult } from 'stratal/storage';
|
|
2
|
+
/**
|
|
3
|
+
* Stored file representation in memory
|
|
4
|
+
*/
|
|
5
|
+
export interface StoredFile {
|
|
6
|
+
content: Uint8Array;
|
|
7
|
+
mimeType: string;
|
|
8
|
+
size: number;
|
|
9
|
+
metadata?: Record<string, string>;
|
|
10
|
+
uploadedAt: Date;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* FakeStorageService
|
|
14
|
+
*
|
|
15
|
+
* In-memory storage implementation for testing.
|
|
16
|
+
* Registered by default in TestingModuleBuilder.
|
|
17
|
+
*
|
|
18
|
+
* Similar to Laravel's Storage::fake() - stores files in memory
|
|
19
|
+
* and provides assertion helpers for testing.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Access via TestingModule
|
|
24
|
+
* module.storage.assertExists('path/to/file.pdf')
|
|
25
|
+
* module.storage.assertMissing('deleted/file.pdf')
|
|
26
|
+
* module.storage.clear() // Reset between tests
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class FakeStorageService extends StorageService {
|
|
30
|
+
protected readonly storageManager: StorageManagerService;
|
|
31
|
+
protected readonly options: StorageConfig;
|
|
32
|
+
private files;
|
|
33
|
+
constructor(storageManager: StorageManagerService, options: StorageConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Upload content to fake storage
|
|
36
|
+
*/
|
|
37
|
+
upload(body: StreamingBlobPayloadInputTypes, relativePath: string, options: UploadOptions, disk?: string): Promise<UploadResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Download a file from fake storage
|
|
40
|
+
*/
|
|
41
|
+
download(path: string): Promise<DownloadResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Delete a file from fake storage
|
|
44
|
+
*/
|
|
45
|
+
delete(path: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a file exists in fake storage
|
|
48
|
+
*/
|
|
49
|
+
exists(path: string): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Generate a fake presigned download URL
|
|
52
|
+
*/
|
|
53
|
+
getPresignedDownloadUrl(path: string, expiresIn?: number): Promise<PresignedUrlResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Generate a fake presigned upload URL
|
|
56
|
+
*/
|
|
57
|
+
getPresignedUploadUrl(path: string, expiresIn?: number): Promise<PresignedUrlResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Generate a fake presigned delete URL
|
|
60
|
+
*/
|
|
61
|
+
getPresignedDeleteUrl(path: string, expiresIn?: number): Promise<PresignedUrlResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Chunked upload (same as regular upload for fake)
|
|
64
|
+
*/
|
|
65
|
+
chunkedUpload(body: StreamingBlobPayloadInputTypes, path: string, options: Omit<UploadOptions, 'size'> & {
|
|
66
|
+
size?: number;
|
|
67
|
+
}, disk?: string): Promise<UploadResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Assert that a file exists at the given path
|
|
70
|
+
*
|
|
71
|
+
* @param path - Path to check
|
|
72
|
+
* @throws AssertionError if file does not exist
|
|
73
|
+
*/
|
|
74
|
+
assertExists(path: string): void;
|
|
75
|
+
/**
|
|
76
|
+
* Assert that a file does NOT exist at the given path
|
|
77
|
+
*
|
|
78
|
+
* @param path - Path to check
|
|
79
|
+
* @throws AssertionError if file exists
|
|
80
|
+
*/
|
|
81
|
+
assertMissing(path: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* Assert storage is empty
|
|
84
|
+
*
|
|
85
|
+
* @throws AssertionError if any files exist
|
|
86
|
+
*/
|
|
87
|
+
assertEmpty(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Assert storage has exactly N files
|
|
90
|
+
*
|
|
91
|
+
* @param count - Expected number of files
|
|
92
|
+
* @throws AssertionError if count doesn't match
|
|
93
|
+
*/
|
|
94
|
+
assertCount(count: number): void;
|
|
95
|
+
/**
|
|
96
|
+
* Get all stored files (for inspection)
|
|
97
|
+
*/
|
|
98
|
+
getStoredFiles(): Map<string, StoredFile>;
|
|
99
|
+
/**
|
|
100
|
+
* Get all stored file paths
|
|
101
|
+
*/
|
|
102
|
+
getStoredPaths(): string[];
|
|
103
|
+
/**
|
|
104
|
+
* Get a specific file by path
|
|
105
|
+
*/
|
|
106
|
+
getFile(path: string): StoredFile | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Clear all stored files (call in beforeEach for test isolation)
|
|
109
|
+
*/
|
|
110
|
+
clear(): void;
|
|
111
|
+
private createPresignedUrl;
|
|
112
|
+
private bodyToUint8Array;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=fake-storage.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-storage.service.d.ts","sourceRoot":"","sources":["../../src/storage/fake-storage.service.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,qBAAqB,EACrB,cAAc,EACd,8BAA8B,EAC9B,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAA;AAGxB;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,UAAU,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,IAAI,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,kBAAmB,SAAQ,cAAc;IAKlD,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,qBAAqB;IAExD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,aAAa;IAN3C,OAAO,CAAC,KAAK,CAAgC;gBAIxB,cAAc,EAAE,qBAAqB,EAErC,OAAO,EAAE,aAAa;IAK3C;;OAEG;IACG,MAAM,CACV,IAAI,EAAE,8BAA8B,EACpC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,aAAa,EACtB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,CAAC;IAsBxB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsB/C;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnC;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItC;;OAEG;IACH,uBAAuB,CACrB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC;IAI9B;;OAEG;IACH,qBAAqB,CACnB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC;IAI9B;;OAEG;IACH,qBAAqB,CACnB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC;IAI9B;;OAEG;IACG,aAAa,CACjB,IAAI,EAAE,8BAA8B,EACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EACxD,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,CAAC;IAWxB;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOhC;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOjC;;;;OAIG;IACH,WAAW,IAAI,IAAI;IAOnB;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOhC;;OAEG;IACH,cAAc,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAIzC;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI7C;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,kBAAkB;YAeZ,gBAAgB;CAiC/B"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { inject, Transient } from 'stratal';
|
|
14
|
+
import { FileNotFoundError, STORAGE_TOKENS, StorageManagerService, StorageService, } from 'stratal/storage';
|
|
15
|
+
import { expect } from 'vitest';
|
|
16
|
+
/**
|
|
17
|
+
* FakeStorageService
|
|
18
|
+
*
|
|
19
|
+
* In-memory storage implementation for testing.
|
|
20
|
+
* Registered by default in TestingModuleBuilder.
|
|
21
|
+
*
|
|
22
|
+
* Similar to Laravel's Storage::fake() - stores files in memory
|
|
23
|
+
* and provides assertion helpers for testing.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Access via TestingModule
|
|
28
|
+
* module.storage.assertExists('path/to/file.pdf')
|
|
29
|
+
* module.storage.assertMissing('deleted/file.pdf')
|
|
30
|
+
* module.storage.clear() // Reset between tests
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
let FakeStorageService = class FakeStorageService extends StorageService {
|
|
34
|
+
storageManager;
|
|
35
|
+
options;
|
|
36
|
+
files = new Map();
|
|
37
|
+
constructor(storageManager, options) {
|
|
38
|
+
super(storageManager, options);
|
|
39
|
+
this.storageManager = storageManager;
|
|
40
|
+
this.options = options;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Upload content to fake storage
|
|
44
|
+
*/
|
|
45
|
+
async upload(body, relativePath, options, disk) {
|
|
46
|
+
const content = await this.bodyToUint8Array(body);
|
|
47
|
+
const diskName = this.resolveDisk(disk);
|
|
48
|
+
this.files.set(relativePath, {
|
|
49
|
+
content,
|
|
50
|
+
mimeType: options.mimeType ?? 'application/octet-stream',
|
|
51
|
+
size: options.size,
|
|
52
|
+
metadata: options.metadata,
|
|
53
|
+
uploadedAt: new Date(),
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
path: relativePath,
|
|
57
|
+
disk: diskName,
|
|
58
|
+
fullPath: relativePath,
|
|
59
|
+
size: options.size,
|
|
60
|
+
mimeType: options.mimeType ?? 'application/octet-stream',
|
|
61
|
+
uploadedAt: new Date(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Download a file from fake storage
|
|
66
|
+
*/
|
|
67
|
+
download(path) {
|
|
68
|
+
const file = this.files.get(path);
|
|
69
|
+
if (!file) {
|
|
70
|
+
return Promise.reject(new FileNotFoundError(path));
|
|
71
|
+
}
|
|
72
|
+
return Promise.resolve({
|
|
73
|
+
toStream: () => new ReadableStream({
|
|
74
|
+
start(controller) {
|
|
75
|
+
controller.enqueue(file.content);
|
|
76
|
+
controller.close();
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
toString: () => Promise.resolve(new TextDecoder().decode(file.content)),
|
|
80
|
+
toArrayBuffer: () => Promise.resolve(file.content),
|
|
81
|
+
contentType: file.mimeType,
|
|
82
|
+
size: file.size,
|
|
83
|
+
metadata: file.metadata,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Delete a file from fake storage
|
|
88
|
+
*/
|
|
89
|
+
delete(path) {
|
|
90
|
+
this.files.delete(path);
|
|
91
|
+
return Promise.resolve();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if a file exists in fake storage
|
|
95
|
+
*/
|
|
96
|
+
exists(path) {
|
|
97
|
+
return Promise.resolve(this.files.has(path));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Generate a fake presigned download URL
|
|
101
|
+
*/
|
|
102
|
+
getPresignedDownloadUrl(path, expiresIn) {
|
|
103
|
+
return Promise.resolve(this.createPresignedUrl(path, 'GET', expiresIn));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Generate a fake presigned upload URL
|
|
107
|
+
*/
|
|
108
|
+
getPresignedUploadUrl(path, expiresIn) {
|
|
109
|
+
return Promise.resolve(this.createPresignedUrl(path, 'PUT', expiresIn));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Generate a fake presigned delete URL
|
|
113
|
+
*/
|
|
114
|
+
getPresignedDeleteUrl(path, expiresIn) {
|
|
115
|
+
return Promise.resolve(this.createPresignedUrl(path, 'DELETE', expiresIn));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Chunked upload (same as regular upload for fake)
|
|
119
|
+
*/
|
|
120
|
+
async chunkedUpload(body, path, options, disk) {
|
|
121
|
+
const content = await this.bodyToUint8Array(body);
|
|
122
|
+
const size = options.size ?? content.length;
|
|
123
|
+
return this.upload(body, path, { ...options, size }, disk);
|
|
124
|
+
}
|
|
125
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
126
|
+
// Test Assertion Helpers
|
|
127
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
128
|
+
/**
|
|
129
|
+
* Assert that a file exists at the given path
|
|
130
|
+
*
|
|
131
|
+
* @param path - Path to check
|
|
132
|
+
* @throws AssertionError if file does not exist
|
|
133
|
+
*/
|
|
134
|
+
assertExists(path) {
|
|
135
|
+
expect(this.files.has(path), `Expected file to exist at: ${path}\nStored files: ${this.getStoredPaths().join(', ') || '(none)'}`).toBe(true);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Assert that a file does NOT exist at the given path
|
|
139
|
+
*
|
|
140
|
+
* @param path - Path to check
|
|
141
|
+
* @throws AssertionError if file exists
|
|
142
|
+
*/
|
|
143
|
+
assertMissing(path) {
|
|
144
|
+
expect(this.files.has(path), `Expected file NOT to exist at: ${path}`).toBe(false);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Assert storage is empty
|
|
148
|
+
*
|
|
149
|
+
* @throws AssertionError if any files exist
|
|
150
|
+
*/
|
|
151
|
+
assertEmpty() {
|
|
152
|
+
expect(this.files.size, `Expected storage to be empty but found ${this.files.size} files: ${this.getStoredPaths().join(', ')}`).toBe(0);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Assert storage has exactly N files
|
|
156
|
+
*
|
|
157
|
+
* @param count - Expected number of files
|
|
158
|
+
* @throws AssertionError if count doesn't match
|
|
159
|
+
*/
|
|
160
|
+
assertCount(count) {
|
|
161
|
+
expect(this.files.size, `Expected ${count} files in storage but found ${this.files.size}`).toBe(count);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get all stored files (for inspection)
|
|
165
|
+
*/
|
|
166
|
+
getStoredFiles() {
|
|
167
|
+
return new Map(this.files);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get all stored file paths
|
|
171
|
+
*/
|
|
172
|
+
getStoredPaths() {
|
|
173
|
+
return Array.from(this.files.keys());
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get a specific file by path
|
|
177
|
+
*/
|
|
178
|
+
getFile(path) {
|
|
179
|
+
return this.files.get(path);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Clear all stored files (call in beforeEach for test isolation)
|
|
183
|
+
*/
|
|
184
|
+
clear() {
|
|
185
|
+
this.files.clear();
|
|
186
|
+
}
|
|
187
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
188
|
+
// Private Helpers
|
|
189
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
190
|
+
createPresignedUrl(path, method, expiresIn = 300) {
|
|
191
|
+
const expiresAt = new Date(Date.now() + expiresIn * 1000);
|
|
192
|
+
return {
|
|
193
|
+
url: `https://fake-storage.test/${path}?method=${method}&expires=${expiresAt.toISOString()}`,
|
|
194
|
+
expiresIn,
|
|
195
|
+
expiresAt,
|
|
196
|
+
method,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
async bodyToUint8Array(body) {
|
|
200
|
+
if (!body) {
|
|
201
|
+
return new Uint8Array(0);
|
|
202
|
+
}
|
|
203
|
+
if (body instanceof Uint8Array) {
|
|
204
|
+
return body;
|
|
205
|
+
}
|
|
206
|
+
if (body instanceof ArrayBuffer) {
|
|
207
|
+
return new Uint8Array(body);
|
|
208
|
+
}
|
|
209
|
+
if (typeof body === 'string') {
|
|
210
|
+
return new TextEncoder().encode(body);
|
|
211
|
+
}
|
|
212
|
+
if (body instanceof Blob) {
|
|
213
|
+
const buffer = await body.arrayBuffer();
|
|
214
|
+
return new Uint8Array(buffer);
|
|
215
|
+
}
|
|
216
|
+
if (body instanceof ReadableStream) {
|
|
217
|
+
return new Uint8Array(await new Response(body).arrayBuffer());
|
|
218
|
+
}
|
|
219
|
+
// FormData or URLSearchParams - convert via Response
|
|
220
|
+
if (body instanceof FormData || body instanceof URLSearchParams) {
|
|
221
|
+
return new Uint8Array(await new Response(body).arrayBuffer());
|
|
222
|
+
}
|
|
223
|
+
return new Uint8Array(0);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
FakeStorageService = __decorate([
|
|
227
|
+
Transient(STORAGE_TOKENS.StorageService),
|
|
228
|
+
__param(0, inject(STORAGE_TOKENS.StorageManager)),
|
|
229
|
+
__param(1, inject(STORAGE_TOKENS.Options)),
|
|
230
|
+
__metadata("design:paramtypes", [StorageManagerService, Object])
|
|
231
|
+
], FakeStorageService);
|
|
232
|
+
export { FakeStorageService };
|
|
233
|
+
//# sourceMappingURL=fake-storage.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-storage.service.js","sourceRoot":"","sources":["../../src/storage/fake-storage.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAmB,MAAM,wBAAwB,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stratal/testing",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Testing utilities and mocks for Stratal framework applications",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Stratal Contributors",
|
|
8
|
+
"homepage": "https://github.com/strataljs/stratal#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/strataljs/stratal.git",
|
|
12
|
+
"directory": "packages/testing"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/strataljs/stratal/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"stratal",
|
|
19
|
+
"testing",
|
|
20
|
+
"mocks",
|
|
21
|
+
"cloudflare-workers",
|
|
22
|
+
"vitest"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18.0.0"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./mocks": {
|
|
37
|
+
"types": "./dist/mocks/index.d.ts",
|
|
38
|
+
"import": "./dist/mocks/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./mocks/nodemailer": {
|
|
41
|
+
"types": "./dist/mocks/nodemailer.d.ts",
|
|
42
|
+
"import": "./dist/mocks/nodemailer.js"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc -p tsconfig.build.json",
|
|
47
|
+
"clean": "rm -rf dist",
|
|
48
|
+
"prebuild": "yarn clean",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"lint": "npx eslint .",
|
|
51
|
+
"lint:fix": "npx eslint --fix ."
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@faker-js/faker": "^9.7.0",
|
|
55
|
+
"@golevelup/ts-vitest": "^2.1.1"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"stratal": "^0.0.1",
|
|
59
|
+
"vitest": "^3.2.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@cloudflare/vitest-pool-workers": "^0.9.0",
|
|
63
|
+
"@cloudflare/workers-types": "^4.20251121.0",
|
|
64
|
+
"@types/node": "^24.10.0",
|
|
65
|
+
"stratal": "workspace:*",
|
|
66
|
+
"typescript": "^5.8.3",
|
|
67
|
+
"vitest": "^3.2.0"
|
|
68
|
+
}
|
|
69
|
+
}
|