feat: Implement basic general folder support (#2051)

- Related: #1748
This commit is contained in:
Dermot Duffy
2025-05-21 19:59:21 -07:00
committed by GitHub
parent 2eb0d9e35e
commit c6a4c8aea2
350 changed files with 12837 additions and 4509 deletions
@@ -1,9 +1,17 @@
import { expect, it } from 'vitest';
import { expect, it, vi } from 'vitest';
import { DownloadAction } from '../../../../src/card-controller/actions/actions/download';
import { createCardAPI } from '../../../test-utils';
import { QueryResults } from '../../../../src/view/query-results';
import { createCardAPI, createView, TestViewMedia } from '../../../test-utils';
it('should handle download action', async () => {
it('should handle download action with selected media', async () => {
const api = createCardAPI();
const selectedMedia = new TestViewMedia();
vi.mocked(api.getViewManager().getView).mockReturnValue(
createView({
queryResults: new QueryResults({ results: [selectedMedia], selectedIndex: 0 }),
}),
);
const action = new DownloadAction(
{},
{
@@ -14,5 +22,22 @@ it('should handle download action', async () => {
await action.execute(api);
expect(api.getDownloadManager().downloadViewerMedia).toBeCalled();
expect(api.getViewItemManager().download).toBeCalledWith(selectedMedia);
});
it('should handle download action without selected media', async () => {
const api = createCardAPI();
vi.mocked(api.getViewManager().getView).mockReturnValue(createView());
const action = new DownloadAction(
{},
{
action: 'fire-dom-event',
advanced_camera_card_action: 'download',
},
);
await action.execute(api);
expect(api.getViewItemManager().download).not.toBeCalled();
});
@@ -0,0 +1,86 @@
import { describe, expect, it, vi } from 'vitest';
import { FolderAction } from '../../../../src/card-controller/actions/actions/folder';
import { FolderQuery } from '../../../../src/card-controller/folders/types';
import { FolderViewQuery } from '../../../../src/view/query';
import { createCardAPI, createFolder } from '../../../test-utils';
describe('should handle folder action', async () => {
it('should handle folder action successfully', async () => {
const api = createCardAPI();
const action = new FolderAction(
{},
{
action: 'fire-dom-event',
advanced_camera_card_action: 'folder',
},
);
const folder = createFolder();
vi.mocked(api.getFoldersManager().getFolder).mockReturnValue(folder);
const query: FolderQuery = {
folder,
path: ['path'],
};
vi.mocked(api.getFoldersManager().generateDefaultFolderQuery).mockReturnValue(query);
await action.execute(api);
expect(
api.getViewManager().setViewByParametersWithExistingQuery,
).toHaveBeenCalledWith({
params: {
view: 'folder',
query: expect.any(FolderViewQuery),
},
});
expect(
vi
.mocked(api.getViewManager().setViewByParametersWithExistingQuery)
.mock.calls[0][0]?.params?.query?.getQuery(),
).toBe(query);
});
it('should do nothing with non-existent folder', async () => {
const api = createCardAPI();
const action = new FolderAction(
{},
{
action: 'fire-dom-event',
advanced_camera_card_action: 'folder',
folder: 'NON-EXISTENT-FOLDER',
},
);
vi.mocked(api.getFoldersManager().getFolder).mockReturnValue(null);
await action.execute(api);
expect(
api.getViewManager().setViewByParametersWithExistingQuery,
).not.toHaveBeenCalled();
});
it('should do nothing with non-existent default query', async () => {
const api = createCardAPI();
const action = new FolderAction(
{},
{
action: 'fire-dom-event',
advanced_camera_card_action: 'folder',
},
);
const folder = createFolder();
vi.mocked(api.getFoldersManager().getFolder).mockReturnValue(folder);
vi.mocked(api.getFoldersManager().generateDefaultFolderQuery).mockReturnValue(null);
await action.execute(api);
expect(
api.getViewManager().setViewByParametersWithExistingQuery,
).not.toHaveBeenCalled();
});
});
@@ -1,18 +1,62 @@
import { expect, it } from 'vitest';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { mock } from 'vitest-mock-extended';
import { ScreenshotAction } from '../../../../src/card-controller/actions/actions/screenshot';
import { createCardAPI } from '../../../test-utils';
import { MediaPlayerController } from '../../../../src/types';
import { downloadURL } from '../../../../src/utils/download';
import { createCardAPI, createMediaLoadedInfo } from '../../../test-utils';
it('should handle screenshot action', async () => {
const api = createCardAPI();
const action = new ScreenshotAction(
{},
{
action: 'fire-dom-event',
advanced_camera_card_action: 'screenshot',
},
);
vi.mock('../../../../src/utils/download');
await action.execute(api);
describe('should handle screenshot action', async () => {
afterEach(() => {
vi.clearAllMocks();
});
expect(api.getDownloadManager().downloadScreenshot).toBeCalled();
it('should handle screenshot action with screenshot URL', async () => {
const api = createCardAPI();
const action = new ScreenshotAction(
{},
{
action: 'fire-dom-event',
advanced_camera_card_action: 'screenshot',
},
);
const mediaPlayerController = mock<MediaPlayerController>();
mediaPlayerController.getScreenshotURL.mockResolvedValue('screenshot-url');
vi.mocked(api.getMediaLoadedInfoManager().get).mockReturnValue(
createMediaLoadedInfo({
mediaPlayerController,
}),
);
await action.execute(api);
expect(downloadURL).toBeCalledWith('screenshot-url', 'screenshot.jpg');
});
it('should handle screenshot action without screenshot URL', async () => {
const api = createCardAPI();
const action = new ScreenshotAction(
{},
{
action: 'fire-dom-event',
advanced_camera_card_action: 'screenshot',
},
);
const mediaPlayerController = mock<MediaPlayerController>();
mediaPlayerController.getScreenshotURL.mockResolvedValue(null);
vi.mocked(api.getMediaLoadedInfoManager().get).mockReturnValue(
createMediaLoadedInfo({
mediaPlayerController,
}),
);
await action.execute(api);
expect(downloadURL).not.toBeCalled();
});
});
@@ -1,13 +1,9 @@
import { afterAll, expect, it, vi } from 'vitest';
import { createCardAPI } from '../../../test-utils';
import { expect, it, vi } from 'vitest';
import { SleepAction } from '../../../../src/card-controller/actions/actions/sleep';
import { sleep } from '../../../../src/utils/basic';
import { sleep } from '../../../../src/utils/sleep';
import { createCardAPI } from '../../../test-utils';
vi.mock('../../../../src/utils/basic');
afterAll(() => {
vi.restoreAllMocks();
});
vi.mock('../../../../src/utils/sleep');
it('should handle sleep action', async () => {
const api = createCardAPI();