@fedify/botkit 0.3.0-dev.111 → 0.3.0-dev.112

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.
@@ -1 +1 @@
1
- {"version":3,"file":"bot-impl.test.js","names":["followRequests: [Session<void>, FollowRequest][]","unfollowed: [Session<void>, Actor][]","accepted: [Session<void>, Actor][]","rejected: [Session<void>, Actor][]","replied: [Session<void>, Message<MessageClass, void>][]","mentioned: [Session<void>, Message<MessageClass, void>][]","messaged: [Session<void>, Message<MessageClass, void>][]","quoted: [Session<void>, Message<MessageClass, void>][]","session","msg","shares: [Session<void>, SharedMessage<MessageClass, void>][]","sharedMessage","likes: [Session<void>, Like<void>][]","like","RawLike","reactions: [Session<void>, Reaction<void>][]","reaction","emojiData: CustomEmoji","remoteEmojiData: CustomEmoji","localEmojiData: CustomEmoji","localEmojiDataNoExt: CustomEmoji","bot: BotImpl<void>","origin: string | URL","recipient?: string | null"],"sources":["../src/bot-impl.test.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport { type InboxContext, MemoryKvStore } from \"@fedify/fedify/federation\";\nimport {\n Accept,\n type Activity,\n type Actor,\n Announce,\n Article,\n Create,\n CryptographicKey,\n Emoji,\n EmojiReact,\n Follow,\n Image,\n Like as RawLike,\n Mention,\n Note,\n Person,\n Place,\n PropertyValue,\n PUBLIC_COLLECTION,\n type Recipient,\n Reject,\n Service,\n Undo,\n} from \"@fedify/fedify/vocab\";\nimport assert from \"node:assert\";\nimport { describe, test } from \"node:test\";\nimport { BotImpl } from \"./bot-impl.ts\";\nimport { parseSemVer } from \"./bot.ts\";\nimport type { CustomEmoji } from \"./emoji.ts\";\nimport type { FollowRequest } from \"./follow.ts\";\nimport type { Message, MessageClass, SharedMessage } from \"./message.ts\";\nimport type { Like, Reaction } from \"./reaction.ts\";\nimport { MemoryRepository } from \"./repository.ts\";\nimport { SessionImpl } from \"./session-impl.ts\";\nimport type { Session } from \"./session.ts\";\nimport { mention, strong, text } from \"./text.ts\";\n\ndescribe(\"BotImpl.getActorSummary()\", () => {\n test(\"without summary\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const session = bot.getSession(\"https://example.com\");\n assert.deepStrictEqual(await bot.getActorSummary(session), null);\n });\n\n test(\"with summary\", async () => {\n const actor = new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n });\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n summary: text`A summary with a mention: ${actor}.`,\n });\n const session = bot.getSession(\"https://example.com\");\n const expected = {\n tags: [\n new Mention({\n href: new URL(\"https://example.com/actor/john\"),\n name: \"@john@example.com\",\n }),\n ],\n text: \"<p>A summary with a mention: \" +\n '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>' +\n \"john@example.com</span></a>.</p>\",\n };\n assert.deepStrictEqual(await bot.getActorSummary(session), expected);\n assert.deepStrictEqual(await bot.getActorSummary(session), expected);\n });\n});\n\ntest(\"BotImpl.getActorProperties()\", async () => {\n const actor = new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n });\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n properties: {\n Foo: strong(\"bar\"),\n Baz: mention(actor),\n Qux: text`quux`,\n },\n });\n const session = bot.getSession(\"https://example.com\");\n const expected = {\n pairs: [\n new PropertyValue({ name: \"Foo\", value: \"<strong>bar</strong>\" }),\n new PropertyValue({\n name: \"Baz\",\n value: '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>' +\n \"john@example.com</span></a>\",\n }),\n new PropertyValue({ name: \"Qux\", value: \"<p>quux</p>\" }),\n ],\n tags: [\n new Mention({\n href: new URL(\"https://example.com/actor/john\"),\n name: \"@john@example.com\",\n }),\n ],\n };\n assert.deepStrictEqual(await bot.getActorProperties(session), expected);\n assert.deepStrictEqual(await bot.getActorProperties(session), expected);\n});\n\ninterface KeyPair {\n private: JsonWebKey;\n public: JsonWebKey;\n}\n\ntest(\"BotImpl.dispatchActor()\", async () => {\n const mentionActor = new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n });\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"test\",\n name: \"Test Bot\",\n summary: text`A summary with a mention: ${mentionActor}.`,\n properties: {\n Foo: strong(\"bar\"),\n Baz: mention(mentionActor),\n Qux: text`quux`,\n },\n icon: new URL(\"https://example.com/icon.png\"),\n image: new URL(\"https://example.com/image.png\"),\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(await bot.dispatchActor(ctx, \"non-existent\"), null);\n const actor = await bot.dispatchActor(ctx, \"bot\");\n assert.ok(actor instanceof Service);\n assert.deepStrictEqual(actor.id, new URL(\"https://example.com/ap/actor/bot\"));\n assert.deepStrictEqual(actor.preferredUsername, \"test\");\n assert.deepStrictEqual(actor.name, \"Test Bot\");\n assert.deepStrictEqual(\n actor.summary,\n \"<p>A summary with a mention: \" +\n '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>john@example.com' +\n \"</span></a>.</p>\",\n );\n const attachments = await Array.fromAsync(actor.getAttachments());\n assert.deepStrictEqual(attachments.length, 3);\n assert.ok(attachments[0] instanceof PropertyValue);\n assert.deepStrictEqual(attachments[0].name, \"Foo\");\n assert.deepStrictEqual(attachments[0].value, \"<strong>bar</strong>\");\n assert.ok(attachments[1] instanceof PropertyValue);\n assert.deepStrictEqual(attachments[1].name, \"Baz\");\n assert.deepStrictEqual(\n attachments[1].value,\n '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>' +\n \"john@example.com</span></a>\",\n );\n assert.ok(attachments[2] instanceof PropertyValue);\n assert.deepStrictEqual(attachments[2].name, \"Qux\");\n assert.deepStrictEqual(attachments[2].value, \"<p>quux</p>\");\n const tags = await Array.fromAsync(actor.getTags());\n assert.deepStrictEqual(tags.length, 1);\n assert.ok(tags[0] instanceof Mention);\n assert.deepStrictEqual(\n tags[0].href,\n new URL(\"https://example.com/actor/john\"),\n );\n assert.deepStrictEqual(tags[0].name, \"@john@example.com\");\n const icon = await actor.getIcon();\n assert.ok(icon instanceof Image);\n assert.deepStrictEqual(icon.url, new URL(\"https://example.com/icon.png\"));\n const image = await actor.getImage();\n assert.ok(image instanceof Image);\n assert.deepStrictEqual(image.url, new URL(\"https://example.com/image.png\"));\n assert.deepStrictEqual(\n actor.inboxId,\n new URL(\"https://example.com/ap/actor/bot/inbox\"),\n );\n assert.deepStrictEqual(\n actor.endpoints?.sharedInbox,\n new URL(\"https://example.com/ap/inbox\"),\n );\n assert.deepStrictEqual(\n actor.followersId,\n new URL(\"https://example.com/ap/actor/bot/followers\"),\n );\n assert.deepStrictEqual(\n actor.outboxId,\n new URL(\"https://example.com/ap/actor/bot/outbox\"),\n );\n const publicKey = await actor.getPublicKey();\n assert.ok(publicKey != null);\n assert.deepStrictEqual(publicKey.ownerId, actor.id);\n assert.ok(publicKey.publicKey != null);\n const keys = await repository.getKeyPairs();\n assert.ok(keys != null);\n assert.deepStrictEqual(publicKey.publicKey, keys[0].publicKey);\n const assertionMethods = await Array.fromAsync(actor.getAssertionMethods());\n assert.deepStrictEqual(assertionMethods.length, 2);\n assert.deepStrictEqual(\n assertionMethods.map((mk) => mk.controllerId),\n [actor.id, actor.id],\n );\n assert.deepStrictEqual(\n await Promise.all(assertionMethods.map((mk) => mk.publicKey)),\n keys.map((k) => k.publicKey),\n );\n});\n\ntest(\"BotImpl.mapHandle()\", () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"username\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(bot.mapHandle(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(bot.mapHandle(ctx, \"username\"), \"bot\");\n});\n\ntest(\"BotImpl.dispatchActorKeyPairs()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchActorKeyPairs(ctx, \"non-existent\"),\n [],\n );\n // Generation:\n const keyPairs = await bot.dispatchActorKeyPairs(ctx, \"bot\");\n const storedKeyPairs = await repository.getKeyPairs();\n assert.deepStrictEqual(keyPairs, storedKeyPairs);\n // Retrieval:\n const keyPairs2 = await bot.dispatchActorKeyPairs(ctx, \"bot\");\n assert.deepStrictEqual(keyPairs2, storedKeyPairs);\n});\n\ntest(\"BotImpl.dispatchFollowers()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n collectionWindow: 2,\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchFollowers(ctx, \"non-existent\", null),\n null,\n );\n assert.deepStrictEqual(\n await bot.dispatchFollowers(ctx, \"non-existent\", \"\"),\n null,\n );\n const empty = await bot.dispatchFollowers(ctx, \"bot\", null);\n assert.deepStrictEqual(empty, { items: [], nextCursor: null });\n\n await repository.addFollower(\n new URL(\"https://example.com/actor/1#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/1\"),\n preferredUsername: \"john\",\n inbox: new URL(\"https://example.com/actor/1/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/2#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/2\"),\n preferredUsername: \"jane\",\n inbox: new URL(\"https://example.com/actor/2/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/3#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/3\"),\n preferredUsername: \"joe\",\n inbox: new URL(\"https://example.com/actor/3/inbox\"),\n }),\n );\n const full = await bot.dispatchFollowers(ctx, \"bot\", null);\n assert.ok(full != null);\n assert.deepStrictEqual(full.nextCursor, null);\n assert.deepStrictEqual(full.items.length, 3);\n const items = full.items.toSorted((a, b) =>\n (a.id?.href ?? \"\").localeCompare(b.id?.href ?? \"\")\n );\n assert.ok(items[0] instanceof Person);\n assert.deepStrictEqual(items[0].id, new URL(\"https://example.com/actor/1\"));\n assert.ok(items[1] instanceof Person);\n assert.deepStrictEqual(items[1].id, new URL(\"https://example.com/actor/2\"));\n assert.ok(items[2] instanceof Person);\n assert.deepStrictEqual(items[2].id, new URL(\"https://example.com/actor/3\"));\n\n const firstPage = await bot.dispatchFollowers(ctx, \"bot\", \"0\");\n assert.ok(firstPage != null);\n assert.deepStrictEqual(firstPage.nextCursor, \"2\");\n assert.deepStrictEqual(firstPage.items.length, 2);\n assert.ok(firstPage.items[0] instanceof Person);\n assert.deepStrictEqual(\n firstPage.items[0].id,\n new URL(\"https://example.com/actor/3\"),\n );\n assert.ok(firstPage.items[1] instanceof Person);\n assert.deepStrictEqual(\n firstPage.items[1].id,\n new URL(\"https://example.com/actor/2\"),\n );\n\n const lastPage = await bot.dispatchFollowers(\n ctx,\n \"bot\",\n \"2\",\n );\n assert.ok(lastPage != null);\n assert.deepStrictEqual(lastPage.nextCursor, null);\n assert.deepStrictEqual(lastPage.items.length, 1);\n assert.ok(lastPage.items[0] instanceof Person);\n assert.deepStrictEqual(\n lastPage.items[0].id,\n new URL(\"https://example.com/actor/1\"),\n );\n});\n\ntest(\"BotImpl.getFollowersFirstCursor()\", () => {\n const kv = new MemoryKvStore();\n const bot = new BotImpl<void>({ kv, username: \"bot\", collectionWindow: 2 });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n bot.getFollowersFirstCursor(ctx, \"non-existent\"),\n null,\n );\n assert.deepStrictEqual(bot.getFollowersFirstCursor(ctx, \"bot\"), \"0\");\n});\n\ntest(\"BotImpl.countFollowers()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"bot\"), 0);\n await repository.addFollower(\n new URL(\"https://example.com/actor/1#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/1\"),\n preferredUsername: \"john\",\n inbox: new URL(\"https://example.com/actor/1/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/2#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/2\"),\n preferredUsername: \"jane\",\n inbox: new URL(\"https://example.com/actor/2/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/3#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/3\"),\n preferredUsername: \"joe\",\n inbox: new URL(\"https://example.com/actor/3/inbox\"),\n }),\n );\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"bot\"), 3);\n});\n\ntest(\"BotImpl.getPermissionChecker()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const publicPost = new Note({\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n });\n const unlistedPost = new Note({\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n });\n const followersPost = new Note({\n tos: [\n new URL(\"https://example.com/ap/actor/bot/followers\"),\n new URL(\"https://example.com/ap/actor/mentioned\"),\n ],\n });\n const directPost = new Note({\n to: new URL(\"https://example.com/ap/actor/mentioned\"),\n });\n const anonymous = await bot.getPermissionChecker(ctx);\n assert.deepStrictEqual(anonymous(publicPost), true);\n assert.deepStrictEqual(anonymous(unlistedPost), true);\n assert.deepStrictEqual(anonymous(followersPost), false);\n assert.deepStrictEqual(anonymous(directPost), false);\n\n const actor = new Person({ id: new URL(\"https://example.com/actor/john\") });\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n const nonFollower = await bot.getPermissionChecker(ctx2);\n assert.deepStrictEqual(nonFollower(publicPost), true);\n assert.deepStrictEqual(nonFollower(unlistedPost), true);\n assert.deepStrictEqual(nonFollower(followersPost), false);\n assert.deepStrictEqual(nonFollower(directPost), false);\n\n await repository.addFollower(\n new URL(\"https://example.com/actor/john#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n }),\n );\n const ctx3 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n ctx3.getSignedKeyOwner = () => Promise.resolve(actor);\n const follower = await bot.getPermissionChecker(ctx3);\n assert.deepStrictEqual(follower(publicPost), true);\n assert.deepStrictEqual(follower(unlistedPost), true);\n assert.deepStrictEqual(follower(followersPost), true);\n assert.deepStrictEqual(follower(directPost), false);\n\n const mentionedActor = new Person({\n id: new URL(\"https://example.com/ap/actor/mentioned\"),\n });\n const ctx4 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n ctx4.getSignedKeyOwner = () => Promise.resolve(mentionedActor);\n const mentioned = await bot.getPermissionChecker(ctx4);\n assert.deepStrictEqual(mentioned(publicPost), true);\n assert.deepStrictEqual(mentioned(unlistedPost), true);\n assert.deepStrictEqual(mentioned(followersPost), true);\n assert.deepStrictEqual(mentioned(directPost), true);\n});\n\ntest(\"BotImpl.dispatchOutbox()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n collectionWindow: 2,\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", null),\n null,\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", \"\"),\n null,\n );\n assert.deepStrictEqual(await bot.dispatchOutbox(ctx, \"bot\", null), {\n items: [],\n nextCursor: null,\n });\n assert.deepStrictEqual(await bot.dispatchOutbox(ctx, \"bot\", \"\"), {\n items: [],\n nextCursor: null,\n });\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n );\n await repository.addMessage(\n \"46442170-836d-4a0d-9142-f31242abe2f9\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, followers!\",\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n );\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", null),\n null,\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", \"\"),\n null,\n );\n const anonymous1 = await bot.dispatchOutbox(ctx, \"bot\", \"\");\n assert.ok(anonymous1 != null);\n assert.deepStrictEqual(anonymous1.nextCursor, \"2025-01-01T00:00:00Z\");\n assert.deepStrictEqual(anonymous1.items.length, 1);\n assert.ok(anonymous1.items[0] instanceof Create);\n assert.deepStrictEqual(\n anonymous1.items[0].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n );\n\n const anonymous2 = await bot.dispatchOutbox(\n ctx,\n \"bot\",\n \"2025-01-01T00:00:00Z\",\n );\n assert.ok(anonymous2 != null);\n assert.deepStrictEqual(anonymous2.nextCursor, null);\n assert.deepStrictEqual(anonymous2.items.length, 1);\n assert.ok(anonymous2.items[0] instanceof Create);\n assert.deepStrictEqual(\n anonymous2.items[0].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n );\n\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n const mentioned = await bot.dispatchOutbox(ctx2, \"bot\", null);\n assert.ok(mentioned != null);\n assert.deepStrictEqual(mentioned.nextCursor, null);\n assert.deepStrictEqual(mentioned.items.length, 3);\n assert.ok(mentioned.items[0] instanceof Create);\n assert.deepStrictEqual(\n mentioned.items[0].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n );\n assert.ok(mentioned.items[1] instanceof Create);\n assert.deepStrictEqual(\n mentioned.items[1].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n );\n assert.ok(mentioned.items[2] instanceof Create);\n assert.deepStrictEqual(\n mentioned.items[2].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n );\n});\n\ntest(\"BotImpl.getOutboxFirstCursor()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(bot.getOutboxFirstCursor(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(bot.getOutboxFirstCursor(ctx, \"bot\"), \"\");\n});\n\ntest(\"BotImpl.countOutbox()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"bot\"), 0);\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n await repository.addMessage(\n \"46442170-836d-4a0d-9142-f31242abe2f9\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"bot\"), 3);\n});\n\ntest(\"BotImpl.dispatchFollow()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchFollow(ctx, { id: crypto.randomUUID() }),\n null,\n );\n\n await repository.addSentFollow(\n \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/john\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n const follow = await bot.dispatchFollow(ctx, {\n id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n });\n assert.ok(follow instanceof Follow);\n assert.deepStrictEqual(\n follow.id,\n new URL(\n \"https://example.com/ap/follow/b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n ),\n );\n assert.deepStrictEqual(\n follow.actorId,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(\n follow.objectId,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.deepStrictEqual(\n follow.toId,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n});\n\ntest(\"BotImpl.authorizeFollow()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n await repository.addSentFollow(\n \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/john\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n assert.ok(\n await bot.authorizeFollow(\n ctx,\n { id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\" },\n new CryptographicKey({}),\n new Person({ id: new URL(\"https://example.com/ap/actor/john\") }),\n ),\n );\n assert.ok(\n await bot.authorizeFollow(\n ctx,\n { id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\" },\n new CryptographicKey({}),\n await new SessionImpl(bot, ctx).getActor(),\n ),\n );\n assert.deepStrictEqual(\n await bot.authorizeFollow(\n ctx,\n { id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\" },\n new CryptographicKey({}),\n new Person({ id: new URL(\"https://example.com/ap/actor/alice\") }),\n ),\n false,\n );\n assert.deepStrictEqual(\n await bot.authorizeFollow(\n ctx,\n { id: crypto.randomUUID() },\n new CryptographicKey({}),\n new Person({ id: new URL(\"https://example.com/ap/actor/john\") }),\n ),\n false,\n );\n});\n\ntest(\"BotImpl.dispatchCreate()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx, { id: \"non-existent\" }),\n null,\n );\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n const create = await bot.dispatchCreate(ctx, {\n id: \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n });\n assert.ok(create instanceof Create);\n assert.deepStrictEqual(\n create.id,\n new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n );\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx2, {\n id: \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n }),\n create,\n );\n\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx, {\n id: \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n }),\n null,\n );\n const create2 = await bot.dispatchCreate(ctx2, {\n id: \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n });\n assert.ok(create2 instanceof Create);\n assert.deepStrictEqual(\n create2.id,\n new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n );\n\n await repository.addMessage(\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx, {\n id: \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n }),\n null,\n );\n});\n\ntest(\"BotImpl.dispatchMessage()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchMessage(Note, ctx, \"non-existent\"),\n null,\n );\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n const note = await bot.dispatchMessage(\n Note,\n ctx,\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n );\n assert.ok(note instanceof Note);\n assert.deepStrictEqual(\n note.id,\n new URL(\"https://example.com/ap/actor/bot/note/1\"),\n );\n\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Note,\n ctx2,\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n note,\n );\n\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Article,\n ctx,\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n null,\n );\n\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Note,\n ctx,\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n null,\n );\n const note2 = await bot.dispatchMessage(\n Note,\n ctx2,\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n );\n assert.ok(note2 instanceof Note);\n assert.deepStrictEqual(\n note2.id,\n new URL(\"https://example.com/ap/actor/bot/note/3\"),\n );\n\n await repository.addMessage(\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Note,\n ctx,\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n null,\n );\n});\n\ntest(\"BotImpl.dispatchAnnounce()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchAnnounce(ctx, { id: \"non-existent\" }),\n null,\n );\n\n await repository.addMessage(\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n const announce = await bot.dispatchAnnounce(ctx, {\n id: \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n });\n assert.ok(announce instanceof Announce);\n assert.deepStrictEqual(\n announce.id,\n new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n );\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchAnnounce(ctx, {\n id: \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n }),\n null,\n );\n\n await repository.addMessage(\n \"d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchAnnounce(ctx, {\n id: \"d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n }),\n null,\n );\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n const announce2 = await bot.dispatchAnnounce(ctx2, {\n id: \"d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n });\n assert.ok(announce2 instanceof Announce);\n assert.deepStrictEqual(\n announce2.id,\n new URL(\n \"https://example.com/ap/actor/bot/announce/d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n ),\n );\n});\n\ntest(\"BotImpl.dispatchSharedKey()\", () => {\n const identifier = crypto.randomUUID();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n identifier,\n });\n const ctx = bot.federation.createContext(new URL(\"https://example.com\"));\n assert.deepStrictEqual(bot.dispatchSharedKey(ctx), { identifier });\n});\n\nfor (const policy of [\"accept\", \"reject\", \"manual\"] as const) {\n test(`BotImpl.onFollowed() [followerPolicy: ${policy}]`, async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n followerPolicy: policy,\n });\n const followRequests: [Session<void>, FollowRequest][] = [];\n bot.onFollow = (session, fr) => void (followRequests.push([session, fr]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await t.test(\"without actor\", async () => {\n const followWithoutActor = new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n object: new URL(\"https://example.com/ap/actor/bot\"),\n });\n await bot.onFollowed(ctx, followWithoutActor);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n });\n\n await t.test(\"with wrong actor\", async () => {\n const followWithWrongActor = new Follow({\n id: new URL(\"https://example.com/ap/actor/bot/follows/bot\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/bot\"),\n });\n await bot.onFollowed(ctx, followWithWrongActor);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n });\n\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n\n await t.test(\"with wrong recipient\", async () => {\n const followWithWrongRecipient = new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n actor,\n object: new URL(\"https://example.com/ap/actor/non-existent\"),\n });\n await bot.onFollowed(ctx, followWithWrongRecipient);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n });\n\n await t.test(\"with correct follow\", async () => {\n const follow = new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n actor,\n object: new URL(\"https://example.com/ap/actor/bot\"),\n });\n await bot.onFollowed(ctx, follow);\n if (policy === \"accept\") {\n assert.deepStrictEqual(await repository.countFollowers(), 1);\n assert.ok(\n await repository.hasFollower(\n new URL(\"https://example.com/ap/actor/john\"),\n ),\n );\n const [storedFollower] = await Array.fromAsync(\n repository.getFollowers(),\n );\n assert.ok(storedFollower instanceof Person);\n assert.deepStrictEqual(storedFollower.id, actor.id);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { activity, recipients } = ctx.sentActivities[0];\n assert.ok(activity instanceof Accept);\n assert.deepStrictEqual(\n activity.actorId,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(activity.objectId, follow.id);\n assert.deepStrictEqual(recipients.length, 1);\n assert.deepStrictEqual(recipients[0], actor);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n assert.deepStrictEqual(followRequests.length, 1);\n } else {\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n if (policy === \"reject\") {\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { activity, recipients } = ctx.sentActivities[0];\n assert.ok(activity instanceof Reject);\n assert.deepStrictEqual(\n activity.actorId,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(activity.objectId, follow.id);\n assert.deepStrictEqual(recipients.length, 1);\n assert.deepStrictEqual(recipients[0], actor);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n } else {\n assert.deepStrictEqual(ctx.sentActivities, []);\n }\n }\n const [session, followRequest] = followRequests[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(followRequest.follower instanceof Person);\n assert.deepStrictEqual(followRequest.follower.id, actor.id);\n });\n });\n}\n\ntest(\"BotImpl.onUnfollowed()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const unfollowed: [Session<void>, Actor][] = [];\n bot.onUnfollow = (session, actor) => void (unfollowed.push([session, actor]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await repository.addFollower(\n new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n );\n\n async function assertNoEffect() {\n assert.deepStrictEqual(await repository.countFollowers(), 1);\n const [follower] = await Array.fromAsync(repository.getFollowers());\n assert.ok(follower instanceof Person);\n assert.deepStrictEqual(\n follower.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.deepStrictEqual(follower.preferredUsername, \"john\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n assert.deepStrictEqual(unfollowed, []);\n }\n\n await t.test(\"without Follow object\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"without Follow.id\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new Follow({}),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"with non-existent Follow.id\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/non-existent\"),\n }),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"with incorrect Follow.actorId\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/wrong-actor\"),\n object: new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n }),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"with correct Follow object\", async () => {\n const undo = new Undo({\n actor: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n object: new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n }),\n });\n await bot.onUnfollowed(ctx, undo);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n assert.deepStrictEqual(unfollowed.length, 1);\n const [session, follower] = unfollowed[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(follower instanceof Person);\n assert.deepStrictEqual(\n follower.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n });\n});\n\ntest(\"BotImpl.onFollowAccepted()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const accepted: [Session<void>, Actor][] = [];\n bot.onAcceptFollow = (session, actor) =>\n void (accepted.push([session, actor]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await t.test(\"without object\", async () => {\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with invalid object URI\", async () => {\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\"https://example.com/\"),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with non-existent object\", async () => {\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(`https://example.com/ap/follow/${crypto.randomUUID()}`),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with non-actor\", async () => {\n await repository.addSentFollow(\n \"2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({}),\n }),\n );\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with actor without URI\", async () => {\n await repository.addSentFollow(\n \"a99ff3bf-72a2-412b-83b9-cba894d38805\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with actor\", async () => {\n await repository.addSentFollow(\n \"3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n }),\n );\n assert.deepStrictEqual(accepted.length, 1);\n const [session, actor] = accepted[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(actor instanceof Person);\n assert.deepStrictEqual(\n actor.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n const follow = await repository.getFollowee(\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.ok(follow != null);\n assert.ok(follow instanceof Follow);\n assert.deepStrictEqual(\n follow.id,\n new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n );\n assert.deepStrictEqual(follow.objectId, actor.id);\n });\n});\n\ntest(\"BotImpl.onFollowRejected()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const rejected: [Session<void>, Actor][] = [];\n bot.onRejectFollow = (session, actor) =>\n void (rejected.push([session, actor]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await t.test(\"without object\", async () => {\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with invalid object URI\", async () => {\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\"https://example.com/\"),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with non-existent object\", async () => {\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(`https://example.com/ap/follow/${crypto.randomUUID()}`),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with non-actor\", async () => {\n await repository.addSentFollow(\n \"2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({}),\n }),\n );\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with actor without URI\", async () => {\n await repository.addSentFollow(\n \"a99ff3bf-72a2-412b-83b9-cba894d38805\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with actor\", async () => {\n await repository.addSentFollow(\n \"3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n }),\n );\n assert.deepStrictEqual(rejected.length, 1);\n const [session, actor] = rejected[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(actor instanceof Person);\n assert.deepStrictEqual(\n actor.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.deepStrictEqual(\n await repository.getSentFollow(\"3bca0b8e-503a-47ea-ad69-6b7c29369fbd\"),\n undefined,\n );\n });\n});\n\ntest(\"BotImpl.onCreated()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n let replied: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onReply = (session, msg) => void (replied.push([session, msg]));\n let mentioned: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onMention = (session, msg) => void (mentioned.push([session, msg]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n let messaged: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onMessage = (session, msg) => void (messaged.push([session, msg]));\n\n await t.test(\"without object\", async () => {\n const createWithoutObject = new Create({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n });\n await bot.onCreated(ctx, createWithoutObject);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, []);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n await t.test(\"with non-message object\", async () => {\n const createWithNonMessageObject = new Create({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new Place({}),\n });\n await bot.onCreated(ctx, createWithNonMessageObject);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, []);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n await repository.addMessage(\n \"a6358f1b-c978-49d3-8065-37a1df6168de\",\n new Create({\n id: new URL(\n \"https://example.com/ap/create/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n\n await t.test(\"on reply\", async () => {\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content: \"It's reply!\",\n replyTarget: new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n }),\n });\n await bot.onCreated(ctx, create);\n assert.deepStrictEqual(replied.length, 1);\n const [session, msg] = replied[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.ok(msg.replyTarget != null);\n assert.deepStrictEqual(\n msg.replyTarget.id,\n new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n );\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, replied);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, [\"followers\"]);\n });\n\n await t.test(\"on mention\", async () => {\n replied = [];\n messaged = [];\n ctx.forwardedRecipients = [];\n\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content:\n '<p><a href=\"https://example.com/ap/actor/bot\">@bot</a> Hey!</p>',\n tags: [\n new Mention({\n href: new URL(\"https://example.com/ap/actor/bot\"),\n name: \"@bot\",\n }),\n ],\n }),\n });\n await bot.onCreated(ctx, create);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned.length, 1);\n const [session, msg] = mentioned[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.deepStrictEqual(msg.mentions.length, 1);\n assert.deepStrictEqual(\n msg.mentions[0].id,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(messaged, mentioned);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n await t.test(\"on quote\", async () => {\n mentioned = [];\n messaged = [];\n ctx.forwardedRecipients = [];\n\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content: \"It's a quote!\",\n quoteUrl: new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n }),\n });\n let quoted: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onQuote = (session, msg) => void (quoted.push([session, msg]));\n\n await bot.onCreated(ctx, create);\n\n assert.deepStrictEqual(quoted.length, 1);\n const [session, msg] = quoted[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.ok(msg.quoteTarget != null);\n assert.deepStrictEqual(\n msg.quoteTarget.id,\n new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n );\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, quoted);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, [\"followers\"]);\n\n quoted = [];\n messaged = [];\n ctx.forwardedRecipients = [];\n });\n\n await t.test(\"on message\", async () => {\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content: \"<p>Hello!</p>\",\n }),\n });\n await bot.onCreated(ctx, create);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged.length, 1);\n const [session, msg] = messaged[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n messaged = [];\n});\n\ntest(\"BotImpl.onAnnounced()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const shares: [Session<void>, SharedMessage<MessageClass, void>][] = [];\n bot.onSharedMessage = (session, sharedMessage) =>\n void (shares.push([session, sharedMessage]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n const announce = new Announce({\n id: new URL(\"https://example.com/ap/actor/bot/announce/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n });\n await bot.onAnnounced(ctx, announce);\n assert.deepStrictEqual(shares.length, 1);\n const [session, sharedMessage] = shares[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(sharedMessage.raw, announce);\n assert.deepStrictEqual(sharedMessage.id, announce.id);\n assert.deepStrictEqual(sharedMessage.actor.id, announce.actorId);\n assert.deepStrictEqual(sharedMessage.visibility, \"public\");\n assert.deepStrictEqual(sharedMessage.original.id, announce.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n});\n\ntest(\"BotImpl.onLiked()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const likes: [Session<void>, Like<void>][] = [];\n bot.onLike = (session, like) => void (likes.push([session, like]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n });\n await bot.onLiked(ctx, rawLike);\n assert.deepStrictEqual(likes.length, 1);\n const [session, like] = likes[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(like.raw, rawLike);\n assert.deepStrictEqual(like.id, rawLike.id);\n assert.deepStrictEqual(like.actor.id, rawLike.actorId);\n assert.deepStrictEqual(like.message.id, rawLike.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n});\n\ntest(\"BotImpl.onUnliked()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const likes: [Session<void>, Like<void>][] = [];\n bot.onUnlike = (session, like) => void (likes.push([session, like]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n });\n const undo = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unlike/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: rawLike,\n });\n await bot.onUnliked(ctx, undo);\n assert.deepStrictEqual(likes.length, 1);\n const [session, like] = likes[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(like.raw, rawLike);\n assert.deepStrictEqual(like.id, rawLike.id);\n assert.deepStrictEqual(like.actor.id, rawLike.actorId);\n assert.deepStrictEqual(like.message.id, rawLike.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n likes.pop();\n const invalidUndo = undo.clone({\n actor: new URL(\"https://example.com/ap/actor/another\"),\n });\n await bot.onUnliked(ctx, invalidUndo);\n assert.deepStrictEqual(likes, []);\n});\n\ntest(\"BotImpl.onReacted()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const reactions: [Session<void>, Reaction<void>][] = [];\n bot.onReact = (session, reaction) =>\n void (reactions.push([session, reaction]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n // Test with Like containing an emoji name\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":heart:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/heart\"),\n name: \":heart:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/heart.png\"),\n }),\n }),\n ],\n });\n\n await bot.onReacted(ctx, rawLike);\n assert.deepStrictEqual(reactions.length, 1);\n const [session, reaction] = reactions[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(reaction.raw, rawLike);\n assert.deepStrictEqual(reaction.id, rawLike.id);\n assert.deepStrictEqual(reaction.actor.id, rawLike.actorId);\n assert.deepStrictEqual(reaction.message.id, rawLike.objectId);\n assert.ok(reaction.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction.emoji.name, \":heart:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n // Test with EmojiReact\n reactions.pop();\n const emojiReact = new EmojiReact({\n id: new URL(\"https://example.com/ap/actor/bot/react/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":thumbsup:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/thumbsup\"),\n name: \":thumbsup:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/thumbsup.png\"),\n }),\n }),\n ],\n });\n\n await bot.onReacted(ctx, emojiReact);\n assert.deepStrictEqual(reactions.length, 1);\n const [session2, reaction2] = reactions[0];\n assert.deepStrictEqual(session2.bot, bot);\n assert.deepStrictEqual(session2.context, ctx);\n assert.deepStrictEqual(reaction2.raw, emojiReact);\n assert.deepStrictEqual(reaction2.id, emojiReact.id);\n assert.deepStrictEqual(reaction2.actor.id, emojiReact.actorId);\n assert.deepStrictEqual(reaction2.message.id, emojiReact.objectId);\n assert.ok(reaction2.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction2.emoji.name, \":thumbsup:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n});\n\ntest(\"BotImpl.onUnreacted()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const reactions: [Session<void>, Reaction<void>][] = [];\n bot.onUnreact = (session, reaction) =>\n void (reactions.push([session, reaction]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n // Test with Like containing an emoji name\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":heart:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/heart\"),\n name: \":heart:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/heart.png\"),\n }),\n }),\n ],\n });\n\n const undo = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unreact/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: rawLike,\n });\n\n await bot.onUnreacted(ctx, undo);\n assert.deepStrictEqual(reactions.length, 1);\n const [session, reaction] = reactions[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(reaction.raw, rawLike);\n assert.deepStrictEqual(reaction.id, rawLike.id);\n assert.deepStrictEqual(reaction.actor.id, rawLike.actorId);\n assert.deepStrictEqual(reaction.message.id, rawLike.objectId);\n assert.ok(reaction.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction.emoji.name, \":heart:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n // Test with EmojiReact\n reactions.pop();\n const emojiReact = new EmojiReact({\n id: new URL(\"https://example.com/ap/actor/bot/react/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":thumbsup:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/thumbsup\"),\n name: \":thumbsup:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/thumbsup.png\"),\n }),\n }),\n ],\n });\n\n const undoEmojiReact = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unreact/2\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: emojiReact,\n });\n\n await bot.onUnreacted(ctx, undoEmojiReact);\n assert.deepStrictEqual(reactions.length, 1);\n const [session2, reaction2] = reactions[0];\n assert.deepStrictEqual(session2.bot, bot);\n assert.deepStrictEqual(session2.context, ctx);\n assert.deepStrictEqual(reaction2.raw, emojiReact);\n assert.deepStrictEqual(reaction2.id, emojiReact.id);\n assert.deepStrictEqual(reaction2.actor.id, emojiReact.actorId);\n assert.deepStrictEqual(reaction2.message.id, emojiReact.objectId);\n assert.ok(reaction2.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction2.emoji.name, \":thumbsup:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n // Test with mismatched actor\n reactions.pop();\n const invalidUndo = undoEmojiReact.clone({\n actor: new URL(\"https://example.com/ap/actor/another\"),\n });\n await bot.onUnreacted(ctx, invalidUndo);\n assert.deepStrictEqual(reactions, []);\n\n // Test with non-reaction object\n reactions.pop();\n const nonReactionUndo = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unreact/3\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({}),\n });\n await bot.onUnreacted(ctx, nonReactionUndo);\n assert.deepStrictEqual(reactions, []);\n});\n\ntest(\"BotImpl.dispatchNodeInfo()\", () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n software: {\n name: \"test\",\n version: parseSemVer(\"1.2.3\"),\n homepage: new URL(\"https://example.com/\"),\n repository: new URL(\"https://git.example.com/\"),\n },\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(bot.dispatchNodeInfo(ctx), {\n software: {\n name: \"test\",\n version: parseSemVer(\"1.2.3\"),\n homepage: new URL(\"https://example.com/\"),\n repository: new URL(\"https://git.example.com/\"),\n },\n protocols: [\"activitypub\"],\n services: {\n outbound: [\"atom1.0\"],\n },\n usage: {\n users: {\n total: 1,\n activeMonth: 1,\n activeHalfyear: 1,\n },\n localPosts: 0,\n localComments: 0,\n },\n });\n});\n\ntest(\"BotImpl.fetch()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const request = new Request(\n \"http://localhost/.well-known/webfinger?resource=acct:bot@example.com\",\n {\n headers: {\n \"X-Forwarded-Host\": \"example.com\",\n \"X-Forwarded-Proto\": \"https\",\n },\n },\n );\n const response = await bot.fetch(request);\n assert.deepStrictEqual(response.status, 404);\n\n const botBehindProxy = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n behindProxy: true,\n });\n const response2 = await botBehindProxy.fetch(request);\n assert.deepStrictEqual(response2.status, 200);\n});\n\ndescribe(\"BotImpl.addCustomEmoji(), BotImpl.addCustomEmojis()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n\n test(\"addCustomEmoji()\", () => {\n const emojiData: CustomEmoji = {\n type: \"image/png\",\n url: \"https://example.com/emoji.png\",\n };\n const deferredEmoji = bot.addCustomEmoji(\"testEmoji\", emojiData);\n assert.deepStrictEqual(typeof deferredEmoji, \"function\");\n assert.deepStrictEqual(bot.customEmojis[\"testEmoji\"], emojiData);\n\n // Test invalid name\n assert.throws(\n () => bot.addCustomEmoji(\"invalid name\", emojiData),\n TypeError,\n \"Invalid custom emoji name\",\n );\n\n // Test duplicate name\n assert.throws(\n () => bot.addCustomEmoji(\"testEmoji\", emojiData),\n TypeError,\n \"Duplicate custom emoji name\",\n );\n\n // Test unsupported media type\n assert.throws(\n () =>\n bot.addCustomEmoji(\"invalidType\", {\n // @ts-expect-error: Intended type error for testing runtime check\n type: \"text/plain\",\n url: \"https://example.com/emoji.txt\",\n }),\n TypeError,\n \"Unsupported media type\",\n );\n });\n\n test(\"addCustomEmojis()\", () => {\n const emojisData = {\n emoji1: { type: \"image/png\", url: \"https://example.com/emoji1.png\" },\n emoji2: { type: \"image/gif\", file: \"/path/to/emoji2.gif\" },\n } as const;\n const deferredEmojis = bot.addCustomEmojis(emojisData);\n\n assert.deepStrictEqual(typeof deferredEmojis[\"emoji1\"], \"function\");\n assert.deepStrictEqual(typeof deferredEmojis[\"emoji2\"], \"function\");\n assert.deepStrictEqual(bot.customEmojis[\"emoji1\"], emojisData.emoji1);\n assert.deepStrictEqual(bot.customEmojis[\"emoji2\"], emojisData.emoji2);\n\n // Test duplicate name within the batch\n assert.throws(\n () =>\n bot.addCustomEmojis({\n emoji1: { type: \"image/png\", url: \"https://example.com/dup1.png\" },\n }),\n TypeError,\n \"Duplicate custom emoji name: emoji1\",\n );\n });\n});\n\ntest(\"BotImpl.getEmoji()\", async () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n\n // Test with remote URL\n const remoteEmojiData: CustomEmoji = {\n type: \"image/png\",\n url: \"https://remote.com/emoji.png\",\n };\n bot.customEmojis[\"remoteEmoji\"] = remoteEmojiData;\n const remoteEmoji = bot.getEmoji(ctx, \"remoteEmoji\", remoteEmojiData);\n assert.ok(remoteEmoji instanceof Emoji);\n assert.deepStrictEqual(\n remoteEmoji.id,\n new URL(\"https://example.com/ap/emoji/remoteEmoji\"),\n );\n assert.deepStrictEqual(remoteEmoji.name, \":remoteEmoji:\");\n const icon = await remoteEmoji.getIcon();\n assert.ok(icon instanceof Image);\n assert.deepStrictEqual(icon.mediaType, \"image/png\");\n assert.deepStrictEqual(icon.url?.href, \"https://remote.com/emoji.png\");\n\n // Test with local file\n const localEmojiData: CustomEmoji = {\n type: \"image/gif\",\n file: \"/path/to/local/emoji.gif\",\n };\n bot.customEmojis[\"localEmoji\"] = localEmojiData;\n const localEmoji = bot.getEmoji(ctx, \"localEmoji\", localEmojiData);\n assert.ok(localEmoji instanceof Emoji);\n assert.deepStrictEqual(\n localEmoji.id,\n new URL(\"https://example.com/ap/emoji/localEmoji\"),\n );\n assert.deepStrictEqual(localEmoji.name, \":localEmoji:\");\n const icon2 = await localEmoji.getIcon();\n assert.ok(icon2 instanceof Image);\n assert.deepStrictEqual(icon2.mediaType, \"image/gif\");\n assert.deepStrictEqual(\n icon2.url?.href,\n \"https://example.com/emojis/localEmoji.gif\",\n );\n\n // Test with local file without extension mapping\n const localEmojiDataNoExt: CustomEmoji = {\n type: \"image/webp\",\n file: \"/path/to/local/emoji\",\n };\n bot.customEmojis[\"localEmojiNoExt\"] = localEmojiDataNoExt;\n const localEmojiNoExt = bot.getEmoji(\n ctx,\n \"localEmojiNoExt\",\n localEmojiDataNoExt,\n );\n const icon3 = await localEmojiNoExt.getIcon();\n assert.ok(icon3 instanceof Image);\n assert.deepStrictEqual(icon3.mediaType, \"image/webp\");\n assert.deepStrictEqual(\n icon3.url?.href,\n \"https://example.com/emojis/localEmojiNoExt.webp\",\n );\n});\n\n// Test BotImpl.dispatchEmoji()\ntest(\"BotImpl.dispatchEmoji()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n const emojiData: CustomEmoji = {\n type: \"image/png\",\n url: \"https://example.com/emoji.png\",\n };\n bot.customEmojis[\"testEmoji\"] = emojiData;\n\n // Test dispatching an existing emoji\n const emoji = bot.dispatchEmoji(ctx, { name: \"testEmoji\" });\n assert.ok(emoji instanceof Emoji);\n assert.deepStrictEqual(\n emoji.id,\n new URL(\"https://example.com/ap/emoji/testEmoji\"),\n );\n assert.deepStrictEqual(emoji.name, \":testEmoji:\");\n\n // Test dispatching a non-existent emoji\n const nonExistent = bot.dispatchEmoji(ctx, { name: \"nonExistent\" });\n assert.deepStrictEqual(nonExistent, null);\n});\n\ntest(\"BotImpl.getFollowersFirstCursor()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n bot.getFollowersFirstCursor(ctx, \"non-existent\"),\n null,\n );\n assert.deepStrictEqual(bot.getFollowersFirstCursor(ctx, \"bot\"), \"0\");\n});\n\ninterface SentActivity {\n recipients: \"followers\" | Recipient[];\n activity: Activity;\n}\n\ninterface MockInboxContext extends InboxContext<void> {\n sentActivities: SentActivity[];\n forwardedRecipients: (\"followers\" | Recipient)[];\n}\n\nfunction createMockInboxContext(\n bot: BotImpl<void>,\n origin: string | URL,\n recipient?: string | null,\n): MockInboxContext {\n const ctx = bot.federation.createContext(\n new URL(origin),\n undefined,\n ) as MockInboxContext;\n ctx.recipient = recipient ?? null;\n ctx.sentActivities = [];\n ctx.sendActivity = (_, recipients, activity) => {\n ctx.sentActivities.push({\n recipients: recipients === \"followers\"\n ? \"followers\"\n : Array.isArray(recipients)\n ? recipients\n : [recipients],\n activity,\n });\n return Promise.resolve();\n };\n ctx.forwardedRecipients = [];\n ctx.forwardActivity = (_, recipients) => {\n if (recipients === \"followers\") {\n ctx.forwardedRecipients.push(\"followers\");\n } else if (Array.isArray(recipients)) {\n ctx.forwardedRecipients.push(...recipients);\n } else {\n ctx.forwardedRecipients.push(recipients);\n }\n return Promise.resolve();\n };\n return ctx;\n}\n\n// cSpell: ignore thumbsup\n"],"mappings":"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"}
1
+ {"version":3,"file":"bot-impl.test.js","names":["followRequests: [Session<void>, FollowRequest][]","unfollowed: [Session<void>, Actor][]","accepted: [Session<void>, Actor][]","rejected: [Session<void>, Actor][]","replied: [Session<void>, Message<MessageClass, void>][]","mentioned: [Session<void>, Message<MessageClass, void>][]","messaged: [Session<void>, Message<MessageClass, void>][]","quoted: [Session<void>, Message<MessageClass, void>][]","session","msg","shares: [Session<void>, SharedMessage<MessageClass, void>][]","sharedMessage","likes: [Session<void>, Like<void>][]","like","RawLike","reactions: [Session<void>, Reaction<void>][]","reaction","emojiData: CustomEmoji","remoteEmojiData: CustomEmoji","localEmojiData: CustomEmoji","localEmojiDataNoExt: CustomEmoji","bot: BotImpl<void>","origin: string | URL","recipient?: string | null","receivedVote: Vote<void> | null"],"sources":["../src/bot-impl.test.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport { type InboxContext, MemoryKvStore } from \"@fedify/fedify/federation\";\nimport {\n Accept,\n type Activity,\n type Actor,\n Announce,\n Article,\n Collection,\n Create,\n CryptographicKey,\n Emoji,\n EmojiReact,\n Follow,\n Image,\n Like as RawLike,\n Mention,\n Note,\n Person,\n Place,\n PropertyValue,\n PUBLIC_COLLECTION,\n Question,\n type Recipient,\n Reject,\n Service,\n Undo,\n Update,\n} from \"@fedify/fedify/vocab\";\nimport assert from \"node:assert\";\nimport { describe, test } from \"node:test\";\nimport { BotImpl } from \"./bot-impl.ts\";\nimport { parseSemVer } from \"./bot.ts\";\nimport type { CustomEmoji } from \"./emoji.ts\";\nimport type { FollowRequest } from \"./follow.ts\";\nimport type { Message, MessageClass, SharedMessage } from \"./message.ts\";\nimport type { Vote } from \"./poll.ts\";\nimport type { Like, Reaction } from \"./reaction.ts\";\nimport { MemoryRepository } from \"./repository.ts\";\nimport { SessionImpl } from \"./session-impl.ts\";\nimport type { Session } from \"./session.ts\";\nimport { mention, strong, text } from \"./text.ts\";\n\ndescribe(\"BotImpl.getActorSummary()\", () => {\n test(\"without summary\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const session = bot.getSession(\"https://example.com\");\n assert.deepStrictEqual(await bot.getActorSummary(session), null);\n });\n\n test(\"with summary\", async () => {\n const actor = new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n });\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n summary: text`A summary with a mention: ${actor}.`,\n });\n const session = bot.getSession(\"https://example.com\");\n const expected = {\n tags: [\n new Mention({\n href: new URL(\"https://example.com/actor/john\"),\n name: \"@john@example.com\",\n }),\n ],\n text: \"<p>A summary with a mention: \" +\n '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>' +\n \"john@example.com</span></a>.</p>\",\n };\n assert.deepStrictEqual(await bot.getActorSummary(session), expected);\n assert.deepStrictEqual(await bot.getActorSummary(session), expected);\n });\n});\n\ntest(\"BotImpl.getActorProperties()\", async () => {\n const actor = new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n });\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n properties: {\n Foo: strong(\"bar\"),\n Baz: mention(actor),\n Qux: text`quux`,\n },\n });\n const session = bot.getSession(\"https://example.com\");\n const expected = {\n pairs: [\n new PropertyValue({ name: \"Foo\", value: \"<strong>bar</strong>\" }),\n new PropertyValue({\n name: \"Baz\",\n value: '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>' +\n \"john@example.com</span></a>\",\n }),\n new PropertyValue({ name: \"Qux\", value: \"<p>quux</p>\" }),\n ],\n tags: [\n new Mention({\n href: new URL(\"https://example.com/actor/john\"),\n name: \"@john@example.com\",\n }),\n ],\n };\n assert.deepStrictEqual(await bot.getActorProperties(session), expected);\n assert.deepStrictEqual(await bot.getActorProperties(session), expected);\n});\n\ninterface KeyPair {\n private: JsonWebKey;\n public: JsonWebKey;\n}\n\ntest(\"BotImpl.dispatchActor()\", async () => {\n const mentionActor = new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n });\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"test\",\n name: \"Test Bot\",\n summary: text`A summary with a mention: ${mentionActor}.`,\n properties: {\n Foo: strong(\"bar\"),\n Baz: mention(mentionActor),\n Qux: text`quux`,\n },\n icon: new URL(\"https://example.com/icon.png\"),\n image: new URL(\"https://example.com/image.png\"),\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(await bot.dispatchActor(ctx, \"non-existent\"), null);\n const actor = await bot.dispatchActor(ctx, \"bot\");\n assert.ok(actor instanceof Service);\n assert.deepStrictEqual(actor.id, new URL(\"https://example.com/ap/actor/bot\"));\n assert.deepStrictEqual(actor.preferredUsername, \"test\");\n assert.deepStrictEqual(actor.name, \"Test Bot\");\n assert.deepStrictEqual(\n actor.summary,\n \"<p>A summary with a mention: \" +\n '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>john@example.com' +\n \"</span></a>.</p>\",\n );\n const attachments = await Array.fromAsync(actor.getAttachments());\n assert.deepStrictEqual(attachments.length, 3);\n assert.ok(attachments[0] instanceof PropertyValue);\n assert.deepStrictEqual(attachments[0].name, \"Foo\");\n assert.deepStrictEqual(attachments[0].value, \"<strong>bar</strong>\");\n assert.ok(attachments[1] instanceof PropertyValue);\n assert.deepStrictEqual(attachments[1].name, \"Baz\");\n assert.deepStrictEqual(\n attachments[1].value,\n '<a href=\"https://example.com/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>' +\n \"john@example.com</span></a>\",\n );\n assert.ok(attachments[2] instanceof PropertyValue);\n assert.deepStrictEqual(attachments[2].name, \"Qux\");\n assert.deepStrictEqual(attachments[2].value, \"<p>quux</p>\");\n const tags = await Array.fromAsync(actor.getTags());\n assert.deepStrictEqual(tags.length, 1);\n assert.ok(tags[0] instanceof Mention);\n assert.deepStrictEqual(\n tags[0].href,\n new URL(\"https://example.com/actor/john\"),\n );\n assert.deepStrictEqual(tags[0].name, \"@john@example.com\");\n const icon = await actor.getIcon();\n assert.ok(icon instanceof Image);\n assert.deepStrictEqual(icon.url, new URL(\"https://example.com/icon.png\"));\n const image = await actor.getImage();\n assert.ok(image instanceof Image);\n assert.deepStrictEqual(image.url, new URL(\"https://example.com/image.png\"));\n assert.deepStrictEqual(\n actor.inboxId,\n new URL(\"https://example.com/ap/actor/bot/inbox\"),\n );\n assert.deepStrictEqual(\n actor.endpoints?.sharedInbox,\n new URL(\"https://example.com/ap/inbox\"),\n );\n assert.deepStrictEqual(\n actor.followersId,\n new URL(\"https://example.com/ap/actor/bot/followers\"),\n );\n assert.deepStrictEqual(\n actor.outboxId,\n new URL(\"https://example.com/ap/actor/bot/outbox\"),\n );\n const publicKey = await actor.getPublicKey();\n assert.ok(publicKey != null);\n assert.deepStrictEqual(publicKey.ownerId, actor.id);\n assert.ok(publicKey.publicKey != null);\n const keys = await repository.getKeyPairs();\n assert.ok(keys != null);\n assert.deepStrictEqual(publicKey.publicKey, keys[0].publicKey);\n const assertionMethods = await Array.fromAsync(actor.getAssertionMethods());\n assert.deepStrictEqual(assertionMethods.length, 2);\n assert.deepStrictEqual(\n assertionMethods.map((mk) => mk.controllerId),\n [actor.id, actor.id],\n );\n assert.deepStrictEqual(\n await Promise.all(assertionMethods.map((mk) => mk.publicKey)),\n keys.map((k) => k.publicKey),\n );\n});\n\ntest(\"BotImpl.mapHandle()\", () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"username\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(bot.mapHandle(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(bot.mapHandle(ctx, \"username\"), \"bot\");\n});\n\ntest(\"BotImpl.dispatchActorKeyPairs()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchActorKeyPairs(ctx, \"non-existent\"),\n [],\n );\n // Generation:\n const keyPairs = await bot.dispatchActorKeyPairs(ctx, \"bot\");\n const storedKeyPairs = await repository.getKeyPairs();\n assert.deepStrictEqual(keyPairs, storedKeyPairs);\n // Retrieval:\n const keyPairs2 = await bot.dispatchActorKeyPairs(ctx, \"bot\");\n assert.deepStrictEqual(keyPairs2, storedKeyPairs);\n});\n\ntest(\"BotImpl.dispatchFollowers()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n collectionWindow: 2,\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchFollowers(ctx, \"non-existent\", null),\n null,\n );\n assert.deepStrictEqual(\n await bot.dispatchFollowers(ctx, \"non-existent\", \"\"),\n null,\n );\n const empty = await bot.dispatchFollowers(ctx, \"bot\", null);\n assert.deepStrictEqual(empty, { items: [], nextCursor: null });\n\n await repository.addFollower(\n new URL(\"https://example.com/actor/1#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/1\"),\n preferredUsername: \"john\",\n inbox: new URL(\"https://example.com/actor/1/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/2#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/2\"),\n preferredUsername: \"jane\",\n inbox: new URL(\"https://example.com/actor/2/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/3#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/3\"),\n preferredUsername: \"joe\",\n inbox: new URL(\"https://example.com/actor/3/inbox\"),\n }),\n );\n const full = await bot.dispatchFollowers(ctx, \"bot\", null);\n assert.ok(full != null);\n assert.deepStrictEqual(full.nextCursor, null);\n assert.deepStrictEqual(full.items.length, 3);\n const items = full.items.toSorted((a, b) =>\n (a.id?.href ?? \"\").localeCompare(b.id?.href ?? \"\")\n );\n assert.ok(items[0] instanceof Person);\n assert.deepStrictEqual(items[0].id, new URL(\"https://example.com/actor/1\"));\n assert.ok(items[1] instanceof Person);\n assert.deepStrictEqual(items[1].id, new URL(\"https://example.com/actor/2\"));\n assert.ok(items[2] instanceof Person);\n assert.deepStrictEqual(items[2].id, new URL(\"https://example.com/actor/3\"));\n\n const firstPage = await bot.dispatchFollowers(ctx, \"bot\", \"0\");\n assert.ok(firstPage != null);\n assert.deepStrictEqual(firstPage.nextCursor, \"2\");\n assert.deepStrictEqual(firstPage.items.length, 2);\n assert.ok(firstPage.items[0] instanceof Person);\n assert.deepStrictEqual(\n firstPage.items[0].id,\n new URL(\"https://example.com/actor/3\"),\n );\n assert.ok(firstPage.items[1] instanceof Person);\n assert.deepStrictEqual(\n firstPage.items[1].id,\n new URL(\"https://example.com/actor/2\"),\n );\n\n const lastPage = await bot.dispatchFollowers(\n ctx,\n \"bot\",\n \"2\",\n );\n assert.ok(lastPage != null);\n assert.deepStrictEqual(lastPage.nextCursor, null);\n assert.deepStrictEqual(lastPage.items.length, 1);\n assert.ok(lastPage.items[0] instanceof Person);\n assert.deepStrictEqual(\n lastPage.items[0].id,\n new URL(\"https://example.com/actor/1\"),\n );\n});\n\ntest(\"BotImpl.getFollowersFirstCursor()\", () => {\n const kv = new MemoryKvStore();\n const bot = new BotImpl<void>({ kv, username: \"bot\", collectionWindow: 2 });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n bot.getFollowersFirstCursor(ctx, \"non-existent\"),\n null,\n );\n assert.deepStrictEqual(bot.getFollowersFirstCursor(ctx, \"bot\"), \"0\");\n});\n\ntest(\"BotImpl.countFollowers()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"bot\"), 0);\n await repository.addFollower(\n new URL(\"https://example.com/actor/1#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/1\"),\n preferredUsername: \"john\",\n inbox: new URL(\"https://example.com/actor/1/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/2#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/2\"),\n preferredUsername: \"jane\",\n inbox: new URL(\"https://example.com/actor/2/inbox\"),\n }),\n );\n await repository.addFollower(\n new URL(\"https://example.com/actor/3#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/3\"),\n preferredUsername: \"joe\",\n inbox: new URL(\"https://example.com/actor/3/inbox\"),\n }),\n );\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countFollowers(ctx, \"bot\"), 3);\n});\n\ntest(\"BotImpl.getPermissionChecker()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const publicPost = new Note({\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n });\n const unlistedPost = new Note({\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n });\n const followersPost = new Note({\n tos: [\n new URL(\"https://example.com/ap/actor/bot/followers\"),\n new URL(\"https://example.com/ap/actor/mentioned\"),\n ],\n });\n const directPost = new Note({\n to: new URL(\"https://example.com/ap/actor/mentioned\"),\n });\n const anonymous = await bot.getPermissionChecker(ctx);\n assert.deepStrictEqual(anonymous(publicPost), true);\n assert.deepStrictEqual(anonymous(unlistedPost), true);\n assert.deepStrictEqual(anonymous(followersPost), false);\n assert.deepStrictEqual(anonymous(directPost), false);\n\n const actor = new Person({ id: new URL(\"https://example.com/actor/john\") });\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n const nonFollower = await bot.getPermissionChecker(ctx2);\n assert.deepStrictEqual(nonFollower(publicPost), true);\n assert.deepStrictEqual(nonFollower(unlistedPost), true);\n assert.deepStrictEqual(nonFollower(followersPost), false);\n assert.deepStrictEqual(nonFollower(directPost), false);\n\n await repository.addFollower(\n new URL(\"https://example.com/actor/john#follow\"),\n new Person({\n id: new URL(\"https://example.com/actor/john\"),\n preferredUsername: \"john\",\n }),\n );\n const ctx3 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n ctx3.getSignedKeyOwner = () => Promise.resolve(actor);\n const follower = await bot.getPermissionChecker(ctx3);\n assert.deepStrictEqual(follower(publicPost), true);\n assert.deepStrictEqual(follower(unlistedPost), true);\n assert.deepStrictEqual(follower(followersPost), true);\n assert.deepStrictEqual(follower(directPost), false);\n\n const mentionedActor = new Person({\n id: new URL(\"https://example.com/ap/actor/mentioned\"),\n });\n const ctx4 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n ctx4.getSignedKeyOwner = () => Promise.resolve(mentionedActor);\n const mentioned = await bot.getPermissionChecker(ctx4);\n assert.deepStrictEqual(mentioned(publicPost), true);\n assert.deepStrictEqual(mentioned(unlistedPost), true);\n assert.deepStrictEqual(mentioned(followersPost), true);\n assert.deepStrictEqual(mentioned(directPost), true);\n});\n\ntest(\"BotImpl.dispatchOutbox()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n collectionWindow: 2,\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", null),\n null,\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", \"\"),\n null,\n );\n assert.deepStrictEqual(await bot.dispatchOutbox(ctx, \"bot\", null), {\n items: [],\n nextCursor: null,\n });\n assert.deepStrictEqual(await bot.dispatchOutbox(ctx, \"bot\", \"\"), {\n items: [],\n nextCursor: null,\n });\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n );\n await repository.addMessage(\n \"46442170-836d-4a0d-9142-f31242abe2f9\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, followers!\",\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n );\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", null),\n null,\n );\n assert.deepStrictEqual(\n await bot.dispatchOutbox(ctx, \"non-existent\", \"\"),\n null,\n );\n const anonymous1 = await bot.dispatchOutbox(ctx, \"bot\", \"\");\n assert.ok(anonymous1 != null);\n assert.deepStrictEqual(anonymous1.nextCursor, \"2025-01-01T00:00:00Z\");\n assert.deepStrictEqual(anonymous1.items.length, 1);\n assert.ok(anonymous1.items[0] instanceof Create);\n assert.deepStrictEqual(\n anonymous1.items[0].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n );\n\n const anonymous2 = await bot.dispatchOutbox(\n ctx,\n \"bot\",\n \"2025-01-01T00:00:00Z\",\n );\n assert.ok(anonymous2 != null);\n assert.deepStrictEqual(anonymous2.nextCursor, null);\n assert.deepStrictEqual(anonymous2.items.length, 1);\n assert.ok(anonymous2.items[0] instanceof Create);\n assert.deepStrictEqual(\n anonymous2.items[0].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n );\n\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n const mentioned = await bot.dispatchOutbox(ctx2, \"bot\", null);\n assert.ok(mentioned != null);\n assert.deepStrictEqual(mentioned.nextCursor, null);\n assert.deepStrictEqual(mentioned.items.length, 3);\n assert.ok(mentioned.items[0] instanceof Create);\n assert.deepStrictEqual(\n mentioned.items[0].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n );\n assert.ok(mentioned.items[1] instanceof Create);\n assert.deepStrictEqual(\n mentioned.items[1].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n );\n assert.ok(mentioned.items[2] instanceof Create);\n assert.deepStrictEqual(\n mentioned.items[2].id,\n new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n );\n});\n\ntest(\"BotImpl.getOutboxFirstCursor()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(bot.getOutboxFirstCursor(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(bot.getOutboxFirstCursor(ctx, \"bot\"), \"\");\n});\n\ntest(\"BotImpl.countOutbox()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"bot\"), 0);\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n await repository.addMessage(\n \"46442170-836d-4a0d-9142-f31242abe2f9\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/46442170-836d-4a0d-9142-f31242abe2f9\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"non-existent\"), null);\n assert.deepStrictEqual(await bot.countOutbox(ctx, \"bot\"), 3);\n});\n\ntest(\"BotImpl.dispatchFollow()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchFollow(ctx, { id: crypto.randomUUID() }),\n null,\n );\n\n await repository.addSentFollow(\n \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/john\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n const follow = await bot.dispatchFollow(ctx, {\n id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n });\n assert.ok(follow instanceof Follow);\n assert.deepStrictEqual(\n follow.id,\n new URL(\n \"https://example.com/ap/follow/b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n ),\n );\n assert.deepStrictEqual(\n follow.actorId,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(\n follow.objectId,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.deepStrictEqual(\n follow.toId,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n});\n\ntest(\"BotImpl.authorizeFollow()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n await repository.addSentFollow(\n \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/john\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n assert.ok(\n await bot.authorizeFollow(\n ctx,\n { id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\" },\n new CryptographicKey({}),\n new Person({ id: new URL(\"https://example.com/ap/actor/john\") }),\n ),\n );\n assert.ok(\n await bot.authorizeFollow(\n ctx,\n { id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\" },\n new CryptographicKey({}),\n await new SessionImpl(bot, ctx).getActor(),\n ),\n );\n assert.deepStrictEqual(\n await bot.authorizeFollow(\n ctx,\n { id: \"b51f6ca8-53e6-4f7d-ac1f-d039e8c6df5a\" },\n new CryptographicKey({}),\n new Person({ id: new URL(\"https://example.com/ap/actor/alice\") }),\n ),\n false,\n );\n assert.deepStrictEqual(\n await bot.authorizeFollow(\n ctx,\n { id: crypto.randomUUID() },\n new CryptographicKey({}),\n new Person({ id: new URL(\"https://example.com/ap/actor/john\") }),\n ),\n false,\n );\n});\n\ntest(\"BotImpl.dispatchCreate()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx, { id: \"non-existent\" }),\n null,\n );\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n const create = await bot.dispatchCreate(ctx, {\n id: \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n });\n assert.ok(create instanceof Create);\n assert.deepStrictEqual(\n create.id,\n new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n );\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx2, {\n id: \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n }),\n create,\n );\n\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx, {\n id: \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n }),\n null,\n );\n const create2 = await bot.dispatchCreate(ctx2, {\n id: \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n });\n assert.ok(create2 instanceof Create);\n assert.deepStrictEqual(\n create2.id,\n new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n );\n\n await repository.addMessage(\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchCreate(ctx, {\n id: \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n }),\n null,\n );\n});\n\ntest(\"BotImpl.dispatchMessage()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchMessage(Note, ctx, \"non-existent\"),\n null,\n );\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n const note = await bot.dispatchMessage(\n Note,\n ctx,\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n );\n assert.ok(note instanceof Note);\n assert.deepStrictEqual(\n note.id,\n new URL(\"https://example.com/ap/actor/bot/note/1\"),\n );\n\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Note,\n ctx2,\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n note,\n );\n\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Article,\n ctx,\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n null,\n );\n\n await repository.addMessage(\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/3\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n content: \"Hello, followers!\",\n }),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Note,\n ctx,\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n ),\n null,\n );\n const note2 = await bot.dispatchMessage(\n Note,\n ctx2,\n \"8386a4c7-06f8-409f-ad72-2bba43e83363\",\n );\n assert.ok(note2 instanceof Note);\n assert.deepStrictEqual(\n note2.id,\n new URL(\"https://example.com/ap/actor/bot/note/3\"),\n );\n\n await repository.addMessage(\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchMessage(\n Note,\n ctx,\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n null,\n );\n});\n\ntest(\"BotImpl.dispatchAnnounce()\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(\n await bot.dispatchAnnounce(ctx, { id: \"non-existent\" }),\n null,\n );\n\n await repository.addMessage(\n \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n const announce = await bot.dispatchAnnounce(ctx, {\n id: \"ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n });\n assert.ok(announce instanceof Announce);\n assert.deepStrictEqual(\n announce.id,\n new URL(\n \"https://example.com/ap/actor/bot/announce/ce8081ac-f238-484b-9a70-5d8a4b66d829\",\n ),\n );\n\n await repository.addMessage(\n \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n new Create({\n id: new URL(\n \"https://example.com/ap/actor/bot/create/78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchAnnounce(ctx, {\n id: \"78acb1ea-4ac6-46b7-bcd4-3a8965d8126e\",\n }),\n null,\n );\n\n await repository.addMessage(\n \"d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n new Announce({\n id: new URL(\n \"https://example.com/ap/actor/bot/announce/d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\"https://example.com/ap/actor/bot/note/2\"),\n }),\n );\n assert.deepStrictEqual(\n await bot.dispatchAnnounce(ctx, {\n id: \"d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n }),\n null,\n );\n const ctx2 = bot.federation.createContext(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n });\n ctx2.getSignedKeyOwner = () => Promise.resolve(actor);\n const announce2 = await bot.dispatchAnnounce(ctx2, {\n id: \"d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n });\n assert.ok(announce2 instanceof Announce);\n assert.deepStrictEqual(\n announce2.id,\n new URL(\n \"https://example.com/ap/actor/bot/announce/d4a7ef9b-682c-4de9-b23c-87747d6725cb\",\n ),\n );\n});\n\ntest(\"BotImpl.dispatchSharedKey()\", () => {\n const identifier = crypto.randomUUID();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n identifier,\n });\n const ctx = bot.federation.createContext(new URL(\"https://example.com\"));\n assert.deepStrictEqual(bot.dispatchSharedKey(ctx), { identifier });\n});\n\nfor (const policy of [\"accept\", \"reject\", \"manual\"] as const) {\n test(`BotImpl.onFollowed() [followerPolicy: ${policy}]`, async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n followerPolicy: policy,\n });\n const followRequests: [Session<void>, FollowRequest][] = [];\n bot.onFollow = (session, fr) => void (followRequests.push([session, fr]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await t.test(\"without actor\", async () => {\n const followWithoutActor = new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n object: new URL(\"https://example.com/ap/actor/bot\"),\n });\n await bot.onFollowed(ctx, followWithoutActor);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n });\n\n await t.test(\"with wrong actor\", async () => {\n const followWithWrongActor = new Follow({\n id: new URL(\"https://example.com/ap/actor/bot/follows/bot\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/bot\"),\n });\n await bot.onFollowed(ctx, followWithWrongActor);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n });\n\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n\n await t.test(\"with wrong recipient\", async () => {\n const followWithWrongRecipient = new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n actor,\n object: new URL(\"https://example.com/ap/actor/non-existent\"),\n });\n await bot.onFollowed(ctx, followWithWrongRecipient);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n });\n\n await t.test(\"with correct follow\", async () => {\n const follow = new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n actor,\n object: new URL(\"https://example.com/ap/actor/bot\"),\n });\n await bot.onFollowed(ctx, follow);\n if (policy === \"accept\") {\n assert.deepStrictEqual(await repository.countFollowers(), 1);\n assert.ok(\n await repository.hasFollower(\n new URL(\"https://example.com/ap/actor/john\"),\n ),\n );\n const [storedFollower] = await Array.fromAsync(\n repository.getFollowers(),\n );\n assert.ok(storedFollower instanceof Person);\n assert.deepStrictEqual(storedFollower.id, actor.id);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { activity, recipients } = ctx.sentActivities[0];\n assert.ok(activity instanceof Accept);\n assert.deepStrictEqual(\n activity.actorId,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(activity.objectId, follow.id);\n assert.deepStrictEqual(recipients.length, 1);\n assert.deepStrictEqual(recipients[0], actor);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n assert.deepStrictEqual(followRequests.length, 1);\n } else {\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n if (policy === \"reject\") {\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { activity, recipients } = ctx.sentActivities[0];\n assert.ok(activity instanceof Reject);\n assert.deepStrictEqual(\n activity.actorId,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(activity.objectId, follow.id);\n assert.deepStrictEqual(recipients.length, 1);\n assert.deepStrictEqual(recipients[0], actor);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n } else {\n assert.deepStrictEqual(ctx.sentActivities, []);\n }\n }\n const [session, followRequest] = followRequests[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(followRequest.follower instanceof Person);\n assert.deepStrictEqual(followRequest.follower.id, actor.id);\n });\n });\n}\n\ntest(\"BotImpl.onUnfollowed()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const unfollowed: [Session<void>, Actor][] = [];\n bot.onUnfollow = (session, actor) => void (unfollowed.push([session, actor]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await repository.addFollower(\n new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n );\n\n async function assertNoEffect() {\n assert.deepStrictEqual(await repository.countFollowers(), 1);\n const [follower] = await Array.fromAsync(repository.getFollowers());\n assert.ok(follower instanceof Person);\n assert.deepStrictEqual(\n follower.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.deepStrictEqual(follower.preferredUsername, \"john\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n assert.deepStrictEqual(unfollowed, []);\n }\n\n await t.test(\"without Follow object\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"without Follow.id\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new Follow({}),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"with non-existent Follow.id\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/non-existent\"),\n }),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"with incorrect Follow.actorId\", async () => {\n const undo = new Undo({\n actor: new URL(\"https://example.com/ap/actor/wrong-actor\"),\n object: new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n }),\n });\n await bot.onUnfollowed(ctx, undo);\n await assertNoEffect();\n });\n\n await t.test(\"with correct Follow object\", async () => {\n const undo = new Undo({\n actor: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n object: new Follow({\n id: new URL(\"https://example.com/ap/actor/john/follows/bot\"),\n }),\n });\n await bot.onUnfollowed(ctx, undo);\n assert.deepStrictEqual(await repository.countFollowers(), 0);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n assert.deepStrictEqual(unfollowed.length, 1);\n const [session, follower] = unfollowed[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(follower instanceof Person);\n assert.deepStrictEqual(\n follower.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n });\n});\n\ntest(\"BotImpl.onFollowAccepted()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const accepted: [Session<void>, Actor][] = [];\n bot.onAcceptFollow = (session, actor) =>\n void (accepted.push([session, actor]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await t.test(\"without object\", async () => {\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with invalid object URI\", async () => {\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\"https://example.com/\"),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with non-existent object\", async () => {\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(`https://example.com/ap/follow/${crypto.randomUUID()}`),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with non-actor\", async () => {\n await repository.addSentFollow(\n \"2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({}),\n }),\n );\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with actor without URI\", async () => {\n await repository.addSentFollow(\n \"a99ff3bf-72a2-412b-83b9-cba894d38805\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n }),\n );\n assert.deepStrictEqual(accepted, []);\n });\n\n await t.test(\"with actor\", async () => {\n await repository.addSentFollow(\n \"3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowAccepted(\n ctx,\n new Accept({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n }),\n );\n assert.deepStrictEqual(accepted.length, 1);\n const [session, actor] = accepted[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(actor instanceof Person);\n assert.deepStrictEqual(\n actor.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n const follow = await repository.getFollowee(\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.ok(follow != null);\n assert.ok(follow instanceof Follow);\n assert.deepStrictEqual(\n follow.id,\n new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n );\n assert.deepStrictEqual(follow.objectId, actor.id);\n });\n});\n\ntest(\"BotImpl.onFollowRejected()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const rejected: [Session<void>, Actor][] = [];\n bot.onRejectFollow = (session, actor) =>\n void (rejected.push([session, actor]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n await t.test(\"without object\", async () => {\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with invalid object URI\", async () => {\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\"https://example.com/\"),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with non-existent object\", async () => {\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(`https://example.com/ap/follow/${crypto.randomUUID()}`),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with non-actor\", async () => {\n await repository.addSentFollow(\n \"2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({}),\n }),\n );\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/2ca58e2a-a34a-43e6-81af-c4f21ffed0c5\",\n ),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with actor without URI\", async () => {\n await repository.addSentFollow(\n \"a99ff3bf-72a2-412b-83b9-cba894d38805\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/a99ff3bf-72a2-412b-83b9-cba894d38805\",\n ),\n }),\n );\n assert.deepStrictEqual(rejected, []);\n });\n\n await t.test(\"with actor\", async () => {\n await repository.addSentFollow(\n \"3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n }),\n );\n await bot.onFollowRejected(\n ctx,\n new Reject({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new URL(\n \"https://example.com/ap/follow/3bca0b8e-503a-47ea-ad69-6b7c29369fbd\",\n ),\n }),\n );\n assert.deepStrictEqual(rejected.length, 1);\n const [session, actor] = rejected[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(actor instanceof Person);\n assert.deepStrictEqual(\n actor.id,\n new URL(\"https://example.com/ap/actor/john\"),\n );\n assert.deepStrictEqual(\n await repository.getSentFollow(\"3bca0b8e-503a-47ea-ad69-6b7c29369fbd\"),\n undefined,\n );\n });\n});\n\ntest(\"BotImpl.onCreated()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n let replied: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onReply = (session, msg) => void (replied.push([session, msg]));\n let mentioned: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onMention = (session, msg) => void (mentioned.push([session, msg]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n let messaged: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onMessage = (session, msg) => void (messaged.push([session, msg]));\n\n await t.test(\"without object\", async () => {\n const createWithoutObject = new Create({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n });\n await bot.onCreated(ctx, createWithoutObject);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, []);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n await t.test(\"with non-message object\", async () => {\n const createWithNonMessageObject = new Create({\n actor: new URL(\"https://example.com/ap/actor/john\"),\n object: new Place({}),\n });\n await bot.onCreated(ctx, createWithNonMessageObject);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, []);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n await repository.addMessage(\n \"a6358f1b-c978-49d3-8065-37a1df6168de\",\n new Create({\n id: new URL(\n \"https://example.com/ap/create/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n }),\n );\n\n await t.test(\"on reply\", async () => {\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content: \"It's reply!\",\n replyTarget: new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n }),\n });\n await bot.onCreated(ctx, create);\n assert.deepStrictEqual(replied.length, 1);\n const [session, msg] = replied[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.ok(msg.replyTarget != null);\n assert.deepStrictEqual(\n msg.replyTarget.id,\n new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n );\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, replied);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, [\"followers\"]);\n });\n\n await t.test(\"on mention\", async () => {\n replied = [];\n messaged = [];\n ctx.forwardedRecipients = [];\n\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content:\n '<p><a href=\"https://example.com/ap/actor/bot\">@bot</a> Hey!</p>',\n tags: [\n new Mention({\n href: new URL(\"https://example.com/ap/actor/bot\"),\n name: \"@bot\",\n }),\n ],\n }),\n });\n await bot.onCreated(ctx, create);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned.length, 1);\n const [session, msg] = mentioned[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.deepStrictEqual(msg.mentions.length, 1);\n assert.deepStrictEqual(\n msg.mentions[0].id,\n new URL(\"https://example.com/ap/actor/bot\"),\n );\n assert.deepStrictEqual(messaged, mentioned);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n await t.test(\"on quote\", async () => {\n mentioned = [];\n messaged = [];\n ctx.forwardedRecipients = [];\n\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content: \"It's a quote!\",\n quoteUrl: new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n }),\n });\n let quoted: [Session<void>, Message<MessageClass, void>][] = [];\n bot.onQuote = (session, msg) => void (quoted.push([session, msg]));\n\n await bot.onCreated(ctx, create);\n\n assert.deepStrictEqual(quoted.length, 1);\n const [session, msg] = quoted[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.ok(msg.quoteTarget != null);\n assert.deepStrictEqual(\n msg.quoteTarget.id,\n new URL(\n \"https://example.com/ap/note/a6358f1b-c978-49d3-8065-37a1df6168de\",\n ),\n );\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged, quoted);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, [\"followers\"]);\n\n quoted = [];\n messaged = [];\n ctx.forwardedRecipients = [];\n });\n\n await t.test(\"on message\", async () => {\n const create = new Create({\n id: new URL(\n \"https://example.com/ap/create/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n actor: new URL(\"https://example.com/ap/actor/john\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/9cfd7129-4cf0-4505-90d8-3cac2dc42434\",\n ),\n attribution: new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n }),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/john/followers\"),\n content: \"<p>Hello!</p>\",\n }),\n });\n await bot.onCreated(ctx, create);\n assert.deepStrictEqual(replied, []);\n assert.deepStrictEqual(mentioned, []);\n assert.deepStrictEqual(messaged.length, 1);\n const [session, msg] = messaged[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.ok(msg.raw instanceof Note);\n assert.deepStrictEqual(msg.raw.id, create.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n });\n\n messaged = [];\n});\n\ntest(\"BotImpl.onAnnounced()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const shares: [Session<void>, SharedMessage<MessageClass, void>][] = [];\n bot.onSharedMessage = (session, sharedMessage) =>\n void (shares.push([session, sharedMessage]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n const announce = new Announce({\n id: new URL(\"https://example.com/ap/actor/bot/announce/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n });\n await bot.onAnnounced(ctx, announce);\n assert.deepStrictEqual(shares.length, 1);\n const [session, sharedMessage] = shares[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(sharedMessage.raw, announce);\n assert.deepStrictEqual(sharedMessage.id, announce.id);\n assert.deepStrictEqual(sharedMessage.actor.id, announce.actorId);\n assert.deepStrictEqual(sharedMessage.visibility, \"public\");\n assert.deepStrictEqual(sharedMessage.original.id, announce.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n});\n\ntest(\"BotImpl.onLiked()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const likes: [Session<void>, Like<void>][] = [];\n bot.onLike = (session, like) => void (likes.push([session, like]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n });\n await bot.onLiked(ctx, rawLike);\n assert.deepStrictEqual(likes.length, 1);\n const [session, like] = likes[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(like.raw, rawLike);\n assert.deepStrictEqual(like.id, rawLike.id);\n assert.deepStrictEqual(like.actor.id, rawLike.actorId);\n assert.deepStrictEqual(like.message.id, rawLike.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n});\n\ntest(\"BotImpl.onUnliked()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const likes: [Session<void>, Like<void>][] = [];\n bot.onUnlike = (session, like) => void (likes.push([session, like]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n });\n const undo = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unlike/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: rawLike,\n });\n await bot.onUnliked(ctx, undo);\n assert.deepStrictEqual(likes.length, 1);\n const [session, like] = likes[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(like.raw, rawLike);\n assert.deepStrictEqual(like.id, rawLike.id);\n assert.deepStrictEqual(like.actor.id, rawLike.actorId);\n assert.deepStrictEqual(like.message.id, rawLike.objectId);\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n likes.pop();\n const invalidUndo = undo.clone({\n actor: new URL(\"https://example.com/ap/actor/another\"),\n });\n await bot.onUnliked(ctx, invalidUndo);\n assert.deepStrictEqual(likes, []);\n});\n\ntest(\"BotImpl.onReacted()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const reactions: [Session<void>, Reaction<void>][] = [];\n bot.onReact = (session, reaction) =>\n void (reactions.push([session, reaction]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n // Test with Like containing an emoji name\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":heart:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/heart\"),\n name: \":heart:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/heart.png\"),\n }),\n }),\n ],\n });\n\n await bot.onReacted(ctx, rawLike);\n assert.deepStrictEqual(reactions.length, 1);\n const [session, reaction] = reactions[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(reaction.raw, rawLike);\n assert.deepStrictEqual(reaction.id, rawLike.id);\n assert.deepStrictEqual(reaction.actor.id, rawLike.actorId);\n assert.deepStrictEqual(reaction.message.id, rawLike.objectId);\n assert.ok(reaction.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction.emoji.name, \":heart:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n // Test with EmojiReact\n reactions.pop();\n const emojiReact = new EmojiReact({\n id: new URL(\"https://example.com/ap/actor/bot/react/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":thumbsup:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/thumbsup\"),\n name: \":thumbsup:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/thumbsup.png\"),\n }),\n }),\n ],\n });\n\n await bot.onReacted(ctx, emojiReact);\n assert.deepStrictEqual(reactions.length, 1);\n const [session2, reaction2] = reactions[0];\n assert.deepStrictEqual(session2.bot, bot);\n assert.deepStrictEqual(session2.context, ctx);\n assert.deepStrictEqual(reaction2.raw, emojiReact);\n assert.deepStrictEqual(reaction2.id, emojiReact.id);\n assert.deepStrictEqual(reaction2.actor.id, emojiReact.actorId);\n assert.deepStrictEqual(reaction2.message.id, emojiReact.objectId);\n assert.ok(reaction2.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction2.emoji.name, \":thumbsup:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n});\n\ntest(\"BotImpl.onUnreacted()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const reactions: [Session<void>, Reaction<void>][] = [];\n bot.onUnreact = (session, reaction) =>\n void (reactions.push([session, reaction]));\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n // Test with Like containing an emoji name\n const rawLike = new RawLike({\n id: new URL(\"https://example.com/ap/actor/bot/like/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":heart:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/heart\"),\n name: \":heart:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/heart.png\"),\n }),\n }),\n ],\n });\n\n const undo = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unreact/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: rawLike,\n });\n\n await bot.onUnreacted(ctx, undo);\n assert.deepStrictEqual(reactions.length, 1);\n const [session, reaction] = reactions[0];\n assert.deepStrictEqual(session.bot, bot);\n assert.deepStrictEqual(session.context, ctx);\n assert.deepStrictEqual(reaction.raw, rawLike);\n assert.deepStrictEqual(reaction.id, rawLike.id);\n assert.deepStrictEqual(reaction.actor.id, rawLike.actorId);\n assert.deepStrictEqual(reaction.message.id, rawLike.objectId);\n assert.ok(reaction.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction.emoji.name, \":heart:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n // Test with EmojiReact\n reactions.pop();\n const emojiReact = new EmojiReact({\n id: new URL(\"https://example.com/ap/actor/bot/react/1\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n name: \":thumbsup:\",\n object: new Note({\n id: new URL(\"https://example.com/ap/actor/bot/note/1\"),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: PUBLIC_COLLECTION,\n cc: new URL(\"https://example.com/ap/actor/bot/followers\"),\n content: \"Hello, world!\",\n }),\n tags: [\n new Emoji({\n id: new URL(\"https://example.com/ap/emoji/thumbsup\"),\n name: \":thumbsup:\",\n icon: new Image({\n mediaType: \"image/png\",\n url: new URL(\"https://example.com/emoji/thumbsup.png\"),\n }),\n }),\n ],\n });\n\n const undoEmojiReact = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unreact/2\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: emojiReact,\n });\n\n await bot.onUnreacted(ctx, undoEmojiReact);\n assert.deepStrictEqual(reactions.length, 1);\n const [session2, reaction2] = reactions[0];\n assert.deepStrictEqual(session2.bot, bot);\n assert.deepStrictEqual(session2.context, ctx);\n assert.deepStrictEqual(reaction2.raw, emojiReact);\n assert.deepStrictEqual(reaction2.id, emojiReact.id);\n assert.deepStrictEqual(reaction2.actor.id, emojiReact.actorId);\n assert.deepStrictEqual(reaction2.message.id, emojiReact.objectId);\n assert.ok(reaction2.emoji instanceof Emoji);\n assert.deepStrictEqual(reaction2.emoji.name, \":thumbsup:\");\n assert.deepStrictEqual(ctx.sentActivities, []);\n assert.deepStrictEqual(ctx.forwardedRecipients, []);\n\n // Test with mismatched actor\n reactions.pop();\n const invalidUndo = undoEmojiReact.clone({\n actor: new URL(\"https://example.com/ap/actor/another\"),\n });\n await bot.onUnreacted(ctx, invalidUndo);\n assert.deepStrictEqual(reactions, []);\n\n // Test with non-reaction object\n reactions.pop();\n const nonReactionUndo = new Undo({\n id: new URL(\"https://example.com/ap/actor/bot/unreact/3\"),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new Note({}),\n });\n await bot.onUnreacted(ctx, nonReactionUndo);\n assert.deepStrictEqual(reactions, []);\n});\n\ntest(\"BotImpl.dispatchNodeInfo()\", () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n software: {\n name: \"test\",\n version: parseSemVer(\"1.2.3\"),\n homepage: new URL(\"https://example.com/\"),\n repository: new URL(\"https://git.example.com/\"),\n },\n });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(bot.dispatchNodeInfo(ctx), {\n software: {\n name: \"test\",\n version: parseSemVer(\"1.2.3\"),\n homepage: new URL(\"https://example.com/\"),\n repository: new URL(\"https://git.example.com/\"),\n },\n protocols: [\"activitypub\"],\n services: {\n outbound: [\"atom1.0\"],\n },\n usage: {\n users: {\n total: 1,\n activeMonth: 1,\n activeHalfyear: 1,\n },\n localPosts: 0,\n localComments: 0,\n },\n });\n});\n\ntest(\"BotImpl.fetch()\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n });\n const request = new Request(\n \"http://localhost/.well-known/webfinger?resource=acct:bot@example.com\",\n {\n headers: {\n \"X-Forwarded-Host\": \"example.com\",\n \"X-Forwarded-Proto\": \"https\",\n },\n },\n );\n const response = await bot.fetch(request);\n assert.deepStrictEqual(response.status, 404);\n\n const botBehindProxy = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"bot\",\n behindProxy: true,\n });\n const response2 = await botBehindProxy.fetch(request);\n assert.deepStrictEqual(response2.status, 200);\n});\n\ndescribe(\"BotImpl.addCustomEmoji(), BotImpl.addCustomEmojis()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n\n test(\"addCustomEmoji()\", () => {\n const emojiData: CustomEmoji = {\n type: \"image/png\",\n url: \"https://example.com/emoji.png\",\n };\n const deferredEmoji = bot.addCustomEmoji(\"testEmoji\", emojiData);\n assert.deepStrictEqual(typeof deferredEmoji, \"function\");\n assert.deepStrictEqual(bot.customEmojis[\"testEmoji\"], emojiData);\n\n // Test invalid name\n assert.throws(\n () => bot.addCustomEmoji(\"invalid name\", emojiData),\n TypeError,\n \"Invalid custom emoji name\",\n );\n\n // Test duplicate name\n assert.throws(\n () => bot.addCustomEmoji(\"testEmoji\", emojiData),\n TypeError,\n \"Duplicate custom emoji name\",\n );\n\n // Test unsupported media type\n assert.throws(\n () =>\n bot.addCustomEmoji(\"invalidType\", {\n // @ts-expect-error: Intended type error for testing runtime check\n type: \"text/plain\",\n url: \"https://example.com/emoji.txt\",\n }),\n TypeError,\n \"Unsupported media type\",\n );\n });\n\n test(\"addCustomEmojis()\", () => {\n const emojisData = {\n emoji1: { type: \"image/png\", url: \"https://example.com/emoji1.png\" },\n emoji2: { type: \"image/gif\", file: \"/path/to/emoji2.gif\" },\n } as const;\n const deferredEmojis = bot.addCustomEmojis(emojisData);\n\n assert.deepStrictEqual(typeof deferredEmojis[\"emoji1\"], \"function\");\n assert.deepStrictEqual(typeof deferredEmojis[\"emoji2\"], \"function\");\n assert.deepStrictEqual(bot.customEmojis[\"emoji1\"], emojisData.emoji1);\n assert.deepStrictEqual(bot.customEmojis[\"emoji2\"], emojisData.emoji2);\n\n // Test duplicate name within the batch\n assert.throws(\n () =>\n bot.addCustomEmojis({\n emoji1: { type: \"image/png\", url: \"https://example.com/dup1.png\" },\n }),\n TypeError,\n \"Duplicate custom emoji name: emoji1\",\n );\n });\n});\n\ntest(\"BotImpl.getEmoji()\", async () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n\n // Test with remote URL\n const remoteEmojiData: CustomEmoji = {\n type: \"image/png\",\n url: \"https://remote.com/emoji.png\",\n };\n bot.customEmojis[\"remoteEmoji\"] = remoteEmojiData;\n const remoteEmoji = bot.getEmoji(ctx, \"remoteEmoji\", remoteEmojiData);\n assert.ok(remoteEmoji instanceof Emoji);\n assert.deepStrictEqual(\n remoteEmoji.id,\n new URL(\"https://example.com/ap/emoji/remoteEmoji\"),\n );\n assert.deepStrictEqual(remoteEmoji.name, \":remoteEmoji:\");\n const icon = await remoteEmoji.getIcon();\n assert.ok(icon instanceof Image);\n assert.deepStrictEqual(icon.mediaType, \"image/png\");\n assert.deepStrictEqual(icon.url?.href, \"https://remote.com/emoji.png\");\n\n // Test with local file\n const localEmojiData: CustomEmoji = {\n type: \"image/gif\",\n file: \"/path/to/local/emoji.gif\",\n };\n bot.customEmojis[\"localEmoji\"] = localEmojiData;\n const localEmoji = bot.getEmoji(ctx, \"localEmoji\", localEmojiData);\n assert.ok(localEmoji instanceof Emoji);\n assert.deepStrictEqual(\n localEmoji.id,\n new URL(\"https://example.com/ap/emoji/localEmoji\"),\n );\n assert.deepStrictEqual(localEmoji.name, \":localEmoji:\");\n const icon2 = await localEmoji.getIcon();\n assert.ok(icon2 instanceof Image);\n assert.deepStrictEqual(icon2.mediaType, \"image/gif\");\n assert.deepStrictEqual(\n icon2.url?.href,\n \"https://example.com/emojis/localEmoji.gif\",\n );\n\n // Test with local file without extension mapping\n const localEmojiDataNoExt: CustomEmoji = {\n type: \"image/webp\",\n file: \"/path/to/local/emoji\",\n };\n bot.customEmojis[\"localEmojiNoExt\"] = localEmojiDataNoExt;\n const localEmojiNoExt = bot.getEmoji(\n ctx,\n \"localEmojiNoExt\",\n localEmojiDataNoExt,\n );\n const icon3 = await localEmojiNoExt.getIcon();\n assert.ok(icon3 instanceof Image);\n assert.deepStrictEqual(icon3.mediaType, \"image/webp\");\n assert.deepStrictEqual(\n icon3.url?.href,\n \"https://example.com/emojis/localEmojiNoExt.webp\",\n );\n});\n\n// Test BotImpl.dispatchEmoji()\ntest(\"BotImpl.dispatchEmoji()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n const emojiData: CustomEmoji = {\n type: \"image/png\",\n url: \"https://example.com/emoji.png\",\n };\n bot.customEmojis[\"testEmoji\"] = emojiData;\n\n // Test dispatching an existing emoji\n const emoji = bot.dispatchEmoji(ctx, { name: \"testEmoji\" });\n assert.ok(emoji instanceof Emoji);\n assert.deepStrictEqual(\n emoji.id,\n new URL(\"https://example.com/ap/emoji/testEmoji\"),\n );\n assert.deepStrictEqual(emoji.name, \":testEmoji:\");\n\n // Test dispatching a non-existent emoji\n const nonExistent = bot.dispatchEmoji(ctx, { name: \"nonExistent\" });\n assert.deepStrictEqual(nonExistent, null);\n});\n\ntest(\"BotImpl.getFollowersFirstCursor()\", () => {\n const bot = new BotImpl<void>({ kv: new MemoryKvStore(), username: \"bot\" });\n const ctx = bot.federation.createContext(\n new URL(\"https://example.com\"),\n undefined,\n );\n assert.deepStrictEqual(\n bot.getFollowersFirstCursor(ctx, \"non-existent\"),\n null,\n );\n assert.deepStrictEqual(bot.getFollowersFirstCursor(ctx, \"bot\"), \"0\");\n});\n\ninterface SentActivity {\n recipients: \"followers\" | Recipient[];\n activity: Activity;\n}\n\ninterface MockInboxContext extends InboxContext<void> {\n sentActivities: SentActivity[];\n forwardedRecipients: (\"followers\" | Recipient)[];\n}\n\nfunction createMockInboxContext(\n bot: BotImpl<void>,\n origin: string | URL,\n recipient?: string | null,\n): MockInboxContext {\n const ctx = bot.federation.createContext(\n new URL(origin),\n undefined,\n ) as MockInboxContext;\n ctx.recipient = recipient ?? null;\n ctx.sentActivities = [];\n ctx.sendActivity = (_, recipients, activity) => {\n ctx.sentActivities.push({\n recipients: recipients === \"followers\"\n ? \"followers\"\n : Array.isArray(recipients)\n ? recipients\n : [recipients],\n activity,\n });\n return Promise.resolve();\n };\n ctx.forwardedRecipients = [];\n ctx.forwardActivity = (_, recipients) => {\n if (recipients === \"followers\") {\n ctx.forwardedRecipients.push(\"followers\");\n } else if (Array.isArray(recipients)) {\n ctx.forwardedRecipients.push(...recipients);\n } else {\n ctx.forwardedRecipients.push(recipients);\n }\n return Promise.resolve();\n };\n return ctx;\n}\n\ntest(\"BotImpl.onVote()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockInboxContext(bot, \"https://example.com\", \"bot\");\n\n // Create a poll first\n const pollId = \"01950000-0000-7000-8000-000000000000\";\n const poll = new Create({\n id: new URL(`https://example.com/ap/create/${pollId}`),\n actor: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n cc: ctx.getFollowersUri(bot.identifier),\n object: new Question({\n id: new URL(`https://example.com/ap/question/${pollId}`),\n attribution: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n cc: ctx.getFollowersUri(bot.identifier),\n content: \"What's your favorite color?\",\n inclusiveOptions: [],\n exclusiveOptions: [\n new Note({ name: \"Red\", replies: new Collection({ totalItems: 0 }) }),\n new Note({ name: \"Blue\", replies: new Collection({ totalItems: 0 }) }),\n new Note({ name: \"Green\", replies: new Collection({ totalItems: 0 }) }),\n ],\n endTime: Temporal.Now.instant().add({ hours: 24 }),\n voters: 0,\n }),\n published: Temporal.Now.instant(),\n });\n await repository.addMessage(pollId, poll);\n\n // Create a voter\n const voter = new Person({\n id: new URL(\"https://hollo.social/@alice\"),\n preferredUsername: \"alice\",\n });\n\n let receivedVote: Vote<void> | null = null;\n bot.onVote = (_session, vote) => {\n receivedVote = vote;\n };\n\n await t.test(\"vote on single choice poll\", async () => {\n ctx.sentActivities = [];\n ctx.forwardedRecipients = [];\n receivedVote = null;\n\n // Create a vote\n const voteCreate = new Create({\n id: new URL(\"https://example.com/ap/create/vote1\"),\n actor: voter,\n to: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\"https://example.com/ap/note/vote1\"),\n attribution: voter,\n to: PUBLIC_COLLECTION,\n name: \"Red\",\n replyTarget: poll.objectId,\n content: \"Red\",\n }),\n published: Temporal.Now.instant(),\n });\n\n // Process the vote\n await bot.onCreated(ctx, voteCreate);\n\n // Check that onVote was called\n assert.ok(receivedVote != null, \"onVote should have been called\");\n const vote = receivedVote as Vote<void>;\n assert.deepStrictEqual(vote.actor.id, voter.id);\n assert.deepStrictEqual(vote.option, \"Red\");\n assert.deepStrictEqual(vote.poll.multiple, false);\n assert.deepStrictEqual(vote.poll.options, [\"Red\", \"Blue\", \"Green\"]);\n\n // Check that Update activity was sent\n assert.ok(ctx.sentActivities.length > 0, \"Update activity should be sent\");\n const updateActivity = ctx.sentActivities.find(\n ({ activity }: { activity: Activity }) => activity instanceof Update,\n );\n assert.ok(updateActivity != null, \"Update activity should be found\");\n assert.ok(updateActivity.activity instanceof Update);\n assert.deepStrictEqual(\n updateActivity.activity.objectId,\n poll.id,\n );\n\n // Check that vote count was updated in repository\n const updatedPoll = await repository.getMessage(pollId);\n assert.ok(updatedPoll instanceof Create);\n const updatedQuestion = await updatedPoll.getObject(ctx);\n assert.ok(updatedQuestion instanceof Question);\n const updatedOptions = await Array.fromAsync(\n updatedQuestion.getExclusiveOptions(ctx),\n );\n const redOption = updatedOptions.find((opt) =>\n opt.name?.toString() === \"Red\"\n );\n assert.ok(redOption != null);\n const replies = await redOption.getReplies(ctx);\n assert.deepStrictEqual(replies?.totalItems, 1);\n });\n\n await t.test(\"vote on multiple choice poll\", async () => {\n // Create a multiple choice poll\n const multiPollId = \"01950000-0000-7000-8000-000000000001\";\n const multiPoll = new Create({\n id: new URL(`https://example.com/ap/create/${multiPollId}`),\n actor: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n cc: ctx.getFollowersUri(bot.identifier),\n object: new Question({\n id: new URL(`https://example.com/ap/question/${multiPollId}`),\n attribution: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n cc: ctx.getFollowersUri(bot.identifier),\n content: \"Which languages do you know?\",\n inclusiveOptions: [\n new Note({\n name: \"JavaScript\",\n replies: new Collection({ totalItems: 0 }),\n }),\n new Note({\n name: \"TypeScript\",\n replies: new Collection({ totalItems: 0 }),\n }),\n new Note({\n name: \"Python\",\n replies: new Collection({ totalItems: 0 }),\n }),\n ],\n exclusiveOptions: [],\n endTime: Temporal.Now.instant().add({ hours: 24 }),\n voters: 0,\n }),\n published: Temporal.Now.instant(),\n });\n await repository.addMessage(multiPollId, multiPoll);\n\n ctx.sentActivities = [];\n ctx.forwardedRecipients = [];\n receivedVote = null;\n\n // Create a vote for JavaScript\n const jsVoteCreate = new Create({\n id: new URL(\"https://example.com/ap/create/vote2\"),\n actor: voter,\n to: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\"https://example.com/ap/note/vote2\"),\n attribution: voter,\n to: PUBLIC_COLLECTION,\n name: \"JavaScript\",\n replyTarget: multiPoll.objectId,\n content: \"JavaScript\",\n }),\n published: Temporal.Now.instant(),\n });\n\n // Process the vote\n await bot.onCreated(ctx, jsVoteCreate);\n\n // Check that onVote was called\n assert.ok(receivedVote != null, \"onVote should have been called\");\n const vote = receivedVote as Vote<void>;\n assert.deepStrictEqual(vote.actor.id, voter.id);\n assert.deepStrictEqual(vote.option, \"JavaScript\");\n assert.deepStrictEqual(vote.poll.multiple, true);\n assert.deepStrictEqual(vote.poll.options, [\n \"JavaScript\",\n \"TypeScript\",\n \"Python\",\n ]);\n });\n\n await t.test(\"ignore vote from poll author\", async () => {\n ctx.sentActivities = [];\n ctx.forwardedRecipients = [];\n receivedVote = null;\n\n // Create a vote from the bot itself\n const selfVoteCreate = new Create({\n id: new URL(\"https://example.com/ap/create/vote3\"),\n actor: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\"https://example.com/ap/note/vote3\"),\n attribution: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n name: \"Red\",\n replyTarget: poll.objectId,\n content: \"Red\",\n }),\n published: Temporal.Now.instant(),\n });\n\n // Process the vote\n await bot.onCreated(ctx, selfVoteCreate);\n\n // Check that onVote was NOT called\n assert.deepStrictEqual(\n receivedVote,\n null,\n \"onVote should not be called for poll author\",\n );\n });\n\n await t.test(\"ignore vote on expired poll\", async () => {\n // Create an expired poll\n const expiredPollId = \"01950000-0000-7000-8000-000000000002\";\n const expiredPoll = new Create({\n id: new URL(`https://example.com/ap/create/${expiredPollId}`),\n actor: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n cc: ctx.getFollowersUri(bot.identifier),\n object: new Question({\n id: new URL(`https://example.com/ap/question/${expiredPollId}`),\n attribution: ctx.getActorUri(bot.identifier),\n to: PUBLIC_COLLECTION,\n cc: ctx.getFollowersUri(bot.identifier),\n content: \"Expired poll?\",\n inclusiveOptions: [],\n exclusiveOptions: [\n new Note({ name: \"Yes\", replies: new Collection({ totalItems: 0 }) }),\n new Note({ name: \"No\", replies: new Collection({ totalItems: 0 }) }),\n ],\n endTime: Temporal.Now.instant().subtract({ hours: 1 }), // Expired\n voters: 0,\n }),\n published: Temporal.Now.instant(),\n });\n await repository.addMessage(expiredPollId, expiredPoll);\n\n ctx.sentActivities = [];\n ctx.forwardedRecipients = [];\n receivedVote = null;\n\n // Create a vote on expired poll\n const expiredVoteCreate = new Create({\n id: new URL(\"https://example.com/ap/create/vote4\"),\n actor: voter,\n to: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\"https://example.com/ap/note/vote4\"),\n attribution: voter,\n to: PUBLIC_COLLECTION,\n name: \"Yes\",\n replyTarget: expiredPoll.objectId,\n content: \"Yes\",\n }),\n published: Temporal.Now.instant(),\n });\n\n // Process the vote\n await bot.onCreated(ctx, expiredVoteCreate);\n\n // Check that onVote was NOT called\n assert.deepStrictEqual(\n receivedVote,\n null,\n \"onVote should not be called for expired poll\",\n );\n });\n\n await t.test(\"ignore vote with invalid option\", async () => {\n ctx.sentActivities = [];\n ctx.forwardedRecipients = [];\n receivedVote = null;\n\n // Create a vote with invalid option\n const invalidVoteCreate = new Create({\n id: new URL(\"https://example.com/ap/create/vote5\"),\n actor: voter,\n to: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\"https://example.com/ap/note/vote5\"),\n attribution: voter,\n to: PUBLIC_COLLECTION,\n name: \"Purple\", // Not a valid option\n replyTarget: poll.objectId,\n content: \"Purple\",\n }),\n published: Temporal.Now.instant(),\n });\n\n // Process the vote\n await bot.onCreated(ctx, invalidVoteCreate);\n\n // Check that onVote was NOT called\n assert.deepStrictEqual(\n receivedVote,\n null,\n \"onVote should not be called for invalid option\",\n );\n });\n});\n\n// cSpell: ignore thumbsup\n"],"mappings":"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"}