Skip to content

Commit

Permalink
fixup: CR suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
addaleax committed Oct 24, 2024
1 parent 724724e commit 9c27dd7
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 50 deletions.
109 changes: 80 additions & 29 deletions packages/compass-components/src/components/file-input.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,15 +256,25 @@ describe('FileInput', function () {
describe('when a file is chosen', function () {
beforeEach(async function () {
render(
<FileInput
id="file-input"
label="Select something"
dataTestId="test-file-input"
onChange={spy}
error={true}
errorMessage={'Error'}
mode="open"
/>
<FileInputBackendProvider
createFileInputBackend={() =>
({
getPathForFile() {
return 'a/b/c';
},
} as any)
}
>
<FileInput
id="file-input"
label="Select something"
dataTestId="test-file-input"
onChange={spy}
error={true}
errorMessage={'Error'}
mode="open"
/>
</FileInputBackendProvider>
);

const fileInput = screen.getByTestId('test-file-input');
Expand All @@ -284,7 +294,7 @@ describe('FileInput', function () {

it('calls onChange with the chosen file', function () {
expect(spy.callCount).to.equal(1);
expect(spy.firstCall.args[0]).to.deep.equal([undefined]); // cannot get the actual path without electron
expect(spy.firstCall.args[0]).to.deep.equal(['a/b/c']);
});
});

Expand Down Expand Up @@ -343,13 +353,19 @@ describe('FileInput', function () {
showOpenDialog: sinon.stub(),
},
};
return { fakeElectron, fakeWindow };
const fakeWebUtils = {
getPathForFile: sinon.stub().returns('a/b/c'),
};
return { fakeElectron, fakeWindow, fakeWebUtils };
}

it('allows using electron-style APIs for file updates', async function () {
const { fakeElectron, fakeWindow } = createFakeElectron();
const { fakeElectron, fakeWindow, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(fakeElectron)();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();
const listener = sinon.stub();
const unsubscribe = backend.onFilesChosen(listener);

Expand Down Expand Up @@ -378,10 +394,24 @@ describe('FileInput', function () {
expect(fakeElectron.dialog.showSaveDialog).to.have.been.calledTwice;
});

it('passes through getPathForFile calls', function () {
const { fakeElectron, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();

expect(backend.getPathForFile({} as any)).to.equal('a/b/c');
});

it('can partially handle browser-compatible accept values', function () {
const { fakeElectron, fakeWindow } = createFakeElectron();
const { fakeElectron, fakeWindow, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(fakeElectron)();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();

fakeElectron.dialog.showSaveDialog.resolves({
canceled: true,
Expand All @@ -404,9 +434,12 @@ describe('FileInput', function () {
});

it('does not override existing file filters', function () {
const { fakeElectron, fakeWindow } = createFakeElectron();
const { fakeElectron, fakeWindow, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(fakeElectron)();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();

fakeElectron.dialog.showSaveDialog.resolves({
canceled: true,
Expand All @@ -430,9 +463,12 @@ describe('FileInput', function () {
});

it('handles multi:false', function () {
const { fakeElectron, fakeWindow } = createFakeElectron();
const { fakeElectron, fakeWindow, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(fakeElectron)();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();

fakeElectron.dialog.showSaveDialog.resolves({
canceled: true,
Expand All @@ -452,9 +488,12 @@ describe('FileInput', function () {
});

it('handles multi:true', function () {
const { fakeElectron, fakeWindow } = createFakeElectron();
const { fakeElectron, fakeWindow, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(fakeElectron)();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();

fakeElectron.dialog.showSaveDialog.resolves({
canceled: true,
Expand All @@ -473,9 +512,12 @@ describe('FileInput', function () {
});

it('can call showOpenDialog if requested', async function () {
const { fakeElectron, fakeWindow } = createFakeElectron();
const { fakeElectron, fakeWindow, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(fakeElectron)();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();
const listener = sinon.stub();
backend.onFilesChosen(listener);

Expand All @@ -501,9 +543,12 @@ describe('FileInput', function () {
});

it('calls the listener with an empty array if the user canceled the request', async function () {
const { fakeElectron } = createFakeElectron();
const { fakeElectron, fakeWebUtils } = createFakeElectron();

const backend = createElectronFileInputBackend(fakeElectron)();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();
const listener = sinon.stub();
backend.onFilesChosen(listener);

Expand All @@ -521,8 +566,11 @@ describe('FileInput', function () {
});

it('handles autoOpen:true', async function () {
const { fakeElectron } = createFakeElectron();
const backend = createElectronFileInputBackend(fakeElectron)();
const { fakeElectron, fakeWebUtils } = createFakeElectron();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();

const listener = sinon.stub();
backend.onFilesChosen(listener);
Expand Down Expand Up @@ -577,8 +625,11 @@ describe('FileInput', function () {
let openFileChooserSpy: sinon.SinonSpy;

beforeEach(async function () {
const { fakeElectron } = createFakeElectron();
const backend = createElectronFileInputBackend(fakeElectron)();
const { fakeElectron, fakeWebUtils } = createFakeElectron();
const backend = createElectronFileInputBackend(
fakeElectron,
fakeWebUtils
)();

listener = sinon.stub();
backend.onFilesChosen(listener);
Expand Down
31 changes: 13 additions & 18 deletions packages/compass-components/src/components/file-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ export type FileInputBackend = {
// Should install a listener that is called when files have been selected.
// Should return an unsubscribe function.
onFilesChosen: (listener: (files: string[]) => void) => () => void;
// Gets the real on-disk path for a `File`, if the current environment supports it.
getPathForFile: (file: File) => string | undefined;
};

export const FileInputBackendContext = createContext<
Expand Down Expand Up @@ -191,6 +193,11 @@ export type ElectronShowFileDialogProvider<ElectronWindow> = {
};
};

export type ElectronWebUtilsProvider = {
// https://github.com/electron/electron/blob/83d704009687956fb4b69cb13ab03664d7950118/docs/breaking-changes.md#removed-filepath
getPathForFile(file: File): string;
};

export const FileInputBackendProvider: React.FunctionComponent<{
createFileInputBackend: (() => FileInputBackend) | null;
}> = ({ children, createFileInputBackend }) => {
Expand All @@ -211,7 +218,8 @@ export const FileInputBackendProvider: React.FunctionComponent<{
// <FileInput ... />
// <FileInputBackendProvider/>
export function createElectronFileInputBackend<ElectronWindow>(
electron: ElectronShowFileDialogProvider<ElectronWindow>
electron: ElectronShowFileDialogProvider<ElectronWindow>,
webUtils: ElectronWebUtilsProvider | null
): () => FileInputBackend {
return () => {
const listeners: ((files: string[]) => void)[] = [];
Expand Down Expand Up @@ -282,24 +290,13 @@ export function createElectronFileInputBackend<ElectronWindow>(
if (index !== -1) listeners.splice(index, 1);
};
},
getPathForFile(file: File): string | undefined {
return webUtils?.getPathForFile(file);
},
};
};
}

// eslint-disable-next-line @typescript-eslint/consistent-type-imports
let _electron: typeof import('electron') | undefined | null;
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
function getElectronWebUtils(): typeof import('electron').webUtils | undefined {
if (_electron === undefined) {
try {
_electron = require('electron');
} catch {
_electron = null;
}
}
return _electron?.webUtils;
}

function FileInput({
autoOpen = false,
id,
Expand Down Expand Up @@ -365,9 +362,7 @@ function FileInput({
(evt: React.ChangeEvent<HTMLInputElement>) => {
const fileList = Array.from(evt.currentTarget.files ?? []);
const files = fileList.map((file) => {
// https://github.com/electron/electron/blob/83d704009687956fb4b69cb13ab03664d7950118/docs/breaking-changes.md#removed-filepath
// eslint-disable-next-line @typescript-eslint/no-var-requires
return getElectronWebUtils()?.getPathForFile(file);
return backend?.getPathForFile(file) ?? '';
});
onChange(files);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ function ExportModal({
const onClickExport = useCallback(() => {
// eslint-disable-next-line @typescript-eslint/consistent-type-imports, @typescript-eslint/no-var-requires
const electron: typeof import('@electron/remote') = require('@electron/remote');
const fileBackend = createElectronFileInputBackend(electron)();
const fileBackend = createElectronFileInputBackend(electron, null)();

fileBackend.onFilesChosen((files: string[]) => {
if (files.length > 0) {
Expand Down
2 changes: 1 addition & 1 deletion packages/compass-workspaces/src/stores/workspaces.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('tabs behavior', function () {

function configureStore() {
const result = activatePluginWithConnections();
return result.plugin.store as WorkspacesStore;
return result.plugin.store;
}

function openTabs(
Expand Down
6 changes: 5 additions & 1 deletion packages/compass/src/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dns from 'dns';
import ensureError from 'ensure-error';
import { ipcRenderer } from 'hadron-ipc';
import * as remote from '@electron/remote';
import { webUtils } from 'electron';
import { globalAppRegistry } from 'hadron-app-registry';
import { defaultPreferencesInstance } from 'compass-preferences-model';
import semver from 'semver';
Expand Down Expand Up @@ -242,7 +243,10 @@ const Application = View.extend({
<CompassElectron
appName={remote.app.getName()}
showWelcomeModal={!wasNetworkOptInShown}
createFileInputBackend={createElectronFileInputBackend(remote)}
createFileInputBackend={createElectronFileInputBackend(
remote,
webUtils
)}
onDisconnect={notifyMainProcessOfDisconnect}
showCollectionSubMenu={showCollectionSubMenu}
hideCollectionSubMenu={hideCollectionSubMenu}
Expand Down

0 comments on commit 9c27dd7

Please sign in to comment.