Skip to content

Commit 9d0dd6f

Browse files
fix: hide new quest badge for users created less than 24 hours ago (#5880)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a3d1ceb commit 9d0dd6f

File tree

2 files changed

+83
-28
lines changed

2 files changed

+83
-28
lines changed

packages/shared/src/components/quest/QuestButton.spec.tsx

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { act, render, screen, waitFor, within } from '@testing-library/react';
55
import userEvent from '@testing-library/user-event';
66
import type { ReactElement, ReactNode } from 'react';
77
import { TestBootProvider } from '../../../__tests__/helpers/boot';
8+
import loggedUser from '../../../__tests__/fixture/loggedUser';
89
import type { QuestDashboard } from '../../graphql/quests';
910
import {
1011
QuestRewardType,
@@ -231,17 +232,25 @@ const questDashboard = {
231232
milestone: [],
232233
};
233234

234-
const renderComponent = (
235+
const renderComponent = ({
235236
optOutLevelSystem = false,
236-
client: QueryClient = new QueryClient(),
237+
client = new QueryClient(),
237238
compact = false,
238239
log = {},
239-
) =>
240+
auth = {},
241+
}: {
242+
optOutLevelSystem?: boolean;
243+
client?: QueryClient;
244+
compact?: boolean;
245+
log?: Record<string, unknown>;
246+
auth?: Record<string, unknown>;
247+
} = {}) =>
240248
render(
241249
<TestBootProvider
242250
client={client}
243251
settings={{ optOutLevelSystem }}
244252
log={log}
253+
auth={auth}
245254
>
246255
<QuestButton compact={compact} />
247256
</TestBootProvider>,
@@ -276,7 +285,7 @@ beforeEach(() => {
276285

277286
describe('QuestButton', () => {
278287
it('should show level progress and xp rewards when levels are enabled', async () => {
279-
renderComponent(false);
288+
renderComponent();
280289

281290
const button = screen.getByRole('button', {
282291
name: /Quests, level 7, 63% progress/i,
@@ -294,7 +303,7 @@ describe('QuestButton', () => {
294303
});
295304

296305
it('should render a smaller trigger when compact', () => {
297-
renderComponent(false, new QueryClient(), true);
306+
renderComponent({ client: new QueryClient(), compact: true });
298307

299308
const button = screen.getByRole('button', {
300309
name: /Quests, level 7, 63% progress/i,
@@ -317,7 +326,7 @@ describe('QuestButton', () => {
317326
isError: false,
318327
});
319328

320-
renderComponent(false);
329+
renderComponent();
321330

322331
expect(
323332
screen.getByRole('button', {
@@ -327,7 +336,7 @@ describe('QuestButton', () => {
327336
});
328337

329338
it('should hide level progress and xp rewards when levels are disabled', async () => {
330-
renderComponent(true);
339+
renderComponent({ optOutLevelSystem: true });
331340

332341
const button = screen.getByRole('button', { name: 'Quests' });
333342

@@ -343,7 +352,7 @@ describe('QuestButton', () => {
343352
});
344353

345354
it('should route feed-based quests back to the main feed', async () => {
346-
renderComponent(false);
355+
renderComponent();
347356

348357
await userEvent.click(
349358
screen.getByRole('button', {
@@ -396,7 +405,7 @@ describe('QuestButton', () => {
396405
isError: false,
397406
});
398407

399-
renderComponent(false);
408+
renderComponent();
400409

401410
await userEvent.click(
402411
screen.getByRole('button', {
@@ -444,7 +453,7 @@ describe('QuestButton', () => {
444453
isError: false,
445454
});
446455

447-
renderComponent(false);
456+
renderComponent();
448457

449458
await userEvent.click(
450459
screen.getByRole('button', {
@@ -490,7 +499,7 @@ describe('QuestButton', () => {
490499
isError: false,
491500
});
492501

493-
renderComponent(false);
502+
renderComponent();
494503

495504
await userEvent.click(
496505
screen.getByRole('button', {
@@ -534,7 +543,7 @@ describe('QuestButton', () => {
534543
isError: false,
535544
});
536545

537-
renderComponent(false);
546+
renderComponent();
538547

539548
await userEvent.click(
540549
screen.getByRole('button', {
@@ -578,7 +587,7 @@ describe('QuestButton', () => {
578587
isError: false,
579588
});
580589

581-
renderComponent(false);
590+
renderComponent();
582591

583592
await userEvent.click(
584593
screen.getByRole('button', {
@@ -598,7 +607,7 @@ describe('QuestButton', () => {
598607
it('should log when opening the quest dropdown', async () => {
599608
const logEvent = jest.fn();
600609

601-
renderComponent(false, new QueryClient(), false, { logEvent });
610+
renderComponent({ log: { logEvent } });
602611

603612
await userEvent.click(
604613
screen.getByRole('button', {
@@ -613,7 +622,7 @@ describe('QuestButton', () => {
613622
});
614623

615624
it('should not show a new indicator when the dashboard reports no new quest rotations', async () => {
616-
renderComponent(false);
625+
renderComponent();
617626

618627
expect(
619628
screen.getByRole('button', {
@@ -627,6 +636,10 @@ describe('QuestButton', () => {
627636

628637
it('should show and clear the new quest indicator after a quest rotation update', async () => {
629638
const client = new QueryClient();
639+
const establishedUser = {
640+
...loggedUser,
641+
createdAt: new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString(),
642+
};
630643
const subscriptions: Array<{
631644
query: string;
632645
next?: () => unknown;
@@ -666,7 +679,7 @@ describe('QuestButton', () => {
666679
);
667680

668681
const view = render(
669-
<TestBootProvider client={client}>
682+
<TestBootProvider client={client} auth={{ user: establishedUser }}>
670683
<QuestButton />
671684
</TestBootProvider>,
672685
);
@@ -698,7 +711,7 @@ describe('QuestButton', () => {
698711
?.next?.();
699712

700713
view.rerender(
701-
<TestBootProvider client={client}>
714+
<TestBootProvider client={client} auth={{ user: establishedUser }}>
702715
<QuestButton />
703716
</TestBootProvider>,
704717
);
@@ -727,7 +740,7 @@ describe('QuestButton', () => {
727740
});
728741

729742
view.rerender(
730-
<TestBootProvider client={client}>
743+
<TestBootProvider client={client} auth={{ user: establishedUser }}>
731744
<QuestButton />
732745
</TestBootProvider>,
733746
);
@@ -921,7 +934,7 @@ describe('QuestButton', () => {
921934
});
922935

923936
it('should stay open when the page scrolls', async () => {
924-
renderComponent(false);
937+
renderComponent();
925938

926939
await userEvent.click(
927940
screen.getByRole('button', {
@@ -969,7 +982,7 @@ describe('QuestButton', () => {
969982
isError: false,
970983
});
971984

972-
renderComponent(false);
985+
renderComponent();
973986
await userEvent.click(
974987
screen.getByRole('button', {
975988
name: /Quests, level 7, 63% progress/i,
@@ -1029,7 +1042,7 @@ describe('QuestButton', () => {
10291042
isError: false,
10301043
});
10311044

1032-
renderComponent(false);
1045+
renderComponent();
10331046

10341047
await userEvent.click(
10351048
screen.getByRole('button', {
@@ -1123,7 +1136,7 @@ describe('QuestButton', () => {
11231136
variables: undefined,
11241137
});
11251138

1126-
renderComponent(false);
1139+
renderComponent();
11271140

11281141
act(() => {
11291142
screen
@@ -1265,7 +1278,7 @@ describe('QuestButton', () => {
12651278
variables: undefined,
12661279
});
12671280

1268-
renderComponent(false);
1281+
renderComponent();
12691282

12701283
act(() => {
12711284
screen
@@ -1338,7 +1351,7 @@ describe('QuestButton', () => {
13381351
isError: false,
13391352
});
13401353

1341-
renderComponent(false);
1354+
renderComponent();
13421355

13431356
await userEvent.click(
13441357
screen.getByRole('button', {
@@ -1388,7 +1401,7 @@ describe('QuestButton', () => {
13881401
isError: false,
13891402
});
13901403

1391-
renderComponent(false);
1404+
renderComponent();
13921405

13931406
await userEvent.click(
13941407
screen.getByRole('button', {
@@ -1435,7 +1448,7 @@ describe('QuestButton', () => {
14351448
isError: false,
14361449
});
14371450

1438-
renderComponent(false);
1451+
renderComponent();
14391452

14401453
await userEvent.click(
14411454
screen.getByRole('button', {
@@ -1473,7 +1486,7 @@ describe('QuestButton', () => {
14731486
},
14741487
);
14751488

1476-
renderComponent(false, client);
1489+
renderComponent({ client });
14771490

14781491
expect(
14791492
Array.from(
@@ -1501,4 +1514,42 @@ describe('QuestButton', () => {
15011514
exact: true,
15021515
});
15031516
});
1517+
1518+
it('should not show new indicator for users created less than 24 hours ago', () => {
1519+
mockUseQuestDashboard.mockReturnValue({
1520+
data: { ...questDashboard, hasNewQuestRotations: true },
1521+
isPending: false,
1522+
isError: false,
1523+
});
1524+
1525+
const newUser = {
1526+
...loggedUser,
1527+
createdAt: new Date(Date.now() - 12 * 60 * 60 * 1000).toISOString(),
1528+
};
1529+
1530+
renderComponent({ auth: { user: newUser } });
1531+
1532+
expect(
1533+
screen.queryByTestId('quest-button-new-indicator'),
1534+
).not.toBeInTheDocument();
1535+
});
1536+
1537+
it('should show new indicator for users created more than 24 hours ago', () => {
1538+
mockUseQuestDashboard.mockReturnValue({
1539+
data: { ...questDashboard, hasNewQuestRotations: true },
1540+
isPending: false,
1541+
isError: false,
1542+
});
1543+
1544+
const establishedUser = {
1545+
...loggedUser,
1546+
createdAt: new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString(),
1547+
};
1548+
1549+
renderComponent({ auth: { user: establishedUser } });
1550+
1551+
expect(
1552+
screen.getByTestId('quest-button-new-indicator'),
1553+
).toBeInTheDocument();
1554+
});
15041555
});

packages/shared/src/components/quest/QuestButton.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1377,7 +1377,11 @@ export const QuestButton = ({
13771377
const triggerVisualClassName = compact ? 'size-8' : 'size-10';
13781378
const triggerLevelClassName = compact ? 'typo-caption2' : 'typo-caption1';
13791379
const [isOpen, setIsOpen] = useState(false);
1380-
const hasNewQuestRotations = data?.hasNewQuestRotations ?? false;
1380+
const isAccountOlderThan24Hours =
1381+
!!user?.createdAt &&
1382+
Date.now() - new Date(user.createdAt).getTime() > 24 * 60 * 60 * 1000;
1383+
const hasNewQuestRotations =
1384+
(data?.hasNewQuestRotations ?? false) && isAccountOlderThan24Hours;
13811385
const claimedStampRotationIdSet = useMemo(
13821386
() => new Set(claimedStampRotationIds),
13831387
[claimedStampRotationIds],

0 commit comments

Comments
 (0)