Fetch relationships everytime we fetch a single chat
This commit is contained in:
parent
98b2fdf9a4
commit
15c22863d7
5 changed files with 157 additions and 7 deletions
|
@ -36,7 +36,9 @@ const TestApp: FC<any> = ({ children, storeProps, routerProps = {} }) => {
|
|||
let store: ReturnType<typeof createTestStore>;
|
||||
let appState = rootState;
|
||||
|
||||
if (storeProps) {
|
||||
if (storeProps && typeof storeProps.getState !== 'undefined') { // storeProps is a store
|
||||
store = storeProps;
|
||||
} else if (storeProps) { // storeProps is state
|
||||
appState = merge(rootState, storeProps);
|
||||
store = createTestStore(appState);
|
||||
} else {
|
||||
|
|
|
@ -3,8 +3,9 @@ import sumBy from 'lodash/sumBy';
|
|||
import { useEffect } from 'react';
|
||||
|
||||
import { __stub } from 'soapbox/api';
|
||||
import { mockStore, queryClient, renderHook, rootState, waitFor } from 'soapbox/jest/test-helpers';
|
||||
import { createTestStore, mockStore, queryClient, renderHook, rootState, waitFor } from 'soapbox/jest/test-helpers';
|
||||
import { normalizeRelationship } from 'soapbox/normalizers';
|
||||
import { Store } from 'soapbox/store';
|
||||
import { flattenPages } from 'soapbox/utils/queries';
|
||||
|
||||
import { IAccount } from '../accounts';
|
||||
|
@ -179,7 +180,7 @@ describe('useChats', () => {
|
|||
|
||||
describe('with a successful request', () => {
|
||||
beforeEach(() => {
|
||||
store = mockStore(ImmutableMap());
|
||||
store = mockStore(rootState);
|
||||
|
||||
__stub((mock) => {
|
||||
mock.onGet('/api/v1/pleroma/chats')
|
||||
|
@ -218,7 +219,13 @@ describe('useChats', () => {
|
|||
});
|
||||
|
||||
describe('useChat()', () => {
|
||||
const relationshipId = '123';
|
||||
let store: Store;
|
||||
|
||||
beforeEach(() => {
|
||||
const state = rootState;
|
||||
store = createTestStore(state);
|
||||
|
||||
queryClient.clear();
|
||||
});
|
||||
|
||||
|
@ -226,14 +233,21 @@ describe('useChat()', () => {
|
|||
beforeEach(() => {
|
||||
__stub((mock) => {
|
||||
mock.onGet(`/api/v1/pleroma/chats/${chat.id}`).reply(200, chat);
|
||||
mock
|
||||
.onGet(`/api/v1/accounts/relationships?id[]=${chat.account.id}`)
|
||||
.reply(200, [normalizeRelationship({ id: relationshipId, blocked_by: true })]);
|
||||
});
|
||||
});
|
||||
|
||||
it('is successful', async () => {
|
||||
const { result } = renderHook(() => useChat(chat.id));
|
||||
expect(store.getState().relationships.getIn([relationshipId, 'blocked_by'])).toBeUndefined();
|
||||
|
||||
const { result } = renderHook(() => useChat(chat.id), undefined, store);
|
||||
|
||||
await waitFor(() => expect(result.current.isFetching).toBe(false));
|
||||
|
||||
expect(store.getState().relationships.getIn([relationshipId, 'id'])).toBe(relationshipId);
|
||||
expect(store.getState().relationships.getIn([relationshipId, 'blocked_by'])).toBe(true);
|
||||
expect(result.current.data.id).toBe(chat.id);
|
||||
});
|
||||
});
|
||||
|
|
107
app/soapbox/queries/__tests__/relationships.test.ts
Normal file
107
app/soapbox/queries/__tests__/relationships.test.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
import { useEffect } from 'react';
|
||||
|
||||
import { __stub } from 'soapbox/api';
|
||||
import { createTestStore, queryClient, renderHook, rootState, waitFor } from 'soapbox/jest/test-helpers';
|
||||
import { normalizeRelationship } from 'soapbox/normalizers';
|
||||
import { Store } from 'soapbox/store';
|
||||
|
||||
import { useFetchRelationships } from '../relationships';
|
||||
|
||||
describe('useFetchRelationships()', () => {
|
||||
let store: Store;
|
||||
|
||||
beforeEach(() => {
|
||||
const state = rootState;
|
||||
store = createTestStore(state);
|
||||
|
||||
queryClient.clear();
|
||||
});
|
||||
|
||||
describe('with a successful query', () => {
|
||||
describe('with one relationship', () => {
|
||||
const id = '123';
|
||||
|
||||
beforeEach(() => {
|
||||
__stub((mock) => {
|
||||
mock
|
||||
.onGet(`/api/v1/accounts/relationships?id[]=${id}`)
|
||||
.reply(200, [normalizeRelationship({ id, blocked_by: true })]);
|
||||
});
|
||||
});
|
||||
|
||||
it('is successful', async() => {
|
||||
const { result } = renderHook(() => {
|
||||
const fetchRelationships = useFetchRelationships();
|
||||
|
||||
useEffect(() => {
|
||||
fetchRelationships.mutate({ accountIds: [id] });
|
||||
}, []);
|
||||
|
||||
return fetchRelationships;
|
||||
}, undefined, store);
|
||||
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
|
||||
expect(store.getState().relationships.size).toBe(1);
|
||||
expect(store.getState().relationships.getIn([id, 'id'])).toBe(id);
|
||||
expect(store.getState().relationships.getIn([id, 'blocked_by'])).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with multiple relationships', () => {
|
||||
const ids = ['123', '456'];
|
||||
|
||||
beforeEach(() => {
|
||||
__stub((mock) => {
|
||||
mock
|
||||
.onGet(`/api/v1/accounts/relationships?id[]=${ids[0]}&id[]=${ids[1]}`)
|
||||
.reply(200, ids.map((id) => normalizeRelationship({ id, blocked_by: true })));
|
||||
});
|
||||
});
|
||||
|
||||
it('is successful', async() => {
|
||||
const { result } = renderHook(() => {
|
||||
const fetchRelationships = useFetchRelationships();
|
||||
|
||||
useEffect(() => {
|
||||
fetchRelationships.mutate({ accountIds: ids });
|
||||
}, []);
|
||||
|
||||
return fetchRelationships;
|
||||
}, undefined, store);
|
||||
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
|
||||
expect(store.getState().relationships.size).toBe(2);
|
||||
expect(store.getState().relationships.getIn([ids[0], 'id'])).toBe(ids[0]);
|
||||
expect(store.getState().relationships.getIn([ids[1], 'id'])).toBe(ids[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with an unsuccessful query', () => {
|
||||
const id = '123';
|
||||
|
||||
beforeEach(() => {
|
||||
__stub((mock) => {
|
||||
mock.onGet(`/api/v1/accounts/relationships?id[]=${id}`).networkError();
|
||||
});
|
||||
});
|
||||
|
||||
it('is successful', async() => {
|
||||
const { result } = renderHook(() => {
|
||||
const fetchRelationships = useFetchRelationships();
|
||||
|
||||
useEffect(() => {
|
||||
fetchRelationships.mutate({ accountIds: [id] });
|
||||
}, []);
|
||||
|
||||
return fetchRelationships;
|
||||
}, undefined, store);
|
||||
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
|
||||
expect(result.current.error).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,7 +1,6 @@
|
|||
import { InfiniteData, useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
|
||||
import sumBy from 'lodash/sumBy';
|
||||
|
||||
import { fetchRelationships } from 'soapbox/actions/accounts';
|
||||
import { importFetchedAccount, importFetchedAccounts } from 'soapbox/actions/importer';
|
||||
import snackbar from 'soapbox/actions/snackbar';
|
||||
import { getNextLink } from 'soapbox/api';
|
||||
|
@ -13,6 +12,7 @@ import { normalizeChatMessage } from 'soapbox/normalizers';
|
|||
import { flattenPages, PaginatedResult, updatePageItem } from 'soapbox/utils/queries';
|
||||
|
||||
import { queryClient } from './client';
|
||||
import { useFetchRelationships } from './relationships';
|
||||
|
||||
import type { IAccount } from './accounts';
|
||||
|
||||
|
@ -129,6 +129,7 @@ const useChats = (search?: string) => {
|
|||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
const { setUnreadChatsCount } = useStatContext();
|
||||
const fetchRelationships = useFetchRelationships();
|
||||
|
||||
const getChats = async (pageParam?: any): Promise<PaginatedResult<IChat>> => {
|
||||
const endpoint = features.chatsV2 ? '/api/v2/pleroma/chats' : '/api/v1/pleroma/chats';
|
||||
|
@ -147,7 +148,7 @@ const useChats = (search?: string) => {
|
|||
setUnreadChatsCount(Number(response.headers['x-unread-messages-count']) || sumBy(data, (chat) => chat.unread));
|
||||
|
||||
// Set the relationships to these users in the redux store.
|
||||
dispatch(fetchRelationships(data.map((item) => item.account.id)));
|
||||
fetchRelationships.mutate({ accountIds: data.map((item) => item.account.id) });
|
||||
dispatch(importFetchedAccounts(data.map((item) => item.account)));
|
||||
|
||||
return {
|
||||
|
@ -183,12 +184,13 @@ const useChats = (search?: string) => {
|
|||
const useChat = (chatId?: string) => {
|
||||
const api = useApi();
|
||||
const dispatch = useAppDispatch();
|
||||
const fetchRelationships = useFetchRelationships();
|
||||
|
||||
const getChat = async () => {
|
||||
if (chatId) {
|
||||
const { data } = await api.get<IChat>(`/api/v1/pleroma/chats/${chatId}`);
|
||||
|
||||
dispatch(fetchRelationships([data.account.id]));
|
||||
fetchRelationships.mutate({ accountIds: [data.account.id] });
|
||||
dispatch(importFetchedAccount(data.account));
|
||||
|
||||
return data;
|
||||
|
|
25
app/soapbox/queries/relationships.ts
Normal file
25
app/soapbox/queries/relationships.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { useMutation } from '@tanstack/react-query';
|
||||
import { AxiosError } from 'axios';
|
||||
|
||||
import { fetchRelationshipsFail, fetchRelationshipsSuccess } from 'soapbox/actions/accounts';
|
||||
import { useApi, useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
const useFetchRelationships = () => {
|
||||
const api = useApi();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
return useMutation(({ accountIds }: { accountIds: string[]}) => {
|
||||
const ids = accountIds.map((id) => `id[]=${id}`).join('&');
|
||||
|
||||
return api.get(`/api/v1/accounts/relationships?${ids}`);
|
||||
}, {
|
||||
onSuccess(response) {
|
||||
dispatch(fetchRelationshipsSuccess(response.data));
|
||||
},
|
||||
onError(error: AxiosError) {
|
||||
dispatch(fetchRelationshipsFail(error));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export { useFetchRelationships };
|
Loading…
Reference in a new issue