From 00df68b2e2bce81a7d775e8e00d41e0014b5a6de Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 18 Feb 2026 15:18:20 +0000 Subject: [PATCH 1/7] refactor: implement SerializableEvent interface for PostCreatedEvent (ADR-0011) - Updated PostCreatedEvent to only contain postId instead of full Post entity - Implemented toJSON() and fromJSON() methods for serialization - Updated event publisher in post.repository.knex.ts to pass postId - Updated FediverseBridge, FeedUpdateService, and NotificationEventService consumers to look up post from repository - Registered PostCreatedEvent with EventSerializer in app.ts - Added unit tests for serialization/deserialization - Updated existing tests to use the new PostCreatedEvent signature Co-authored-by: Michael Barrett --- .../publish-post-create-activity.json | 2 +- src/activitypub/fediverse-bridge.ts | 6 ++- src/activitypub/fediverse-bridge.unit.test.ts | 45 +++++++++++++++--- src/app.ts | 4 ++ src/feed/feed-update.service.ts | 6 ++- src/feed/feed-update.service.unit.test.ts | 46 +++++++++++++++++-- .../notification-event.service.ts | 12 +++-- .../notification-event.service.unit.test.ts | 35 ++++++++++++-- src/post/post-created.event.ts | 23 ++++++++-- src/post/post-created.event.unit.test.ts | 39 ++++++++++++++++ .../post.repository.knex.integration.test.ts | 4 +- src/post/post.repository.knex.ts | 2 +- 12 files changed, 195 insertions(+), 29 deletions(-) create mode 100644 src/post/post-created.event.unit.test.ts diff --git a/src/activitypub/__snapshots__/publish-post-create-activity.json b/src/activitypub/__snapshots__/publish-post-create-activity.json index 047c75cee..f770374a5 100644 --- a/src/activitypub/__snapshots__/publish-post-create-activity.json +++ b/src/activitypub/__snapshots__/publish-post-create-activity.json @@ -36,7 +36,7 @@ "name": "Post title", "preview": { "content": "Post excerpt", - "id": "https://example.com/note/post-123", + "id": "https://example.com/note/111", "type": "Note", }, "published": "2025-01-12T10:30:00Z", diff --git a/src/activitypub/fediverse-bridge.ts b/src/activitypub/fediverse-bridge.ts index b23a20b97..5d9051620 100644 --- a/src/activitypub/fediverse-bridge.ts +++ b/src/activitypub/fediverse-bridge.ts @@ -89,7 +89,11 @@ export class FediverseBridge { } private async handlePostCreated(event: PostCreatedEvent) { - const post = event.getPost(); + const post = await this.postRepository.getById(event.getPostId()); + if (!post) { + return; + } + if (!post.author.isInternal) { return; } diff --git a/src/activitypub/fediverse-bridge.unit.test.ts b/src/activitypub/fediverse-bridge.unit.test.ts index 2eb5c670e..5d2a8dce3 100644 --- a/src/activitypub/fediverse-bridge.unit.test.ts +++ b/src/activitypub/fediverse-bridge.unit.test.ts @@ -376,7 +376,7 @@ describe('FediverseBridge', () => { author.apFollowers = new URL('https://example.com/user/foo/followers'); const post = Object.create(Post); - post.id = 'post-123'; + post.id = 456; post.author = author; post.type = PostType.Note; post.content = 'Note content'; @@ -385,11 +385,14 @@ describe('FediverseBridge', () => { post.uuid = 'cb1e7e92-5560-4ceb-9272-7e9d0e2a7da4'; post.publishedAt = new Date('2025-01-01T00:00:00Z'); - const event = new PostCreatedEvent(post); + vi.mocked(postRepository.getById).mockResolvedValue(post); + + const event = new PostCreatedEvent(post.id as number); events.emit(PostCreatedEvent.getName(), event); await nextTick(); + expect(postRepository.getById).toHaveBeenCalledWith(post.id); expect(sendActivity).toHaveBeenCalledOnce(); expect(context.data.globaldb.set).toHaveBeenCalled(); @@ -417,7 +420,7 @@ describe('FediverseBridge', () => { mentionedAccount.isInternal = true; const post = Object.create(Post); - post.id = 'post-123'; + post.id = 789; post.author = author; post.type = PostType.Note; post.content = 'Hello! @test@example.com'; @@ -426,11 +429,15 @@ describe('FediverseBridge', () => { post.uuid = 'cb1e7e92-5560-4ceb-9272-7e9d0e2a7da4'; post.publishedAt = new Date('2025-01-01T00:00:00Z'); - const event = new PostCreatedEvent(post); + vi.mocked(postRepository.getById).mockResolvedValue(post); + + const event = new PostCreatedEvent(post.id as number); events.emit(PostCreatedEvent.getName(), event); await nextTick(); + expect(postRepository.getById).toHaveBeenCalledWith(post.id); + const storedActivity = await globalDbSet.mock.calls[0][1]; await expect(storedActivity).toMatchFileSnapshot( './__snapshots__/publish-note-create-activity-with-mentions.json', @@ -451,7 +458,7 @@ describe('FediverseBridge', () => { author.apFollowers = new URL('https://example.com/user/foo/followers'); const post = Object.create(Post); - post.id = 'post-123'; + post.id = 111; post.author = author; post.type = PostType.Article; post.title = 'Post title'; @@ -463,11 +470,14 @@ describe('FediverseBridge', () => { post.apId = new URL('https://example.com/article/post-123'); post.uuid = 'cb1e7e92-5560-4ceb-9272-7e9d0e2a7da4'; - const event = new PostCreatedEvent(post); + vi.mocked(postRepository.getById).mockResolvedValue(post); + + const event = new PostCreatedEvent(post.id as number); events.emit(PostCreatedEvent.getName(), event); await nextTick(); + expect(postRepository.getById).toHaveBeenCalledWith(post.id); expect(sendActivity).toHaveBeenCalledOnce(); expect(context.data.globaldb.set).toHaveBeenCalled(); @@ -489,15 +499,36 @@ describe('FediverseBridge', () => { author.isInternal = false; const post = Object.create(Post); + post.id = 222; post.author = author; post.type = PostType.Note; post.content = 'Test content'; - const event = new PostCreatedEvent(post); + vi.mocked(postRepository.getById).mockResolvedValue(post); + + const event = new PostCreatedEvent(post.id as number); events.emit(PostCreatedEvent.getName(), event); await nextTick(); + expect(postRepository.getById).toHaveBeenCalledWith(post.id); + expect(sendActivity).not.toHaveBeenCalled(); + expect(context.data.globaldb.set).not.toHaveBeenCalled(); + }); + + it('should not create or send activities if post is not found on the PostCreatedEvent', async () => { + await bridge.init(); + + const sendActivity = vi.spyOn(context, 'sendActivity'); + + vi.mocked(postRepository.getById).mockResolvedValue(null); + + const event = new PostCreatedEvent(999); + events.emit(PostCreatedEvent.getName(), event); + + await nextTick(); + + expect(postRepository.getById).toHaveBeenCalledWith(999); expect(sendActivity).not.toHaveBeenCalled(); expect(context.data.globaldb.set).not.toHaveBeenCalled(); }); diff --git a/src/app.ts b/src/app.ts index 040fb9ff5..bd08e1683 100644 --- a/src/app.ts +++ b/src/app.ts @@ -117,6 +117,7 @@ import { type GCloudPubSubPushMessageQueue, } from '@/mq/gcloud-pubsub-push/mq'; import type { NotificationEventService } from '@/notification/notification-event.service'; +import { PostCreatedEvent } from '@/post/post-created.event'; import { PostDerepostedEvent } from '@/post/post-dereposted.event'; import type { PostInteractionCountsService } from '@/post/post-interaction-counts.service'; import { PostInteractionCountsUpdateRequestedEvent } from '@/post/post-interaction-counts-update-requested.event'; @@ -283,6 +284,9 @@ container container .resolve('eventSerializer') .register(PostUpdatedEvent.getName(), PostUpdatedEvent); +container + .resolve('eventSerializer') + .register(PostCreatedEvent.getName(), PostCreatedEvent); /** Fedify */ diff --git a/src/feed/feed-update.service.ts b/src/feed/feed-update.service.ts index 584797ff3..e88b8ebf5 100644 --- a/src/feed/feed-update.service.ts +++ b/src/feed/feed-update.service.ts @@ -52,7 +52,11 @@ export class FeedUpdateService { } private async handlePostCreatedEvent(event: PostCreatedEvent) { - const post = event.getPost(); + const post = await this.postRepository.getById(event.getPostId()); + + if (!post) { + return; + } if (isPublicPost(post) || isFollowersOnlyPost(post)) { await this.feedService.addPostToFeeds(post); diff --git a/src/feed/feed-update.service.unit.test.ts b/src/feed/feed-update.service.unit.test.ts index 82187f0f1..4b2db2708 100644 --- a/src/feed/feed-update.service.unit.test.ts +++ b/src/feed/feed-update.service.unit.test.ts @@ -73,11 +73,19 @@ describe('FeedUpdateService', () => { type: PostType.Article, audience: Audience.Public, }); + // biome-ignore lint/suspicious/noExplicitAny: Test helper to set post id + (post as any).id = 123; - events.emit(PostCreatedEvent.getName(), new PostCreatedEvent(post)); + vi.mocked(postRepository.getById).mockResolvedValue(post); + + events.emit( + PostCreatedEvent.getName(), + new PostCreatedEvent(post.id as number), + ); await vi.runAllTimersAsync(); + expect(postRepository.getById).toHaveBeenCalledWith(post.id); expect(feedService.addPostToFeeds).toHaveBeenCalledWith(post); expect(feedService.addPostToDiscoveryFeeds).toHaveBeenCalledWith( post, @@ -89,25 +97,55 @@ describe('FeedUpdateService', () => { type: PostType.Article, audience: Audience.FollowersOnly, }); + // biome-ignore lint/suspicious/noExplicitAny: Test helper to set post id + (post as any).id = 124; - events.emit(PostCreatedEvent.getName(), new PostCreatedEvent(post)); + vi.mocked(postRepository.getById).mockResolvedValue(post); + + events.emit( + PostCreatedEvent.getName(), + new PostCreatedEvent(post.id as number), + ); await vi.runAllTimersAsync(); + expect(postRepository.getById).toHaveBeenCalledWith(post.id); expect(feedService.addPostToFeeds).toHaveBeenCalledWith(post); expect(feedService.addPostToDiscoveryFeeds).toHaveBeenCalledWith( post, ); }); - it('should not add direct post to user nor discovery feeds when created', () => { + it('should not add direct post to user nor discovery feeds when created', async () => { const post = Post.createFromData(account, { type: PostType.Article, audience: Audience.Direct, }); + // biome-ignore lint/suspicious/noExplicitAny: Test helper to set post id + (post as any).id = 125; + + vi.mocked(postRepository.getById).mockResolvedValue(post); - events.emit(PostCreatedEvent.getName(), new PostCreatedEvent(post)); + events.emit( + PostCreatedEvent.getName(), + new PostCreatedEvent(post.id as number), + ); + + await vi.runAllTimersAsync(); + + expect(postRepository.getById).toHaveBeenCalledWith(post.id); + expect(feedService.addPostToFeeds).not.toHaveBeenCalled(); + expect(feedService.addPostToDiscoveryFeeds).not.toHaveBeenCalled(); + }); + + it('should not add post to feeds if post was deleted', async () => { + vi.mocked(postRepository.getById).mockResolvedValue(null); + + events.emit(PostCreatedEvent.getName(), new PostCreatedEvent(126)); + + await vi.runAllTimersAsync(); + expect(postRepository.getById).toHaveBeenCalledWith(126); expect(feedService.addPostToFeeds).not.toHaveBeenCalled(); expect(feedService.addPostToDiscoveryFeeds).not.toHaveBeenCalled(); }); diff --git a/src/notification/notification-event.service.ts b/src/notification/notification-event.service.ts index 7df58f744..e3d48c37d 100644 --- a/src/notification/notification-event.service.ts +++ b/src/notification/notification-event.service.ts @@ -84,14 +84,20 @@ export class NotificationEventService { } private async handlePostCreatedEvent(event: PostCreatedEvent) { - await this.notificationService.createReplyNotification(event.getPost()); + const post = await this.postRepository.getById(event.getPostId()); + + if (!post) { + return; + } + + await this.notificationService.createReplyNotification(post); // Create a mention notification for each mention in the post - const mentions = event.getPost().mentions; + const mentions = post.mentions; if (mentions && mentions.length > 0) { for (const mention of mentions) { await this.notificationService.createMentionNotification( - event.getPost(), + post, mention.id, ); } diff --git a/src/notification/notification-event.service.unit.test.ts b/src/notification/notification-event.service.unit.test.ts index df8974961..e3e6dd82a 100644 --- a/src/notification/notification-event.service.unit.test.ts +++ b/src/notification/notification-event.service.unit.test.ts @@ -130,24 +130,46 @@ describe('NotificationEventService', () => { }); describe('handling a post reply', () => { - it('should create a reply notification', () => { + it('should create a reply notification', async () => { const post = { id: 123, author: { id: 456, }, inReplyTo: 789, - } as Post; + mentions: [], + } as unknown as Post; + + vi.mocked(postRepository.getById).mockResolvedValue(post); events.emit( PostCreatedEvent.getName(), - new PostCreatedEvent(post as Post), + new PostCreatedEvent(post.id as number), ); + await new Promise(process.nextTick); + + expect(postRepository.getById).toHaveBeenCalledWith(post.id); expect( notificationService.createReplyNotification, ).toHaveBeenCalledWith(post); }); + + it('should not create a reply notification if post was deleted', async () => { + vi.mocked(postRepository.getById).mockResolvedValue(null); + + events.emit( + PostCreatedEvent.getName(), + new PostCreatedEvent(123), + ); + + await new Promise(process.nextTick); + + expect(postRepository.getById).toHaveBeenCalledWith(123); + expect( + notificationService.createReplyNotification, + ).not.toHaveBeenCalled(); + }); }); describe('handling a post deleted event', () => { @@ -225,13 +247,18 @@ describe('NotificationEventService', () => { ], } as unknown as Post; + vi.mocked(postRepository.getById).mockResolvedValue(postWithMention); + events.emit( PostCreatedEvent.getName(), - new PostCreatedEvent(postWithMention), + new PostCreatedEvent(postWithMention.id as number), ); await new Promise(process.nextTick); + expect(postRepository.getById).toHaveBeenCalledWith( + postWithMention.id, + ); expect( notificationService.createMentionNotification, ).toHaveBeenCalledWith( diff --git a/src/post/post-created.event.ts b/src/post/post-created.event.ts index e68ec07f6..3c722edf1 100644 --- a/src/post/post-created.event.ts +++ b/src/post/post-created.event.ts @@ -1,13 +1,26 @@ -import type { Post } from '@/post/post.entity'; +import type { SerializableEvent } from '@/events/event'; -export class PostCreatedEvent { - constructor(private readonly post: Post) {} +export class PostCreatedEvent implements SerializableEvent { + constructor(private readonly postId: number) {} - getPost(): Post { - return this.post; + getPostId(): number { + return this.postId; } static getName(): string { return 'post.created'; } + + toJSON(): Record { + return { + postId: this.postId, + }; + } + + static fromJSON(data: Record): PostCreatedEvent { + if (typeof data.postId !== 'number') { + throw new Error('postId must be a number'); + } + return new PostCreatedEvent(data.postId); + } } diff --git a/src/post/post-created.event.unit.test.ts b/src/post/post-created.event.unit.test.ts new file mode 100644 index 000000000..973dddbbf --- /dev/null +++ b/src/post/post-created.event.unit.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from 'vitest'; + +import { PostCreatedEvent } from '@/post/post-created.event'; + +describe('PostCreatedEvent', () => { + it('should be serializable', () => { + const event = new PostCreatedEvent(123); + + expect(event.toJSON()).toEqual({ + postId: 123, + }); + }); + + it('should be deserializable', () => { + const event = PostCreatedEvent.fromJSON({ + postId: 123, + }); + + expect(event.getPostId()).toEqual(123); + }); + + it('should throw an error if postId is not a number', () => { + expect(() => + PostCreatedEvent.fromJSON({ + postId: 'not a number', + }), + ).toThrow('postId must be a number'); + }); + + it('should throw an error if postId is missing', () => { + expect(() => PostCreatedEvent.fromJSON({})).toThrow( + 'postId must be a number', + ); + }); + + it('should return the correct event name', () => { + expect(PostCreatedEvent.getName()).toBe('post.created'); + }); +}); diff --git a/src/post/post.repository.knex.integration.test.ts b/src/post/post.repository.knex.integration.test.ts index 759f3c7d1..e5a88608e 100644 --- a/src/post/post.repository.knex.integration.test.ts +++ b/src/post/post.repository.knex.integration.test.ts @@ -582,7 +582,7 @@ describe('KnexPostRepository', () => { expect(eventsEmitSpy).toHaveBeenCalledWith( PostCreatedEvent.getName(), - new PostCreatedEvent(post), + new PostCreatedEvent(post.id as number), ); }); @@ -1442,7 +1442,7 @@ describe('KnexPostRepository', () => { expect(eventsEmitSpy).nthCalledWith( 1, PostCreatedEvent.getName(), - new PostCreatedEvent(post), + new PostCreatedEvent(post.id as number), ); }); diff --git a/src/post/post.repository.knex.ts b/src/post/post.repository.knex.ts index 652b8b1e9..305664cb9 100644 --- a/src/post/post.repository.knex.ts +++ b/src/post/post.repository.knex.ts @@ -502,7 +502,7 @@ export class KnexPostRepository { if (isNewPost) { await this.events.emitAsync( PostCreatedEvent.getName(), - new PostCreatedEvent(post), + new PostCreatedEvent(post.id as number), ); } From d6a74d2261568c90654d81cfc51794599bf1de89 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 18 Feb 2026 15:22:08 +0000 Subject: [PATCH 2/7] fix: apply biome formatting to notification-event.service.unit.test.ts Co-authored-by: Michael Barrett --- src/notification/notification-event.service.unit.test.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/notification/notification-event.service.unit.test.ts b/src/notification/notification-event.service.unit.test.ts index e3e6dd82a..cd969ef25 100644 --- a/src/notification/notification-event.service.unit.test.ts +++ b/src/notification/notification-event.service.unit.test.ts @@ -158,10 +158,7 @@ describe('NotificationEventService', () => { it('should not create a reply notification if post was deleted', async () => { vi.mocked(postRepository.getById).mockResolvedValue(null); - events.emit( - PostCreatedEvent.getName(), - new PostCreatedEvent(123), - ); + events.emit(PostCreatedEvent.getName(), new PostCreatedEvent(123)); await new Promise(process.nextTick); @@ -247,7 +244,9 @@ describe('NotificationEventService', () => { ], } as unknown as Post; - vi.mocked(postRepository.getById).mockResolvedValue(postWithMention); + vi.mocked(postRepository.getById).mockResolvedValue( + postWithMention, + ); events.emit( PostCreatedEvent.getName(), From 16b916080d23c92d6aaf81f31ff1413783d92f34 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 18 Feb 2026 15:36:44 +0000 Subject: [PATCH 3/7] refactor: make PostCreatedEvent tests consistent with other events - Add instance getName() method to PostCreatedEvent - Restructure tests to match the pattern used by other events - Add tests for getName (static and instance), getPostId, toJSON, fromJSON, and round-trip serialization - Add null validation test for fromJSON Co-authored-by: Michael Barrett --- src/post/post-created.event.ts | 4 ++ src/post/post-created.event.unit.test.ts | 80 +++++++++++++++++------- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/post/post-created.event.ts b/src/post/post-created.event.ts index 3c722edf1..c2d24dba8 100644 --- a/src/post/post-created.event.ts +++ b/src/post/post-created.event.ts @@ -7,6 +7,10 @@ export class PostCreatedEvent implements SerializableEvent { return this.postId; } + getName(): string { + return PostCreatedEvent.getName(); + } + static getName(): string { return 'post.created'; } diff --git a/src/post/post-created.event.unit.test.ts b/src/post/post-created.event.unit.test.ts index 973dddbbf..2682791a5 100644 --- a/src/post/post-created.event.unit.test.ts +++ b/src/post/post-created.event.unit.test.ts @@ -3,37 +3,75 @@ import { describe, expect, it } from 'vitest'; import { PostCreatedEvent } from '@/post/post-created.event'; describe('PostCreatedEvent', () => { - it('should be serializable', () => { - const event = new PostCreatedEvent(123); + describe('getName', () => { + it('should return the event name from static method', () => { + expect(PostCreatedEvent.getName()).toBe('post.created'); + }); + + it('should return the event name from instance method', () => { + const event = new PostCreatedEvent(123); - expect(event.toJSON()).toEqual({ - postId: 123, + expect(event.getName()).toBe('post.created'); }); }); - it('should be deserializable', () => { - const event = PostCreatedEvent.fromJSON({ - postId: 123, - }); + describe('getPostId', () => { + it('should return the post id', () => { + const event = new PostCreatedEvent(123); - expect(event.getPostId()).toEqual(123); + expect(event.getPostId()).toBe(123); + }); }); - it('should throw an error if postId is not a number', () => { - expect(() => - PostCreatedEvent.fromJSON({ - postId: 'not a number', - }), - ).toThrow('postId must be a number'); + describe('toJSON', () => { + it('should serialize the event to JSON', () => { + const event = new PostCreatedEvent(123); + + expect(event.toJSON()).toEqual({ + postId: 123, + }); + }); }); - it('should throw an error if postId is missing', () => { - expect(() => PostCreatedEvent.fromJSON({})).toThrow( - 'postId must be a number', - ); + describe('fromJSON', () => { + it('should deserialize the event from JSON', () => { + const event = PostCreatedEvent.fromJSON({ + postId: 123, + }); + + expect(event.getPostId()).toBe(123); + }); + + it('should throw an error if postId is missing', () => { + expect(() => PostCreatedEvent.fromJSON({})).toThrow( + 'postId must be a number', + ); + }); + + it('should throw an error if postId is not a number', () => { + expect(() => + PostCreatedEvent.fromJSON({ + postId: 'not a number', + }), + ).toThrow('postId must be a number'); + }); + + it('should throw an error if postId is null', () => { + expect(() => + PostCreatedEvent.fromJSON({ + postId: null, + }), + ).toThrow('postId must be a number'); + }); }); - it('should return the correct event name', () => { - expect(PostCreatedEvent.getName()).toBe('post.created'); + describe('round-trip serialization', () => { + it('should correctly serialize and deserialize', () => { + const original = new PostCreatedEvent(999); + const json = original.toJSON(); + const restored = PostCreatedEvent.fromJSON(json); + + expect(restored.getPostId()).toBe(original.getPostId()); + }); }); }); From 1294677c888fe2759a7e3df76a9776558e35f1fe Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 19 Feb 2026 09:17:49 +0000 Subject: [PATCH 4/7] fix: use consistent post ID (456) in fediverse-bridge tests - Changed post.id from 111 to 456 in Article test to follow existing pattern - Updated URL references from post-123 to 456 Co-authored-by: Michael Barrett --- .../__snapshots__/publish-post-create-activity.json | 8 ++++---- src/activitypub/fediverse-bridge.unit.test.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/activitypub/__snapshots__/publish-post-create-activity.json b/src/activitypub/__snapshots__/publish-post-create-activity.json index f770374a5..c56ddfa6e 100644 --- a/src/activitypub/__snapshots__/publish-post-create-activity.json +++ b/src/activitypub/__snapshots__/publish-post-create-activity.json @@ -31,19 +31,19 @@ "attributedTo": "https://example.com/user/foo", "cc": "https://example.com/user/foo/followers", "content": "Post content", - "id": "https://example.com/article/post-123", - "image": "https://example.com/img/post-123_feature.jpg", + "id": "https://example.com/article/456", + "image": "https://example.com/img/456_feature.jpg", "name": "Post title", "preview": { "content": "Post excerpt", - "id": "https://example.com/note/111", + "id": "https://example.com/note/456", "type": "Note", }, "published": "2025-01-12T10:30:00Z", "to": "as:Public", "type": "Article", "updated": "2025-01-12T10:30:00Z", - "url": "https://example.com/post/post-123", + "url": "https://example.com/post/456", }, "to": "as:Public", "type": "Create", diff --git a/src/activitypub/fediverse-bridge.unit.test.ts b/src/activitypub/fediverse-bridge.unit.test.ts index 5d2a8dce3..0ddfa37af 100644 --- a/src/activitypub/fediverse-bridge.unit.test.ts +++ b/src/activitypub/fediverse-bridge.unit.test.ts @@ -458,16 +458,16 @@ describe('FediverseBridge', () => { author.apFollowers = new URL('https://example.com/user/foo/followers'); const post = Object.create(Post); - post.id = 111; + post.id = 456; post.author = author; post.type = PostType.Article; post.title = 'Post title'; post.content = 'Post content'; post.excerpt = 'Post excerpt'; - post.imageUrl = new URL('https://example.com/img/post-123_feature.jpg'); + post.imageUrl = new URL('https://example.com/img/456_feature.jpg'); post.publishedAt = new Date('2025-01-12T10:30:00Z'); - post.url = new URL('https://example.com/post/post-123'); - post.apId = new URL('https://example.com/article/post-123'); + post.url = new URL('https://example.com/post/456'); + post.apId = new URL('https://example.com/article/456'); post.uuid = 'cb1e7e92-5560-4ceb-9272-7e9d0e2a7da4'; vi.mocked(postRepository.getById).mockResolvedValue(post); From 512c080125bce28905dc979560fd9833a32de826 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 19 Feb 2026 09:18:40 +0000 Subject: [PATCH 5/7] fix: use 456 for post ID in remaining fediverse-bridge tests - Updated external accounts test to use post.id = 456 - Updated post not found test to use 456 Co-authored-by: Michael Barrett --- src/activitypub/fediverse-bridge.unit.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/activitypub/fediverse-bridge.unit.test.ts b/src/activitypub/fediverse-bridge.unit.test.ts index 0ddfa37af..3f026955a 100644 --- a/src/activitypub/fediverse-bridge.unit.test.ts +++ b/src/activitypub/fediverse-bridge.unit.test.ts @@ -499,7 +499,7 @@ describe('FediverseBridge', () => { author.isInternal = false; const post = Object.create(Post); - post.id = 222; + post.id = 456; post.author = author; post.type = PostType.Note; post.content = 'Test content'; @@ -523,12 +523,12 @@ describe('FediverseBridge', () => { vi.mocked(postRepository.getById).mockResolvedValue(null); - const event = new PostCreatedEvent(999); + const event = new PostCreatedEvent(456); events.emit(PostCreatedEvent.getName(), event); await nextTick(); - expect(postRepository.getById).toHaveBeenCalledWith(999); + expect(postRepository.getById).toHaveBeenCalledWith(456); expect(sendActivity).not.toHaveBeenCalled(); expect(context.data.globaldb.set).not.toHaveBeenCalled(); }); From 7dcabe0c31dab2e69c9c624494f1d23f287a99e5 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 19 Feb 2026 09:19:18 +0000 Subject: [PATCH 6/7] fix: use 123 for post ID in 'post not found' test Follow existing pattern where 123 is used for IDs in not-found scenarios Co-authored-by: Michael Barrett --- src/activitypub/fediverse-bridge.unit.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/activitypub/fediverse-bridge.unit.test.ts b/src/activitypub/fediverse-bridge.unit.test.ts index 3f026955a..f076e6183 100644 --- a/src/activitypub/fediverse-bridge.unit.test.ts +++ b/src/activitypub/fediverse-bridge.unit.test.ts @@ -523,12 +523,12 @@ describe('FediverseBridge', () => { vi.mocked(postRepository.getById).mockResolvedValue(null); - const event = new PostCreatedEvent(456); + const event = new PostCreatedEvent(123); events.emit(PostCreatedEvent.getName(), event); await nextTick(); - expect(postRepository.getById).toHaveBeenCalledWith(456); + expect(postRepository.getById).toHaveBeenCalledWith(123); expect(sendActivity).not.toHaveBeenCalled(); expect(context.data.globaldb.set).not.toHaveBeenCalled(); }); From ca8929d491679ba7b3111b70cd30b5d24fa70e63 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 19 Feb 2026 09:20:00 +0000 Subject: [PATCH 7/7] fix: use consistent post ID (123) in feed-update.service tests All PostCreatedEvent tests now use 123 for the post ID Co-authored-by: Michael Barrett --- src/feed/feed-update.service.unit.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/feed/feed-update.service.unit.test.ts b/src/feed/feed-update.service.unit.test.ts index 4b2db2708..4ec090578 100644 --- a/src/feed/feed-update.service.unit.test.ts +++ b/src/feed/feed-update.service.unit.test.ts @@ -98,7 +98,7 @@ describe('FeedUpdateService', () => { audience: Audience.FollowersOnly, }); // biome-ignore lint/suspicious/noExplicitAny: Test helper to set post id - (post as any).id = 124; + (post as any).id = 123; vi.mocked(postRepository.getById).mockResolvedValue(post); @@ -122,7 +122,7 @@ describe('FeedUpdateService', () => { audience: Audience.Direct, }); // biome-ignore lint/suspicious/noExplicitAny: Test helper to set post id - (post as any).id = 125; + (post as any).id = 123; vi.mocked(postRepository.getById).mockResolvedValue(post); @@ -141,11 +141,11 @@ describe('FeedUpdateService', () => { it('should not add post to feeds if post was deleted', async () => { vi.mocked(postRepository.getById).mockResolvedValue(null); - events.emit(PostCreatedEvent.getName(), new PostCreatedEvent(126)); + events.emit(PostCreatedEvent.getName(), new PostCreatedEvent(123)); await vi.runAllTimersAsync(); - expect(postRepository.getById).toHaveBeenCalledWith(126); + expect(postRepository.getById).toHaveBeenCalledWith(123); expect(feedService.addPostToFeeds).not.toHaveBeenCalled(); expect(feedService.addPostToDiscoveryFeeds).not.toHaveBeenCalled(); });