diff --git a/packages/feeds-client/__integration-tests__/stories.test.ts b/packages/feeds-client/__integration-tests__/stories.test.ts index db08bb9e..9f49a18c 100644 --- a/packages/feeds-client/__integration-tests__/stories.test.ts +++ b/packages/feeds-client/__integration-tests__/stories.test.ts @@ -3,6 +3,7 @@ import { createTestClient, createTestTokenGenerator, getTestUser, + markWatchedAndSync, waitForEvent, } from './utils'; @@ -72,16 +73,10 @@ describe('Stories Feed', () => { it(`user 2 marks the story as watched`, async () => { await user2StoriesFeed.getOrCreate({ watch: true }); - user2StoriesFeed.on('feeds.stories_feed.updated', (_) => {}); - await Promise.all([ - waitForEvent(user2StoriesFeed, 'feeds.stories_feed.updated'), - user2StoriesFeed.markActivity({ - mark_watched: [ - user2StoriesFeed.state.getLatestValue().aggregated_activities![0] - .activities![0].id, - ], - }), + await markWatchedAndSync(user2StoriesFeed, [ + user2StoriesFeed.state.getLatestValue().aggregated_activities![0] + .activities![0].id, ]); expect( @@ -129,11 +124,8 @@ describe('Stories Feed', () => { } }); - await Promise.all([ - waitForEvent(feed, 'feeds.stories_feed.updated'), - feed.markActivity({ - mark_watched: [feed.state.getLatestValue().activities![0].id], - }), + await markWatchedAndSync(feed, [ + feed.state.getLatestValue().activities![0].id, ]); expect(feed.state.getLatestValue().activities![0].is_watched).toBe(true); diff --git a/packages/feeds-client/__integration-tests__/utils.ts b/packages/feeds-client/__integration-tests__/utils.ts index 7051e771..1d3b286d 100644 --- a/packages/feeds-client/__integration-tests__/utils.ts +++ b/packages/feeds-client/__integration-tests__/utils.ts @@ -90,6 +90,7 @@ const WAIT_FOR_EVENT_MS = 30_000; export const waitForEvent = ( client: FeedsClient | Feed, type: FeedsEvent['type'] | WSEvent['type'], + timeoutMs = WAIT_FOR_EVENT_MS, ) => { return new Promise((resolve, reject) => { const listener = (e: FeedsEvent | WSEvent) => { @@ -103,9 +104,32 @@ export const waitForEvent = ( // @ts-expect-error client expects WSEvents client.off(type, listener); reject(new Error(`Event not received: ${type}`)); - }, WAIT_FOR_EVENT_MS); + }, timeoutMs); // @ts-expect-error client expects WSEvents client.on(type, listener); }); }; + +/** + * Marks activities as watched and prefers the realtime + * `feeds.stories_feed.updated` event. If that event is dropped by the API + * (known intermittent flake), falls back to reloading the feed. + */ +export const markWatchedAndSync = async ( + feed: Feed, + activityIds: string[], + eventTimeoutMs = 5_000, +) => { + const eventPromise = waitForEvent( + feed, + 'feeds.stories_feed.updated', + eventTimeoutMs, + ); + await feed.markActivity({ mark_watched: activityIds }); + try { + await eventPromise; + } catch { + await feed.getOrCreate({ watch: true }); + } +};