From a94600449d54a972eee0d229d84525b2e6922727 Mon Sep 17 00:00:00 2001 From: Brad Bazemore Date: Wed, 14 Jan 2026 14:57:06 -0500 Subject: [PATCH] fix: wait for profile to load before showing community toast The toast was incorrectly showing for users with forum_username because: 1. Component mounts with profile still loading (undefined) 2. undefined is falsy, so the guard passed through 3. Toast scheduled before profile actually loaded Fix: Explicitly check for undefined and wait until profile loads. Added tests for profile loading race condition scenarios. Co-Authored-By: Claude Opus 4.5 --- src/hooks/useCommunityPromoToast.test.ts | 59 ++++++++++++++++++++++++ src/hooks/useCommunityPromoToast.ts | 6 +++ 2 files changed, 65 insertions(+) diff --git a/src/hooks/useCommunityPromoToast.test.ts b/src/hooks/useCommunityPromoToast.test.ts index 9a4e7fd..febfd2d 100644 --- a/src/hooks/useCommunityPromoToast.test.ts +++ b/src/hooks/useCommunityPromoToast.test.ts @@ -83,6 +83,65 @@ describe('useCommunityPromoToast', () => { expect(mockToast).not.toHaveBeenCalled(); }); + it('does not show toast when profile is still loading (forumUsername undefined)', () => { + renderHook(() => + useCommunityPromoToast({ + userCreatedAt: getDateDaysAgo(5), + forumUsername: undefined, // Profile hasn't loaded yet + isAuthenticated: true, + }) + ); + + vi.advanceTimersByTime(2000); + expect(mockToast).not.toHaveBeenCalled(); + }); + + it('shows toast only after profile loads with null forum_username', () => { + const { rerender } = renderHook( + ({ forumUsername }) => + useCommunityPromoToast({ + userCreatedAt: getDateDaysAgo(5), + forumUsername, + isAuthenticated: true, + }), + { + initialProps: { forumUsername: undefined as string | null | undefined }, + } + ); + + // Profile still loading - should not show toast + vi.advanceTimersByTime(2000); + expect(mockToast).not.toHaveBeenCalled(); + + // Profile loads with null forum_username - should show toast + rerender({ forumUsername: null }); + vi.advanceTimersByTime(2000); + expect(mockToast).toHaveBeenCalledTimes(1); + }); + + it('does not show toast when profile loads with existing forum_username', () => { + const { rerender } = renderHook( + ({ forumUsername }) => + useCommunityPromoToast({ + userCreatedAt: getDateDaysAgo(5), + forumUsername, + isAuthenticated: true, + }), + { + initialProps: { forumUsername: undefined as string | null | undefined }, + } + ); + + // Profile still loading - should not show toast + vi.advanceTimersByTime(2000); + expect(mockToast).not.toHaveBeenCalled(); + + // Profile loads with existing forum_username - should NOT show toast + rerender({ forumUsername: 'existingUser' }); + vi.advanceTimersByTime(2000); + expect(mockToast).not.toHaveBeenCalled(); + }); + it('does not show toast when less than 3 days since signup', () => { renderHook(() => useCommunityPromoToast({ diff --git a/src/hooks/useCommunityPromoToast.ts b/src/hooks/useCommunityPromoToast.ts index 8a6b7f2..90f18bc 100644 --- a/src/hooks/useCommunityPromoToast.ts +++ b/src/hooks/useCommunityPromoToast.ts @@ -33,6 +33,12 @@ export function useCommunityPromoToast({ return; } + // Guard: Wait for profile to load before deciding + // undefined = profile still loading, null = profile loaded but no forum username + if (forumUsername === undefined) { + return; + } + // Guard: User has already authenticated with Discourse if (forumUsername) { return;