Repository navigation
fix: v15 regressions found in side-by-side QA #3364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
cd365d1
bdc59ce
423b8b9
b055a45
19dc2fb
a020d7c
a7cb14f
6549418
fa1d151
f75f571
db9bcd8
d414ba9
2e7d280
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -82,6 +82,45 @@ | |
| expect(queryChannels).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| // A live event can route a channel into a list that was never queried (e.g. a message makes a | ||
| // channel unread before the "Unread" list was ever shown): `items` is then defined, but no page | ||
| // was loaded, so the first query still has to run. | ||
| it('queries the first page of a list that a live event reached first', async () => { | ||
| const { client, queryChannels } = await setupClient(); | ||
| const paginator = new ChannelPaginator({ client, id: 'channels:a' }); | ||
| paginator.ingestItem(client.channel('messaging', 'ingested')); | ||
| expect(paginator.items).toHaveLength(1); | ||
|
|
||
| renderList(client, paginator); | ||
|
|
||
| await waitFor(() => expect(queryChannels).toHaveBeenCalledTimes(1)); | ||
| }); | ||
|
|
||
| it('queries the first page of a list that a live event reached and left again', async () => { | ||
| const { client, queryChannels } = await setupClient(); | ||
| const paginator = new ChannelPaginator({ client, id: 'channels:a' }); | ||
| const channel = client.channel('messaging', 'ingested'); | ||
| paginator.ingestItem(channel); | ||
| paginator.removeItem({ item: channel }); | ||
| expect(paginator.items).toEqual([]); | ||
|
|
||
| renderList(client, paginator); | ||
|
|
||
| await waitFor(() => expect(queryChannels).toHaveBeenCalledTimes(1)); | ||
| }); | ||
|
|
||
| it('does not query a seeded list that a live event reached', async () => { | ||
| const { client, queryChannels } = await setupClient(); | ||
| const paginator = new ChannelPaginator({ client, id: 'channels:a' }); | ||
| paginator.setItems({ isLastPage: true, valueOrFactory: [] }); | ||
| paginator.ingestItem(client.channel('messaging', 'ingested')); | ||
|
|
||
| renderList(client, paginator); | ||
|
|
||
| await waitFor(() => expect(paginator.items).toHaveLength(1)); | ||
| expect(queryChannels).not.toHaveBeenCalled(); | ||
|
Comment on lines
+120
to
+121
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait for the debounced query before asserting that none occurred.
|
||
| }); | ||
|
|
||
| it('re-queries when the list data is discarded while it stays mounted', async () => { | ||
| const { client, queryChannels } = await setupClient(); | ||
| const paginator = new ChannelPaginator({ client, id: 'channels:a' }); | ||
|
|
@@ -95,7 +134,7 @@ | |
| client.channelManager.resetPaginatorStates(); | ||
| }); | ||
|
|
||
| await waitFor(() => expect(queryChannels).toHaveBeenCalledTimes(2)); | ||
|
Check failure on line 137 in src/components/ChannelList/__tests__/ChannelList.test.tsx
|
||
| await waitFor(() => expect(paginator.items).toEqual([])); | ||
| }); | ||
|
|
||
|
|
@@ -225,7 +264,7 @@ | |
|
|
||
| expect(paginator.items).toEqual([channel]); | ||
| expect(screen.queryByText("Couldn't load conversations")).not.toBeInTheDocument(); | ||
| expect(queryChannels).toHaveBeenCalledTimes(2); | ||
|
Check failure on line 267 in src/components/ChannelList/__tests__/ChannelList.test.tsx
|
||
| }); | ||
|
|
||
| it('renders the ListLoadErrorIndicator override with the error and the retry', async () => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| import React from 'react'; | ||
| import { act, render, screen } from '@testing-library/react'; | ||
| import { StateStore } from '@stream-io/state-store'; | ||
| import type { PaginatorState } from 'stream-chat'; | ||
|
|
||
| import { InfiniteScrollWithComponents } from '../InfiniteScrollWithComponents'; | ||
|
|
||
| type Item = { cid: string; id: string; name: string }; | ||
|
|
||
| const Nothing = () => null; | ||
|
|
||
| const renderList = ( | ||
| state: StateStore<PaginatorState<Item>>, | ||
| getItemId?: (item: Item) => string, | ||
| ) => | ||
| render( | ||
| <InfiniteScrollWithComponents<Item> | ||
| EmptyListIndicator={Nothing} | ||
| EndReachedIndicator={Nothing} | ||
| FirstPageLoadingIndicator={Nothing} | ||
| ListItem={({ item }) => <div data-testid='row'>{item.name}</div>} | ||
| LoadingNextPageIndicator={Nothing} | ||
| paginator={{ getItemId, hasMoreHead: false, hasMoreTail: false, state }} | ||
| />, | ||
| ); | ||
|
|
||
| describe('InfiniteScrollWithComponents', () => { | ||
| // Channel ids are unique only per type (`team:general` and `livestream:general`), so a channel | ||
| // list keyed by `id` shared keys between rows and React rendered ghost rows on reorder. | ||
| it('keys rows by the paginator item id, so rows sharing an `id` render once each', () => { | ||
| const consoleError = vi.spyOn(console, 'error').mockImplementation(() => undefined); | ||
| const teamGeneral = { cid: 'team:general', id: 'general', name: 'team' }; | ||
| const liveGeneral = { cid: 'livestream:general', id: 'general', name: 'livestream' }; | ||
| const other = { cid: 'messaging:other', id: 'other', name: 'other' }; | ||
| const state = new StateStore<PaginatorState<Item>>({ | ||
| hasMoreHead: false, | ||
| hasMoreTail: false, | ||
| isLoading: false, | ||
| items: [teamGeneral, liveGeneral, other], | ||
| } as PaginatorState<Item>); | ||
|
|
||
| renderList(state, (item) => item.cid); | ||
| act(() => { | ||
| state.partialNext({ items: [other, liveGeneral, teamGeneral] }); | ||
| }); | ||
|
|
||
| expect(screen.getAllByTestId('row').map((row) => row.textContent)).toEqual([ | ||
| 'other', | ||
| 'livestream', | ||
| 'team', | ||
| ]); | ||
| // React's argument count for this warning varies by version, so only the message is matched. | ||
| expect( | ||
| consoleError.mock.calls.some( | ||
| ([message]) => typeof message === 'string' && message.includes('same key'), | ||
| ), | ||
| ).toBe(false); | ||
| consoleError.mockRestore(); | ||
| }); | ||
|
|
||
| it('falls back to `id` when the paginator has no item id', () => { | ||
| const state = new StateStore<PaginatorState<Item>>({ | ||
| hasMoreHead: false, | ||
| hasMoreTail: false, | ||
| isLoading: false, | ||
| items: [{ cid: 'a:1', id: '1', name: 'one' }], | ||
| } as PaginatorState<Item>); | ||
|
|
||
| renderList(state); | ||
|
|
||
| expect(screen.getAllByTestId('row').map((row) => row.textContent)).toEqual(['one']); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a
stream-chatversion that provideshasLoadedPage.The declared
stream-chatversion,10.0.0-rc.31, does not provide this getter. The supplied pipeline fails with TS2339 at this line. If compilation is bypassed, the missing getter reads asundefined, so the selector can schedule another query after a successful load. Update the dependency, lockfile, and supported peer minimum to a release that provides the getter. (raw.githubusercontent.com)GitHub Actions: Size / 0_Compressed Size.txt
[error] 45-45: TypeScript error TS2339: Property 'hasLoadedPage' does not exist on type 'ChannelPaginator'. The command 'tsc --project tsconfig.lib.json' failed with exit code 1.
GitHub Actions: Size / Compressed Size
[error] 45-45: TypeScript (tsc --project tsconfig.lib.json): TS2339: Property 'hasLoadedPage' does not exist on type 'ChannelPaginator'.
GitHub Check: ESLint, Prettier & Types
[failure] 45-45:
Property 'hasLoadedPage' does not exist on type 'ChannelPaginator'.
Source: Pipeline failures