1
- import { render , screen , within } from "@testing-library/react" ;
1
+ import { screen , within } from "@testing-library/react" ;
2
2
import {
3
3
afterAll ,
4
4
afterEach ,
@@ -10,6 +10,7 @@ import {
10
10
vi ,
11
11
} from "vitest" ;
12
12
import userEvent from "@testing-library/user-event" ;
13
+ import { renderWithProviders } from "test-utils" ;
13
14
import { formatTimeDelta } from "#/utils/format-time-delta" ;
14
15
import { ConversationCard } from "#/components/features/conversation-panel/conversation-card" ;
15
16
import { clickOnEditButton } from "./utils" ;
@@ -20,7 +21,11 @@ describe("ConversationCard", () => {
20
21
const onChangeTitle = vi . fn ( ) ;
21
22
22
23
beforeAll ( ( ) => {
23
- vi . stubGlobal ( "window" , { open : vi . fn ( ) } ) ;
24
+ vi . stubGlobal ( "window" , {
25
+ open : vi . fn ( ) ,
26
+ addEventListener : vi . fn ( ) ,
27
+ removeEventListener : vi . fn ( ) ,
28
+ } ) ;
24
29
} ) ;
25
30
26
31
afterEach ( ( ) => {
@@ -32,7 +37,7 @@ describe("ConversationCard", () => {
32
37
} ) ;
33
38
34
39
it ( "should render the conversation card" , ( ) => {
35
- render (
40
+ renderWithProviders (
36
41
< ConversationCard
37
42
onDelete = { onDelete }
38
43
onChangeTitle = { onChangeTitle }
@@ -51,7 +56,7 @@ describe("ConversationCard", () => {
51
56
} ) ;
52
57
53
58
it ( "should render the selectedRepository if available" , ( ) => {
54
- const { rerender } = render (
59
+ const { rerender } = renderWithProviders (
55
60
< ConversationCard
56
61
onDelete = { onDelete }
57
62
onChangeTitle = { onChangeTitle }
@@ -82,7 +87,7 @@ describe("ConversationCard", () => {
82
87
83
88
it ( "should toggle a context menu when clicking the ellipsis button" , async ( ) => {
84
89
const user = userEvent . setup ( ) ;
85
- render (
90
+ renderWithProviders (
86
91
< ConversationCard
87
92
onDelete = { onDelete }
88
93
onChangeTitle = { onChangeTitle }
@@ -107,7 +112,7 @@ describe("ConversationCard", () => {
107
112
108
113
it ( "should call onDelete when the delete button is clicked" , async ( ) => {
109
114
const user = userEvent . setup ( ) ;
110
- render (
115
+ renderWithProviders (
111
116
< ConversationCard
112
117
onDelete = { onDelete }
113
118
isActive
@@ -131,7 +136,7 @@ describe("ConversationCard", () => {
131
136
132
137
test ( "clicking the selectedRepository should not trigger the onClick handler" , async ( ) => {
133
138
const user = userEvent . setup ( ) ;
134
- render (
139
+ renderWithProviders (
135
140
< ConversationCard
136
141
onDelete = { onDelete }
137
142
isActive
@@ -152,7 +157,7 @@ describe("ConversationCard", () => {
152
157
153
158
test ( "conversation title should call onChangeTitle when changed and blurred" , async ( ) => {
154
159
const user = userEvent . setup ( ) ;
155
- render (
160
+ renderWithProviders (
156
161
< ConversationCard
157
162
onDelete = { onDelete }
158
163
isActive
@@ -181,7 +186,7 @@ describe("ConversationCard", () => {
181
186
182
187
it ( "should reset title and not call onChangeTitle when the title is empty" , async ( ) => {
183
188
const user = userEvent . setup ( ) ;
184
- render (
189
+ renderWithProviders (
185
190
< ConversationCard
186
191
onDelete = { onDelete }
187
192
isActive
@@ -205,7 +210,7 @@ describe("ConversationCard", () => {
205
210
206
211
test ( "clicking the title should trigger the onClick handler" , async ( ) => {
207
212
const user = userEvent . setup ( ) ;
208
- render (
213
+ renderWithProviders (
209
214
< ConversationCard
210
215
onClick = { onClick }
211
216
onDelete = { onDelete }
@@ -225,7 +230,7 @@ describe("ConversationCard", () => {
225
230
226
231
test ( "clicking the title should not trigger the onClick handler if edit mode" , async ( ) => {
227
232
const user = userEvent . setup ( ) ;
228
- render (
233
+ renderWithProviders (
229
234
< ConversationCard
230
235
onDelete = { onDelete }
231
236
isActive
@@ -246,7 +251,7 @@ describe("ConversationCard", () => {
246
251
247
252
test ( "clicking the delete button should not trigger the onClick handler" , async ( ) => {
248
253
const user = userEvent . setup ( ) ;
249
- render (
254
+ renderWithProviders (
250
255
< ConversationCard
251
256
onDelete = { onDelete }
252
257
isActive
@@ -268,11 +273,80 @@ describe("ConversationCard", () => {
268
273
expect ( onClick ) . not . toHaveBeenCalled ( ) ;
269
274
} ) ;
270
275
276
+ it ( "should show display cost button only when showDisplayCostOption is true" , async ( ) => {
277
+ const user = userEvent . setup ( ) ;
278
+ const { rerender } = renderWithProviders (
279
+ < ConversationCard
280
+ onDelete = { onDelete }
281
+ onChangeTitle = { onChangeTitle }
282
+ isActive
283
+ title = "Conversation 1"
284
+ selectedRepository = { null }
285
+ lastUpdatedAt = "2021-10-01T12:00:00Z"
286
+ /> ,
287
+ ) ;
288
+
289
+ const ellipsisButton = screen . getByTestId ( "ellipsis-button" ) ;
290
+ await user . click ( ellipsisButton ) ;
291
+
292
+ // Wait for context menu to appear
293
+ const menu = await screen . findByTestId ( "context-menu" ) ;
294
+ expect (
295
+ within ( menu ) . queryByTestId ( "display-cost-button" ) ,
296
+ ) . not . toBeInTheDocument ( ) ;
271
297
298
+ // Close menu
299
+ await user . click ( ellipsisButton ) ;
300
+
301
+ rerender (
302
+ < ConversationCard
303
+ onDelete = { onDelete }
304
+ onChangeTitle = { onChangeTitle }
305
+ showDisplayCostOption
306
+ isActive
307
+ title = "Conversation 1"
308
+ selectedRepository = { null }
309
+ lastUpdatedAt = "2021-10-01T12:00:00Z"
310
+ /> ,
311
+ ) ;
312
+
313
+ // Open menu again
314
+ await user . click ( ellipsisButton ) ;
315
+
316
+ // Wait for context menu to appear and check for display cost button
317
+ const newMenu = await screen . findByTestId ( "context-menu" ) ;
318
+ within ( newMenu ) . getByTestId ( "display-cost-button" ) ;
319
+ } ) ;
320
+
321
+ it ( "should show metrics modal when clicking the display cost button" , async ( ) => {
322
+ const user = userEvent . setup ( ) ;
323
+ renderWithProviders (
324
+ < ConversationCard
325
+ onDelete = { onDelete }
326
+ isActive
327
+ onChangeTitle = { onChangeTitle }
328
+ title = "Conversation 1"
329
+ selectedRepository = { null }
330
+ lastUpdatedAt = "2021-10-01T12:00:00Z"
331
+ showDisplayCostOption
332
+ /> ,
333
+ ) ;
334
+
335
+ const ellipsisButton = screen . getByTestId ( "ellipsis-button" ) ;
336
+ await user . click ( ellipsisButton ) ;
337
+
338
+ const menu = screen . getByTestId ( "context-menu" ) ;
339
+ const displayCostButton = within ( menu ) . getByTestId ( "display-cost-button" ) ;
340
+
341
+ await user . click ( displayCostButton ) ;
342
+
343
+ // Verify if metrics modal is displayed by checking for the modal content
344
+ expect ( screen . getByText ( "Metrics Information" ) ) . toBeInTheDocument ( ) ;
345
+ } ) ;
272
346
273
347
it ( "should not display the edit or delete options if the handler is not provided" , async ( ) => {
274
348
const user = userEvent . setup ( ) ;
275
- const { rerender } = render (
349
+ const { rerender } = renderWithProviders (
276
350
< ConversationCard
277
351
onClick = { onClick }
278
352
onChangeTitle = { onChangeTitle }
@@ -285,8 +359,9 @@ describe("ConversationCard", () => {
285
359
const ellipsisButton = screen . getByTestId ( "ellipsis-button" ) ;
286
360
await user . click ( ellipsisButton ) ;
287
361
288
- expect ( screen . queryByTestId ( "edit-button" ) ) . toBeInTheDocument ( ) ;
289
- expect ( screen . queryByTestId ( "delete-button" ) ) . not . toBeInTheDocument ( ) ;
362
+ const menu = await screen . findByTestId ( "context-menu" ) ;
363
+ expect ( within ( menu ) . queryByTestId ( "edit-button" ) ) . toBeInTheDocument ( ) ;
364
+ expect ( within ( menu ) . queryByTestId ( "delete-button" ) ) . not . toBeInTheDocument ( ) ;
290
365
291
366
// toggle to hide the context menu
292
367
await user . click ( ellipsisButton ) ;
@@ -302,13 +377,15 @@ describe("ConversationCard", () => {
302
377
) ;
303
378
304
379
await user . click ( ellipsisButton ) ;
305
-
306
- expect ( screen . queryByTestId ( "edit-button" ) ) . not . toBeInTheDocument ( ) ;
307
- expect ( screen . queryByTestId ( "delete-button" ) ) . toBeInTheDocument ( ) ;
380
+ const newMenu = await screen . findByTestId ( "context-menu" ) ;
381
+ expect (
382
+ within ( newMenu ) . queryByTestId ( "edit-button" ) ,
383
+ ) . not . toBeInTheDocument ( ) ;
384
+ expect ( within ( newMenu ) . queryByTestId ( "delete-button" ) ) . toBeInTheDocument ( ) ;
308
385
} ) ;
309
386
310
387
it ( "should not render the ellipsis button if there are no actions" , ( ) => {
311
- const { rerender } = render (
388
+ const { rerender } = renderWithProviders (
312
389
< ConversationCard
313
390
onClick = { onClick }
314
391
onDelete = { onDelete }
@@ -347,7 +424,7 @@ describe("ConversationCard", () => {
347
424
348
425
describe ( "state indicator" , ( ) => {
349
426
it ( "should render the 'STOPPED' indicator by default" , ( ) => {
350
- render (
427
+ renderWithProviders (
351
428
< ConversationCard
352
429
onDelete = { onDelete }
353
430
isActive
@@ -362,7 +439,7 @@ describe("ConversationCard", () => {
362
439
} ) ;
363
440
364
441
it ( "should render the other indicators when provided" , ( ) => {
365
- render (
442
+ renderWithProviders (
366
443
< ConversationCard
367
444
onDelete = { onDelete }
368
445
isActive
0 commit comments