@fedify/testing 1.8.1-dev.1233 → 1.8.1-dev.1238
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mod.d.ts +1 -1
- package/dist/mod.js +3 -3
- package/package.json +10 -6
- package/context.ts +0 -156
- package/deno.json +0 -41
- package/docloader.ts +0 -8
- package/mock.test.ts +0 -361
- package/mock.ts +0 -1000
- package/mod.ts +0 -12
- package/tsdown.config.ts +0 -16
package/dist/mod.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ResourceDescriptor } from "@fedify/fedify/webfinger";
|
|
|
5
5
|
import { JsonValue, NodeInfo } from "@fedify/fedify/nodeinfo";
|
|
6
6
|
import { DocumentLoader } from "@fedify/fedify/runtime";
|
|
7
7
|
|
|
8
|
-
//#region mock.d.ts
|
|
8
|
+
//#region src/mock.d.ts
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Represents a sent activity with metadata about how it was sent.
|
package/dist/mod.js
CHANGED
|
@@ -3,7 +3,7 @@ import { RouterError } from "@fedify/fedify/federation";
|
|
|
3
3
|
import { lookupObject, traverseCollection } from "@fedify/fedify/vocab";
|
|
4
4
|
import { lookupWebFinger } from "@fedify/fedify/webfinger";
|
|
5
5
|
|
|
6
|
-
//#region docloader.ts
|
|
6
|
+
//#region src/docloader.ts
|
|
7
7
|
const mockDocumentLoader = async (url) => ({
|
|
8
8
|
contextUrl: null,
|
|
9
9
|
document: {},
|
|
@@ -11,7 +11,7 @@ const mockDocumentLoader = async (url) => ({
|
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
//#endregion
|
|
14
|
-
//#region context.ts
|
|
14
|
+
//#region src/context.ts
|
|
15
15
|
function createContext(values) {
|
|
16
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: lookupWebFinger$1, sendActivity, routeActivity } = values;
|
|
17
17
|
function throwRouteError() {
|
|
@@ -108,7 +108,7 @@ function createInboxContext(args) {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
//#endregion
|
|
111
|
-
//#region mock.ts
|
|
111
|
+
//#region src/mock.ts
|
|
112
112
|
/**
|
|
113
113
|
* Helper function to expand URI templates with values.
|
|
114
114
|
* Supports simple placeholders like {identifier}, {handle}, etc.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/testing",
|
|
3
|
-
"version": "1.8.1-dev.
|
|
3
|
+
"version": "1.8.1-dev.1238+4e631e65",
|
|
4
4
|
"description": "Testing utilities for Fedify applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fedify",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
21
|
"url": "git+https://github.com/fedify-dev/fedify.git",
|
|
22
|
-
"directory": "testing"
|
|
22
|
+
"directory": "packages/testing"
|
|
23
23
|
},
|
|
24
24
|
"bugs": {
|
|
25
25
|
"url": "https://github.com/fedify-dev/fedify/issues"
|
|
@@ -40,8 +40,15 @@
|
|
|
40
40
|
},
|
|
41
41
|
"./package.json": "./package.json"
|
|
42
42
|
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"package.json"
|
|
46
|
+
],
|
|
43
47
|
"peerDependencies": {
|
|
44
|
-
"@fedify/fedify": "1.8.1-dev.
|
|
48
|
+
"@fedify/fedify": "1.8.1-dev.1238+4e631e65"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@opentelemetry/api": "^1.9.0"
|
|
45
52
|
},
|
|
46
53
|
"devDependencies": {
|
|
47
54
|
"@js-temporal/polyfill": "^0.5.1",
|
|
@@ -50,9 +57,6 @@
|
|
|
50
57
|
"tsdown": "^0.12.9",
|
|
51
58
|
"typescript": "^5.8.3"
|
|
52
59
|
},
|
|
53
|
-
"dependencies": {
|
|
54
|
-
"@opentelemetry/api": "^1.9.0"
|
|
55
|
-
},
|
|
56
60
|
"scripts": {
|
|
57
61
|
"build": "tsdown",
|
|
58
62
|
"prepublish": "tsdown",
|
package/context.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Context,
|
|
3
|
-
Federation,
|
|
4
|
-
InboxContext,
|
|
5
|
-
RequestContext,
|
|
6
|
-
} from "@fedify/fedify/federation";
|
|
7
|
-
import { RouterError } from "@fedify/fedify/federation";
|
|
8
|
-
import {
|
|
9
|
-
lookupObject as globalLookupObject,
|
|
10
|
-
traverseCollection as globalTraverseCollection,
|
|
11
|
-
} from "@fedify/fedify/vocab";
|
|
12
|
-
import { lookupWebFinger as globalLookupWebFinger } from "@fedify/fedify/webfinger";
|
|
13
|
-
import { trace } from "@opentelemetry/api";
|
|
14
|
-
import { mockDocumentLoader } from "./docloader.ts";
|
|
15
|
-
|
|
16
|
-
// NOTE: Copied from @fedify/fedify/testing/context.ts
|
|
17
|
-
|
|
18
|
-
export function createContext<TContextData>(
|
|
19
|
-
values: Partial<Context<TContextData>> & {
|
|
20
|
-
url?: URL;
|
|
21
|
-
data: TContextData;
|
|
22
|
-
federation: Federation<TContextData>;
|
|
23
|
-
},
|
|
24
|
-
): Context<TContextData> {
|
|
25
|
-
const {
|
|
26
|
-
federation,
|
|
27
|
-
url = new URL("http://example.com/"),
|
|
28
|
-
canonicalOrigin,
|
|
29
|
-
data,
|
|
30
|
-
documentLoader,
|
|
31
|
-
contextLoader,
|
|
32
|
-
tracerProvider,
|
|
33
|
-
clone,
|
|
34
|
-
getNodeInfoUri,
|
|
35
|
-
getActorUri,
|
|
36
|
-
getObjectUri,
|
|
37
|
-
getCollectionUri,
|
|
38
|
-
getOutboxUri,
|
|
39
|
-
getInboxUri,
|
|
40
|
-
getFollowingUri,
|
|
41
|
-
getFollowersUri,
|
|
42
|
-
getLikedUri,
|
|
43
|
-
getFeaturedUri,
|
|
44
|
-
getFeaturedTagsUri,
|
|
45
|
-
parseUri,
|
|
46
|
-
getActorKeyPairs,
|
|
47
|
-
getDocumentLoader,
|
|
48
|
-
lookupObject,
|
|
49
|
-
traverseCollection,
|
|
50
|
-
lookupNodeInfo,
|
|
51
|
-
lookupWebFinger,
|
|
52
|
-
sendActivity,
|
|
53
|
-
routeActivity,
|
|
54
|
-
} = values;
|
|
55
|
-
function throwRouteError(): URL {
|
|
56
|
-
throw new RouterError("Not implemented");
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
federation,
|
|
60
|
-
data,
|
|
61
|
-
origin: url.origin,
|
|
62
|
-
canonicalOrigin: canonicalOrigin ?? url.origin,
|
|
63
|
-
host: url.host,
|
|
64
|
-
hostname: url.hostname,
|
|
65
|
-
documentLoader: documentLoader ?? mockDocumentLoader,
|
|
66
|
-
contextLoader: contextLoader ?? mockDocumentLoader,
|
|
67
|
-
tracerProvider: tracerProvider ?? trace.getTracerProvider(),
|
|
68
|
-
clone: clone ?? ((data) => createContext({ ...values, data })),
|
|
69
|
-
getNodeInfoUri: getNodeInfoUri ?? throwRouteError,
|
|
70
|
-
getActorUri: getActorUri ?? throwRouteError,
|
|
71
|
-
getObjectUri: getObjectUri ?? throwRouteError,
|
|
72
|
-
getCollectionUri: getCollectionUri ?? throwRouteError,
|
|
73
|
-
getOutboxUri: getOutboxUri ?? throwRouteError,
|
|
74
|
-
getInboxUri: getInboxUri ?? throwRouteError,
|
|
75
|
-
getFollowingUri: getFollowingUri ?? throwRouteError,
|
|
76
|
-
getFollowersUri: getFollowersUri ?? throwRouteError,
|
|
77
|
-
getLikedUri: getLikedUri ?? throwRouteError,
|
|
78
|
-
getFeaturedUri: getFeaturedUri ?? throwRouteError,
|
|
79
|
-
getFeaturedTagsUri: getFeaturedTagsUri ?? throwRouteError,
|
|
80
|
-
parseUri: parseUri ?? ((_uri) => {
|
|
81
|
-
throw new Error("Not implemented");
|
|
82
|
-
}),
|
|
83
|
-
getDocumentLoader: getDocumentLoader ?? ((_params) => {
|
|
84
|
-
throw new Error("Not implemented");
|
|
85
|
-
}),
|
|
86
|
-
getActorKeyPairs: getActorKeyPairs ?? ((_handle) => Promise.resolve([])),
|
|
87
|
-
lookupObject: lookupObject ?? ((uri, options = {}) => {
|
|
88
|
-
return globalLookupObject(uri, {
|
|
89
|
-
documentLoader: options.documentLoader ?? documentLoader ??
|
|
90
|
-
mockDocumentLoader,
|
|
91
|
-
contextLoader: options.contextLoader ?? contextLoader ??
|
|
92
|
-
mockDocumentLoader,
|
|
93
|
-
});
|
|
94
|
-
}),
|
|
95
|
-
traverseCollection: traverseCollection ?? ((collection, options = {}) => {
|
|
96
|
-
return globalTraverseCollection(collection, {
|
|
97
|
-
documentLoader: options.documentLoader ?? documentLoader ??
|
|
98
|
-
mockDocumentLoader,
|
|
99
|
-
contextLoader: options.contextLoader ?? contextLoader ??
|
|
100
|
-
mockDocumentLoader,
|
|
101
|
-
});
|
|
102
|
-
}),
|
|
103
|
-
lookupNodeInfo: lookupNodeInfo ?? ((_params) => {
|
|
104
|
-
throw new Error("Not implemented");
|
|
105
|
-
}),
|
|
106
|
-
lookupWebFinger: lookupWebFinger ?? ((resource, options = {}) => {
|
|
107
|
-
return globalLookupWebFinger(resource, options);
|
|
108
|
-
}),
|
|
109
|
-
sendActivity: sendActivity ?? ((_params) => {
|
|
110
|
-
throw new Error("Not implemented");
|
|
111
|
-
}),
|
|
112
|
-
routeActivity: routeActivity ?? ((_params) => {
|
|
113
|
-
throw new Error("Not implemented");
|
|
114
|
-
}),
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function createRequestContext<TContextData>(
|
|
119
|
-
args: Partial<RequestContext<TContextData>> & {
|
|
120
|
-
url: URL;
|
|
121
|
-
data: TContextData;
|
|
122
|
-
federation: Federation<TContextData>;
|
|
123
|
-
},
|
|
124
|
-
): RequestContext<TContextData> {
|
|
125
|
-
return {
|
|
126
|
-
...createContext(args),
|
|
127
|
-
clone: args.clone ?? ((data) => createRequestContext({ ...args, data })),
|
|
128
|
-
request: args.request ?? new Request(args.url),
|
|
129
|
-
url: args.url,
|
|
130
|
-
getActor: args.getActor ?? (() => Promise.resolve(null)),
|
|
131
|
-
getObject: args.getObject ?? (() => Promise.resolve(null)),
|
|
132
|
-
getSignedKey: args.getSignedKey ?? (() => Promise.resolve(null)),
|
|
133
|
-
getSignedKeyOwner: args.getSignedKeyOwner ?? (() => Promise.resolve(null)),
|
|
134
|
-
sendActivity: args.sendActivity ?? ((_params) => {
|
|
135
|
-
throw new Error("Not implemented");
|
|
136
|
-
}),
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function createInboxContext<TContextData>(
|
|
141
|
-
args: Partial<InboxContext<TContextData>> & {
|
|
142
|
-
url?: URL;
|
|
143
|
-
data: TContextData;
|
|
144
|
-
recipient?: string | null;
|
|
145
|
-
federation: Federation<TContextData>;
|
|
146
|
-
},
|
|
147
|
-
): InboxContext<TContextData> {
|
|
148
|
-
return {
|
|
149
|
-
...createContext(args),
|
|
150
|
-
clone: args.clone ?? ((data) => createInboxContext({ ...args, data })),
|
|
151
|
-
recipient: args.recipient ?? null,
|
|
152
|
-
forwardActivity: args.forwardActivity ?? ((_params) => {
|
|
153
|
-
throw new Error("Not implemented");
|
|
154
|
-
}),
|
|
155
|
-
};
|
|
156
|
-
}
|
package/deno.json
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@fedify/testing",
|
|
3
|
-
"version": "1.8.1-dev.1233+f748fcc5",
|
|
4
|
-
"license": "MIT",
|
|
5
|
-
"exports": {
|
|
6
|
-
".": "./mod.ts"
|
|
7
|
-
},
|
|
8
|
-
"imports": {
|
|
9
|
-
"@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0"
|
|
10
|
-
},
|
|
11
|
-
"exclude": [
|
|
12
|
-
".github",
|
|
13
|
-
"node_modules",
|
|
14
|
-
"npm",
|
|
15
|
-
"pnpm-lock.yaml"
|
|
16
|
-
],
|
|
17
|
-
"tasks": {
|
|
18
|
-
"build": "pnpm build",
|
|
19
|
-
"check": "deno fmt --check && deno lint && deno check mod.ts",
|
|
20
|
-
"test": "deno test --allow-read --allow-net",
|
|
21
|
-
"test:node": {
|
|
22
|
-
"dependencies": [
|
|
23
|
-
"build"
|
|
24
|
-
],
|
|
25
|
-
"command": "node --experimental-transform-types --test"
|
|
26
|
-
},
|
|
27
|
-
"test:bun": {
|
|
28
|
-
"dependencies": [
|
|
29
|
-
"build"
|
|
30
|
-
],
|
|
31
|
-
"command": "bun test --timeout 15000"
|
|
32
|
-
},
|
|
33
|
-
"test-all": {
|
|
34
|
-
"dependencies": [
|
|
35
|
-
"test",
|
|
36
|
-
"test:node",
|
|
37
|
-
"test:bun"
|
|
38
|
-
]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
package/docloader.ts
DELETED
package/mock.test.ts
DELETED
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
import { Create, Note, Person } from "@fedify/fedify/vocab";
|
|
2
|
-
import { assertEquals, assertRejects } from "@std/assert";
|
|
3
|
-
import { test } from "../fedify/testing/mod.ts";
|
|
4
|
-
import { MockContext, MockFederation } from "./mock.ts";
|
|
5
|
-
|
|
6
|
-
test("getSentActivities returns sent activities", async () => {
|
|
7
|
-
const mockFederation = new MockFederation<void>();
|
|
8
|
-
const context = mockFederation.createContext(
|
|
9
|
-
new URL("https://example.com"),
|
|
10
|
-
undefined,
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
// Create a test activity
|
|
14
|
-
const activity = new Create({
|
|
15
|
-
id: new URL("https://example.com/activities/1"),
|
|
16
|
-
actor: new URL("https://example.com/users/alice"),
|
|
17
|
-
object: new Note({
|
|
18
|
-
id: new URL("https://example.com/notes/1"),
|
|
19
|
-
content: "Hello, world!",
|
|
20
|
-
}),
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Send the activity
|
|
24
|
-
await context.sendActivity(
|
|
25
|
-
{ identifier: "alice" },
|
|
26
|
-
new Person({ id: new URL("https://example.com/users/bob") }),
|
|
27
|
-
activity,
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
// Check that the activity was recorded
|
|
31
|
-
assertEquals(mockFederation.sentActivities.length, 1);
|
|
32
|
-
assertEquals(mockFederation.sentActivities[0].activity, activity);
|
|
33
|
-
assertEquals(mockFederation.sentActivities[0].queued, false);
|
|
34
|
-
assertEquals(mockFederation.sentActivities[0].sentOrder, 1);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test("reset clears sent activities", async () => {
|
|
38
|
-
const mockFederation = new MockFederation<void>();
|
|
39
|
-
const context = mockFederation.createContext(
|
|
40
|
-
new URL("https://example.com"),
|
|
41
|
-
undefined,
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
// Send an activity
|
|
45
|
-
const activity = new Create({
|
|
46
|
-
id: new URL("https://example.com/activities/1"),
|
|
47
|
-
actor: new URL("https://example.com/users/alice"),
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
await context.sendActivity(
|
|
51
|
-
{ identifier: "alice" },
|
|
52
|
-
new Person({ id: new URL("https://example.com/users/bob") }),
|
|
53
|
-
activity,
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
// Verify it was sent
|
|
57
|
-
assertEquals(mockFederation.sentActivities.length, 1);
|
|
58
|
-
assertEquals(mockFederation.sentActivities[0].activity, activity);
|
|
59
|
-
|
|
60
|
-
// Clear sent activities
|
|
61
|
-
mockFederation.reset();
|
|
62
|
-
|
|
63
|
-
// Verify they were cleared
|
|
64
|
-
assertEquals(mockFederation.sentActivities.length, 0);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("receiveActivity triggers inbox listeners", async () => {
|
|
68
|
-
// Provide contextData through constructor
|
|
69
|
-
const mockFederation = new MockFederation<{ test: string }>({
|
|
70
|
-
contextData: { test: "data" },
|
|
71
|
-
});
|
|
72
|
-
let receivedActivity: Create | null = null;
|
|
73
|
-
|
|
74
|
-
// Set up an inbox listener
|
|
75
|
-
mockFederation
|
|
76
|
-
.setInboxListeners("/users/{identifier}/inbox")
|
|
77
|
-
// deno-lint-ignore require-await
|
|
78
|
-
.on(Create, async (_ctx, activity) => {
|
|
79
|
-
receivedActivity = activity;
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// Create and receive an activity
|
|
83
|
-
const activity = new Create({
|
|
84
|
-
id: new URL("https://example.com/activities/1"),
|
|
85
|
-
actor: new URL("https://example.com/users/alice"),
|
|
86
|
-
object: new Note({
|
|
87
|
-
id: new URL("https://example.com/notes/1"),
|
|
88
|
-
content: "Test note",
|
|
89
|
-
}),
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
await mockFederation.receiveActivity(activity);
|
|
93
|
-
|
|
94
|
-
// Verify the listener was triggered
|
|
95
|
-
assertEquals(receivedActivity, activity);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test("MockContext tracks sent activities", async () => {
|
|
99
|
-
const mockFederation = new MockFederation<void>();
|
|
100
|
-
const mockContext = new MockContext({
|
|
101
|
-
url: new URL("https://example.com"),
|
|
102
|
-
data: undefined,
|
|
103
|
-
federation: mockFederation,
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// Create a test activity
|
|
107
|
-
const activity = new Create({
|
|
108
|
-
id: new URL("https://example.com/activities/1"),
|
|
109
|
-
actor: new URL("https://example.com/users/alice"),
|
|
110
|
-
object: new Note({
|
|
111
|
-
id: new URL("https://example.com/notes/1"),
|
|
112
|
-
content: "Hello from MockContext!",
|
|
113
|
-
}),
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// Send the activity
|
|
117
|
-
await mockContext.sendActivity(
|
|
118
|
-
{ identifier: "alice" },
|
|
119
|
-
new Person({ id: new URL("https://example.com/users/bob") }),
|
|
120
|
-
activity,
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
// Check that the activity was recorded in the context
|
|
124
|
-
const contextSentActivities = mockContext.getSentActivities();
|
|
125
|
-
assertEquals(contextSentActivities.length, 1);
|
|
126
|
-
assertEquals(contextSentActivities[0].activity, activity);
|
|
127
|
-
|
|
128
|
-
// Check that it was also recorded in the federation
|
|
129
|
-
assertEquals(mockFederation.sentActivities.length, 1);
|
|
130
|
-
assertEquals(mockFederation.sentActivities[0].activity, activity);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test("MockContext URI methods should work correctly", () => {
|
|
134
|
-
const mockFederation = new MockFederation<void>();
|
|
135
|
-
const mockContext = new MockContext({
|
|
136
|
-
url: new URL("https://example.com"),
|
|
137
|
-
data: undefined,
|
|
138
|
-
federation: mockFederation,
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// Test URI generation methods
|
|
142
|
-
assertEquals(
|
|
143
|
-
mockContext.getActorUri("alice").href,
|
|
144
|
-
"https://example.com/users/alice",
|
|
145
|
-
);
|
|
146
|
-
assertEquals(
|
|
147
|
-
mockContext.getInboxUri("alice").href,
|
|
148
|
-
"https://example.com/users/alice/inbox",
|
|
149
|
-
);
|
|
150
|
-
assertEquals(mockContext.getInboxUri().href, "https://example.com/inbox");
|
|
151
|
-
assertEquals(
|
|
152
|
-
mockContext.getOutboxUri("alice").href,
|
|
153
|
-
"https://example.com/users/alice/outbox",
|
|
154
|
-
);
|
|
155
|
-
assertEquals(
|
|
156
|
-
mockContext.getFollowingUri("alice").href,
|
|
157
|
-
"https://example.com/users/alice/following",
|
|
158
|
-
);
|
|
159
|
-
assertEquals(
|
|
160
|
-
mockContext.getFollowersUri("alice").href,
|
|
161
|
-
"https://example.com/users/alice/followers",
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
const actorUri = new URL("https://example.com/users/alice");
|
|
165
|
-
const parsed = mockContext.parseUri(actorUri);
|
|
166
|
-
assertEquals(parsed?.type, "actor");
|
|
167
|
-
if (parsed?.type === "actor") {
|
|
168
|
-
assertEquals(parsed.identifier, "alice");
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
test("MockContext URI methods respect registered paths", () => {
|
|
173
|
-
const mockFederation = new MockFederation<void>();
|
|
174
|
-
|
|
175
|
-
// Register custom paths with dummy dispatchers
|
|
176
|
-
mockFederation.setNodeInfoDispatcher("/.well-known/nodeinfo", () => ({
|
|
177
|
-
software: { name: "test", version: { major: 1, minor: 0, patch: 0 } },
|
|
178
|
-
protocols: [],
|
|
179
|
-
usage: {
|
|
180
|
-
users: {},
|
|
181
|
-
localPosts: 0,
|
|
182
|
-
localComments: 0,
|
|
183
|
-
},
|
|
184
|
-
}));
|
|
185
|
-
mockFederation.setActorDispatcher("/actors/{identifier}", () => null);
|
|
186
|
-
mockFederation.setObjectDispatcher(Note, "/notes/{id}", () => null);
|
|
187
|
-
mockFederation.setInboxListeners(
|
|
188
|
-
"/actors/{identifier}/inbox",
|
|
189
|
-
"/shared-inbox",
|
|
190
|
-
);
|
|
191
|
-
mockFederation.setOutboxDispatcher("/actors/{identifier}/outbox", () => null);
|
|
192
|
-
mockFederation.setFollowingDispatcher(
|
|
193
|
-
"/actors/{identifier}/following",
|
|
194
|
-
() => null,
|
|
195
|
-
);
|
|
196
|
-
mockFederation.setFollowersDispatcher(
|
|
197
|
-
"/actors/{identifier}/followers",
|
|
198
|
-
() => null,
|
|
199
|
-
);
|
|
200
|
-
mockFederation.setLikedDispatcher("/actors/{identifier}/liked", () => null);
|
|
201
|
-
mockFederation.setFeaturedDispatcher(
|
|
202
|
-
"/actors/{identifier}/featured",
|
|
203
|
-
() => null,
|
|
204
|
-
);
|
|
205
|
-
mockFederation.setFeaturedTagsDispatcher(
|
|
206
|
-
"/actors/{identifier}/tags",
|
|
207
|
-
() => null,
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
const context = mockFederation.createContext(
|
|
211
|
-
new URL("https://example.com"),
|
|
212
|
-
undefined,
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
// Test that URIs use the registered paths
|
|
216
|
-
assertEquals(
|
|
217
|
-
context.getNodeInfoUri().href,
|
|
218
|
-
"https://example.com/.well-known/nodeinfo",
|
|
219
|
-
);
|
|
220
|
-
assertEquals(
|
|
221
|
-
context.getActorUri("alice").href,
|
|
222
|
-
"https://example.com/actors/alice",
|
|
223
|
-
);
|
|
224
|
-
assertEquals(
|
|
225
|
-
context.getObjectUri(Note, { id: "123" }).href,
|
|
226
|
-
"https://example.com/notes/123",
|
|
227
|
-
);
|
|
228
|
-
assertEquals(
|
|
229
|
-
context.getInboxUri("alice").href,
|
|
230
|
-
"https://example.com/actors/alice/inbox",
|
|
231
|
-
);
|
|
232
|
-
assertEquals(
|
|
233
|
-
context.getInboxUri().href,
|
|
234
|
-
"https://example.com/shared-inbox",
|
|
235
|
-
);
|
|
236
|
-
assertEquals(
|
|
237
|
-
context.getOutboxUri("alice").href,
|
|
238
|
-
"https://example.com/actors/alice/outbox",
|
|
239
|
-
);
|
|
240
|
-
assertEquals(
|
|
241
|
-
context.getFollowingUri("alice").href,
|
|
242
|
-
"https://example.com/actors/alice/following",
|
|
243
|
-
);
|
|
244
|
-
assertEquals(
|
|
245
|
-
context.getFollowersUri("alice").href,
|
|
246
|
-
"https://example.com/actors/alice/followers",
|
|
247
|
-
);
|
|
248
|
-
assertEquals(
|
|
249
|
-
context.getLikedUri("alice").href,
|
|
250
|
-
"https://example.com/actors/alice/liked",
|
|
251
|
-
);
|
|
252
|
-
assertEquals(
|
|
253
|
-
context.getFeaturedUri("alice").href,
|
|
254
|
-
"https://example.com/actors/alice/featured",
|
|
255
|
-
);
|
|
256
|
-
assertEquals(
|
|
257
|
-
context.getFeaturedTagsUri("alice").href,
|
|
258
|
-
"https://example.com/actors/alice/tags",
|
|
259
|
-
);
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
test("receiveActivity throws error when contextData not initialized", async () => {
|
|
263
|
-
const mockFederation = new MockFederation<void>();
|
|
264
|
-
|
|
265
|
-
// Set up an inbox listener without initializing contextData
|
|
266
|
-
mockFederation
|
|
267
|
-
.setInboxListeners("/users/{identifier}/inbox")
|
|
268
|
-
.on(Create, async (_ctx, _activity) => {
|
|
269
|
-
/* should not happen */
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
const activity = new Create({
|
|
273
|
-
id: new URL("https://example.com/activities/1"),
|
|
274
|
-
actor: new URL("https://example.com/users/alice"),
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
// Should throw error
|
|
278
|
-
await assertRejects(
|
|
279
|
-
() => mockFederation.receiveActivity(activity),
|
|
280
|
-
Error,
|
|
281
|
-
"MockFederation.receiveActivity(): contextData is not initialized. Please provide contextData through the constructor or call startQueue() before receiving activities.",
|
|
282
|
-
);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
test("MockFederation distinguishes between immediate and queued activities", async () => {
|
|
286
|
-
const mockFederation = new MockFederation<void>();
|
|
287
|
-
|
|
288
|
-
// Start the queue to enable queued sending
|
|
289
|
-
await mockFederation.startQueue(undefined);
|
|
290
|
-
|
|
291
|
-
const context = mockFederation.createContext(
|
|
292
|
-
new URL("https://example.com"),
|
|
293
|
-
undefined,
|
|
294
|
-
);
|
|
295
|
-
|
|
296
|
-
const activity1 = new Create({
|
|
297
|
-
id: new URL("https://example.com/activities/1"),
|
|
298
|
-
actor: new URL("https://example.com/users/alice"),
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
const activity2 = new Create({
|
|
302
|
-
id: new URL("https://example.com/activities/2"),
|
|
303
|
-
actor: new URL("https://example.com/users/alice"),
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
// Send activities after queue is started - should be marked as queued
|
|
307
|
-
await context.sendActivity(
|
|
308
|
-
{ identifier: "alice" },
|
|
309
|
-
new Person({ id: new URL("https://example.com/users/bob") }),
|
|
310
|
-
activity1,
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
await context.sendActivity(
|
|
314
|
-
{ identifier: "alice" },
|
|
315
|
-
new Person({ id: new URL("https://example.com/users/bob") }),
|
|
316
|
-
activity2,
|
|
317
|
-
);
|
|
318
|
-
|
|
319
|
-
// Check activity details
|
|
320
|
-
assertEquals(mockFederation.sentActivities.length, 2);
|
|
321
|
-
assertEquals(mockFederation.sentActivities[0].activity, activity1);
|
|
322
|
-
assertEquals(mockFederation.sentActivities[1].activity, activity2);
|
|
323
|
-
|
|
324
|
-
// Both should be marked as sent via queue
|
|
325
|
-
assertEquals(mockFederation.sentActivities[0].queued, true);
|
|
326
|
-
assertEquals(mockFederation.sentActivities[1].queued, true);
|
|
327
|
-
assertEquals(mockFederation.sentActivities[0].queue, "outbox");
|
|
328
|
-
assertEquals(mockFederation.sentActivities[1].queue, "outbox");
|
|
329
|
-
assertEquals(mockFederation.sentActivities[0].sentOrder, 1);
|
|
330
|
-
assertEquals(mockFederation.sentActivities[1].sentOrder, 2);
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
test("MockFederation without queue sends all activities immediately", async () => {
|
|
334
|
-
const mockFederation = new MockFederation<void>();
|
|
335
|
-
|
|
336
|
-
const context = mockFederation.createContext(
|
|
337
|
-
new URL("https://example.com"),
|
|
338
|
-
undefined,
|
|
339
|
-
);
|
|
340
|
-
|
|
341
|
-
const activity = new Create({
|
|
342
|
-
id: new URL("https://example.com/activities/1"),
|
|
343
|
-
actor: new URL("https://example.com/users/alice"),
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
// Send activity - should be marked as immediate since queue not started
|
|
347
|
-
await context.sendActivity(
|
|
348
|
-
{ identifier: "alice" },
|
|
349
|
-
new Person({ id: new URL("https://example.com/users/bob") }),
|
|
350
|
-
activity,
|
|
351
|
-
);
|
|
352
|
-
|
|
353
|
-
// Check activity details
|
|
354
|
-
assertEquals(mockFederation.sentActivities.length, 1);
|
|
355
|
-
assertEquals(mockFederation.sentActivities[0].activity, activity);
|
|
356
|
-
|
|
357
|
-
// Should be marked as sent immediately
|
|
358
|
-
assertEquals(mockFederation.sentActivities[0].queued, false);
|
|
359
|
-
assertEquals(mockFederation.sentActivities[0].queue, undefined);
|
|
360
|
-
assertEquals(mockFederation.sentActivities[0].sentOrder, 1);
|
|
361
|
-
});
|