@fedify/testing 2.0.0-dev.1485 → 2.0.0-dev.150
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 +1 -1
- package/dist/mod.cjs +733 -0
- package/dist/mod.d.cts +126 -0
- package/dist/mod.d.ts +82 -251
- package/dist/mod.js +112 -38
- package/package.json +10 -8
package/dist/mod.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { trace } from "@opentelemetry/api";
|
|
2
1
|
import { RouterError } from "@fedify/fedify/federation";
|
|
3
2
|
import { lookupObject, traverseCollection } from "@fedify/fedify/vocab";
|
|
4
|
-
import { lookupWebFinger } from "@fedify/fedify/webfinger";
|
|
5
3
|
|
|
6
4
|
//#region src/docloader.ts
|
|
7
5
|
const mockDocumentLoader = async (url) => ({
|
|
@@ -12,8 +10,12 @@ const mockDocumentLoader = async (url) => ({
|
|
|
12
10
|
|
|
13
11
|
//#endregion
|
|
14
12
|
//#region src/context.ts
|
|
13
|
+
const noopTracerProvider$1 = { getTracer: () => ({
|
|
14
|
+
startActiveSpan: () => void 0,
|
|
15
|
+
startSpan: () => void 0
|
|
16
|
+
}) };
|
|
15
17
|
function createContext(values) {
|
|
16
|
-
const { federation, url = new URL("http://example.com/"), canonicalOrigin, data, documentLoader, contextLoader, tracerProvider, clone, getNodeInfoUri, getActorUri, getObjectUri, getCollectionUri, getOutboxUri, getInboxUri, getFollowingUri, getFollowersUri, getLikedUri, getFeaturedUri, getFeaturedTagsUri, parseUri, getActorKeyPairs, getDocumentLoader, lookupObject: lookupObject$1, traverseCollection: traverseCollection$1, lookupNodeInfo, lookupWebFinger
|
|
18
|
+
const { federation, url = new URL("http://example.com/"), canonicalOrigin, data, documentLoader, contextLoader, tracerProvider, clone, getNodeInfoUri, getActorUri, getObjectUri, getCollectionUri, getOutboxUri, getInboxUri, getFollowingUri, getFollowersUri, getLikedUri, getFeaturedUri, getFeaturedTagsUri, parseUri, getActorKeyPairs, getDocumentLoader, lookupObject: lookupObject$1, traverseCollection: traverseCollection$1, lookupNodeInfo, lookupWebFinger, sendActivity, routeActivity } = values;
|
|
17
19
|
function throwRouteError() {
|
|
18
20
|
throw new RouterError("Not implemented");
|
|
19
21
|
}
|
|
@@ -26,7 +28,7 @@ function createContext(values) {
|
|
|
26
28
|
hostname: url.hostname,
|
|
27
29
|
documentLoader: documentLoader ?? mockDocumentLoader,
|
|
28
30
|
contextLoader: contextLoader ?? mockDocumentLoader,
|
|
29
|
-
tracerProvider: tracerProvider ??
|
|
31
|
+
tracerProvider: tracerProvider ?? noopTracerProvider$1,
|
|
30
32
|
clone: clone ?? ((data$1) => createContext({
|
|
31
33
|
...values,
|
|
32
34
|
data: data$1
|
|
@@ -64,8 +66,8 @@ function createContext(values) {
|
|
|
64
66
|
lookupNodeInfo: lookupNodeInfo ?? ((_params) => {
|
|
65
67
|
throw new Error("Not implemented");
|
|
66
68
|
}),
|
|
67
|
-
lookupWebFinger: lookupWebFinger
|
|
68
|
-
return
|
|
69
|
+
lookupWebFinger: lookupWebFinger ?? ((_resource, _options = {}) => {
|
|
70
|
+
return Promise.resolve(null);
|
|
69
71
|
}),
|
|
70
72
|
sendActivity: sendActivity ?? ((_params) => {
|
|
71
73
|
throw new Error("Not implemented");
|
|
@@ -75,6 +77,13 @@ function createContext(values) {
|
|
|
75
77
|
})
|
|
76
78
|
};
|
|
77
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Creates a RequestContext for testing purposes.
|
|
82
|
+
* Not exported - used internally only. Public API is in mock.ts
|
|
83
|
+
* @param args Partial RequestContext properties
|
|
84
|
+
* @returns A RequestContext instance
|
|
85
|
+
* @since 1.8.0
|
|
86
|
+
*/
|
|
78
87
|
function createRequestContext(args) {
|
|
79
88
|
return {
|
|
80
89
|
...createContext(args),
|
|
@@ -93,6 +102,13 @@ function createRequestContext(args) {
|
|
|
93
102
|
})
|
|
94
103
|
};
|
|
95
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Creates an InboxContext for testing purposes.
|
|
107
|
+
* Not exported - used internally only. Public API is in mock.ts
|
|
108
|
+
* @param args Partial InboxContext properties
|
|
109
|
+
* @returns An InboxContext instance
|
|
110
|
+
* @since 1.8.0
|
|
111
|
+
*/
|
|
96
112
|
function createInboxContext(args) {
|
|
97
113
|
return {
|
|
98
114
|
...createContext(args),
|
|
@@ -109,6 +125,10 @@ function createInboxContext(args) {
|
|
|
109
125
|
|
|
110
126
|
//#endregion
|
|
111
127
|
//#region src/mock.ts
|
|
128
|
+
const noopTracerProvider = { getTracer: () => ({
|
|
129
|
+
startActiveSpan: () => void 0,
|
|
130
|
+
startSpan: () => void 0
|
|
131
|
+
}) };
|
|
112
132
|
/**
|
|
113
133
|
* Helper function to expand URI templates with values.
|
|
114
134
|
* Supports simple placeholders like {identifier}, {handle}, etc.
|
|
@@ -129,17 +149,17 @@ function expandUriTemplate(template, values) {
|
|
|
129
149
|
* @example
|
|
130
150
|
* ```typescript
|
|
131
151
|
* import { Create } from "@fedify/fedify/vocab";
|
|
132
|
-
* import {
|
|
152
|
+
* import { createFederation } from "@fedify/testing";
|
|
133
153
|
*
|
|
134
154
|
* // Create a mock federation with contextData
|
|
135
|
-
* const federation =
|
|
155
|
+
* const federation = createFederation<{ userId: string }>({
|
|
136
156
|
* contextData: { userId: "test-user" }
|
|
137
157
|
* });
|
|
138
158
|
*
|
|
139
159
|
* // Set up inbox listeners
|
|
140
160
|
* federation
|
|
141
161
|
* .setInboxListeners("/users/{identifier}/inbox")
|
|
142
|
-
* .on(Create, async (ctx, activity) => {
|
|
162
|
+
* .on(Create, async (ctx: any, activity: any) => {
|
|
143
163
|
* console.log("Received:", activity);
|
|
144
164
|
* });
|
|
145
165
|
*
|
|
@@ -160,6 +180,7 @@ var MockFederation = class {
|
|
|
160
180
|
activeQueues = /* @__PURE__ */ new Set();
|
|
161
181
|
sentCounter = 0;
|
|
162
182
|
nodeInfoDispatcher;
|
|
183
|
+
webFingerDispatcher;
|
|
163
184
|
actorDispatchers = /* @__PURE__ */ new Map();
|
|
164
185
|
actorPath;
|
|
165
186
|
inboxPath;
|
|
@@ -191,6 +212,9 @@ var MockFederation = class {
|
|
|
191
212
|
this.nodeInfoDispatcher = dispatcher;
|
|
192
213
|
this.nodeInfoPath = path;
|
|
193
214
|
}
|
|
215
|
+
setWebFingerLinksDispatcher(dispatcher) {
|
|
216
|
+
this.webFingerDispatcher = dispatcher;
|
|
217
|
+
}
|
|
194
218
|
setActorDispatcher(path, dispatcher) {
|
|
195
219
|
this.actorDispatchers.set(path, dispatcher);
|
|
196
220
|
this.actorPath = path;
|
|
@@ -291,6 +315,9 @@ var MockFederation = class {
|
|
|
291
315
|
},
|
|
292
316
|
setSharedKeyDispatcher() {
|
|
293
317
|
return this;
|
|
318
|
+
},
|
|
319
|
+
withIdempotency() {
|
|
320
|
+
return this;
|
|
294
321
|
}
|
|
295
322
|
};
|
|
296
323
|
}
|
|
@@ -309,22 +336,9 @@ var MockFederation = class {
|
|
|
309
336
|
}
|
|
310
337
|
createContext(baseUrlOrRequest, contextData) {
|
|
311
338
|
const mockFederation = this;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
data: contextData,
|
|
316
|
-
federation: mockFederation,
|
|
317
|
-
sendActivity: async (sender, recipients, activity, options) => {
|
|
318
|
-
const tempContext = new MockContext({
|
|
319
|
-
url: new URL(baseUrlOrRequest.url),
|
|
320
|
-
data: contextData,
|
|
321
|
-
federation: mockFederation
|
|
322
|
-
});
|
|
323
|
-
await tempContext.sendActivity(sender, recipients, activity, options);
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
else return new MockContext({
|
|
327
|
-
url: baseUrlOrRequest,
|
|
339
|
+
const url = baseUrlOrRequest instanceof Request ? new URL(baseUrlOrRequest.url) : baseUrlOrRequest;
|
|
340
|
+
return new MockContext({
|
|
341
|
+
url,
|
|
328
342
|
data: contextData,
|
|
329
343
|
federation: mockFederation
|
|
330
344
|
});
|
|
@@ -382,22 +396,66 @@ var MockFederation = class {
|
|
|
382
396
|
}
|
|
383
397
|
};
|
|
384
398
|
/**
|
|
399
|
+
* Creates a mock Federation instance for testing purposes.
|
|
400
|
+
*
|
|
401
|
+
* @template TContextData The type of context data to use
|
|
402
|
+
* @param options Optional configuration for the mock federation
|
|
403
|
+
* @returns A Federation instance that can be used for testing
|
|
404
|
+
* @since 1.9.1
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* ```typescript
|
|
408
|
+
* import { Create } from "@fedify/fedify/vocab";
|
|
409
|
+
* import { createFederation } from "@fedify/testing";
|
|
410
|
+
*
|
|
411
|
+
* // Create a mock federation with contextData
|
|
412
|
+
* const federation = createFederation<{ userId: string }>({
|
|
413
|
+
* contextData: { userId: "test-user" }
|
|
414
|
+
* });
|
|
415
|
+
*
|
|
416
|
+
* // Set up inbox listeners
|
|
417
|
+
* federation
|
|
418
|
+
* .setInboxListeners("/users/{identifier}/inbox")
|
|
419
|
+
* .on(Create, async (ctx, activity) => {
|
|
420
|
+
* console.log("Received:", activity);
|
|
421
|
+
* });
|
|
422
|
+
*
|
|
423
|
+
* // Simulate receiving an activity
|
|
424
|
+
* const createActivity = new Create({
|
|
425
|
+
* id: new URL("https://example.com/create/1"),
|
|
426
|
+
* actor: new URL("https://example.com/users/alice")
|
|
427
|
+
* });
|
|
428
|
+
* await federation.receiveActivity(createActivity);
|
|
429
|
+
*
|
|
430
|
+
* // Check sent activities
|
|
431
|
+
* console.log(federation.sentActivities);
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
function createFederation(options = {}) {
|
|
435
|
+
return new MockFederation(options);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
385
438
|
* A mock implementation of the {@link Context} interface for unit testing.
|
|
386
439
|
* This class provides a way to test Fedify applications without needing
|
|
387
440
|
* a real federation context.
|
|
388
441
|
*
|
|
442
|
+
* Note: This class is not exported from the public API to avoid JSR type
|
|
443
|
+
* analyzer issues. The MockContext class has complex type dependencies that
|
|
444
|
+
* can cause JSR's type analyzer to hang during processing (issue #468).
|
|
445
|
+
* Use {@link MockFederation.createContext}, {@link createContext},
|
|
446
|
+
* {@link createRequestContext}, or {@link createInboxContext} instead.
|
|
447
|
+
*
|
|
389
448
|
* @example
|
|
390
449
|
* ```typescript
|
|
391
450
|
* import { Person, Create } from "@fedify/fedify/vocab";
|
|
392
|
-
* import {
|
|
451
|
+
* import { createFederation } from "@fedify/testing";
|
|
393
452
|
*
|
|
394
|
-
* // Create a mock context
|
|
395
|
-
* const
|
|
396
|
-
* const context =
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
* });
|
|
453
|
+
* // Create a mock federation and context
|
|
454
|
+
* const federation = createFederation<{ userId: string }>();
|
|
455
|
+
* const context = federation.createContext(
|
|
456
|
+
* new URL("https://example.com"),
|
|
457
|
+
* { userId: "test-user" }
|
|
458
|
+
* );
|
|
401
459
|
*
|
|
402
460
|
* // Send an activity
|
|
403
461
|
* const recipient = new Person({ id: new URL("https://example.com/users/bob") });
|
|
@@ -411,8 +469,8 @@ var MockFederation = class {
|
|
|
411
469
|
* activity
|
|
412
470
|
* );
|
|
413
471
|
*
|
|
414
|
-
* // Check sent activities
|
|
415
|
-
* const sent =
|
|
472
|
+
* // Check sent activities from the federation
|
|
473
|
+
* const sent = federation.sentActivities;
|
|
416
474
|
* console.log(sent[0].activity);
|
|
417
475
|
* ```
|
|
418
476
|
*
|
|
@@ -429,6 +487,8 @@ var MockContext = class MockContext {
|
|
|
429
487
|
documentLoader;
|
|
430
488
|
contextLoader;
|
|
431
489
|
tracerProvider;
|
|
490
|
+
request;
|
|
491
|
+
url;
|
|
432
492
|
sentActivities = [];
|
|
433
493
|
constructor(options) {
|
|
434
494
|
const url = options.url ?? new URL("https://example.com");
|
|
@@ -436,6 +496,8 @@ var MockContext = class MockContext {
|
|
|
436
496
|
this.canonicalOrigin = url.origin;
|
|
437
497
|
this.host = url.host;
|
|
438
498
|
this.hostname = url.hostname;
|
|
499
|
+
this.url = url;
|
|
500
|
+
this.request = new Request(url);
|
|
439
501
|
this.data = options.data;
|
|
440
502
|
this.federation = options.federation;
|
|
441
503
|
this.documentLoader = options.documentLoader ?? (async (url$1) => ({
|
|
@@ -444,11 +506,23 @@ var MockContext = class MockContext {
|
|
|
444
506
|
documentUrl: url$1
|
|
445
507
|
}));
|
|
446
508
|
this.contextLoader = options.contextLoader ?? this.documentLoader;
|
|
447
|
-
this.tracerProvider = options.tracerProvider ??
|
|
509
|
+
this.tracerProvider = options.tracerProvider ?? noopTracerProvider;
|
|
510
|
+
}
|
|
511
|
+
getActor(_handle) {
|
|
512
|
+
return Promise.resolve(null);
|
|
513
|
+
}
|
|
514
|
+
getObject(_cls, _values) {
|
|
515
|
+
return Promise.resolve(null);
|
|
516
|
+
}
|
|
517
|
+
getSignedKey() {
|
|
518
|
+
return Promise.resolve(null);
|
|
519
|
+
}
|
|
520
|
+
getSignedKeyOwner() {
|
|
521
|
+
return Promise.resolve(null);
|
|
448
522
|
}
|
|
449
523
|
clone(data) {
|
|
450
524
|
return new MockContext({
|
|
451
|
-
url:
|
|
525
|
+
url: this.url,
|
|
452
526
|
data,
|
|
453
527
|
federation: this.federation,
|
|
454
528
|
documentLoader: this.documentLoader,
|
|
@@ -630,4 +704,4 @@ var MockContext = class MockContext {
|
|
|
630
704
|
};
|
|
631
705
|
|
|
632
706
|
//#endregion
|
|
633
|
-
export {
|
|
707
|
+
export { createContext, createFederation, createInboxContext, createRequestContext };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/testing",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.150+7daa59dd",
|
|
4
4
|
"description": "Testing utilities for Fedify applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fedify",
|
|
@@ -29,13 +29,18 @@
|
|
|
29
29
|
"https://github.com/sponsors/dahlia"
|
|
30
30
|
],
|
|
31
31
|
"type": "module",
|
|
32
|
-
"main": "./dist/mod.
|
|
32
|
+
"main": "./dist/mod.cjs",
|
|
33
33
|
"module": "./dist/mod.js",
|
|
34
34
|
"types": "./dist/mod.d.ts",
|
|
35
35
|
"exports": {
|
|
36
36
|
".": {
|
|
37
|
-
"types":
|
|
37
|
+
"types": {
|
|
38
|
+
"import": "./dist/mod.d.ts",
|
|
39
|
+
"require": "./dist/mod.d.cts",
|
|
40
|
+
"default": "./dist/mod.d.ts"
|
|
41
|
+
},
|
|
38
42
|
"import": "./dist/mod.js",
|
|
43
|
+
"require": "./dist/mod.cjs",
|
|
39
44
|
"default": "./dist/mod.js"
|
|
40
45
|
},
|
|
41
46
|
"./package.json": "./package.json"
|
|
@@ -45,17 +50,14 @@
|
|
|
45
50
|
"package.json"
|
|
46
51
|
],
|
|
47
52
|
"peerDependencies": {
|
|
48
|
-
"@fedify/fedify": "2.0.0-dev.
|
|
49
|
-
},
|
|
50
|
-
"dependencies": {
|
|
51
|
-
"@opentelemetry/api": "^1.9.0"
|
|
53
|
+
"@fedify/fedify": "^2.0.0-dev.150+7daa59dd"
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
54
56
|
"@js-temporal/polyfill": "^0.5.1",
|
|
55
57
|
"@std/assert": "npm:@jsr/std__assert@^1.0.13",
|
|
56
58
|
"@std/async": "npm:@jsr/std__async@^1.0.13",
|
|
57
59
|
"tsdown": "^0.12.9",
|
|
58
|
-
"typescript": "^5.9.
|
|
60
|
+
"typescript": "^5.9.3"
|
|
59
61
|
},
|
|
60
62
|
"scripts": {
|
|
61
63
|
"build": "tsdown",
|