sforkowany z mirror/soapbox
Fetch relationships everytime we fetch a single chat
rodzic
98b2fdf9a4
commit
15c22863d7
|
@ -36,7 +36,9 @@ const TestApp: FC<any> = ({ children, storeProps, routerProps = {} }) => {
|
||||||
let store: ReturnType<typeof createTestStore>;
|
let store: ReturnType<typeof createTestStore>;
|
||||||
let appState = rootState;
|
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);
|
appState = merge(rootState, storeProps);
|
||||||
store = createTestStore(appState);
|
store = createTestStore(appState);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,8 +3,9 @@ import sumBy from 'lodash/sumBy';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { __stub } from 'soapbox/api';
|
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 { normalizeRelationship } from 'soapbox/normalizers';
|
||||||
|
import { Store } from 'soapbox/store';
|
||||||
import { flattenPages } from 'soapbox/utils/queries';
|
import { flattenPages } from 'soapbox/utils/queries';
|
||||||
|
|
||||||
import { IAccount } from '../accounts';
|
import { IAccount } from '../accounts';
|
||||||
|
@ -179,7 +180,7 @@ describe('useChats', () => {
|
||||||
|
|
||||||
describe('with a successful request', () => {
|
describe('with a successful request', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
store = mockStore(ImmutableMap());
|
store = mockStore(rootState);
|
||||||
|
|
||||||
__stub((mock) => {
|
__stub((mock) => {
|
||||||
mock.onGet('/api/v1/pleroma/chats')
|
mock.onGet('/api/v1/pleroma/chats')
|
||||||
|
@ -218,7 +219,13 @@ describe('useChats', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('useChat()', () => {
|
describe('useChat()', () => {
|
||||||
|
const relationshipId = '123';
|
||||||
|
let store: Store;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
const state = rootState;
|
||||||
|
store = createTestStore(state);
|
||||||
|
|
||||||
queryClient.clear();
|
queryClient.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -226,14 +233,21 @@ describe('useChat()', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
__stub((mock) => {
|
__stub((mock) => {
|
||||||
mock.onGet(`/api/v1/pleroma/chats/${chat.id}`).reply(200, chat);
|
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 () => {
|
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));
|
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);
|
expect(result.current.data.id).toBe(chat.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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 { InfiniteData, useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
|
||||||
import sumBy from 'lodash/sumBy';
|
import sumBy from 'lodash/sumBy';
|
||||||
|
|
||||||
import { fetchRelationships } from 'soapbox/actions/accounts';
|
|
||||||
import { importFetchedAccount, importFetchedAccounts } from 'soapbox/actions/importer';
|
import { importFetchedAccount, importFetchedAccounts } from 'soapbox/actions/importer';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
import { getNextLink } from 'soapbox/api';
|
import { getNextLink } from 'soapbox/api';
|
||||||
|
@ -13,6 +12,7 @@ import { normalizeChatMessage } from 'soapbox/normalizers';
|
||||||
import { flattenPages, PaginatedResult, updatePageItem } from 'soapbox/utils/queries';
|
import { flattenPages, PaginatedResult, updatePageItem } from 'soapbox/utils/queries';
|
||||||
|
|
||||||
import { queryClient } from './client';
|
import { queryClient } from './client';
|
||||||
|
import { useFetchRelationships } from './relationships';
|
||||||
|
|
||||||
import type { IAccount } from './accounts';
|
import type { IAccount } from './accounts';
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ const useChats = (search?: string) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { setUnreadChatsCount } = useStatContext();
|
const { setUnreadChatsCount } = useStatContext();
|
||||||
|
const fetchRelationships = useFetchRelationships();
|
||||||
|
|
||||||
const getChats = async (pageParam?: any): Promise<PaginatedResult<IChat>> => {
|
const getChats = async (pageParam?: any): Promise<PaginatedResult<IChat>> => {
|
||||||
const endpoint = features.chatsV2 ? '/api/v2/pleroma/chats' : '/api/v1/pleroma/chats';
|
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));
|
setUnreadChatsCount(Number(response.headers['x-unread-messages-count']) || sumBy(data, (chat) => chat.unread));
|
||||||
|
|
||||||
// Set the relationships to these users in the redux store.
|
// 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)));
|
dispatch(importFetchedAccounts(data.map((item) => item.account)));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -183,12 +184,13 @@ const useChats = (search?: string) => {
|
||||||
const useChat = (chatId?: string) => {
|
const useChat = (chatId?: string) => {
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const fetchRelationships = useFetchRelationships();
|
||||||
|
|
||||||
const getChat = async () => {
|
const getChat = async () => {
|
||||||
if (chatId) {
|
if (chatId) {
|
||||||
const { data } = await api.get<IChat>(`/api/v1/pleroma/chats/${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));
|
dispatch(importFetchedAccount(data.account));
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -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 };
|
Ładowanie…
Reference in New Issue