|
1 | 1 | import { describe, it, expect, vi, beforeEach } from 'vitest'; |
2 | 2 | import { render, screen, fireEvent } from '@testing-library/react'; |
3 | | -import { MemoryRouter } from 'react-router-dom'; |
| 3 | +import { MemoryRouter, useLocation, useNavigate } from 'react-router-dom'; |
4 | 4 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; |
5 | 5 | import { MessagesPage } from '@/pages/MessagesPage'; |
6 | 6 |
|
@@ -89,13 +89,32 @@ const mockMessagesData = { |
89 | 89 | totalCount: 2, |
90 | 90 | }; |
91 | 91 |
|
| 92 | +// Exposes the live router URL to assertions, and a button that simulates the |
| 93 | +// app's sidebar navigation to another queue while (realistically) carrying the |
| 94 | +// existing query params along — including a stale ?message= deep link. |
| 95 | +function LocationProbe() { |
| 96 | + const location = useLocation(); |
| 97 | + const navigate = useNavigate(); |
| 98 | + return ( |
| 99 | + <> |
| 100 | + <span data-testid="location-search">{location.search}</span> |
| 101 | + <button onClick={() => navigate('/messages?namespace=ns1&queue=other-queue&message=msg-1')}> |
| 102 | + go-other-queue |
| 103 | + </button> |
| 104 | + </> |
| 105 | + ); |
| 106 | +} |
| 107 | + |
92 | 108 | function createWrapper(initialPath = '/messages?namespace=ns1&queue=test-queue') { |
93 | 109 | const queryClient = new QueryClient({ |
94 | 110 | defaultOptions: { queries: { retry: false }, mutations: { retry: false } }, |
95 | 111 | }); |
96 | 112 | return ({ children }: { children: React.ReactNode }) => ( |
97 | 113 | <MemoryRouter initialEntries={[initialPath]}> |
98 | | - <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> |
| 114 | + <QueryClientProvider client={queryClient}> |
| 115 | + {children} |
| 116 | + <LocationProbe /> |
| 117 | + </QueryClientProvider> |
99 | 118 | </MemoryRouter> |
100 | 119 | ); |
101 | 120 | } |
@@ -288,12 +307,39 @@ describe('MessagesPage', () => { |
288 | 307 | expect(screen.getByTestId('selected-id')).toHaveTextContent('msg-2'); |
289 | 308 | }); |
290 | 309 |
|
| 310 | + it('mirrors the selection into the URL so the link is shareable', () => { |
| 311 | + const Wrapper = createWrapper(); |
| 312 | + render(<Wrapper><MessagesPage /></Wrapper>); |
| 313 | + expect(screen.getByTestId('location-search')).not.toHaveTextContent('message='); |
| 314 | + fireEvent.click(screen.getByText('Select msg-2')); |
| 315 | + expect(screen.getByTestId('location-search')).toHaveTextContent('message=msg-2'); |
| 316 | + }); |
| 317 | + |
291 | 318 | it('clears the selection when switching queue tabs', () => { |
292 | 319 | const Wrapper = createWrapper('/messages?namespace=ns1&queue=test-queue&message=msg-1'); |
293 | 320 | render(<Wrapper><MessagesPage /></Wrapper>); |
294 | 321 | expect(screen.getByTestId('selected-id')).toHaveTextContent('msg-1'); |
295 | 322 | fireEvent.click(screen.getByText(/Dead-Letter \(/)); |
296 | 323 | expect(screen.getByTestId('selected-id')).toHaveTextContent('none'); |
297 | 324 | }); |
| 325 | + |
| 326 | + it('removes the message param from the URL when switching queue tabs', () => { |
| 327 | + const Wrapper = createWrapper('/messages?namespace=ns1&queue=test-queue&message=msg-1'); |
| 328 | + render(<Wrapper><MessagesPage /></Wrapper>); |
| 329 | + expect(screen.getByTestId('location-search')).toHaveTextContent('message=msg-1'); |
| 330 | + fireEvent.click(screen.getByText(/Dead-Letter \(/)); |
| 331 | + expect(screen.getByTestId('location-search')).not.toHaveTextContent('message='); |
| 332 | + }); |
| 333 | + |
| 334 | + it('clears selection and the stale message param when navigating to another entity', () => { |
| 335 | + const Wrapper = createWrapper('/messages?namespace=ns1&queue=test-queue&message=msg-1'); |
| 336 | + render(<Wrapper><MessagesPage /></Wrapper>); |
| 337 | + expect(screen.getByTestId('selected-id')).toHaveTextContent('msg-1'); |
| 338 | + // Sidebar-style navigation to a different queue carrying the old param along |
| 339 | + fireEvent.click(screen.getByText('go-other-queue')); |
| 340 | + expect(screen.getByTestId('selected-id')).toHaveTextContent('none'); |
| 341 | + expect(screen.getByTestId('location-search')).toHaveTextContent('queue=other-queue'); |
| 342 | + expect(screen.getByTestId('location-search')).not.toHaveTextContent('message='); |
| 343 | + }); |
298 | 344 | }); |
299 | 345 | }); |
0 commit comments