Skip to content

Commit f28fa08

Browse files
:recycle refactor(day-view): use single floating context(#1360)
* :recycle refactor(day-view): use single floating context - Updated import paths for hooks and context providers in Day view components. - Removed unused `useMaxAgendaZIndex` hook and its associated tests. - Introduced `useOpenAgendaEventPreview` and `useOpenEventContextMenu` hooks for handling event previews and context menus. - Modified `useDateInView` and `useDateNavigation` hooks to use the new context structure. - Enhanced `DayViewContent` to include new components for event previews and context menus. - Updated event form handling in `useOpenEventForm` to improve cursor positioning and event data management. - Refactored tests to align with new import paths and structure. - Cleaned up unused imports and variables across various files. * :recycle refactor(useOpenEventForm): remove unused parameters from tests
1 parent a273dd9 commit f28fa08

File tree

101 files changed

+1599
-1941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1599
-1941
lines changed

AGENTS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Always reference these instructions first and fallback to search or bash command
66

77
1. When working in `packages/web`, follow React best practices and idiomatic patterns
88
2. When working in `packages/backend` or `packages/core`, follow Node.js best practices and idiomatic patterns
9+
3. Always use module aliased paths for imports when importing Compass modules.
910

1011
## Working Effectively
1112

@@ -19,7 +20,7 @@ Always reference these instructions first and fallback to search or bash command
1920

2021
- **CRITICAL**: The backend requires external service credentials (Google OAuth, Supertokens, MongoDB) to run properly
2122
- **Web Development** (RECOMMENDED for coding):
22-
- `yarn dev:web` - Takes ~10 seconds to build. Serves on http://localhost:9080/
23+
- `yarn dev:web` - Takes ~10 seconds to build. Serves on <http://localhost:9080/>
2324
- Frontend works standalone without backend services
2425
- **Backend Development** (requires full setup):
2526
- `yarn dev:backend` - Fails without proper .env configuration
@@ -31,6 +32,8 @@ Always reference these instructions first and fallback to search or bash command
3132

3233
- Write tests the way a user would use the application by using the DOM and user interactions with `@testing-library/user-event` rather than internal implementation details of React components.
3334
- Do NOT use `data-` attributes or CSS selectors to locate elements. Use semantic locators and roles instead.
35+
- When writing tests, avoid mocking as much as possible.
36+
- Where mocking is inevitable, use spies to sub out specific module functions before attempting to mock the whole module.
3437

3538
#### Running Tests
3639

@@ -141,7 +144,7 @@ TZ=Etc/UTC
141144
1. **Start Development**: `yarn dev:web` (frontend only, always works)
142145
2. **Run Tests**: `yarn test:core && yarn test:web` (skips problematic backend tests)
143146
3. **Check Code Style**: `yarn prettier . --write`
144-
4. **Manual Validation**: Open http://localhost:9080/ and verify login page loads
147+
4. **Manual Validation**: Open <http://localhost:9080/> and verify login page loads
145148

146149
### Styling
147150

packages/web/src/auth/UserProvider.test.tsx

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { rest } from "msw";
33
import { usePostHog } from "posthog-js/react";
44
import { act } from "react";
55
import "@testing-library/jest-dom";
6-
import { render, waitFor } from "@testing-library/react";
7-
import { Status } from "../../../core/src/errors/status.codes";
8-
import { server } from "../__tests__/__mocks__/server/mock.server";
9-
import { ENV_WEB } from "../common/constants/env.constants";
10-
import { UserProvider } from "./UserProvider";
6+
import { render, screen, waitFor } from "@testing-library/react";
7+
import { Status } from "@core/errors/status.codes";
8+
import { server } from "@web/__tests__/__mocks__/server/mock.server";
9+
import { UserProvider } from "@web/auth/UserProvider";
10+
import { UserApi } from "@web/common/apis/user.api";
11+
import { ENV_WEB } from "@web/common/constants/env.constants";
1112

1213
// Mock PostHog
1314
jest.mock("posthog-js/react");
@@ -35,15 +36,17 @@ describe("UserProvider", () => {
3536
identify: mockIdentify,
3637
} as any);
3738

38-
await act(() =>
39-
render(
40-
<UserProvider>
41-
<div>Test Child</div>
42-
</UserProvider>,
43-
),
39+
render(
40+
<UserProvider>
41+
<div>Test Child</div>
42+
</UserProvider>,
4443
);
4544

4645
// Wait for async data fetch and PostHog identify to be called
46+
await waitFor(() => {
47+
expect(screen.getByText("Test Child")).toBeInTheDocument();
48+
});
49+
4750
expect(mockIdentify).toHaveBeenCalledWith(testEmail, {
4851
email: testEmail,
4952
userId: testUserId,
@@ -57,14 +60,16 @@ describe("UserProvider", () => {
5760
// Mock PostHog as disabled (returns undefined/null)
5861
mockUsePostHog.mockReturnValue(undefined as any);
5962

60-
await act(() =>
61-
render(
62-
<UserProvider>
63-
<div>Test Child</div>
64-
</UserProvider>,
65-
),
63+
render(
64+
<UserProvider>
65+
<div>Test Child</div>
66+
</UserProvider>,
6667
);
6768

69+
await waitFor(() => {
70+
expect(screen.getByText("Test Child")).toBeInTheDocument();
71+
});
72+
6873
// Verify identify was never called
6974
expect(mockIdentify).not.toHaveBeenCalled();
7075
});
@@ -84,19 +89,22 @@ describe("UserProvider", () => {
8489
identify: mockIdentify,
8590
} as any);
8691

87-
await act(() =>
88-
render(
89-
<UserProvider>
90-
<div>Test Child</div>
91-
</UserProvider>,
92-
),
92+
render(
93+
<UserProvider>
94+
<div>Test Child</div>
95+
</UserProvider>,
9396
);
9497

98+
await waitFor(() => {
99+
expect(screen.getByText("Test Child")).toBeInTheDocument();
100+
});
101+
95102
// Verify identify was not called because email is missing
96103
expect(mockIdentify).not.toHaveBeenCalled();
97104
});
98105

99106
it("should NOT call posthog.identify when userId is missing", async () => {
107+
const getProfileSpy = jest.spyOn(UserApi, "getProfile");
100108
server.use(
101109
rest.get(`${ENV_WEB.API_BASEURL}/user/profile`, (_req, res, ctx) => {
102110
return res(
@@ -111,14 +119,19 @@ describe("UserProvider", () => {
111119
identify: mockIdentify,
112120
} as any);
113121

114-
await act(() =>
115-
render(
116-
<UserProvider>
117-
<div>Test Child</div>
118-
</UserProvider>,
119-
),
122+
render(
123+
<UserProvider>
124+
<div>Test Child</div>
125+
</UserProvider>,
120126
);
127+
128+
await waitFor(() => expect(getProfileSpy).toHaveBeenCalled());
129+
await act(async () => {
130+
await getProfileSpy.mock.results[0].value;
131+
});
132+
121133
expect(mockIdentify).not.toHaveBeenCalled();
134+
getProfileSpy.mockRestore();
122135
});
123136

124137
it("should handle posthog.identify not being a function gracefully", async () => {
@@ -136,6 +149,10 @@ describe("UserProvider", () => {
136149
);
137150
}).not.toThrow();
138151

152+
await waitFor(() => {
153+
expect(screen.getByText("Test Child")).toBeInTheDocument();
154+
});
155+
139156
// Verify identify was not called
140157
expect(mockIdentify).not.toHaveBeenCalled();
141158
});
@@ -161,24 +178,23 @@ describe("UserProvider", () => {
161178
identify: mockIdentify,
162179
} as any);
163180

164-
const { getByText } = await act(() =>
165-
render(
166-
<UserProvider>
167-
<div>Test Child Content</div>
168-
</UserProvider>,
169-
),
181+
render(
182+
<UserProvider>
183+
<div>Test Child Content</div>
184+
</UserProvider>,
170185
);
171186

172187
// Initially should show loading
173-
expect(getByText("Loading...")).toBeInTheDocument();
188+
expect(screen.getByText("Loading...")).toBeInTheDocument();
174189

175190
// After data loads, should show children
176191
await waitFor(() => {
177-
expect(getByText("Test Child Content")).toBeInTheDocument();
192+
expect(screen.getByText("Test Child Content")).toBeInTheDocument();
178193
});
179194
});
180195

181196
it("should handle session fetch errors gracefully", async () => {
197+
const getProfileSpy = jest.spyOn(UserApi, "getProfile");
182198
server.use(
183199
rest.get(`${ENV_WEB.API_BASEURL}/user/profile`, (_req, res, ctx) => {
184200
return res(ctx.status(Status.UNAUTHORIZED));
@@ -193,14 +209,21 @@ describe("UserProvider", () => {
193209
identify: mockIdentify,
194210
} as any);
195211

196-
await act(() =>
197-
render(
198-
<UserProvider>
199-
<div>Test Child</div>
200-
</UserProvider>,
201-
),
212+
render(
213+
<UserProvider>
214+
<div>Test Child</div>
215+
</UserProvider>,
202216
);
203217

218+
await waitFor(() => expect(getProfileSpy).toHaveBeenCalled());
219+
await act(async () => {
220+
try {
221+
await getProfileSpy.mock.results[0].value;
222+
} catch (e) {
223+
// Ignore error
224+
}
225+
});
226+
204227
expect(consoleErrorSpy).toHaveBeenCalledWith(
205228
new AxiosError("Request failed with status code 401"),
206229
);
@@ -209,6 +232,7 @@ describe("UserProvider", () => {
209232
expect(mockIdentify).not.toHaveBeenCalled();
210233

211234
consoleErrorSpy.mockRestore();
235+
getProfileSpy.mockRestore();
212236
});
213237
});
214238
});

packages/web/src/common/constants/web.constants.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ export const ID_SOMEDAY_EVENTS = "ID_SOMEDAY_EVENTS";
2020
export const ID_SOMEDAY_EVENT_FORM = "Someday Event Form";
2121
export const ID_EVENT_FORM_ACTION_MENU = "event-action-menu";
2222
export const ID_SOMEDAY_EVENT_ACTION_MENU = "someday-event-action-menu";
23-
export const DATA_EVENT_ELEMENT_ORDER = "data-event-order";
24-
export const DATA_EVENT_ELEMENT_Z_INDEX = "data-event-z-index";
25-
export const DATA_EVENT_ELEMENT_OVERLAPPING = "data-event-overlapping";
2623
export const DATA_EVENT_ELEMENT_ID = "data-event-id";
2724
export const DATA_TASK_ELEMENT_ID = "data-task-id";
2825
export const ID_CONTEXT_MENU_ITEMS = "context-menu-items";

packages/web/src/common/context/mouse-position.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useMovementEvent } from "@web/common/hooks/useMovementEvent";
1212
import {
1313
DomMovement,
1414
getElementAtPoint,
15-
} from "@web/common/utils/dom-events/event-emitter.util";
15+
} from "@web/common/utils/dom/event-emitter.util";
1616

1717
export interface MouseState {
1818
mousedown: boolean;

0 commit comments

Comments
 (0)