Skip to content

Commit e94941a

Browse files
committed
chore(web): re-add PlannerSidebar tests
1 parent e2cee8e commit e94941a

3 files changed

Lines changed: 123 additions & 54 deletions

File tree

docs/development/testing-playbook.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ E2E workflow (`test-e2e.yml`) is separate and runs on pull requests to `main` vi
4747
- `bun run test:core` uses `bun test` with a small compatibility preload for the core BSON mock setup.
4848
- `bun run test:web` runs `bun test --cwd packages/web` directly. Web tests should be isolated enough to run in one Bun process without batching.
4949
- `bun run test:backend` and `bun run test:scripts` intentionally retain the existing Jest harness while their hoist-heavy module-mocking patterns are migrated.
50-
- `bun run test:<project>` is the stable CI-facing entrypoint for every package; the root dispatcher chooses the correct runner per project.
5150

5251
## Retained Jest Layout
5352

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { render, screen } from "@testing-library/react";
2+
import dayjs from "@core/util/date/dayjs";
3+
import { describe, expect, it, mock } from "bun:test";
4+
import { createPlannerSidebar } from "./PlannerSidebar";
5+
6+
const PlannerSidebar = createPlannerSidebar({
7+
PlannerAccountSummary: () => <div>Account summary</div>,
8+
PlannerMonthPicker: () => <div>Calendar picker</div>,
9+
PlannerSidebarActions: () => <div>Sidebar actions</div>,
10+
ShortcutsOverlay: () => null,
11+
SomedayEventSections: () => <div>Week and month planning buckets</div>,
12+
});
13+
14+
const sidebarProps = {
15+
calendarDate: dayjs("2026-05-12"),
16+
isShortcutsOpen: false,
17+
onCloseShortcuts: mock(),
18+
onToggleShortcuts: mock(),
19+
onSelectDate: mock(),
20+
shortcutSections: [],
21+
viewEnd: dayjs("2026-05-16"),
22+
viewStart: dayjs("2026-05-10"),
23+
};
24+
25+
describe("PlannerSidebar", () => {
26+
it("shows Someday event sections by default", () => {
27+
render(<PlannerSidebar {...sidebarProps} />);
28+
29+
expect(screen.getByRole("region", { name: "Someday events" })).toBeTruthy();
30+
expect(screen.getByText("Week and month planning buckets")).toBeTruthy();
31+
});
32+
33+
it("hides Someday event sections when requested", () => {
34+
render(
35+
<PlannerSidebar {...sidebarProps} showSomedayEventSections={false} />,
36+
);
37+
38+
expect(screen.queryByRole("region", { name: "Someday events" })).toBeNull();
39+
expect(screen.queryByText("Week and month planning buckets")).toBeNull();
40+
expect(screen.getByText("Calendar picker")).toBeTruthy();
41+
expect(screen.getByText("Account summary")).toBeTruthy();
42+
expect(screen.getByText("Sidebar actions")).toBeTruthy();
43+
});
44+
});
Lines changed: 79 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { type HTMLAttributes } from "react";
22
import { type Dayjs } from "@core/util/date/dayjs";
33
import { ID_SIDEBAR } from "@web/common/constants/web.constants";
4-
import { type ShortcutOverlaySection } from "@web/components/Shortcuts/ShortcutOverlay/ShortcutsOverlay";
4+
import {
5+
ShortcutsOverlay,
6+
type ShortcutOverlaySection,
7+
} from "@web/components/Shortcuts/ShortcutOverlay/ShortcutsOverlay";
58
import { PlannerAccountSummary } from "./PlannerAccountSummary/PlannerAccountSummary";
69
import { PlannerMonthPicker } from "./PlannerMonthPicker/PlannerMonthPicker";
710
import { PlannerSidebarActions } from "./PlannerSidebarActions/PlannerSidebarActions";
8-
import { ShortcutsOverlay } from "./ShortcutsOverlay/ShortcutsOverlay";
911
import { SomedayEventSections } from "./SomedayEventSections/SomedayEventSections";
1012

11-
interface Props extends HTMLAttributes<HTMLDivElement> {
13+
export interface PlannerSidebarProps extends HTMLAttributes<HTMLDivElement> {
1214
calendarDate: Dayjs;
1315
monthsShown?: number;
1416
isShortcutsOpen: boolean;
@@ -22,58 +24,82 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
2224
viewStart: Dayjs;
2325
}
2426

25-
export function PlannerSidebar({
26-
calendarDate,
27-
monthsShown = 1,
28-
isShortcutsOpen,
29-
onCloseShortcuts,
30-
onToggleShortcuts,
31-
onSelectDate,
32-
onToggleSidebar,
33-
shortcutSections,
34-
showSomedayEventSections = true,
35-
viewEnd,
36-
viewStart,
37-
...props
38-
}: Props) {
39-
return (
40-
<aside
41-
{...props}
42-
aria-label="Planner sidebar"
43-
className="relative flex h-full w-[285px] min-w-[285px] flex-col overflow-hidden border-border-primary border-r bg-panel-bg pt-5 text-panel-text"
44-
id={ID_SIDEBAR}
45-
>
46-
<div className="flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto px-4 pb-5 [scrollbar-gutter:stable]">
47-
<PlannerMonthPicker
48-
monthsShown={monthsShown}
49-
onSelectDate={onSelectDate}
50-
onToggleSidebar={onToggleSidebar}
51-
selectedDate={calendarDate}
52-
/>
27+
type PlannerSidebarDependencies = {
28+
PlannerAccountSummary: typeof PlannerAccountSummary;
29+
PlannerMonthPicker: typeof PlannerMonthPicker;
30+
PlannerSidebarActions: typeof PlannerSidebarActions;
31+
ShortcutsOverlay: typeof ShortcutsOverlay;
32+
SomedayEventSections: typeof SomedayEventSections;
33+
};
34+
35+
export function createPlannerSidebar({
36+
PlannerAccountSummary: PlannerAccountSummaryComponent,
37+
PlannerMonthPicker: PlannerMonthPickerComponent,
38+
PlannerSidebarActions: PlannerSidebarActionsComponent,
39+
ShortcutsOverlay: ShortcutsOverlayComponent,
40+
SomedayEventSections: SomedayEventSectionsComponent,
41+
}: PlannerSidebarDependencies) {
42+
return function PlannerSidebar({
43+
calendarDate,
44+
monthsShown = 1,
45+
isShortcutsOpen,
46+
onCloseShortcuts,
47+
onToggleShortcuts,
48+
onSelectDate,
49+
onToggleSidebar,
50+
shortcutSections,
51+
showSomedayEventSections = true,
52+
viewEnd,
53+
viewStart,
54+
...props
55+
}: PlannerSidebarProps) {
56+
return (
57+
<aside
58+
{...props}
59+
aria-label="Planner sidebar"
60+
className="relative flex h-full w-[285px] min-w-[285px] flex-col overflow-hidden border-border-primary border-r bg-panel-bg pt-5 text-panel-text"
61+
id={ID_SIDEBAR}
62+
>
63+
<div className="flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto px-4 pb-5 [scrollbar-gutter:stable]">
64+
<PlannerMonthPickerComponent
65+
monthsShown={monthsShown}
66+
onSelectDate={onSelectDate}
67+
onToggleSidebar={onToggleSidebar}
68+
selectedDate={calendarDate}
69+
/>
5370

54-
{showSomedayEventSections ? (
55-
<section aria-label="Someday events">
56-
<SomedayEventSections
57-
calendarDate={calendarDate}
58-
viewEnd={viewEnd}
59-
viewStart={viewStart}
60-
/>
61-
</section>
62-
) : null}
63-
</div>
71+
{showSomedayEventSections ? (
72+
<section aria-label="Someday events">
73+
<SomedayEventSectionsComponent
74+
calendarDate={calendarDate}
75+
viewEnd={viewEnd}
76+
viewStart={viewStart}
77+
/>
78+
</section>
79+
) : null}
80+
</div>
6481

65-
<PlannerAccountSummary />
82+
<PlannerAccountSummaryComponent />
6683

67-
<PlannerSidebarActions
68-
isShortcutsOpen={isShortcutsOpen}
69-
onToggleShortcuts={onToggleShortcuts}
70-
/>
84+
<PlannerSidebarActionsComponent
85+
isShortcutsOpen={isShortcutsOpen}
86+
onToggleShortcuts={onToggleShortcuts}
87+
/>
7188

72-
<ShortcutsOverlay
73-
isOpen={isShortcutsOpen}
74-
onClose={onCloseShortcuts}
75-
sections={shortcutSections}
76-
/>
77-
</aside>
78-
);
89+
<ShortcutsOverlayComponent
90+
isOpen={isShortcutsOpen}
91+
onClose={onCloseShortcuts}
92+
sections={shortcutSections}
93+
/>
94+
</aside>
95+
);
96+
};
7997
}
98+
99+
export const PlannerSidebar = createPlannerSidebar({
100+
PlannerAccountSummary,
101+
PlannerMonthPicker,
102+
PlannerSidebarActions,
103+
ShortcutsOverlay,
104+
SomedayEventSections,
105+
});

0 commit comments

Comments
 (0)