@api-client/core 0.18.38 → 0.18.40

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.
Files changed (56) hide show
  1. package/RELEASE_SETUP.md +4 -2
  2. package/build/src/browser.d.ts +1 -1
  3. package/build/src/browser.d.ts.map +1 -1
  4. package/build/src/browser.js.map +1 -1
  5. package/build/src/mocking/ModelingMock.d.ts +19 -0
  6. package/build/src/mocking/ModelingMock.d.ts.map +1 -0
  7. package/build/src/mocking/ModelingMock.js +19 -0
  8. package/build/src/mocking/ModelingMock.js.map +1 -0
  9. package/build/src/mocking/ProjectMock.js +1 -1
  10. package/build/src/mocking/ProjectMock.js.map +1 -1
  11. package/build/src/mocking/lib/File.d.ts +34 -0
  12. package/build/src/mocking/lib/File.d.ts.map +1 -0
  13. package/build/src/mocking/lib/File.js +64 -0
  14. package/build/src/mocking/lib/File.js.map +1 -0
  15. package/build/src/mocking/lib/Group.d.ts +16 -0
  16. package/build/src/mocking/lib/Group.d.ts.map +1 -0
  17. package/build/src/mocking/lib/Group.js +39 -0
  18. package/build/src/mocking/lib/Group.js.map +1 -0
  19. package/build/src/mocking/lib/Invitation.d.ts +16 -0
  20. package/build/src/mocking/lib/Invitation.d.ts.map +1 -0
  21. package/build/src/mocking/lib/Invitation.js +42 -0
  22. package/build/src/mocking/lib/Invitation.js.map +1 -0
  23. package/build/src/mocking/lib/Organization.d.ts +16 -0
  24. package/build/src/mocking/lib/Organization.d.ts.map +1 -0
  25. package/build/src/mocking/lib/Organization.js +34 -0
  26. package/build/src/mocking/lib/Organization.js.map +1 -0
  27. package/build/src/mocking/lib/Patch.d.ts +29 -0
  28. package/build/src/mocking/lib/Patch.d.ts.map +1 -0
  29. package/build/src/mocking/lib/Patch.js +102 -0
  30. package/build/src/mocking/lib/Patch.js.map +1 -0
  31. package/build/src/mocking/lib/Trash.d.ts +16 -0
  32. package/build/src/mocking/lib/Trash.d.ts.map +1 -0
  33. package/build/src/mocking/lib/Trash.js +39 -0
  34. package/build/src/mocking/lib/Trash.js.map +1 -0
  35. package/build/src/mocking/lib/User.d.ts +12 -12
  36. package/build/src/mocking/lib/User.d.ts.map +1 -1
  37. package/build/src/mocking/lib/User.js +29 -26
  38. package/build/src/mocking/lib/User.js.map +1 -1
  39. package/build/src/sdk/SdkMock.d.ts +129 -156
  40. package/build/src/sdk/SdkMock.d.ts.map +1 -1
  41. package/build/src/sdk/SdkMock.js +816 -634
  42. package/build/src/sdk/SdkMock.js.map +1 -1
  43. package/build/tsconfig.tsbuildinfo +1 -1
  44. package/data/models/example-generator-api.json +6 -6
  45. package/package.json +7 -4
  46. package/src/mocking/ModelingMock.ts +19 -0
  47. package/src/mocking/ProjectMock.ts +1 -1
  48. package/src/mocking/lib/File.ts +72 -0
  49. package/src/mocking/lib/Group.ts +52 -0
  50. package/src/mocking/lib/Invitation.ts +58 -0
  51. package/src/mocking/lib/Organization.ts +42 -0
  52. package/src/mocking/lib/Patch.ts +128 -0
  53. package/src/mocking/lib/Trash.ts +47 -0
  54. package/src/mocking/lib/User.ts +30 -29
  55. package/src/sdk/SdkMock.ts +1141 -692
  56. package/TESTING_READY.md +0 -114
@@ -1,51 +1,53 @@
1
- import { nanoid } from '../nanoid.js'
1
+ import {
2
+ type ResponseGenerator,
3
+ setupWorker,
4
+ type MockHandler,
5
+ type SetupWorkerOptions,
6
+ type InterceptOptions,
7
+ } from '@jarrodek/amw'
2
8
  import type { IOrganization } from '../models/store/Organization.js'
3
9
  import type { GroupSchema } from '../models/store/Group.js'
4
10
  import type { IUser } from '../models/store/User.js'
5
11
  import type { InvitationSchema } from '../models/store/Invitation.js'
6
- import { OrganizationKind, GroupKind, InvitationKind } from '../models/kinds.js'
7
- import { Kind as UserKind } from '../models/store/User.js'
8
- import { File, type IFile, type FileBreadcrumb } from '../models/store/File.js'
9
- import { CertificateFileKind, DomainFileKind, FolderKind, ProjectKind } from '../models/kinds.js'
12
+ import { type IFile, type FileBreadcrumb } from '../models/store/File.js'
10
13
  import type { ContextListResult, IBulkOperationResult } from '../events/BaseEvents.js'
11
- import type { MediaPatchRevision } from '../patch/types.js'
12
- import type { IFolder } from '../models/Folder.js'
13
14
  import type { TrashEntry } from '../models/TrashEntry.js'
14
- import type { StoreSdk } from './StoreSdkWeb.js'
15
- import * as sinon from 'sinon'
16
- import { Exception } from '../exceptions/exception.js'
15
+ import { RouteBuilder } from './RouteBuilder.js'
16
+ import { ModelingMock } from '../mocking/ModelingMock.js'
17
17
 
18
- /**
19
- * Options for customizing mock responses.
20
- */
21
- export interface MockResponseOptions {
22
- /**
23
- * Custom response data to return instead of generated random data.
24
- */
25
- data?: unknown
18
+ export interface MockResult {
26
19
  /**
27
- * HTTP status code to return. Defaults to 200.
20
+ * Custom response generator for the mock intercept.
28
21
  */
29
- status?: number
22
+ response?: ResponseGenerator
30
23
  /**
31
- * Custom headers to include in the response.
24
+ * If true, the request body will be generated using the body generator.
25
+ * It is useful when only setting up response headers or status code, but
26
+ * the request body should still be generated, even when missing in the `response` option.
32
27
  */
33
- headers?: Record<string, string>
28
+ forceBody?: boolean
34
29
  }
35
30
 
36
- /**
37
- * A stub reference that can be used to restore the original behavior.
38
- */
39
- export interface StubReference {
31
+ export interface MockListResult extends MockResult {
32
+ /**
33
+ * Number of items to generate in the list response.
34
+ */
35
+ size?: number
40
36
  /**
41
- * Restores the original behavior.
37
+ * If true, the response will include a cursor for pagination.
38
+ * If false, the response will not include a cursor.
39
+ * If not set, a random choice will be made.
42
40
  */
43
- restore: () => void
41
+ cursor?: boolean
44
42
  }
45
43
 
46
44
  /**
47
- * SDK mocking utility for testing. Provides simple API to mock SDK calls
48
- * with random or custom responses.
45
+ * SDK mocking utility for testing. Uses Service Workers to intercept HTTP requests
46
+ * and provide mock responses for API calls.
47
+ *
48
+ * This class uses the `@jarrodek/amw` library to set up a Service Worker that intercepts
49
+ * fetch requests matching the configured routes. Each method adds an intercept for a specific
50
+ * API endpoint, returning either random generated data or custom responses.
49
51
  *
50
52
  * @example
51
53
  * ```typescript
@@ -53,194 +55,527 @@ export interface StubReference {
53
55
  * import { StoreSdk } from '@api-client/core/sdk/StoreSdkWeb.js';
54
56
  *
55
57
  * const sdk = new StoreSdk('http://localhost:8080');
56
- * const mocker = new SdkMock(sdk);
58
+ * const mocker = new SdkMock({
59
+ * swPath: '/mockServiceWorker.js', // Path to the Service Worker script
60
+ * base: 'http://localhost:8080' // Base URL matching the SDK
61
+ * });
62
+ *
63
+ * // Initialize the Service Worker
64
+ * await mocker.setup();
65
+ *
66
+ * // Add intercept - returns random organizations
67
+ * await mocker.organizations.list();
57
68
  *
58
- * // Simple usage - returns random valid organization
59
- * const stub1 = mocker.organizations.list();
69
+ * // Custom response with specific data
70
+ * await mocker.organizations.create({
71
+ * response: {
72
+ * status: 201,
73
+ * headers: { 'Content-Type': 'application/json', 'X-Custom-Header': 'value' },
74
+ * body: JSON.stringify({ key: 'custom-id', name: 'Custom Org' })
75
+ * }
76
+ * });
60
77
  *
61
- * // Custom response
62
- * const stub2 = mocker.organizations.create({
63
- * data: { key: 'org-1', name: 'Test Org', ... }
78
+ * // Control pagination in list responses
79
+ * await mocker.groups.list({
80
+ * size: 10, // Number of items to generate
81
+ * cursor: true // Include pagination cursor
64
82
  * });
65
83
  *
66
- * // Custom status and headers
67
- * const stub3 = mocker.users.me({
68
- * status: 404,
69
- * headers: { 'X-Custom': 'value' }
84
+ * // Error simulation
85
+ * await mocker.users.me({
86
+ * response: {
87
+ * status: 404,
88
+ * headers: { 'Content-Type': 'application/json' },
89
+ * body: JSON.stringify({ error: 'Not found' })
90
+ * }
70
91
  * });
71
92
  *
72
- * // Restore all stubs
73
- * mocker.restore();
93
+ * // Remove all intercepts (keep Service Worker active)
94
+ * await mocker.reset();
95
+ *
96
+ * // Stop and remove the Service Worker
97
+ * await mocker.teardown();
74
98
  * ```
99
+ *
100
+ * @TODO: Add a in-memory state store so that mocks can maintain state across requests.
101
+ * This way, operations like create, update, delete can affect subsequent list/read calls
102
+ * and we can mimic the API behavior more closely.
75
103
  */
76
104
  export class SdkMock {
77
- private stubs: StubReference[] = []
105
+ handler?: MockHandler
106
+ gen = new ModelingMock()
107
+
108
+ constructor(public options?: SetupWorkerOptions) {}
109
+
110
+ /**
111
+ * Initializes the mock handler. It uses options provided in the constructor.
112
+ * It has to be called before using any of the mock methods.
113
+ */
114
+ async setup(): Promise<void> {
115
+ this.handler = await setupWorker(this.options)
116
+ }
117
+
118
+ /**
119
+ * Removes the mock worker and all intercepts.
120
+ */
121
+ async teardown(): Promise<void> {
122
+ await this.mock.stop()
123
+ }
124
+
125
+ /**
126
+ * Removes all added intercepts.
127
+ */
128
+ async reset(): Promise<void> {
129
+ await this.mock.reset()
130
+ }
131
+
132
+ get mock(): MockHandler {
133
+ if (!this.handler) {
134
+ throw new Error('Mock handler not initialized. Call setup() first.')
135
+ }
136
+ return this.handler
137
+ }
138
+
139
+ protected createCursorOption(init: MockListResult = {}): string | undefined {
140
+ if (init.cursor === false) {
141
+ return undefined
142
+ }
143
+ const hasCursor = init.cursor === true ? true : this.gen.faker.datatype.boolean()
144
+ if (!hasCursor) {
145
+ return undefined
146
+ }
147
+ return this.gen.faker.internet.jwt()
148
+ }
78
149
 
79
- constructor(private sdk: StoreSdk) {}
150
+ protected createDefaultResponse(
151
+ status: number,
152
+ headers?: Record<string, string>,
153
+ body?: () => string,
154
+ userConfig?: MockResult
155
+ ): ResponseGenerator {
156
+ let respond: ResponseGenerator
157
+ if (userConfig?.response) {
158
+ // user config takes precedence
159
+ respond = userConfig.response
160
+ } else {
161
+ respond = {}
162
+ }
163
+ // Set defaults if not provided in user config
164
+ if (!respond.status) {
165
+ respond.status = status
166
+ }
167
+ // only set headers if the user didn't configure the response only.
168
+ // The user may want to remove default headers.
169
+ if (!userConfig || !userConfig.response) {
170
+ respond.headers = headers
171
+ }
172
+ if (!respond.body && userConfig?.forceBody && body) {
173
+ // when body is missing and forceBody is set, generate the body
174
+ respond.body = body()
175
+ } else if (body && (!userConfig || !userConfig.response)) {
176
+ // we set the body by default when the user config is missing
177
+ respond.body = body()
178
+ }
179
+ return respond
180
+ }
80
181
 
81
182
  /**
82
183
  * Organization API mocks.
83
184
  */
84
185
  organizations = {
85
186
  /**
86
- * Mocks the `organizations.list()` method.
87
- * @param options Optional response customization.
88
- * @returns A stub reference that can be used to restore the original behavior.
187
+ * Adds an intercept to mock the `organizations.list()` method.
188
+ * @param options Optional response configuration
89
189
  */
90
- list: (options?: MockResponseOptions): StubReference => {
91
- return this.createStub('organizations', 'list', () => {
92
- const defaultData = {
93
- items: [this.generateOrganization(), this.generateOrganization()],
94
- nextPageToken: undefined,
95
- }
96
- if (options?.status !== undefined && options.status !== 200) {
97
- throw new Exception('Mocked error', { status: options.status })
98
- }
99
- return (options?.data ?? defaultData) as unknown
100
- })
190
+ list: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
191
+ const { mock } = this
192
+ // const respond = init?.response ?? {
193
+ // status: 200,
194
+ // headers: { 'content-type': 'application/json' },
195
+ // body: JSON.stringify({
196
+ // items: this.gen.organization.organizations(init?.size ?? 5),
197
+ // cursor: this.createCursorOption(init),
198
+ // } as ContextListResult<IOrganization>),
199
+ // }
200
+ const respond = this.createDefaultResponse(
201
+ 200,
202
+ { 'content-type': 'application/json' },
203
+ () =>
204
+ JSON.stringify({
205
+ items: this.gen.organization.organizations(init?.size ?? 5),
206
+ cursor: this.createCursorOption(init),
207
+ } as ContextListResult<IOrganization>),
208
+ init
209
+ )
210
+ await mock.add(
211
+ {
212
+ match: {
213
+ uri: RouteBuilder.organizations(),
214
+ methods: ['GET'],
215
+ },
216
+ respond,
217
+ },
218
+ options
219
+ )
101
220
  },
102
221
 
103
222
  /**
104
- * Mocks the `organizations.create()` method.
105
- * @param options Optional response customization.
106
- * @returns A stub reference that can be used to restore the original behavior.
223
+ * Adds an intercept to mock the `organizations.create()` method.
224
+ * @param options Optional response configuration
107
225
  */
108
- create: (options?: MockResponseOptions): StubReference => {
109
- return this.createStub('organizations', 'create', () => {
110
- const defaultData = this.generateOrganization()
111
- if (options?.status !== undefined && options.status !== 200) {
112
- throw new Exception('Mocked error', { status: options.status })
113
- }
114
- return (options?.data ?? defaultData) as unknown
115
- })
226
+ create: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
227
+ const { mock } = this
228
+ // const respond = init?.response ?? {
229
+ // status: 200,
230
+ // headers: { 'content-type': 'application/json' },
231
+ // body: JSON.stringify(this.gen.organization.organization()),
232
+ // }
233
+ const respond = this.createDefaultResponse(
234
+ 200,
235
+ { 'content-type': 'application/json' },
236
+ () => JSON.stringify(this.gen.organization.organization()),
237
+ init
238
+ )
239
+ await mock.add(
240
+ {
241
+ match: {
242
+ uri: RouteBuilder.organizations(),
243
+ methods: ['POST'],
244
+ },
245
+ respond,
246
+ },
247
+ options
248
+ )
116
249
  },
117
250
 
118
251
  invitations: {
119
- list: (options?: MockResponseOptions): StubReference => {
120
- return this.createStub('organizations.invitations', 'list', () => {
121
- const defaultData = {
122
- items: [this.generateInvitation(), this.generateInvitation()],
123
- }
124
- if (options?.status !== undefined && options.status !== 200) {
125
- throw new Exception('Mocked error', { status: options.status })
126
- }
127
- return (options?.data ?? defaultData) as unknown
128
- })
252
+ list: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
253
+ const { mock } = this
254
+ // const respond = init?.response ?? {
255
+ // status: 200,
256
+ // headers: { 'content-type': 'application/json' },
257
+ // body: JSON.stringify({
258
+ // items: this.gen.invitation.invitations(init?.size ?? 5),
259
+ // cursor: this.createCursorOption(init),
260
+ // } as ContextListResult<InvitationSchema>),
261
+ // }
262
+ const respond = this.createDefaultResponse(
263
+ 200,
264
+ { 'content-type': 'application/json' },
265
+ () => {
266
+ const obj: ContextListResult<InvitationSchema> = {
267
+ items: this.gen.invitation.invitations(init?.size ?? 5),
268
+ cursor: this.createCursorOption(init),
269
+ }
270
+ return JSON.stringify(obj)
271
+ },
272
+ init
273
+ )
274
+ await mock.add(
275
+ {
276
+ match: {
277
+ uri: RouteBuilder.invitations(':oid'),
278
+ methods: ['GET'],
279
+ },
280
+ respond,
281
+ },
282
+ options
283
+ )
129
284
  },
130
- create: (options?: MockResponseOptions): StubReference => {
131
- return this.createStub('organizations.invitations', 'create', () => {
132
- const defaultData = this.generateInvitation()
133
- if (options?.status !== undefined && options.status !== 200) {
134
- throw new Exception('Mocked error', { status: options.status })
135
- }
136
- return (options?.data ?? defaultData) as unknown
137
- })
285
+ create: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
286
+ const { mock } = this
287
+ // const respond = init?.response ?? {
288
+ // status: 200,
289
+ // headers: { 'content-type': 'application/json' },
290
+ // body: JSON.stringify(this.gen.invitation.invitation()),
291
+ // }
292
+ const respond = this.createDefaultResponse(
293
+ 200,
294
+ { 'content-type': 'application/json' },
295
+ () => JSON.stringify(this.gen.invitation.invitation()),
296
+ init
297
+ )
298
+ await mock.add(
299
+ {
300
+ match: {
301
+ uri: RouteBuilder.invitations(':oid'),
302
+ methods: ['POST'],
303
+ },
304
+ respond,
305
+ },
306
+ options
307
+ )
138
308
  },
139
- findByToken: (options?: MockResponseOptions): StubReference => {
140
- return this.createStub('organizations.invitations', 'findByToken', () => {
141
- const defaultData = this.generateInvitation()
142
- if (options?.status !== undefined && options.status !== 200) {
143
- throw new Exception('Mocked error', { status: options.status })
144
- }
145
- return (options?.data ?? defaultData) as unknown
146
- })
309
+ findByToken: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
310
+ const { mock } = this
311
+ // const respond = init?.response ?? {
312
+ // status: 200,
313
+ // headers: { 'content-type': 'application/json' },
314
+ // body: JSON.stringify(this.gen.invitation.invitation()),
315
+ // }
316
+ const respond = this.createDefaultResponse(
317
+ 200,
318
+ { 'content-type': 'application/json' },
319
+ () => JSON.stringify(this.gen.invitation.invitation()),
320
+ init
321
+ )
322
+
323
+ await mock.add(
324
+ {
325
+ match: {
326
+ uri: RouteBuilder.findInvitation(),
327
+ methods: ['GET'],
328
+ },
329
+ respond,
330
+ },
331
+ options
332
+ )
147
333
  },
148
- decline: (options?: MockResponseOptions): StubReference => {
149
- return this.createStub('organizations.invitations', 'decline', () => {
150
- const defaultData = this.generateInvitation()
151
- if (options?.status !== undefined && options.status !== 200) {
152
- throw new Exception('Mocked error', { status: options.status })
153
- }
154
- return (options?.data ?? defaultData) as unknown
155
- })
334
+ decline: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
335
+ const { mock } = this
336
+ // const respond = init?.response ?? {
337
+ // status: 200,
338
+ // headers: { 'content-type': 'application/json' },
339
+ // body: JSON.stringify(this.gen.invitation.invitation()),
340
+ // }
341
+ const respond = this.createDefaultResponse(
342
+ 200,
343
+ { 'content-type': 'application/json' },
344
+ () => JSON.stringify(this.gen.invitation.invitation()),
345
+ init
346
+ )
347
+
348
+ await mock.add(
349
+ {
350
+ match: {
351
+ uri: RouteBuilder.declineInvitation(':oid', ':id'),
352
+ methods: ['POST'],
353
+ },
354
+ respond,
355
+ },
356
+ options
357
+ )
156
358
  },
157
- delete: (options?: MockResponseOptions): StubReference => {
158
- return this.createStub('organizations.invitations', 'delete', () => {
159
- const defaultData = this.generateInvitation()
160
- if (options?.status !== undefined && options.status !== 200) {
161
- throw new Exception('Mocked error', { status: options.status })
162
- }
163
- return (options?.data ?? defaultData) as unknown
164
- })
359
+ delete: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
360
+ const { mock } = this
361
+ // const respond = init?.response ?? {
362
+ // status: 200,
363
+ // headers: { 'content-type': 'application/json' },
364
+ // body: JSON.stringify(this.gen.invitation.invitation()),
365
+ // }
366
+ const respond = this.createDefaultResponse(
367
+ 200,
368
+ { 'content-type': 'application/json' },
369
+ () => JSON.stringify(this.gen.invitation.invitation()),
370
+ init
371
+ )
372
+
373
+ await mock.add(
374
+ {
375
+ match: {
376
+ uri: RouteBuilder.invitation(':oid', ':id'),
377
+ methods: ['DELETE'],
378
+ },
379
+ respond,
380
+ },
381
+ options
382
+ )
165
383
  },
166
- patch: (options?: MockResponseOptions): StubReference => {
167
- return this.createStub('organizations.invitations', 'patch', () => {
168
- const defaultData = this.generateInvitation()
169
- if (options?.status !== undefined && options.status !== 200) {
170
- throw new Exception('Mocked error', { status: options.status })
171
- }
172
- return (options?.data ?? defaultData) as unknown
173
- })
384
+ patch: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
385
+ const { mock } = this
386
+ // const respond = init?.response ?? {
387
+ // status: 200,
388
+ // headers: { 'content-type': 'application/json' },
389
+ // body: JSON.stringify(this.gen.invitation.invitation()),
390
+ // }
391
+ const respond = this.createDefaultResponse(
392
+ 200,
393
+ { 'content-type': 'application/json' },
394
+ () => JSON.stringify(this.gen.invitation.invitation()),
395
+ init
396
+ )
397
+ await mock.add(
398
+ {
399
+ match: {
400
+ uri: RouteBuilder.invitation(':oid', ':id'),
401
+ methods: ['PATCH'],
402
+ },
403
+ respond,
404
+ },
405
+ options
406
+ )
174
407
  },
175
- resend: (options?: MockResponseOptions): StubReference => {
176
- return this.createStub('organizations.invitations', 'resend', () => {
177
- const defaultData = this.generateInvitation()
178
- if (options?.status !== undefined && options.status !== 200) {
179
- throw new Exception('Mocked error', { status: options.status })
180
- }
181
- return (options?.data ?? defaultData) as unknown
182
- })
408
+ resend: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
409
+ const { mock } = this
410
+ // const respond = init?.response ?? {
411
+ // status: 200,
412
+ // headers: { 'content-type': 'application/json' },
413
+ // body: JSON.stringify(this.gen.invitation.invitation()),
414
+ // }
415
+ const respond = this.createDefaultResponse(
416
+ 200,
417
+ { 'content-type': 'application/json' },
418
+ () => JSON.stringify(this.gen.invitation.invitation()),
419
+ init
420
+ )
421
+
422
+ await mock.add(
423
+ {
424
+ match: {
425
+ uri: RouteBuilder.resendInvitation(':oid', ':id'),
426
+ methods: ['PUT'],
427
+ },
428
+ respond,
429
+ },
430
+ options
431
+ )
183
432
  },
184
433
  },
185
434
 
186
435
  users: {
187
- list: (options?: MockResponseOptions): StubReference => {
188
- return this.createStub('organizations.users', 'list', () => {
189
- const defaultData = {
190
- items: [this.generateUser(), this.generateUser()],
191
- }
192
- if (options?.status !== undefined && options.status !== 200) {
193
- throw new Exception('Mocked error', { status: options.status })
194
- }
195
- return (options?.data ?? defaultData) as unknown
196
- })
436
+ list: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
437
+ const { mock } = this
438
+ // const respond = init?.response ?? {
439
+ // status: 200,
440
+ // headers: { 'content-type': 'application/json' },
441
+ // body: JSON.stringify({
442
+ // items: this.gen.user.users(init?.size ?? 5),
443
+ // cursor: this.createCursorOption(init),
444
+ // } as ContextListResult<IUser>),
445
+ // }
446
+ const respond = this.createDefaultResponse(
447
+ 200,
448
+ { 'content-type': 'application/json' },
449
+ () => {
450
+ const obj: ContextListResult<IUser> = {
451
+ items: this.gen.user.users(init?.size ?? 5),
452
+ cursor: this.createCursorOption(init),
453
+ }
454
+ return JSON.stringify(obj)
455
+ },
456
+ init
457
+ )
458
+ await mock.add(
459
+ {
460
+ match: {
461
+ uri: RouteBuilder.organizationUsers(':oid'),
462
+ methods: ['GET'],
463
+ },
464
+ respond,
465
+ },
466
+ options
467
+ )
197
468
  },
198
- read: (options?: MockResponseOptions): StubReference => {
199
- return this.createStub('organizations.users', 'read', () => {
200
- const defaultData = this.generateUser()
201
- if (options?.status !== undefined && options.status !== 200) {
202
- throw new Exception('Mocked error', { status: options.status })
203
- }
204
- return (options?.data ?? defaultData) as unknown
205
- })
469
+ read: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
470
+ const { mock } = this
471
+ // const respond = init?.response ?? {
472
+ // status: 200,
473
+ // headers: { 'content-type': 'application/json' },
474
+ // body: JSON.stringify(this.gen.user.user()),
475
+ // }
476
+ const respond = this.createDefaultResponse(
477
+ 200,
478
+ { 'content-type': 'application/json' },
479
+ () => JSON.stringify(this.gen.user.user()),
480
+ init
481
+ )
482
+ await mock.add(
483
+ {
484
+ match: {
485
+ uri: RouteBuilder.organizationUser(':oid', ':id'),
486
+ methods: ['GET'],
487
+ },
488
+ respond,
489
+ },
490
+ options
491
+ )
206
492
  },
207
- readBatch: (options?: MockResponseOptions): StubReference => {
208
- return this.createStub('organizations.users', 'readBatch', () => {
209
- const defaultData = {
210
- items: [this.generateUser(), this.generateUser()],
211
- }
212
- if (options?.status !== undefined && options.status !== 200) {
213
- throw new Exception('Mocked error', { status: options.status })
214
- }
215
- return (options?.data ?? defaultData) as unknown
216
- })
493
+ readBatch: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
494
+ const { mock } = this
495
+ const path = RouteBuilder.organizationUserBatch(':oid')
496
+ const respond = init?.response ?? {
497
+ status: 200,
498
+ headers: { 'content-type': 'application/json' },
499
+ body: JSON.stringify({
500
+ items: this.gen.user.users(init?.size ?? 5),
501
+ cursor: this.createCursorOption(init),
502
+ } as ContextListResult<IUser>),
503
+ }
504
+ await mock.add(
505
+ {
506
+ match: {
507
+ uri: path,
508
+ methods: ['POST'],
509
+ },
510
+ respond,
511
+ },
512
+ options
513
+ )
217
514
  },
218
- activate: (options?: MockResponseOptions): StubReference => {
219
- return this.createStub('organizations.users', 'activate', () => {
220
- const defaultData = this.generateUser()
221
- if (options?.status !== undefined && options.status !== 200) {
222
- throw new Exception('Mocked error', { status: options.status })
223
- }
224
- return (options?.data ?? defaultData) as unknown
225
- })
515
+ activate: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
516
+ const { mock } = this
517
+ // const respond = init?.response ?? {
518
+ // status: 200,
519
+ // headers: { 'content-type': 'application/json' },
520
+ // body: JSON.stringify(this.gen.user.user()),
521
+ // }
522
+ const respond = this.createDefaultResponse(
523
+ 200,
524
+ { 'content-type': 'application/json' },
525
+ () => JSON.stringify(this.gen.user.user()),
526
+ init
527
+ )
528
+ await mock.add(
529
+ {
530
+ match: {
531
+ uri: RouteBuilder.organizationUserActivate(':oid', ':id'),
532
+ methods: ['POST'],
533
+ },
534
+ respond,
535
+ },
536
+ options
537
+ )
226
538
  },
227
- deactivate: (options?: MockResponseOptions): StubReference => {
228
- return this.createStub('organizations.users', 'deactivate', () => {
229
- const defaultData = this.generateUser()
230
- if (options?.status !== undefined && options.status !== 200) {
231
- throw new Exception('Mocked error', { status: options.status })
232
- }
233
- return (options?.data ?? defaultData) as unknown
234
- })
539
+ deactivate: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
540
+ const { mock } = this
541
+ // const respond = init?.response ?? {
542
+ // status: 200,
543
+ // headers: { 'content-type': 'application/json' },
544
+ // body: JSON.stringify(this.gen.user.user()),
545
+ // }
546
+ const respond = this.createDefaultResponse(
547
+ 200,
548
+ { 'content-type': 'application/json' },
549
+ () => JSON.stringify(this.gen.user.user()),
550
+ init
551
+ )
552
+ await mock.add(
553
+ {
554
+ match: {
555
+ uri: RouteBuilder.organizationUserDeactivate(':oid', ':id'),
556
+ methods: ['POST'],
557
+ },
558
+ respond,
559
+ },
560
+ options
561
+ )
235
562
  },
236
- delete: (options?: MockResponseOptions): StubReference => {
237
- return this.createStub('organizations.users', 'delete', () => {
238
- const status = options?.status ?? 204
239
- if (status !== 204) {
240
- throw new Exception('Mocked error', { status })
241
- }
242
- return undefined
243
- })
563
+ delete: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
564
+ const { mock } = this
565
+ // const respond = init?.response ?? {
566
+ // status: 204,
567
+ // }
568
+ const respond = this.createDefaultResponse(204, undefined, undefined, init)
569
+ await mock.add(
570
+ {
571
+ match: {
572
+ uri: RouteBuilder.organizationUser(':oid', ':id'),
573
+ methods: ['DELETE'],
574
+ },
575
+ respond,
576
+ },
577
+ options
578
+ )
244
579
  },
245
580
  },
246
581
  }
@@ -252,106 +587,175 @@ export class SdkMock {
252
587
  /**
253
588
  * Mocks the `groups.list()` method.
254
589
  * @param options Optional response customization.
255
- * @returns A stub reference that can be used to restore the original behavior.
256
590
  */
257
- list: (options?: MockResponseOptions): StubReference => {
258
- return this.createStub('groups', 'list', () => {
259
- const defaultData = {
260
- items: [this.generateGroup(), this.generateGroup()],
261
- nextPageToken: undefined,
262
- }
263
- if (options?.status !== undefined && options.status !== 200) {
264
- throw new Exception('Mocked error', { status: options.status })
265
- }
266
- return (options?.data ?? defaultData) as unknown
267
- })
591
+ list: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
592
+ const { mock } = this
593
+ // const respond = init?.response ?? {
594
+ // status: 200,
595
+ // headers: { 'content-type': 'application/json' },
596
+ // body: JSON.stringify({
597
+ // items: this.gen.group.groups(init?.size ?? 5),
598
+ // cursor: this.createCursorOption(init),
599
+ // } as ContextListResult<GroupSchema>),
600
+ // }
601
+ const respond = this.createDefaultResponse(
602
+ 200,
603
+ { 'content-type': 'application/json' },
604
+ () => {
605
+ const obj: ContextListResult<GroupSchema> = {
606
+ items: this.gen.group.groups(init?.size ?? 5),
607
+ cursor: this.createCursorOption(init),
608
+ }
609
+ return JSON.stringify(obj)
610
+ },
611
+ init
612
+ )
613
+ await mock.add(
614
+ {
615
+ match: {
616
+ uri: RouteBuilder.groups(':oid'),
617
+ methods: ['GET'],
618
+ },
619
+ respond,
620
+ },
621
+ options
622
+ )
268
623
  },
269
624
 
270
625
  /**
271
626
  * Mocks the `groups.create()` method.
272
627
  * @param options Optional response customization.
273
- * @returns A stub reference that can be used to restore the original behavior.
274
- */
275
- create: (options?: MockResponseOptions): StubReference => {
276
- return this.createStub('groups', 'create', () => {
277
- const defaultData = this.generateGroup()
278
- const status = options?.status ?? 201
279
- if (status !== 201) {
280
- throw new Exception('Mocked error', { status })
281
- }
282
- return (options?.data ?? defaultData) as unknown
283
- })
284
- },
285
-
286
- /**
287
- * Mocks the `groups.read()` method.
288
- * @param options Optional response customization.
289
- * @returns A stub reference that can be used to restore the original behavior.
290
628
  */
291
- read: (options?: MockResponseOptions): StubReference => {
292
- return this.createStub('groups', 'read', () => {
293
- const defaultData = this.generateGroup()
294
- if (options?.status !== undefined && options.status !== 200) {
295
- throw new Exception('Mocked error', { status: options.status })
296
- }
297
- return (options?.data ?? defaultData) as unknown
298
- })
629
+ create: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
630
+ const { mock } = this
631
+ // const respond = init?.response ?? {
632
+ // status: 201,
633
+ // headers: { 'content-type': 'application/json' },
634
+ // body: JSON.stringify(this.gen.group.group()),
635
+ // }
636
+ const respond = this.createDefaultResponse(
637
+ 201,
638
+ { 'content-type': 'application/json' },
639
+ () => JSON.stringify(this.gen.group.group()),
640
+ init
641
+ )
642
+ await mock.add(
643
+ {
644
+ match: {
645
+ uri: RouteBuilder.groups(':oid'),
646
+ methods: ['POST'],
647
+ },
648
+ respond,
649
+ },
650
+ options
651
+ )
299
652
  },
300
653
 
301
654
  /**
302
655
  * Mocks the `groups.update()` method.
303
656
  * @param options Optional response customization.
304
- * @returns A stub reference that can be used to restore the original behavior.
305
657
  */
306
- update: (options?: MockResponseOptions): StubReference => {
307
- return this.createStub('groups', 'update', () => {
308
- const defaultData = this.generateGroup()
309
- if (options?.status !== undefined && options.status !== 200) {
310
- throw new Exception('Mocked error', { status: options.status })
311
- }
312
- return (options?.data ?? defaultData) as unknown
313
- })
658
+ update: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
659
+ const { mock } = this
660
+ // const respond = init?.response ?? {
661
+ // status: 200,
662
+ // headers: { 'content-type': 'application/json' },
663
+ // body: JSON.stringify(this.gen.group.group()),
664
+ // }
665
+ const respond = this.createDefaultResponse(
666
+ 200,
667
+ { 'content-type': 'application/json' },
668
+ () => JSON.stringify(this.gen.group.group()),
669
+ init
670
+ )
671
+ await mock.add(
672
+ {
673
+ match: {
674
+ uri: RouteBuilder.group(':oid', ':key'),
675
+ methods: ['PATCH'],
676
+ },
677
+ respond,
678
+ },
679
+ options
680
+ )
314
681
  },
315
682
 
316
683
  /**
317
684
  * Mocks the `groups.delete()` method.
318
685
  * @param options Optional response customization.
319
- * @returns A stub reference that can be used to restore the original behavior.
320
686
  */
321
- delete: (options?: MockResponseOptions): StubReference => {
322
- return this.createStub('groups', 'delete', () => {
323
- const status = options?.status ?? 204
324
- if (status !== 204) {
325
- throw new Exception('Mocked error', { status })
326
- }
327
- return undefined
328
- })
687
+ delete: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
688
+ const { mock } = this
689
+ // const respond = init?.response ?? {
690
+ // status: 204,
691
+ // }
692
+ const respond = this.createDefaultResponse(204, undefined, undefined, init)
693
+ await mock.add(
694
+ {
695
+ match: {
696
+ uri: RouteBuilder.group(':oid', ':key'),
697
+ methods: ['DELETE'],
698
+ },
699
+ respond,
700
+ },
701
+ options
702
+ )
329
703
  },
330
704
 
331
705
  /**
332
706
  * Mocks the `groups.addUsers()` method.
333
707
  */
334
- addUsers: (options?: MockResponseOptions): StubReference => {
335
- return this.createStub('groups', 'addUsers', () => {
336
- const defaultData = this.generateGroup()
337
- if (options?.status !== undefined && options.status !== 200) {
338
- throw new Exception('Mocked error', { status: options.status })
339
- }
340
- return (options?.data ?? defaultData) as unknown
341
- })
708
+ addUsers: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
709
+ const { mock } = this
710
+ // const respond = init?.response ?? {
711
+ // status: 200,
712
+ // headers: { 'content-type': 'application/json' },
713
+ // body: JSON.stringify(this.gen.group.group()),
714
+ // }
715
+ const respond = this.createDefaultResponse(
716
+ 200,
717
+ { 'content-type': 'application/json' },
718
+ () => JSON.stringify(this.gen.group.group()),
719
+ init
720
+ )
721
+ await mock.add(
722
+ {
723
+ match: {
724
+ uri: RouteBuilder.groupUsers(':oid', ':key'),
725
+ methods: ['POST'],
726
+ },
727
+ respond,
728
+ },
729
+ options
730
+ )
342
731
  },
343
732
 
344
733
  /**
345
734
  * Mocks the `groups.removeUsers()` method.
346
735
  */
347
- removeUsers: (options?: MockResponseOptions): StubReference => {
348
- return this.createStub('groups', 'removeUsers', () => {
349
- const defaultData = this.generateGroup()
350
- if (options?.status !== undefined && options.status !== 200) {
351
- throw new Exception('Mocked error', { status: options.status })
352
- }
353
- return (options?.data ?? defaultData) as unknown
354
- })
736
+ removeUsers: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
737
+ const { mock } = this
738
+ // const respond = init?.response ?? {
739
+ // status: 200,
740
+ // headers: { 'content-type': 'application/json' },
741
+ // body: JSON.stringify(this.gen.group.group()),
742
+ // }
743
+ const respond = this.createDefaultResponse(
744
+ 200,
745
+ { 'content-type': 'application/json' },
746
+ () => JSON.stringify(this.gen.group.group()),
747
+ init
748
+ )
749
+ await mock.add(
750
+ {
751
+ match: {
752
+ uri: RouteBuilder.groupUsers(':oid', ':key'),
753
+ methods: ['DELETE'],
754
+ },
755
+ respond,
756
+ },
757
+ options
758
+ )
355
759
  },
356
760
  }
357
761
 
@@ -362,16 +766,30 @@ export class SdkMock {
362
766
  /**
363
767
  * Mocks the `user.me()` method.
364
768
  * @param options Optional response customization.
365
- * @returns A stub reference that can be used to restore the original behavior.
366
769
  */
367
- me: (options?: MockResponseOptions): StubReference => {
368
- return this.createStub('user', 'me', () => {
369
- const defaultData = this.generateUser()
370
- if (options?.status !== undefined && options.status !== 200) {
371
- throw new Exception(`Mocked error. Status: ${options.status}`, { status: options.status })
372
- }
373
- return (options?.data ?? defaultData) as unknown
374
- })
770
+ me: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
771
+ const { mock } = this
772
+ // const respond = init?.response ?? {
773
+ // status: 200,
774
+ // headers: { 'content-type': 'application/json' },
775
+ // body: JSON.stringify(this.gen.user.user()),
776
+ // }
777
+ const respond = this.createDefaultResponse(
778
+ 200,
779
+ { 'content-type': 'application/json' },
780
+ () => JSON.stringify(this.gen.user.user()),
781
+ init
782
+ )
783
+ await mock.add(
784
+ {
785
+ match: {
786
+ uri: RouteBuilder.usersMe(),
787
+ methods: ['GET'],
788
+ },
789
+ respond,
790
+ },
791
+ options
792
+ )
375
793
  },
376
794
  }
377
795
 
@@ -382,233 +800,437 @@ export class SdkMock {
382
800
  /**
383
801
  * Mocks the `file.list()` method.
384
802
  */
385
- list: (options?: MockResponseOptions): StubReference => {
386
- return this.createStub('file', 'list', () => {
387
- const defaultData: ContextListResult<IFile> = {
388
- items: [this.generateFile(), this.generateFile()],
389
- }
390
- if (options?.status !== undefined && options.status !== 200) {
391
- throw new Exception('Mocked error', { status: options.status })
392
- }
393
- return (options?.data ?? defaultData) as unknown
394
- })
803
+ list: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
804
+ const { mock } = this
805
+ // const respond = init?.response ?? {
806
+ // status: 200,
807
+ // headers: { 'content-type': 'application/json' },
808
+ // body: JSON.stringify({
809
+ // items: this.gen.file.files(init?.size ?? 5),
810
+ // cursor: this.createCursorOption(init),
811
+ // } as ContextListResult<IFile>),
812
+ // }
813
+ const respond = this.createDefaultResponse(
814
+ 200,
815
+ { 'content-type': 'application/json' },
816
+ () => {
817
+ const obj: ContextListResult<IFile> = {
818
+ items: this.gen.file.files(init?.size ?? 5),
819
+ cursor: this.createCursorOption(init),
820
+ }
821
+ return JSON.stringify(obj)
822
+ },
823
+ init
824
+ )
825
+ await mock.add(
826
+ {
827
+ match: {
828
+ uri: RouteBuilder.files(':oid'),
829
+ methods: ['GET'],
830
+ },
831
+ respond,
832
+ },
833
+ options
834
+ )
395
835
  },
396
836
 
397
837
  /**
398
838
  * Mocks the `file.createMeta()` method.
399
839
  */
400
- createMeta: (options?: MockResponseOptions): StubReference => {
401
- return this.createStub('file', 'createMeta', () => {
402
- const defaultData: IFile = this.generateFile()
403
- const status = options?.status ?? 201
404
- if (status !== 201) {
405
- throw new Exception('Mocked error', { status })
406
- }
407
- return (options?.data ?? defaultData) as unknown
408
- })
840
+ createMeta: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
841
+ const { mock } = this
842
+ // const respond = init?.response ?? {
843
+ // status: 201,
844
+ // headers: { 'content-type': 'application/json' },
845
+ // body: JSON.stringify(this.gen.file.file()),
846
+ // }
847
+ const respond = this.createDefaultResponse(
848
+ 201,
849
+ { 'content-type': 'application/json' },
850
+ () => JSON.stringify(this.gen.file.file()),
851
+ init
852
+ )
853
+ await mock.add(
854
+ {
855
+ match: {
856
+ uri: RouteBuilder.files(':oid'),
857
+ methods: ['POST'],
858
+ },
859
+ respond,
860
+ },
861
+ options
862
+ )
409
863
  },
410
864
 
411
865
  /**
412
866
  * Mocks the `file.createMedia()` method.
413
867
  */
414
- createMedia: (options?: MockResponseOptions): StubReference => {
415
- return this.createStub('file', 'createMedia', () => {
416
- const status = options?.status ?? 200
417
- if (status !== 200) {
418
- throw new Exception('Mocked error', { status })
419
- }
420
- return undefined
421
- })
868
+ createMedia: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
869
+ const { mock } = this
870
+ // const respond = init?.response ?? {
871
+ // status: 200,
872
+ // }
873
+ const respond = this.createDefaultResponse(200, undefined, undefined, init)
874
+ await mock.add(
875
+ {
876
+ match: {
877
+ uri: RouteBuilder.fileMedia(':oid', ':id'),
878
+ methods: ['PUT'],
879
+ },
880
+ respond,
881
+ },
882
+ options
883
+ )
422
884
  },
423
885
 
424
886
  /**
425
887
  * Mocks the `file.create()` method.
426
888
  */
427
- create: (options?: MockResponseOptions): StubReference => {
428
- return this.createStub('file', 'create', () => {
429
- const status = options?.status ?? 201
430
- if (status !== 201) {
431
- throw new Exception('Mocked error', { status })
432
- }
433
- const defaultData: IFile = this.generateFile()
434
- return (options?.data ?? defaultData) as unknown
435
- })
889
+ create: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
890
+ await this.file.createMeta(init, options)
891
+ // When SDK's file.create() is called, it responds with
892
+ // what the result of file.createMeta() would be.
893
+ // Because of that, we don't need to configure the media request.
894
+ await this.file.createMedia(undefined, options)
436
895
  },
437
896
 
438
897
  /**
439
898
  * Mocks the `file.createFolder()` method.
440
899
  */
441
- createFolder: (options?: MockResponseOptions): StubReference => {
442
- return this.createStub('file', 'createFolder', () => {
443
- const status = options?.status ?? 201
444
- if (status !== 201) {
445
- throw new Exception('Mocked error', { status })
446
- }
447
- const defaultData: IFolder = this.generateFolder()
448
- return (options?.data ?? defaultData) as unknown
449
- })
900
+ createFolder: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
901
+ const { mock } = this
902
+ // const respond = init?.response ?? {
903
+ // status: 201,
904
+ // headers: { 'content-type': 'application/json' },
905
+ // body: JSON.stringify(this.gen.file.folder()),
906
+ // }
907
+ const respond = this.createDefaultResponse(
908
+ 201,
909
+ { 'content-type': 'application/json' },
910
+ () => JSON.stringify(this.gen.file.folder()),
911
+ init
912
+ )
913
+ await mock.add(
914
+ {
915
+ match: {
916
+ uri: RouteBuilder.files(':oid'),
917
+ methods: ['POST'],
918
+ },
919
+ respond,
920
+ },
921
+ options
922
+ )
450
923
  },
451
924
 
452
925
  /**
453
926
  * Mocks the `file.read()` method.
454
927
  */
455
- read: (options?: MockResponseOptions): StubReference => {
456
- return this.createStub('file', 'read', () => {
457
- const defaultData: IFile = this.generateFile()
458
- if (options?.status !== undefined && options.status !== 200) {
459
- throw new Exception('Mocked error', { status: options.status })
460
- }
461
- return (options?.data ?? defaultData) as unknown
462
- })
928
+ read: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
929
+ const { mock } = this
930
+ // const respond = init?.response ?? {
931
+ // status: 200,
932
+ // headers: { 'content-type': 'application/json' },
933
+ // body: JSON.stringify(this.gen.file.file()),
934
+ // }
935
+ const respond = this.createDefaultResponse(
936
+ 200,
937
+ { 'content-type': 'application/json' },
938
+ () => JSON.stringify(this.gen.file.file()),
939
+ init
940
+ )
941
+ await mock.add(
942
+ {
943
+ match: {
944
+ uri: RouteBuilder.file(':oid', ':id'),
945
+ methods: ['GET'],
946
+ },
947
+ respond,
948
+ },
949
+ options
950
+ )
463
951
  },
464
952
 
465
953
  /**
466
954
  * Mocks the `file.readMedia()` method.
467
955
  */
468
- readMedia: (options?: MockResponseOptions): StubReference => {
469
- return this.createStub('file', 'readMedia', () => {
470
- if (options?.status !== undefined && options.status !== 200) {
471
- throw new Exception('Mocked error', { status: options.status })
472
- }
473
- const defaultData = { media: { ok: true }, version: 1 }
474
- return (options?.data ?? defaultData) as unknown
475
- })
956
+ readMedia: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
957
+ const { mock } = this
958
+ // const respond = init?.response ?? {
959
+ // status: 200,
960
+ // headers: {
961
+ // 'content-type': 'application/json',
962
+ // 'x-version': `${this.gen.faker.number.int({ min: 1, max: 100 })}`,
963
+ // },
964
+ // body: JSON.stringify({ data: this.gen.faker.lorem.sentences() }),
965
+ // }
966
+ const respond = this.createDefaultResponse(
967
+ 200,
968
+ {
969
+ 'content-type': 'application/json',
970
+ 'x-version': `${this.gen.faker.number.int({ min: 1, max: 100 })}`,
971
+ },
972
+ () => JSON.stringify({ data: this.gen.faker.lorem.sentences() }),
973
+ init
974
+ )
975
+ await mock.add(
976
+ {
977
+ match: {
978
+ uri: RouteBuilder.fileMedia(':oid', ':id'),
979
+ methods: ['GET'],
980
+ },
981
+ respond,
982
+ },
983
+ options
984
+ )
476
985
  },
477
986
 
478
987
  /**
479
988
  * Mocks the `file.readBulk()` method.
480
989
  */
481
- readBulk: (options?: MockResponseOptions): StubReference => {
482
- return this.createStub('file', 'readBulk', () => {
483
- const defaultData: IBulkOperationResult<IFile> = {
484
- items: [this.generateFile(), undefined],
485
- }
486
- if (options?.status !== undefined && options.status !== 200) {
487
- throw new Exception('Mocked error', { status: options.status })
488
- }
489
- return (options?.data ?? defaultData) as unknown
490
- })
990
+ readBulk: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
991
+ const { mock } = this
992
+ // const respond = init?.response ?? {
993
+ // status: 200,
994
+ // headers: { 'content-type': 'application/json' },
995
+ // body: JSON.stringify({
996
+ // items: this.gen.file.files(init?.size ?? 5),
997
+ // } as IBulkOperationResult<IFile>),
998
+ // }
999
+ const respond = this.createDefaultResponse(
1000
+ 200,
1001
+ { 'content-type': 'application/json' },
1002
+ () => {
1003
+ const obj: IBulkOperationResult<IFile> = {
1004
+ items: this.gen.file.files(init?.size ?? 5),
1005
+ }
1006
+ return JSON.stringify(obj)
1007
+ },
1008
+ init
1009
+ )
1010
+ await mock.add(
1011
+ {
1012
+ match: {
1013
+ uri: RouteBuilder.filesBatch(':oid'),
1014
+ methods: ['POST'],
1015
+ },
1016
+ respond,
1017
+ },
1018
+ options
1019
+ )
491
1020
  },
492
1021
 
493
1022
  /**
494
1023
  * Mocks the `file.patch()` method.
495
1024
  */
496
- patch: (options?: MockResponseOptions): StubReference => {
497
- return this.createStub('file', 'patch', () => {
498
- const defaultData: IFile = this.generateFile()
499
- if (options?.status !== undefined && options.status !== 200) {
500
- throw new Exception('Mocked error', { status: options.status })
501
- }
502
- return (options?.data ?? defaultData) as unknown
503
- })
1025
+ patch: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1026
+ const { mock } = this
1027
+ // const respond = init?.response ?? {
1028
+ // status: 200,
1029
+ // headers: { 'content-type': 'application/json' },
1030
+ // body: JSON.stringify(this.gen.file.file()),
1031
+ // }
1032
+ const respond = this.createDefaultResponse(
1033
+ 200,
1034
+ { 'content-type': 'application/json' },
1035
+ () => JSON.stringify(this.gen.file.file()),
1036
+ init
1037
+ )
1038
+ await mock.add(
1039
+ {
1040
+ match: {
1041
+ uri: RouteBuilder.file(':oid', ':id'),
1042
+ methods: ['PATCH'],
1043
+ },
1044
+ respond,
1045
+ },
1046
+ options
1047
+ )
504
1048
  },
505
1049
 
506
1050
  /**
507
1051
  * Mocks the `file.patchMedia()` method.
508
1052
  */
509
- patchMedia: (options?: MockResponseOptions): StubReference => {
510
- return this.createStub('file', 'patchMedia', () => {
511
- const defaultData: MediaPatchRevision = this.generateMediaPatchRevision()
512
- if (options?.status !== undefined && options.status !== 200) {
513
- throw new Exception('Mocked error', { status: options.status })
514
- }
515
- return (options?.data ?? defaultData) as unknown
516
- })
1053
+ patchMedia: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1054
+ const { mock } = this
1055
+ // const respond = init?.response ?? {
1056
+ // status: 200,
1057
+ // headers: { 'content-type': 'application/json' },
1058
+ // body: JSON.stringify(this.gen.patch.mediaPatchRevision()),
1059
+ // }
1060
+ const respond = this.createDefaultResponse(
1061
+ 200,
1062
+ { 'content-type': 'application/json' },
1063
+ () => JSON.stringify(this.gen.patch.mediaPatchRevision()),
1064
+ init
1065
+ )
1066
+ await mock.add(
1067
+ {
1068
+ match: {
1069
+ uri: RouteBuilder.fileMedia(':oid', ':id'),
1070
+ methods: ['PATCH'],
1071
+ },
1072
+ respond,
1073
+ },
1074
+ options
1075
+ )
517
1076
  },
518
1077
 
519
1078
  /**
520
1079
  * Mocks the `file.delete()` method.
521
1080
  */
522
- delete: (options?: MockResponseOptions): StubReference => {
523
- return this.createStub('file', 'delete', () => {
524
- const status = options?.status ?? 204
525
- if (status !== 204) {
526
- throw new Exception('Mocked error', { status })
527
- }
528
- return undefined
529
- })
1081
+ delete: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1082
+ const { mock } = this
1083
+ // const respond = init?.response ?? {
1084
+ // status: 204,
1085
+ // }
1086
+ const respond = this.createDefaultResponse(204, undefined, undefined, init)
1087
+ await mock.add(
1088
+ {
1089
+ match: {
1090
+ uri: RouteBuilder.file(':oid', ':id'),
1091
+ methods: ['DELETE'],
1092
+ },
1093
+ respond,
1094
+ },
1095
+ options
1096
+ )
530
1097
  },
531
1098
 
532
1099
  /**
533
1100
  * Mocks the `file.deleteBulk()` method.
534
1101
  */
535
- deleteBulk: (options?: MockResponseOptions): StubReference => {
536
- return this.createStub('file', 'deleteBulk', () => {
537
- const status = options?.status ?? 204
538
- if (status !== 204) {
539
- throw new Exception('Mocked error', { status })
540
- }
541
- return undefined
542
- })
1102
+ deleteBulk: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1103
+ const { mock } = this
1104
+ // const respond = init?.response ?? {
1105
+ // status: 204,
1106
+ // }
1107
+ const respond = this.createDefaultResponse(204, undefined, undefined, init)
1108
+ await mock.add(
1109
+ {
1110
+ match: {
1111
+ uri: RouteBuilder.files(':oid'),
1112
+ methods: ['DELETE'],
1113
+ },
1114
+ respond,
1115
+ },
1116
+ options
1117
+ )
543
1118
  },
544
1119
 
545
1120
  /**
546
1121
  * Mocks the `file.patchUsers()` method.
547
1122
  */
548
- patchUsers: (options?: MockResponseOptions): StubReference => {
549
- return this.createStub('file', 'patchUsers', () => {
550
- const defaultData: IFile = this.generateFile()
551
- if (options?.status !== undefined && options.status !== 200) {
552
- throw new Exception('Mocked error', { status: options.status })
553
- }
554
- return (options?.data ?? defaultData) as unknown
555
- })
1123
+ patchUsers: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1124
+ const { mock } = this
1125
+ // const respond = init?.response ?? {
1126
+ // status: 200,
1127
+ // headers: { 'content-type': 'application/json' },
1128
+ // body: JSON.stringify(this.gen.file.file()),
1129
+ // }
1130
+ const respond = this.createDefaultResponse(
1131
+ 200,
1132
+ { 'content-type': 'application/json' },
1133
+ () => JSON.stringify(this.gen.file.file()),
1134
+ init
1135
+ )
1136
+ await mock.add(
1137
+ {
1138
+ match: {
1139
+ uri: RouteBuilder.filesAccess(':oid', ':id'),
1140
+ methods: ['PATCH'],
1141
+ },
1142
+ respond,
1143
+ },
1144
+ options
1145
+ )
556
1146
  },
557
1147
 
558
1148
  /**
559
1149
  * Mocks the `file.addUser()` method.
560
1150
  */
561
- addUser: (options?: MockResponseOptions): StubReference => {
562
- return this.createStub('file', 'addUser', () => {
563
- const defaultData: IFile = this.generateFile()
564
- if (options?.status !== undefined && options.status !== 200) {
565
- throw new Exception('Mocked error', { status: options.status })
566
- }
567
- return (options?.data ?? defaultData) as unknown
568
- })
1151
+ addUser: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1152
+ await this.file.patchUsers(init, options)
569
1153
  },
570
1154
 
571
1155
  /**
572
1156
  * Mocks the `file.removeUser()` method.
573
1157
  */
574
- removeUser: (options?: MockResponseOptions): StubReference => {
575
- return this.createStub('file', 'removeUser', () => {
576
- const defaultData: IFile = this.generateFile()
577
- if (options?.status !== undefined && options.status !== 200) {
578
- throw new Exception('Mocked error', { status: options.status })
579
- }
580
- return (options?.data ?? defaultData) as unknown
581
- })
1158
+ removeUser: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1159
+ await this.file.patchUsers(init, options)
582
1160
  },
583
1161
 
584
1162
  /**
585
1163
  * Mocks the `file.listUsers()` method.
586
1164
  */
587
- listUsers: (options?: MockResponseOptions): StubReference => {
588
- return this.createStub('file', 'listUsers', () => {
589
- const defaultData: ContextListResult<IUser> = {
590
- items: [this.generateUser(), this.generateUser()],
591
- }
592
- if (options?.status !== undefined && options.status !== 200) {
593
- throw new Exception('Mocked error', { status: options.status })
594
- }
595
- return (options?.data ?? defaultData) as unknown
596
- })
1165
+ listUsers: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
1166
+ const { mock } = this
1167
+ // const respond = init?.response ?? {
1168
+ // status: 200,
1169
+ // headers: { 'content-type': 'application/json' },
1170
+ // body: JSON.stringify({
1171
+ // items: this.gen.user.users(init?.size ?? 5),
1172
+ // cursor: this.createCursorOption(init),
1173
+ // } as ContextListResult<IUser>),
1174
+ // }
1175
+ const respond = this.createDefaultResponse(
1176
+ 200,
1177
+ { 'content-type': 'application/json' },
1178
+ () => {
1179
+ const obj: ContextListResult<IUser> = {
1180
+ items: this.gen.user.users(init?.size ?? 5),
1181
+ cursor: this.createCursorOption(init),
1182
+ }
1183
+ return JSON.stringify(obj)
1184
+ },
1185
+ init
1186
+ )
1187
+ await mock.add(
1188
+ {
1189
+ match: {
1190
+ uri: RouteBuilder.fileUsers(':oid', ':id'),
1191
+ methods: ['GET'],
1192
+ },
1193
+ respond,
1194
+ },
1195
+ options
1196
+ )
597
1197
  },
598
1198
 
599
1199
  /**
600
1200
  * Mocks the `file.breadcrumbs()` method.
601
1201
  */
602
- breadcrumbs: (options?: MockResponseOptions): StubReference => {
603
- return this.createStub('file', 'breadcrumbs', () => {
604
- const defaultData: ContextListResult<FileBreadcrumb> = {
605
- items: this.generateBreadcrumbs(),
606
- }
607
- if (options?.status !== undefined && options.status !== 200) {
608
- throw new Exception('Mocked error', { status: options.status })
609
- }
610
- return (options?.data ?? defaultData) as unknown
611
- })
1202
+ breadcrumbs: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
1203
+ const { mock } = this
1204
+ // const respond = init?.response ?? {
1205
+ // status: 200,
1206
+ // headers: { 'content-type': 'application/json' },
1207
+ // body: JSON.stringify({
1208
+ // items: this.gen.file.fileBreadcrumbs(init?.size ?? 5),
1209
+ // cursor: this.createCursorOption(init),
1210
+ // } as ContextListResult<FileBreadcrumb>),
1211
+ // }
1212
+ const respond = this.createDefaultResponse(
1213
+ 200,
1214
+ { 'content-type': 'application/json' },
1215
+ () => {
1216
+ const obj: ContextListResult<FileBreadcrumb> = {
1217
+ items: this.gen.file.fileBreadcrumbs(init?.size ?? 5),
1218
+ cursor: this.createCursorOption(init),
1219
+ }
1220
+ return JSON.stringify(obj)
1221
+ },
1222
+ init
1223
+ )
1224
+ await mock.add(
1225
+ {
1226
+ match: {
1227
+ uri: RouteBuilder.fileBreadcrumbs(':oid', ':id'),
1228
+ methods: ['GET'],
1229
+ },
1230
+ respond,
1231
+ },
1232
+ options
1233
+ )
612
1234
  },
613
1235
  }
614
1236
 
@@ -616,16 +1238,38 @@ export class SdkMock {
616
1238
  * Shared API mocks.
617
1239
  */
618
1240
  shared = {
619
- list: (options?: MockResponseOptions): StubReference => {
620
- return this.createStub('shared', 'list', () => {
621
- const defaultData: ContextListResult<IFile> = {
622
- items: [this.generateFile(), this.generateFile()],
623
- }
624
- if (options?.status !== undefined && options.status !== 200) {
625
- throw new Exception('Mocked error', { status: options.status })
626
- }
627
- return (options?.data ?? defaultData) as unknown
628
- })
1241
+ list: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
1242
+ const { mock } = this
1243
+ // const respond = init?.response ?? {
1244
+ // status: 200,
1245
+ // headers: { 'content-type': 'application/json' },
1246
+ // body: JSON.stringify({
1247
+ // items: this.gen.file.files(init?.size ?? 5),
1248
+ // cursor: this.createCursorOption(init),
1249
+ // } as ContextListResult<IFile>),
1250
+ // }
1251
+ const respond = this.createDefaultResponse(
1252
+ 200,
1253
+ { 'content-type': 'application/json' },
1254
+ () => {
1255
+ const obj: ContextListResult<IFile> = {
1256
+ items: this.gen.file.files(init?.size ?? 5),
1257
+ cursor: this.createCursorOption(init),
1258
+ }
1259
+ return JSON.stringify(obj)
1260
+ },
1261
+ init
1262
+ )
1263
+ await mock.add(
1264
+ {
1265
+ match: {
1266
+ uri: RouteBuilder.shared(':oid'),
1267
+ methods: ['GET'],
1268
+ },
1269
+ respond,
1270
+ },
1271
+ options
1272
+ )
629
1273
  },
630
1274
  }
631
1275
 
@@ -633,284 +1277,89 @@ export class SdkMock {
633
1277
  * Trash API mocks.
634
1278
  */
635
1279
  trash = {
636
- list: (options?: MockResponseOptions): StubReference => {
637
- return this.createStub('trash', 'list', () => {
638
- const defaultData: ContextListResult<TrashEntry> = {
639
- items: [this.generateTrashEntry(), this.generateTrashEntry()],
640
- }
641
- if (options?.status !== undefined && options.status !== 200) {
642
- throw new Exception('Mocked error', { status: options.status })
643
- }
644
- return (options?.data ?? defaultData) as unknown
645
- })
646
- },
647
- delete: (options?: MockResponseOptions): StubReference => {
648
- return this.createStub('trash', 'delete', () => {
649
- const status = options?.status ?? 204
650
- if (status !== 204) {
651
- throw new Exception('Mocked error', { status })
652
- }
653
- return undefined
654
- })
655
- },
656
- restore: (options?: MockResponseOptions): StubReference => {
657
- return this.createStub('trash', 'restore', () => {
658
- const status = options?.status ?? 204
659
- if (status !== 204) {
660
- throw new Exception('Mocked error', { status })
661
- }
662
- return undefined
663
- })
664
- },
665
- empty: (options?: MockResponseOptions): StubReference => {
666
- return this.createStub('trash', 'empty', () => {
667
- const status = options?.status ?? 204
668
- if (status !== 204) {
669
- throw new Exception('Mocked error', { status })
670
- }
671
- return undefined
672
- })
1280
+ list: async (init?: MockListResult, options?: InterceptOptions): Promise<void> => {
1281
+ const { mock } = this
1282
+ // const respond = init?.response ?? {
1283
+ // status: 200,
1284
+ // headers: { 'content-type': 'application/json' },
1285
+ // body: JSON.stringify({
1286
+ // items: this.gen.trash.trashEntries(init?.size ?? 5),
1287
+ // cursor: this.createCursorOption(init),
1288
+ // } as ContextListResult<TrashEntry>),
1289
+ // }
1290
+ const respond = this.createDefaultResponse(
1291
+ 200,
1292
+ { 'content-type': 'application/json' },
1293
+ () => {
1294
+ const obj: ContextListResult<TrashEntry> = {
1295
+ items: this.gen.trash.trashEntries(init?.size ?? 5),
1296
+ cursor: this.createCursorOption(init),
1297
+ }
1298
+ return JSON.stringify(obj)
1299
+ },
1300
+ init
1301
+ )
1302
+ await mock.add(
1303
+ {
1304
+ match: {
1305
+ uri: RouteBuilder.trash(':oid'),
1306
+ methods: ['GET'],
1307
+ },
1308
+ respond,
1309
+ },
1310
+ options
1311
+ )
673
1312
  },
674
- }
675
-
676
- /**
677
- * Restores all stubs created by this mocker.
678
- */
679
- restore(): void {
680
- this.stubs.forEach((stub) => stub.restore())
681
- this.stubs = []
682
- }
683
-
684
- /**
685
- * Creates a stub for a specific SDK method.
686
- * @param api The API name (e.g., 'organizations', 'groups', 'user', 'auth').
687
- * @param method The method name to stub.
688
- * @param implementation The stub implementation that returns the mocked data.
689
- * @returns A stub reference.
690
- */
691
- private createStub(
692
- api:
693
- | 'organizations'
694
- | 'groups'
695
- | 'user'
696
- | 'auth'
697
- | 'file'
698
- | 'shared'
699
- | 'trash'
700
- | 'organizations.invitations'
701
- | 'organizations.users',
702
- method: string,
703
- implementation: () => unknown
704
- ): StubReference {
705
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
706
- let target: any = this.sdk
707
- const parts = api.split('.')
708
- for (const part of parts) {
709
- target = target[part]
710
- if (!target) {
711
- throw new Error(`API '${api}' not found in SDK`)
712
- }
713
- }
714
-
715
- const original = target[method]
716
- if (typeof original !== 'function') {
717
- throw new Error(`Method '${method}' not found in ${api} API`)
718
- }
719
-
720
- // Create stub using sinon
721
- const stub = sinon.stub(target, method).callsFake(async () => implementation())
722
-
723
- const stubRef: StubReference = {
724
- restore: () => {
725
- if (stub) {
726
- stub.restore()
727
- }
728
- const index = this.stubs.indexOf(stubRef)
729
- if (index > -1) {
730
- this.stubs.splice(index, 1)
731
- }
732
- },
733
- }
734
-
735
- this.stubs.push(stubRef)
736
- return stubRef
737
- }
738
-
739
- /**
740
- * Generates a random organization object.
741
- */
742
- private generateOrganization(): IOrganization {
743
- return {
744
- kind: OrganizationKind,
745
- key: nanoid(),
746
- name: `Organization ${this.randomString()}`,
747
- createdBy: nanoid(),
748
- createdDate: Date.now() - Math.random() * 1000 * 60 * 60 * 24 * 30,
749
- grantType: this.randomChoice(['owner', 'manager', 'editor', 'viewer'] as const),
750
- }
751
- }
752
-
753
- /**
754
- * Generates a random group object.
755
- */
756
- private generateGroup(): GroupSchema {
757
- return {
758
- kind: GroupKind,
759
- key: nanoid(),
760
- name: `Group ${this.randomString()}`,
761
- description: `Description for ${this.randomString()}`,
762
- owner: nanoid(),
763
- oid: nanoid(),
764
- users: [],
765
- createdAt: Date.now() - Math.random() * 1000 * 60 * 60 * 24 * 30,
766
- updatedAt: Date.now() - Math.random() * 1000 * 60 * 60 * 24 * 7,
767
- icon: `https://example.com/icon-${nanoid()}.png`,
768
- color: this.randomColor(),
769
- }
770
- }
771
-
772
- /**
773
- * Generates a random user object.
774
- */
775
- private generateUser(): IUser {
776
- const firstName = this.randomString()
777
- const lastName = this.randomString()
778
- return {
779
- kind: UserKind,
780
- key: nanoid(),
781
- name: `${firstName} ${lastName}`,
782
- email: [
1313
+ delete: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1314
+ const { mock } = this
1315
+ // const respond = init?.response ?? {
1316
+ // status: 204,
1317
+ // }
1318
+ const respond = this.createDefaultResponse(204, undefined, undefined, init)
1319
+ await mock.add(
783
1320
  {
784
- email: `${firstName.toLowerCase()}.${lastName.toLowerCase()}@example.com`,
785
- verified: true,
1321
+ match: {
1322
+ uri: RouteBuilder.trashBatchDelete(':oid'),
1323
+ methods: ['DELETE'],
1324
+ },
1325
+ respond,
786
1326
  },
787
- ],
788
- status: 'active',
789
- created: Date.now() - Math.random() * 1000 * 60 * 60 * 24 * 365,
790
- updated: Date.now() - Math.random() * 1000 * 60 * 60 * 24 * 7,
791
- }
792
- }
793
-
794
- /**
795
- * Generates a random file meta object.
796
- */
797
- private generateFile(): IFile {
798
- const kind = this.randomChoice([ProjectKind, DomainFileKind, CertificateFileKind, FolderKind] as const)
799
- const name = `File ${this.randomString()}`
800
- return File.createSchema({ kind, info: { name } })
801
- }
802
-
803
- /**
804
- * Generates a random folder meta object.
805
- */
806
- private generateFolder(): IFolder {
807
- const file = File.createSchema({ kind: FolderKind, info: { name: `Folder ${this.randomString()}` } }) as IFolder
808
- return file
809
- }
810
-
811
- /**
812
- * Generates a random media patch revision object.
813
- */
814
- private generateMediaPatchRevision(): MediaPatchRevision {
815
- const version = Math.floor(Math.random() * 10) + 1
816
- return {
817
- id: nanoid(),
818
- timestamp: Date.now(),
819
- patch: [],
820
- version,
821
- revert: [],
822
- newVersion: version + 1,
823
- }
824
- }
825
-
826
- /**
827
- * Generates a random breadcrumbs list.
828
- */
829
- private generateBreadcrumbs(): FileBreadcrumb[] {
830
- const depth = 2 + Math.floor(Math.random() * 2) // 2-3
831
- const items: FileBreadcrumb[] = []
832
- for (let i = 0; i < depth; i += 1) {
833
- items.push({ key: nanoid(), kind: i === depth - 1 ? ProjectKind : FolderKind, name: this.randomString() })
834
- }
835
- return items
836
- }
837
-
838
- /**
839
- * Generates a random invitation object.
840
- */
841
- private generateInvitation(): InvitationSchema {
842
- const firstName = this.randomString()
843
- const lastName = this.randomString()
844
- const now = Date.now()
845
- return {
846
- kind: InvitationKind,
847
- key: nanoid(),
848
- uid: nanoid(),
849
- oid: nanoid(),
850
- email: `${firstName.toLowerCase()}.${lastName.toLowerCase()}@example.com`,
851
- name: `${firstName} ${lastName}`,
852
- token: nanoid(),
853
- expiresAt: now + 7 * 24 * 60 * 60 * 1000,
854
- status: 'pending',
855
- grantType: this.randomChoice(['owner', 'manager', 'editor', 'viewer'] as const),
856
- createdAt: now - Math.random() * 1000 * 60 * 60 * 24,
857
- updatedAt: now - Math.random() * 1000 * 60 * 60,
858
- resent: 0,
859
- lastSentAt: now - Math.random() * 1000 * 60 * 60,
860
- }
861
- }
862
-
863
- /**
864
- * Generates a random trash entry.
865
- */
866
- private generateTrashEntry(): TrashEntry {
867
- return {
868
- key: nanoid(),
869
- refKey: nanoid(),
870
- kind: this.randomChoice([ProjectKind, DomainFileKind, CertificateFileKind, FolderKind] as const),
871
- name: `Deleted ${this.randomString()}`,
872
- info: { byMe: false, time: Date.now() - Math.floor(Math.random() * 1000000), user: nanoid(), name: 'User' },
873
- capabilities: { canDelete: true, canRestore: true },
874
- }
875
- }
876
-
877
- /**
878
- * Generates a random string.
879
- */
880
- private randomString(): string {
881
- const words = [
882
- 'Alpha',
883
- 'Beta',
884
- 'Gamma',
885
- 'Delta',
886
- 'Epsilon',
887
- 'Zeta',
888
- 'Theta',
889
- 'Lambda',
890
- 'Sigma',
891
- 'Omega',
892
- 'Phoenix',
893
- 'Dragon',
894
- 'Tiger',
895
- 'Eagle',
896
- 'Falcon',
897
- ]
898
- return words[Math.floor(Math.random() * words.length)]
899
- }
900
-
901
- /**
902
- * Returns a random choice from an array.
903
- */
904
- private randomChoice<T>(choices: readonly T[]): T {
905
- return choices[Math.floor(Math.random() * choices.length)]
906
- }
907
-
908
- /**
909
- * Generates a random hex color.
910
- */
911
- private randomColor(): string {
912
- return `#${Math.floor(Math.random() * 16777215)
913
- .toString(16)
914
- .padStart(6, '0')}`
1327
+ options
1328
+ )
1329
+ },
1330
+ restore: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1331
+ const { mock } = this
1332
+ // const respond = init?.response ?? {
1333
+ // status: 204,
1334
+ // }
1335
+ const respond = this.createDefaultResponse(204, undefined, undefined, init)
1336
+ await mock.add(
1337
+ {
1338
+ match: {
1339
+ uri: RouteBuilder.trashBatchRestore(':oid'),
1340
+ methods: ['POST'],
1341
+ },
1342
+ respond,
1343
+ },
1344
+ options
1345
+ )
1346
+ },
1347
+ empty: async (init?: MockResult, options?: InterceptOptions): Promise<void> => {
1348
+ const { mock } = this
1349
+ // const respond = init?.response ?? {
1350
+ // status: 204,
1351
+ // }
1352
+ const respond = this.createDefaultResponse(204, undefined, undefined, init)
1353
+ await mock.add(
1354
+ {
1355
+ match: {
1356
+ uri: RouteBuilder.trashEmpty(':oid'),
1357
+ methods: ['DELETE'],
1358
+ },
1359
+ respond,
1360
+ },
1361
+ options
1362
+ )
1363
+ },
915
1364
  }
916
1365
  }