mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 02:44:55 +00:00
Merge pull request #13423 from strapi/features/ML-folder-bulk-move
ML: Add bulk move hook
This commit is contained in:
commit
5f6d3779fa
223
packages/core/upload/admin/src/hooks/tests/useBulkMove.test.js
Normal file
223
packages/core/upload/admin/src/hooks/tests/useBulkMove.test.js
Normal file
@ -0,0 +1,223 @@
|
||||
import React from 'react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { QueryClientProvider, QueryClient, useQueryClient } from 'react-query';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { BrowserRouter as Router, Route } from 'react-router-dom';
|
||||
|
||||
import { NotificationsProvider, useNotification } from '@strapi/helper-plugin';
|
||||
|
||||
import { axiosInstance } from '../../utils';
|
||||
import { useBulkMove } from '../useBulkMove';
|
||||
|
||||
const FIXTURE_ASSETS = [
|
||||
{
|
||||
id: 1,
|
||||
type: 'asset',
|
||||
},
|
||||
|
||||
{
|
||||
id: 2,
|
||||
type: 'asset',
|
||||
},
|
||||
];
|
||||
|
||||
const FIXTURE_FOLDERS = [
|
||||
{
|
||||
id: 11,
|
||||
type: 'folder',
|
||||
},
|
||||
|
||||
{
|
||||
id: 12,
|
||||
type: 'folder',
|
||||
},
|
||||
];
|
||||
|
||||
const FIXTURE_DESTINATION_FOLDER_ID = 1;
|
||||
|
||||
console.error = jest.fn().mockImplementation();
|
||||
|
||||
jest.mock('../../utils', () => ({
|
||||
...jest.requireActual('../../utils'),
|
||||
axiosInstance: {
|
||||
post: jest.fn((url, payload) => {
|
||||
const res = { data: { data: {} } };
|
||||
|
||||
if (payload?.fileIds) {
|
||||
res.data.data.files = FIXTURE_ASSETS;
|
||||
}
|
||||
|
||||
if (payload?.folderIds) {
|
||||
res.data.data.folders = FIXTURE_FOLDERS;
|
||||
}
|
||||
|
||||
return Promise.resolve(res);
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
const notificationStatusMock = jest.fn();
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
...jest.requireActual('@strapi/helper-plugin'),
|
||||
useNotification: () => notificationStatusMock,
|
||||
}));
|
||||
|
||||
const refetchQueriesMock = jest.fn();
|
||||
|
||||
jest.mock('react-query', () => ({
|
||||
...jest.requireActual('react-query'),
|
||||
useQueryClient: () => ({
|
||||
refetchQueries: refetchQueriesMock,
|
||||
}),
|
||||
}));
|
||||
|
||||
const client = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
function ComponentFixture({ children }) {
|
||||
return (
|
||||
<Router>
|
||||
<Route>
|
||||
<QueryClientProvider client={client}>
|
||||
<NotificationsProvider toggleNotification={() => jest.fn()}>
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
{children}
|
||||
</IntlProvider>
|
||||
</NotificationsProvider>
|
||||
</QueryClientProvider>
|
||||
</Route>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
function setup(...args) {
|
||||
return new Promise(resolve => {
|
||||
act(() => {
|
||||
resolve(renderHook(() => useBulkMove(...args), { wrapper: ComponentFixture }));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('useBulkMove', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('does call the proper endpoint', async () => {
|
||||
const {
|
||||
result: { current },
|
||||
} = await setup();
|
||||
const { move } = current;
|
||||
|
||||
await act(async () => {
|
||||
await move(FIXTURE_DESTINATION_FOLDER_ID, FIXTURE_ASSETS);
|
||||
});
|
||||
|
||||
expect(axiosInstance.post).toHaveBeenCalledWith(
|
||||
'/upload/actions/bulk-move',
|
||||
expect.any(Object)
|
||||
);
|
||||
});
|
||||
|
||||
test('does properly collect all asset ids', async () => {
|
||||
const {
|
||||
result: { current },
|
||||
} = await setup();
|
||||
const { move } = current;
|
||||
|
||||
await act(async () => {
|
||||
await move(FIXTURE_DESTINATION_FOLDER_ID, FIXTURE_ASSETS);
|
||||
});
|
||||
|
||||
expect(axiosInstance.post).toHaveBeenCalledWith(expect.any(String), {
|
||||
destinationFolderId: FIXTURE_DESTINATION_FOLDER_ID,
|
||||
fileIds: FIXTURE_ASSETS.map(({ id }) => id),
|
||||
});
|
||||
});
|
||||
|
||||
test('does properly collect all folder ids', async () => {
|
||||
const {
|
||||
result: { current },
|
||||
} = await setup();
|
||||
const { move } = current;
|
||||
|
||||
await act(async () => {
|
||||
await move(FIXTURE_DESTINATION_FOLDER_ID, FIXTURE_FOLDERS);
|
||||
});
|
||||
|
||||
expect(axiosInstance.post).toHaveBeenCalledWith(expect.any(String), {
|
||||
destinationFolderId: FIXTURE_DESTINATION_FOLDER_ID,
|
||||
folderIds: FIXTURE_FOLDERS.map(({ id }) => id),
|
||||
});
|
||||
});
|
||||
|
||||
test('does properly collect folder and asset ids', async () => {
|
||||
const {
|
||||
result: { current },
|
||||
} = await setup();
|
||||
const { move } = current;
|
||||
|
||||
await act(async () => {
|
||||
await move(FIXTURE_DESTINATION_FOLDER_ID, [...FIXTURE_FOLDERS, ...FIXTURE_ASSETS]);
|
||||
});
|
||||
|
||||
expect(axiosInstance.post).toHaveBeenCalledWith(expect.any(String), {
|
||||
destinationFolderId: FIXTURE_DESTINATION_FOLDER_ID,
|
||||
fileIds: FIXTURE_ASSETS.map(({ id }) => id),
|
||||
folderIds: FIXTURE_FOLDERS.map(({ id }) => id),
|
||||
});
|
||||
});
|
||||
|
||||
test('does re-fetch assets, if files were deleted', async () => {
|
||||
const toggleNotification = useNotification();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const {
|
||||
result: { current },
|
||||
waitFor,
|
||||
} = await setup();
|
||||
const { move } = current;
|
||||
|
||||
await act(async () => {
|
||||
await move(FIXTURE_DESTINATION_FOLDER_ID, FIXTURE_ASSETS);
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(queryClient.refetchQueries).toHaveBeenCalledWith(['upload', 'assets'], {
|
||||
active: true,
|
||||
})
|
||||
);
|
||||
|
||||
await waitFor(() => expect(toggleNotification).toHaveBeenCalled());
|
||||
});
|
||||
|
||||
test('does re-fetch folders, if folders were deleted', async () => {
|
||||
const queryClient = useQueryClient();
|
||||
const toggleNotification = useNotification();
|
||||
|
||||
const {
|
||||
result: { current },
|
||||
waitFor,
|
||||
} = await setup();
|
||||
const { move } = current;
|
||||
|
||||
await act(async () => {
|
||||
await move(FIXTURE_DESTINATION_FOLDER_ID, FIXTURE_FOLDERS);
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(queryClient.refetchQueries).toHaveBeenCalledWith(['upload', 'folders'], {
|
||||
active: true,
|
||||
})
|
||||
);
|
||||
|
||||
await waitFor(() => expect(toggleNotification).toHaveBeenCalled());
|
||||
});
|
||||
});
|
||||
61
packages/core/upload/admin/src/hooks/useBulkMove.js
Normal file
61
packages/core/upload/admin/src/hooks/useBulkMove.js
Normal file
@ -0,0 +1,61 @@
|
||||
import { useMutation, useQueryClient } from 'react-query';
|
||||
import { useNotification } from '@strapi/helper-plugin';
|
||||
|
||||
import pluginId from '../pluginId';
|
||||
import { axiosInstance, getRequestUrl, getTrad } from '../utils';
|
||||
|
||||
export const useBulkMove = () => {
|
||||
const toggleNotification = useNotification();
|
||||
const queryClient = useQueryClient();
|
||||
const url = getRequestUrl('actions/bulk-move');
|
||||
|
||||
const bulkMoveQuery = ({ destinationFolderId, filesAndFolders }) => {
|
||||
const payload = filesAndFolders.reduce((acc, selected) => {
|
||||
const { id, type } = selected;
|
||||
const key = type === 'asset' ? 'fileIds' : 'folderIds';
|
||||
|
||||
if (!acc[key]) {
|
||||
acc[key] = [];
|
||||
}
|
||||
|
||||
acc[key].push(id);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return axiosInstance.post(url, { ...payload, destinationFolderId });
|
||||
};
|
||||
|
||||
const mutation = useMutation(bulkMoveQuery, {
|
||||
onSuccess: res => {
|
||||
const {
|
||||
data: { data },
|
||||
} = res;
|
||||
|
||||
if (data?.files?.length > 0) {
|
||||
queryClient.refetchQueries([pluginId, 'assets'], { active: true });
|
||||
queryClient.refetchQueries([pluginId, 'asset-count'], { active: true });
|
||||
}
|
||||
|
||||
if (data?.folders?.length > 0) {
|
||||
queryClient.refetchQueries([pluginId, 'folders'], { active: true });
|
||||
}
|
||||
|
||||
toggleNotification({
|
||||
type: 'success',
|
||||
message: {
|
||||
id: getTrad('modal.move.success-label'),
|
||||
defaultMessage: 'Changes successfully saved',
|
||||
},
|
||||
});
|
||||
},
|
||||
onError: error => {
|
||||
toggleNotification({ type: 'warning', message: error.message });
|
||||
},
|
||||
});
|
||||
|
||||
const move = (destinationFolderId, filesAndFolders) =>
|
||||
mutation.mutateAsync({ destinationFolderId, filesAndFolders });
|
||||
|
||||
return { ...mutation, move };
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user