Skip to content

Commit c3411c0

Browse files
committed
fix: update following unit tests
1 parent 0cfcb46 commit c3411c0

4 files changed

Lines changed: 54 additions & 62 deletions

File tree

src/__tests__/profile/FollowingScreen.test.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ jest.mock('@/services/connections', () => ({
1717
getUserFollowing: jest.fn(),
1818
}));
1919

20+
jest.mock('@react-navigation/native', () => {
21+
const actualNav = jest.requireActual('@react-navigation/native');
22+
return {
23+
...actualNav,
24+
useFocusEffect: jest.fn().mockImplementation((callback) => callback()),
25+
};
26+
});
27+
2028
const mockQueryClient = new QueryClient({
2129
defaultOptions: {
2230
queries: { retry: false },

src/__tests__/screens/profile/connections/FollowingScreen.test.tsx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
12
import { render } from '@testing-library/react-native';
23

34
import { ThemeProvider } from '@/hooks/useTheme';
@@ -21,6 +22,14 @@ jest.mock('@/components/ui/Avatar', () => ({
2122
default: jest.fn(() => null),
2223
}));
2324

25+
jest.mock('@react-navigation/native', () => {
26+
const actualNav = jest.requireActual('@react-navigation/native');
27+
return {
28+
...actualNav,
29+
useFocusEffect: jest.fn().mockImplementation((callback) => callback()),
30+
};
31+
});
32+
2433
jest.mock('@/components/ui/Spinner', () => {
2534
// eslint-disable-next-line @typescript-eslint/no-require-imports
2635
const { ActivityIndicator } = require('react-native');
@@ -49,6 +58,24 @@ const mockFollowing = [
4958
},
5059
];
5160

61+
jest.mock('@react-navigation/native', () => {
62+
const actualNav = jest.requireActual('@react-navigation/native');
63+
return {
64+
...actualNav,
65+
useFocusEffect: jest.fn().mockImplementation((callback) => callback()),
66+
};
67+
});
68+
69+
const queryClient = new QueryClient();
70+
71+
const renderWithClient = (ui: React.ReactElement) => {
72+
return render(ui, {
73+
wrapper: ({ children }) => (
74+
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
75+
),
76+
});
77+
};
78+
5279
describe('FollowingScreen', () => {
5380
const username = 'testuser';
5481

@@ -70,7 +97,7 @@ describe('FollowingScreen', () => {
7097
error: null,
7198
});
7299

73-
const { getByTestId } = render(
100+
const { getByTestId } = renderWithClient(
74101
<ThemeProvider>
75102
<FollowingScreen username={username} />
76103
</ThemeProvider>
@@ -89,7 +116,7 @@ describe('FollowingScreen', () => {
89116
error: new Error('Network error'),
90117
});
91118

92-
const { getByText } = render(
119+
const { getByText } = renderWithClient(
93120
<ThemeProvider>
94121
<FollowingScreen username={username} />
95122
</ThemeProvider>
@@ -115,7 +142,7 @@ describe('FollowingScreen', () => {
115142
error: null,
116143
});
117144

118-
const { queryByTestId } = render(
145+
const { queryByTestId } = renderWithClient(
119146
<ThemeProvider>
120147
<FollowingScreen username={username} />
121148
</ThemeProvider>
@@ -143,13 +170,13 @@ describe('FollowingScreen', () => {
143170
error: null,
144171
});
145172

146-
const { getByTestId } = render(
173+
const { getByTestId } = renderWithClient(
147174
<ThemeProvider>
148175
<FollowingScreen username={username} />
149176
</ThemeProvider>
150177
);
151178

152-
expect(getByTestId('spinner-small')).toBeTruthy();
179+
expect(getByTestId('footer-spinner')).toBeTruthy();
153180
});
154181

155182
it('does not render footer when not fetching next page', () => {
@@ -169,7 +196,7 @@ describe('FollowingScreen', () => {
169196
error: null,
170197
});
171198

172-
const { queryByTestId } = render(
199+
const { queryByTestId } = renderWithClient(
173200
<ThemeProvider>
174201
<FollowingScreen username={username} />
175202
</ThemeProvider>

src/hooks/profile/useBlockMutation.tsx

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ async function updateLists(queryClient: QueryClient, username: string, isBlocked
3434
mutes: false,
3535
};
3636

37-
for (const key of listKeys) {
37+
for (const key of queryKeys) {
3838
const queries = queryClient.getQueriesData<InfiniteListResponse>({
3939
queryKey: [key],
4040
});
@@ -145,68 +145,25 @@ function updateTweetLikersAndRetweetersLists(
145145
retweetersQueries.forEach(([queryKey, data]) => {
146146
if (!data) return;
147147

148-
const pages = data.pages.map((page) => ({
149-
...page,
150-
data: page.data.map((user) => {
151-
if (user.username === username) {
152-
isFound[key] = true;
153-
return {
148+
const pages = data.pages.map((page) => ({
149+
...page,
150+
data: page.data.map((user) =>
151+
user.username === username
152+
? {
154153
...user,
155154
relationship: {
156155
...user.relationship,
157156
blocking: isBlocked,
158157
follower: isBlocked ? false : user.relationship?.follower,
159158
following: isBlocked ? false : user.relationship?.following,
160159
},
161-
};
162-
} else return user;
163-
}),
164-
}));
165-
166-
queryClient.setQueryData(queryKey, { ...data, pages });
167-
});
168-
}
169-
170-
if (isBlocked && !isFound.blocks) {
171-
let profile = queryClient.getQueryData<UserProfile>(['profile', username]);
172-
if (!profile) {
173-
// fetch it if not found in cache
174-
profile = await queryClient.fetchQuery<UserProfile>({
175-
queryKey: ['profile', username],
176-
});
177-
}
178-
179-
if (profile) {
180-
// map to compact user type first
181-
const newProfile = {
182-
username: profile.username,
183-
displayName: profile.displayName,
184-
bio: profile.bio,
185-
avatarUrl: profile.avatarUrl,
186-
bioEntities: profile.bioEntities,
187-
relationship: { ...profile.relationship, following: true },
188-
};
189-
190-
const blocksList = queryClient.getQueryData<InfiniteListResponse>(['blocks']);
191-
192-
if (!blocksList) return;
193-
194-
const updatedPages = blocksList.pages.map((page, index) => {
195-
if (index === 0) {
196-
return {
197-
...page,
198-
data: [newProfile, ...page.data],
199-
};
200-
}
201-
return page;
202-
});
160+
}
161+
: user
162+
),
163+
}));
203164

204-
queryClient.setQueryData(['blocks'], {
205-
...blocksList,
206-
pages: updatedPages,
207-
});
208-
}
209-
}
165+
queryClient.setQueryData(queryKey, { ...data, pages });
166+
});
210167
}
211168

212169
export function useBlockMutation() {

src/screens/profile/connections/FollowingScreen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export default function FollowingScreen({ username }: FollowingScreenProps) {
137137
ListFooterComponent={renderFooter}
138138
ListEmptyComponent={
139139
isLoading ? (
140-
<View style={styles.spinner}>
140+
<View style={styles.spinner} testID="spinner-large">
141141
<Spinner size="large" />
142142
</View>
143143
) : error ? (

0 commit comments

Comments
 (0)