chore(main): prefer-import-in-mock (#17133)

* chore(main): prefer-import-in-mock

Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>

* fix: type issue

Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>

---------

Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>
This commit is contained in:
axel7083 2026-04-21 09:24:57 +02:00 committed by GitHub
parent a94fd69497
commit 22edd8a72c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 366 additions and 359 deletions

View file

@ -16,6 +16,7 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import type * as Electron from 'electron';
import { Menu } from 'electron';
import { aboutMenuItem } from 'electron-util/main';
import { beforeEach, expect, test, vi } from 'vitest';
@ -23,7 +24,7 @@ import { beforeEach, expect, test, vi } from 'vitest';
import { ApplicationMenuBuilder } from './application-menu-builder.js';
import type { ZoomLevelHandler } from './plugin/zoom-level-handler.js';
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
class MyCustomWindow {
static readonly singleton = new MyCustomWindow();
@ -53,10 +54,10 @@ vi.mock('electron', async () => {
getApplicationMenu: vi.fn(),
setApplicationMenu: vi.fn(),
},
};
} as unknown as typeof Electron;
});
vi.mock('electron-util/main', async () => {
vi.mock(import('electron-util/main'), async () => {
return {
aboutMenuItem: vi.fn(),
};

View file

@ -16,12 +16,13 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import type Electron from 'electron';
import { BrowserWindow } from 'electron';
import { beforeEach, expect, test, vi } from 'vitest';
import { findWindow } from './electron-util.js';
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
class MyCustomWindow {
static readonly singleton = new MyCustomWindow();
@ -46,7 +47,7 @@ vi.mock('electron', async () => {
return {
BrowserWindow: MyCustomWindow,
};
} as unknown as typeof Electron;
});
beforeEach(() => {

View file

@ -17,6 +17,7 @@
***********************************************************************/
import type { IConfigurationChangeEvent, IConfigurationRegistry } from '@podman-desktop/core-api/configuration';
import type Electron from 'electron';
import type { App } from 'electron';
import { app, BrowserWindow, Menu } from 'electron';
import { aboutMenuItem } from 'electron-util/main';
@ -43,15 +44,16 @@ const constants = vi.hoisted(() => {
});
/* eslint-disable @typescript-eslint/no-empty-function */
vi.mock('electron-is-dev', async () => {
/* eslint-disable import/no-extraneous-dependencies */
vi.mock(import('electron-is-dev'), async () => {
return {};
});
vi.mock('electron-context-menu', async () => {
vi.mock(import('electron-context-menu'), async () => {
return {
default: vi.fn(),
};
});
vi.mock('electron-util/main', async () => {
vi.mock(import('electron-util/main'), async () => {
return {
aboutMenuItem: vi.fn().mockReturnValue({ label: 'foo' }),
};
@ -85,7 +87,7 @@ vi.mock(import('./util.js'), () => ({
isLinux: vi.fn().mockReturnValue(false),
}));
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
autoUpdater: {
on: vi.fn(),
@ -154,7 +156,7 @@ vi.mock('electron', async () => {
setContextMenu = vi.fn();
},
),
};
} as unknown as typeof Electron;
});
beforeEach(() => {

View file

@ -27,9 +27,9 @@ import { isLinux, isMac, isWindows } from '/@/util.js';
import { Main } from './main.js';
// mock electron
vi.mock('electron');
vi.mock('/@/util.js');
vi.mock('/@/security-restrictions.js');
vi.mock(import('electron'));
vi.mock(import('/@/util.js'));
vi.mock(import('/@/security-restrictions.js'));
vi.mock(import('electron-context-menu'), () => ({
default: vi.fn(),
}));

View file

@ -17,6 +17,7 @@
***********************************************************************/
import type { Configuration } from '@podman-desktop/api';
import type Electron from 'electron';
import { app, BrowserWindow, ipcMain, screen } from 'electron';
import { afterEach, assert, beforeEach, describe, expect, test, vi } from 'vitest';
@ -40,7 +41,7 @@ vi.mock(import('./util.js'), async () => ({
stoppedExtensions: { val: true },
}));
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
autoUpdater: {
on: vi.fn(),
@ -70,7 +71,7 @@ vi.mock('electron', async () => {
BrowserWindow: Object.assign(vi.fn(), {
getAllWindows: vi.fn().mockReturnValue([]),
}),
};
} as unknown as typeof Electron;
});
let originalArgv: string[] = [];

View file

@ -24,7 +24,7 @@ import { isWindows } from '/@/util.js';
import { DefaultProtocolClient } from './default-protocol-client.js';
vi.mock('/@/util.js');
vi.mock(import('/@/util.js'));
const ELECTRON_APP_MOCK: ElectronApp = {
setAsDefaultProtocolClient: vi.fn(),

View file

@ -19,6 +19,7 @@
import type { ApiSenderType } from '@podman-desktop/core-api/api-sender';
import { AppearanceSettings } from '@podman-desktop/core-api/appearance';
import type { IConfigurationChangeEvent } from '@podman-desktop/core-api/configuration';
import type Electron from 'electron';
import { nativeTheme } from 'electron';
import { beforeAll, expect, test, vi } from 'vitest';
@ -30,10 +31,10 @@ import type { LockedConfiguration } from './locked-configuration.js';
let configurationRegistry: ConfigurationRegistry;
vi.mock('electron', () => {
vi.mock(import('electron'), () => {
return {
nativeTheme: {},
};
} as unknown as typeof Electron;
});
const apiSender: ApiSenderType = {

View file

@ -33,25 +33,25 @@ const END_CERTIFICATE = '-----END CERTIFICATE-----';
const CR = '\n';
// mock spawn
vi.mock('node:child_process', () => {
vi.mock(import('node:child_process'), () => {
return {
spawn: vi.fn(),
};
});
vi.mock('./util/spawn-promise.js', () => {
vi.mock(import('./util/spawn-promise.js'), () => {
return {
spawnWithPromise: vi.fn(),
};
});
vi.mock('node:fs');
vi.mock(import('node:fs'));
// Fake root certificates for mocking tls.rootCertificates
// These are simple fake PEM strings (not valid X.509, but sufficient for testing fallback behavior)
const FAKE_ROOT_CERTIFICATES = ['fake-cert-1', 'fake-cert-2'];
vi.mock('node:tls', () => {
vi.mock(import('node:tls'), () => {
return {
rootCertificates: ['fake-cert-1', 'fake-cert-2'],
};
@ -73,7 +73,7 @@ interface WincaAPIOptions {
onend?: () => void;
}
vi.mock('win-ca/api', () => {
vi.mock(import('win-ca/api'), () => {
const wincaAPI = vi.fn();
(wincaAPI as unknown as WincaProcedure).exe = vi.fn();
(wincaAPI as unknown as WincaProcedure).inject = vi.fn();

View file

@ -26,7 +26,7 @@ import type { DefaultConfiguration } from './default-configuration.js';
import type { Directories } from './directories.js';
import type { LockedConfiguration } from './locked-configuration.js';
vi.mock('./util', () => {
vi.mock(import('/@/util.js'), () => {
return {
isUnixLike: vi.fn(),
};

View file

@ -17,7 +17,8 @@
***********************************************************************/
// Import to access mocked functionionalities such as using vi.mock (we don't want to actually call node:fs methods)
import * as fs from 'node:fs';
import { cpSync, readFileSync, writeFileSync } from 'node:fs';
import { access, copyFile, mkdir, readFile, writeFile } from 'node:fs/promises';
import type { IDisposable } from '@podman-desktop/core-api';
import type { ApiSenderType } from '@podman-desktop/core-api/api-sender';
@ -35,17 +36,18 @@ import type { LockedConfiguration } from './locked-configuration.js';
import type { NotificationRegistry } from './tasks/notification-registry.js';
// mock the fs module
vi.mock('node:fs', () => ({
vi.mock(import('node:fs'), () => ({
readFileSync: vi.fn(),
writeFileSync: vi.fn(),
cpSync: vi.fn(),
promises: {
access: vi.fn(),
mkdir: vi.fn(),
writeFile: vi.fn(),
readFile: vi.fn(),
copyFile: vi.fn(),
},
}));
vi.mock(import('node:fs/promises'), () => ({
access: vi.fn(),
mkdir: vi.fn(),
writeFile: vi.fn(),
readFile: vi.fn(),
copyFile: vi.fn(),
}));
// mock DefaultConfiguration for the new managed defaults functionality
@ -93,19 +95,19 @@ beforeEach(async () => {
getManagedDefaultsDirectoryMock.mockReturnValue('/usr/share/podman-desktop');
// Mock basic fs functions needed for initialization
const readFileSync = vi.mocked(fs.readFileSync);
const accessMock = vi.mocked(fs.promises.access);
const mkdirMock = vi.mocked(fs.promises.mkdir);
const writeFileMock = vi.mocked(fs.promises.writeFile);
const readFileMock = vi.mocked(fs.promises.readFile);
const cpSync = vi.mocked(fs.cpSync);
const readFileSyncMock = vi.mocked(readFileSync);
const accessMock = vi.mocked(access);
const mkdirMock = vi.mocked(mkdir);
const writeFileMock = vi.mocked(writeFile);
const readFileMock = vi.mocked(readFile);
const cpSyncMock = vi.mocked(cpSync);
readFileSync.mockReturnValue(JSON.stringify({}));
readFileSyncMock.mockReturnValue(JSON.stringify({}));
accessMock.mockResolvedValue(undefined);
mkdirMock.mockResolvedValue(undefined);
writeFileMock.mockResolvedValue(undefined);
readFileMock.mockResolvedValue(JSON.stringify({}));
cpSync.mockReturnValue(undefined);
cpSyncMock.mockReturnValue(undefined);
// Setup DefaultConfiguration mock for the new functionality
getContentMock.mockResolvedValue({});
@ -224,17 +226,17 @@ test('Should not find configuration after dispose', async () => {
test('should work with an invalid configuration file', async () => {
// Mock fs functions needed for this specific test
const readFileSync = vi.mocked(fs.readFileSync);
const accessMock = vi.mocked(fs.promises.access);
const readFileMock = vi.mocked(fs.promises.readFile);
const copyFileMock = vi.mocked(fs.promises.copyFile);
const readFileSyncMock = vi.mocked(readFileSync);
const accessMock = vi.mocked(access);
const readFileMock = vi.mocked(readFile);
const copyFileMock = vi.mocked(copyFile);
getConfigurationDirectoryMock.mockReturnValue('/my-config-dir');
configurationRegistry = new ConfigurationRegistry(apiSender, directories, defaultConfiguration, lockedConfiguration);
readFileSync.mockReturnValue('invalid JSON content');
readFileSyncMock.mockReturnValue('invalid JSON content');
// Mock fs.promises methods for this test
// Mock promises methods for this test
accessMock.mockResolvedValue(undefined);
readFileMock.mockResolvedValue('invalid JSON content');
copyFileMock.mockResolvedValue(undefined);
@ -394,7 +396,7 @@ describe('should be notified when a configuration is updated', async () => {
test('should remove the object configuration if value is equal to default one', async () => {
// Mock fs function needed for this specific test
const writeFileSync = vi.mocked(fs.writeFileSync);
const writeFileSyncMock = vi.mocked(writeFileSync);
const node: IConfigurationNode = {
id: 'custom',
@ -434,7 +436,7 @@ test('should remove the object configuration if value is equal to default one',
{ label: 'bar', value: 2 },
]);
expect(writeFileSync).toHaveBeenNthCalledWith(
expect(writeFileSyncMock).toHaveBeenNthCalledWith(
2,
expect.anything(),
expect.stringContaining(JSON.stringify({}, undefined, 2)),
@ -443,11 +445,11 @@ test('should remove the object configuration if value is equal to default one',
// Tests for applyManagedDefaults method
describe('applyManagedDefaults function tests', () => {
let writeFileSync: ReturnType<typeof vi.mocked<typeof fs.writeFileSync>>;
let writeFileSyncMock: ReturnType<typeof vi.mocked<typeof writeFileSync>>;
beforeEach(() => {
writeFileSync = vi.mocked(fs.writeFileSync);
writeFileSync.mockClear();
writeFileSyncMock = vi.mocked(writeFileSync);
writeFileSyncMock.mockClear();
});
test('apply default-config.json values to undefined keys in config', async () => {
@ -482,8 +484,8 @@ describe('applyManagedDefaults function tests', () => {
'setting.bar': 'defaultValue2',
};
// Mock fs.promises.readFile to return user settings.json
const readFileMock = vi.mocked(fs.promises.readFile);
// Mock readFile to return user settings.json
const readFileMock = vi.mocked(readFile);
readFileMock.mockResolvedValue(JSON.stringify(userSettings));
getContentMock.mockResolvedValue(managedDefaults);
@ -650,12 +652,12 @@ describe('applyManagedDefaults function tests', () => {
// Clear previous calls and trigger saveDefault to check what would be written
// now that configurations are registered
writeFileSync.mockClear();
writeFileSyncMock.mockClear();
testRegistry.saveDefault();
// The value should NOT be in the settings.json since it matches the schema default
expect(writeFileSync).toHaveBeenCalled();
const writtenContent = JSON.parse(writeFileSync.mock.calls[0]?.[1] as string);
expect(writeFileSyncMock).toHaveBeenCalled();
const writtenContent = JSON.parse(writeFileSyncMock.mock.calls[0]?.[1] as string);
expect(writtenContent['my.fake.property']).toBeUndefined();
});
@ -686,12 +688,12 @@ describe('applyManagedDefaults function tests', () => {
testRegistry.registerConfigurations([node]);
// Clear previous calls and trigger saveDefault to check what would be written
writeFileSync.mockClear();
writeFileSyncMock.mockClear();
testRegistry.saveDefault();
// The value SHOULD be in the settings.json since it differs from schema default
expect(writeFileSync).toHaveBeenCalled();
const writtenContent = JSON.parse(writeFileSync.mock.calls[0]?.[1] as string);
expect(writeFileSyncMock).toHaveBeenCalled();
const writtenContent = JSON.parse(writeFileSyncMock.mock.calls[0]?.[1] as string);
expect(writtenContent['my.fake.property']).toEqual('customValue');
});
});

View file

@ -17,7 +17,7 @@
***********************************************************************/
import * as fs from 'node:fs';
import { promises as fsPromises } from 'node:fs';
import * as fsPromises from 'node:fs/promises';
import * as path from 'node:path';
import { isDeepStrictEqual } from 'node:util';

View file

@ -421,25 +421,16 @@ const configurationRegistry = {
getConfiguration: getConfigurationMock,
} as unknown as ConfigurationRegistry;
vi.mock('node:fs', async () => {
return {
promises: {
readdir: vi.fn(),
},
createWriteStream: vi.fn(),
existsSync: vi.fn(),
};
});
vi.mock('node:stream/promises', async () => {
vi.mock(import('node:fs'));
vi.mock(import('node:stream/promises'), async () => {
return {
pipeline: vi.fn(),
readFile: vi.fn(),
};
});
vi.mock('node:fs/promises');
vi.mock('/@/plugin/podman/kube.js');
vi.mock(import('node:fs/promises'));
vi.mock(import('/@/plugin/podman/kube.js'));
beforeEach(() => {
vi.mocked(apiSender.receive).mockClear();

View file

@ -35,6 +35,11 @@ import type { Directories } from './directories.js';
import type { Proxy } from './proxy.js';
import { Exec } from './util/exec.js';
vi.mock(import('node:fs'));
vi.mock(import('/@/plugin/util/exec.js'));
vi.mock(import('/@/util.js'));
vi.mock(import('js-yaml'));
let contributionManager: TestContributionManager;
let composeFileExample: ComposeObject;
@ -216,9 +221,6 @@ test('Should add a service to expose port if socket', async () => {
});
test('Check invalid port file', async () => {
vi.mock('node:fs');
vi.mock('js-yaml');
const metadata = {
vm: {
composefile: 'dummy-compose-file',
@ -314,20 +316,7 @@ test('waitForAContainerConnection delayed twice', async () => {
});
describe('findComposeBinary', () => {
vi.mock('./util', () => {
return {
isWindows: vi.fn(),
isMac: vi.fn(),
isUnixLike: vi.fn(),
exec: vi.fn(),
};
});
vi.mock(import('/@/plugin/util/exec.js'));
test('Check findComposeBinary on Windows', async () => {
vi.mock('node:fs');
vi.spyOn(util, 'isWindows').mockImplementation(() => true);
// mock exec
@ -339,8 +328,6 @@ describe('findComposeBinary', () => {
});
test('Check findComposeBinary not exists on Windows', async () => {
vi.mock('node:fs');
vi.spyOn(util, 'isWindows').mockImplementation(() => true);
// mock exec
@ -353,8 +340,6 @@ describe('findComposeBinary', () => {
});
test('Check findComposeBinary on macOS', async () => {
vi.mock('node:fs');
vi.spyOn(util, 'isMac').mockImplementation(() => true);
vi.spyOn(util, 'isWindows').mockImplementation(() => false);
@ -371,8 +356,6 @@ describe('findComposeBinary', () => {
});
test('Check findComposeBinary on Linux', async () => {
vi.mock('node:fs');
vi.spyOn(util, 'isUnixLike').mockImplementation(() => true);
vi.spyOn(util, 'isMac').mockImplementation(() => false);
vi.spyOn(util, 'isWindows').mockImplementation(() => false);
@ -698,8 +681,6 @@ test('delete extension', async () => {
});
test('init', async () => {
vi.mock('node:fs');
// mock existsSync as always returning true
vi.mocked(fs.existsSync).mockReturnValue(true);

View file

@ -24,7 +24,7 @@ import { DefaultConfiguration } from './default-configuration.js';
import type { Directories } from './directories.js';
// mock the fs module
vi.mock('node:fs/promises');
vi.mock(import('node:fs/promises'));
let defaultConfiguration: DefaultConfiguration;
const getManagedDefaultsDirectoryMock = vi.fn();

View file

@ -35,13 +35,13 @@ const fakeBrowserWindow: BrowserWindow = {
},
} as unknown as BrowserWindow;
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
dialog: {
showOpenDialog: vi.fn(),
showSaveDialog: vi.fn(),
},
};
} as unknown as typeof Electron;
});
class TestDialogRegistry extends DialogRegistry {}

View file

@ -37,7 +37,7 @@ beforeEach(() => {
process.env = { ...originalProcessEnv };
// Mock file system
vi.mock('node:fs');
vi.mock(import('node:fs'));
vi.spyOn(fs, 'existsSync').mockReturnValue(true);
vi.spyOn(fs, 'mkdirSync').mockImplementation(() => '');
});

View file

@ -282,7 +282,7 @@ describe('handleExtensionVMServiceRequest', () => {
});
test('Check handlePluginInstall', async () => {
vi.mock('node:fs');
vi.mock(import('node:fs'));
const allReplies: string[] = [];

View file

@ -46,7 +46,7 @@ beforeEach(() => {
});
test('Check extractExtensionFiles', async () => {
vi.mock('node:fs/promises');
vi.mock(import('node:fs/promises'));
const metadataJson = {
name: 'My Extension',

View file

@ -17,6 +17,7 @@
***********************************************************************/
import type { SimpleContainerInfo } from '@podman-desktop/core-api';
import type Electron from 'electron';
import type { IpcMainEvent } from 'electron';
import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
@ -27,11 +28,11 @@ import { DockerPluginAdapter } from './docker-plugin-adapter.js';
let dockerPluginAdapter: TestDockerPluginAdapter;
vi.mock('electron', () => {
vi.mock(import('electron'), () => {
const mockIpcMain = {
on: vi.fn().mockReturnThis(),
};
return { ipcMain: mockIpcMain };
return { ipcMain: mockIpcMain } as unknown as typeof Electron;
});
const contributionManager = {} as unknown as ContributionManager;

View file

@ -22,6 +22,7 @@ import { promises } from 'node:fs';
import type { ProviderContainerConnection } from '@podman-desktop/api';
import type { DockerSocketServerInfoType, ProviderInfo } from '@podman-desktop/core-api';
import type { ApiSenderType } from '@podman-desktop/core-api/api-sender';
import type * as Dockerode from 'dockerode';
import { beforeAll, describe, expect, test, vi } from 'vitest';
import { ConfigurationRegistry } from '/@/plugin/configuration-registry.js';
@ -50,13 +51,13 @@ class TestDockerCompatibility extends DockerCompatibility {
}
// mock exists sync
vi.mock('node:fs');
vi.mock(import('node:fs'));
const dockerodeInfoMock = vi.fn();
const dockerodePodmanInfoMock = vi.fn();
vi.mock('dockerode', async () => {
class Dockerode {
vi.mock(import('dockerode'), async () => {
class DockerodeMock {
async info(): Promise<unknown> {
return dockerodeInfoMock();
}
@ -65,7 +66,7 @@ vi.mock('dockerode', async () => {
}
}
return { default: Dockerode };
return { default: DockerodeMock } as unknown as typeof Dockerode;
});
vi.mock(import('/@/util.js'));

View file

@ -18,6 +18,7 @@
import type { Configuration } from '@podman-desktop/api';
import type { IConfigurationPropertyRecordedSchema } from '@podman-desktop/core-api/configuration';
import type Electron from 'electron';
import { shell } from 'electron';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
@ -27,11 +28,15 @@ import { ExperimentalFeatureFeedbackHandler } from './experimental-feature-feedb
import type { MessageBox } from './message-box.js';
import type { Telemetry } from './telemetry/telemetry.js';
vi.mock('electron', () => ({
shell: {
openExternal: vi.fn().mockResolvedValue(undefined),
},
}));
vi.mock(
import('electron'),
() =>
({
shell: {
openExternal: vi.fn().mockResolvedValue(undefined),
},
}) as unknown as typeof Electron,
);
const features: Record<string, IConfigurationPropertyRecordedSchema> = {
'feat.feature1': {

View file

@ -16,7 +16,8 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import { existsSync, promises } from 'node:fs';
import { existsSync } from 'node:fs';
import * as promises from 'node:fs/promises';
import path from 'node:path';
import type { Configuration } from '@podman-desktop/api';
@ -27,6 +28,7 @@ import type {
ProviderInfo,
ProviderKubernetesConnectionInfo,
} from '@podman-desktop/core-api';
import type Electron from 'electron';
import { beforeEach, expect, test, vi } from 'vitest';
import type { ConfigurationRegistry } from '/@/plugin/configuration-registry.js';
@ -38,20 +40,20 @@ import type { ProviderRegistry } from '/@/plugin/provider-registry.js';
import { ExploreFeatures } from './explore-features.js';
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
app: {
getAppPath: vi.fn().mockReturnValue('a-custom-appPath'),
},
};
} as unknown as typeof Electron;
});
vi.mock('node:fs', () => ({
promises: {
readFile: vi.fn(),
},
vi.mock(import('node:fs'), () => ({
existsSync: vi.fn(),
}));
vi.mock(import('node:fs/promises'), () => ({
readFile: vi.fn(),
}));
const configurationRegistryMock = {
getConfiguration: vi.fn().mockReturnValue({

View file

@ -29,8 +29,8 @@ import type { ExtensionManifest } from './extension-manifest-schema.js';
let extensionAnalyzer: ExtensionAnalyzer;
vi.mock('node:fs');
vi.mock('node:fs/promises');
vi.mock(import('node:fs'));
vi.mock(import('node:fs/promises'));
beforeEach(() => {
vi.resetAllMocks();
@ -72,8 +72,8 @@ describe('analyze extension and main', () => {
});
test('check for extension with linked folder', async () => {
vi.mock('node:fs');
vi.mock('node:fs/promises');
vi.mock(import('node:fs'));
vi.mock(import('node:fs/promises'));
// mock fs.existsSync
const fsExistsSyncMock = vi.spyOn(fs, 'existsSync');
@ -108,7 +108,7 @@ describe('analyze extension and main', () => {
});
test('check for extension without main entry', async () => {
vi.mock('node:fs');
vi.mock(import('node:fs'));
// mock fs.existsSync
const fsExistsSyncMock = vi.spyOn(fs, 'existsSync');
@ -140,7 +140,7 @@ describe('analyze extension and main', () => {
});
test('check for extension with devMode', async () => {
vi.mock('node:fs');
vi.mock(import('node:fs'));
// mock fs.existsSync
const fsExistsSyncMock = vi.spyOn(fs, 'existsSync');

View file

@ -325,12 +325,12 @@ const createApi = (disposables?: { dispose(): unknown }[]): typeof containerDesk
return extensionLoader.createApi(analyzedExtension);
};
vi.mock('electron', () => {
vi.mock(import('electron'), () => {
return {
app: {
getVersion: vi.fn(),
},
};
} as unknown as typeof Electron;
});
vi.mock(import('/@/util.js'));
@ -392,7 +392,7 @@ beforeEach(() => {
);
});
vi.mock('node:fs');
vi.mock(import('node:fs'));
beforeEach(() => {
telemetryTrackMock.mockImplementation(() => Promise.resolve());
@ -548,7 +548,7 @@ test('Should load file from watching scanning folder', async () => {
// reduce timeout delay for tests
extensionLoader.setWatchTimeout(50);
vi.mock('node:fs');
vi.mock(import('node:fs'));
// mock fs.watch
const fsWatchMock = vi.spyOn(fs, 'watch');
fsWatchMock.mockImplementation((filename: fs.PathLike, listener?: fs.WatchListener<string>): fs.FSWatcher => {
@ -1340,7 +1340,7 @@ describe('Removing extension by user', async () => {
});
test('check dispose when deactivating', async () => {
vi.mock('node:fs');
vi.mock(import('node:fs'));
const extensionId = 'fooPublisher.fooName';
extensionLoader.setActivatedExtension(extensionId, {
@ -2437,7 +2437,7 @@ describe('containerEngine', async () => {
describe('extensionContext', async () => {
test('secrets', async () => {
vi.mock('node:fs');
vi.mock(import('node:fs'));
vi.mocked(fs.existsSync).mockReturnValue(true);

View file

@ -25,8 +25,8 @@ import { beforeEach, expect, test, vi } from 'vitest';
import { ExtensionTypeScriptConfigParser } from './extension-tsconfig-parser.js';
vi.mock('node:fs');
vi.mock('get-tsconfig');
vi.mock(import('node:fs'));
vi.mock(import('get-tsconfig'));
beforeEach(() => {
vi.restoreAllMocks();

View file

@ -26,7 +26,7 @@ import type { AnalyzedExtension } from './extension-analyzer.js';
import type { ActivatedExtension } from './extension-loader.js';
import { ExtensionWatcher } from './extension-watcher.js';
vi.mock('get-tsconfig');
vi.mock(import('get-tsconfig'));
const fileSystemMonitoring = {
createFileSystemWatcher: vi.fn(),

View file

@ -28,19 +28,23 @@ import productJSONFile from '/@product.json' with { type: 'json' };
import { FeedbackHandler } from './feedback-handler.js';
vi.mock('electron', () => ({
shell: {
openExternal: vi.fn(),
},
}));
vi.mock(
import('electron'),
() =>
({
shell: {
openExternal: vi.fn(),
},
}) as unknown as typeof Electron,
);
vi.mock('/@/util.js', () => ({
vi.mock(import('/@/util.js'), () => ({
isLinux: vi.fn(),
isMac: vi.fn(),
isWindows: vi.fn(),
}));
vi.mock('node:os', () => ({
vi.mock(import('node:os'), () => ({
homedir: vi.fn(() => '/home/user'),
release: vi.fn(),
}));

View file

@ -83,13 +83,13 @@ afterEach(() => {
server?.close();
});
vi.mock('fzstd', () => {
vi.mock(import('fzstd'), () => {
return {
decompress: vi.fn(),
};
});
vi.mock('tar', async () => {
vi.mock(import('tar'), async () => {
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
const tarActual = await vi.importActual<typeof import('tar')>('tar');

View file

@ -95,7 +95,7 @@ const mainWindowDeferred = Promise.withResolvers<BrowserWindow>();
const handlers = new Map<string, any>();
beforeAll(async () => {
vi.mock('electron', () => {
vi.mock(import('electron'), () => {
return {
shell: {
openExternal: vi.fn(),
@ -116,7 +116,7 @@ beforeAll(async () => {
BrowserWindow: {
getAllWindows: vi.fn(),
},
};
} as unknown as typeof Electron;
});
const trayMenuMock = {} as unknown as TrayMenu;
pluginSystem = new TestPluginSystem(trayMenuMock, mainWindowDeferred);

View file

@ -22,6 +22,7 @@ import type { CheckingState, ContextGeneralState, KubeContext, ResourceName } fr
import type { ApiSenderType } from '@podman-desktop/core-api/api-sender';
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
import type * as ContextConstant from './contexts-constants.js';
import type { ContextsInformersRegistry } from './contexts-informers-registry.js';
import { ContextsManager } from './contexts-manager.js';
import type { ContextsStatesRegistry } from './contexts-states-registry.js';
@ -112,7 +113,7 @@ function contextHasBeenChecked(contextName: string): boolean {
return false;
}
vi.mock('@kubernetes/client-node', async importOriginal => {
vi.mock(import('@kubernetes/client-node'), async importOriginal => {
const actual = await importOriginal<typeof kubeclient>();
return {
...actual,
@ -128,7 +129,7 @@ const backoffLimitMock = vi.fn();
const backoffLimitCurrentContextMock = vi.fn();
const backoffJitterMock = vi.fn();
const dispatchTimeoutMock = vi.fn();
vi.mock('./contexts-constants.js', () => {
vi.mock(import('./contexts-constants.js'), () => {
return {
get connectTimeout(): number {
return connectTimeoutMock();
@ -154,7 +155,7 @@ vi.mock('./contexts-constants.js', () => {
get dispatchTimeout(): number {
return dispatchTimeoutMock();
},
};
} as unknown as typeof ContextConstant;
});
const originalConsoleDebug = console.debug;

View file

@ -16,7 +16,7 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import net from 'node:net';
import { createServer, type Server, type Socket } from 'node:net';
import {
AppsV1Api,
@ -66,18 +66,11 @@ const mockAppsV1Api = {
vi.mock(import('@kubernetes/client-node'));
vi.mock('node:net', async () => {
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
const { Server } = await vi.importActual<typeof import('node:net')>('node:net');
vi.mock(import('node:net'), async importOriginal => {
const { Server } = await importOriginal();
return {
Server,
default: {
createServer: vi.fn(() => ({
listen: vi.fn(),
on: vi.fn(),
close: vi.fn(),
})),
},
createServer: vi.fn(),
};
});
@ -150,7 +143,7 @@ class TestablePortForwardConnectionService extends PortForwardConnectionService
return super.getForwardingSetup(resource, forward);
}
public override createServer(forwardSetup: ForwardingSetup): net.Server {
public override createServer(forwardSetup: ForwardingSetup): Server {
return super.createServer(forwardSetup);
}
@ -208,16 +201,14 @@ describe('PortForwardConnectionService', () => {
close: vi.fn(),
};
(net.createServer as unknown as MockedFunction<typeof net.createServer>).mockReturnValue(
server as unknown as net.Server,
);
vi.mocked(createServer).mockReturnValue(server as unknown as Server);
(global.fetch as unknown as MockedFunction<typeof fetch>).mockResolvedValueOnce(
new Response(undefined, { status: 200 }),
);
const disposable = await service.performForward(forwardSetup);
expect(net.createServer).toHaveBeenCalled();
expect(createServer).toHaveBeenCalled();
expect(server.listen).toHaveBeenCalledWith(3000, 'localhost');
expect(disposable.dispose).toBeInstanceOf(Function);
});
@ -232,7 +223,7 @@ describe('PortForwardConnectionService', () => {
const socket = {
on: vi.fn(),
end: vi.fn(),
} as unknown as net.Socket;
} as unknown as Socket;
const server = {
listen: vi.fn(),
@ -240,13 +231,13 @@ describe('PortForwardConnectionService', () => {
close: vi.fn(),
};
(net.createServer as unknown as MockedFunction<typeof net.createServer>).mockImplementation(
vi.mocked(createServer).mockImplementation(
// @ts-expect-error we're sure in the method signature
(connectionListener?: (socket: net.Socket) => void) => {
if (connectionListener) {
connectionListener(socket);
}
return server as unknown as net.Server;
return server as unknown as Server;
},
);
@ -263,7 +254,7 @@ describe('PortForwardConnectionService', () => {
const createdServer = service.createServer(forwardSetup as never);
expect(net.createServer).toHaveBeenCalled();
expect(createServer).toHaveBeenCalled();
expect(PortForward.prototype.portForward).toHaveBeenCalledWith(
forwardSetup.namespace,
forwardSetup.name,

View file

@ -15,7 +15,8 @@
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import net from 'node:net';
import type { Server } from 'node:net';
import { createServer } from 'node:net';
import type { V1Deployment, V1Pod, V1Service } from '@kubernetes/client-node';
import { PortForward } from '@kubernetes/client-node';
@ -91,8 +92,8 @@ export class PortForwardConnectionService {
* @param forwardSetup - The forwarding setup information.
* @returns The created server.
*/
protected createServer(forwardSetup: ForwardingSetup): net.Server {
return net.createServer(socket => {
protected createServer(forwardSetup: ForwardingSetup): Server {
return createServer(socket => {
const kubernetesPortForward = new PortForward(this.kubeClient.getKubeConfig());
kubernetesPortForward
.portForward(

View file

@ -32,12 +32,12 @@ import {
} from '/@/plugin/kubernetes/kubernetes-port-forward-service.js';
import type { ConfigManagementService } from '/@/plugin/kubernetes/kubernetes-port-forward-storage.js';
vi.mock('/@/plugin/kubernetes/kubernetes-port-forward-connection.js');
vi.mock('/@/plugin/kubernetes/kubernetes-port-forward-storage.js');
vi.mock('/@/plugin/kubernetes/kubernetes-port-forward-validation.js');
vi.mock('/@/plugin/util/port.js');
vi.mock('/@/plugin/directories.js');
vi.mock('node:crypto');
vi.mock(import('/@/plugin/kubernetes/kubernetes-port-forward-connection.js'));
vi.mock(import('/@/plugin/kubernetes/kubernetes-port-forward-storage.js'));
vi.mock(import('/@/plugin/kubernetes/kubernetes-port-forward-validation.js'));
vi.mock(import('/@/plugin/util/port.js'));
vi.mock(import('/@/plugin/directories.js'));
vi.mock(import('node:crypto'));
class TestKubernetesPortForwardServiceProvider extends KubernetesPortForwardServiceProvider {
public override getKubeConfigKey(kubeConfig: KubeConfig): string {

View file

@ -33,7 +33,7 @@ import {
PreferenceFolderBasedStorage,
} from '/@/plugin/kubernetes/kubernetes-port-forward-storage.js';
vi.mock('node:fs/promises', () => ({
vi.mock(import('node:fs/promises'), () => ({
mkdir: vi.fn(),
access: vi.fn(),
writeFile: vi.fn(),

View file

@ -24,7 +24,7 @@ import type { Directories } from './directories.js';
import { LockedConfiguration } from './locked-configuration.js';
// mock the fs/promises module
vi.mock('node:fs/promises');
vi.mock(import('node:fs/promises'));
let lockedConfiguration: LockedConfiguration;
const getManagedDefaultsDirectoryMock = vi.fn();

View file

@ -77,7 +77,7 @@ describe('an OnboardingRegistry instance exists', () => {
registerOnboardingDisposable = onboardingRegistry.registerOnboarding(extension, manifest.contributes.onboarding);
getConfigMock.mockReturnValue(true);
vi.mock('node:fs');
vi.mock(import('node:fs'));
readFileSync.mockReturnValue(JSON.stringify({}));
});

View file

@ -25,9 +25,9 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
import { getImageNamePrefix, KubePlayContext } from '/@/plugin/podman/kube.js';
vi.mock('node:fs');
vi.mock('node:fs/promises');
vi.mock('tar-fs');
vi.mock(import('node:fs'));
vi.mock(import('node:fs/promises'));
vi.mock(import('tar-fs'));
beforeEach(() => {
vi.resetAllMocks();

View file

@ -22,7 +22,7 @@
import { get } from 'node:http';
import * as nodeurl from 'node:url';
import type { HttpsProxyAgentOptions } from 'hpagent';
import type * as hpagent from 'hpagent';
import { HttpsProxyAgent } from 'hpagent';
import { beforeEach, expect, test, vi } from 'vitest';
@ -30,22 +30,21 @@ import type { Certificates } from './certificates.js';
import type { Proxy } from './proxy.js';
import * as ProxyResolver from './proxy-resolver.js';
vi.mock('http', () => {
vi.mock(import('node:http'), () => {
return {
get: vi.fn(),
request: vi.fn(),
};
});
vi.mock('https', () => {
vi.mock(import('node:https'), () => {
return {
get: vi.fn(),
request: vi.fn(),
Agent: vi.fn(),
};
});
vi.mock('hpagent', () => {
vi.mock(import('hpagent'), () => {
return {
HttpProxyAgent: function (): void {
// @ts-ignore: this implicit any type
@ -55,7 +54,7 @@ vi.mock('hpagent', () => {
// @ts-ignore: this implicit any type
this.https = true;
},
};
} as unknown as typeof hpagent;
});
function createProxy(enabled: boolean, httpsProxy?: string, httpProxy?: string): Proxy {
@ -148,7 +147,7 @@ test('patched http get when called with url and callback calls original with opt
expect(get).toHaveBeenCalledTimes(2);
expect(get).toBeCalledWith(
{
agent: new HttpsProxyAgent({} as HttpsProxyAgentOptions),
agent: new HttpsProxyAgent({} as hpagent.HttpsProxyAgentOptions),
hostname: `fe80${colon}${colon}1802${colon}20ff${colon}fe8d${colon}d4ce`,
path: '/',
port: '',
@ -171,7 +170,7 @@ test('patched http get translates username@password in url to auth option', () =
expect(get).toHaveBeenCalledTimes(2);
expect(get).toBeCalledWith(
{
agent: new HttpsProxyAgent({} as HttpsProxyAgentOptions),
agent: new HttpsProxyAgent({} as hpagent.HttpsProxyAgentOptions),
hostname: 'rest.url',
path: '/',
port: '',
@ -198,7 +197,7 @@ test('patched http get works when url passed as protocol and hostname in options
}
expect(get).toBeCalledWith(
{
agent: new HttpsProxyAgent({} as HttpsProxyAgentOptions),
agent: new HttpsProxyAgent({} as hpagent.HttpsProxyAgentOptions),
...options,
},
callback,

View file

@ -38,14 +38,14 @@ import { getProxySettingsFromSystem } from './proxy-system.js';
const URL = 'https://podman-desktop.io';
vi.mock('./proxy-system.js', () => {
vi.mock(import('./proxy-system.js'), () => {
return {
getProxySettingsFromSystem: vi.fn(),
};
});
// Mock the fs module
vi.mock('node:fs');
vi.mock(import('node:fs'));
const readFileSync = vi.spyOn(fs, 'readFileSync');
const writeFileSync = vi.spyOn(fs, 'writeFileSync');
const existsSync = vi.spyOn(fs, 'existsSync');

View file

@ -26,6 +26,8 @@ import type { ExtensionsCatalog } from '/@/plugin/extension/catalog/extensions-c
import type { ExtensionLoader } from '/@/plugin/extension/extension-loader.js';
import type { Featured } from '/@/plugin/featured/featured.js';
// eslint-disable-next-line no-restricted-imports
import type * as Recommendations from '../../../../../recommendations.json';
import { RecommendationsRegistry } from './recommendations-registry.js';
let recommendationsRegistry: RecommendationsRegistry;
@ -33,26 +35,30 @@ let recommendationsRegistry: RecommendationsRegistry;
const registerConfigurationsMock = vi.fn();
const getRecommendationIgnored = vi.fn();
vi.mock('../../../../../recommendations.json', () => ({
default: {
extensions: Array.from({ length: 10 }, (_, i) => ({
extensionId: `dummy.id-${i}`,
title: 'dummy title',
description: 'dummy description',
icon: 'data:image/png;base64-icon',
thumbnail: 'data:image/png;base64-thumbnail',
publishDate: '2020-01-01',
})),
registries: [
{
id: 'my.registry.com',
name: 'My Extension',
extensionId: 'my.extensionId',
errors: ['is denied'],
vi.mock(
import('../../../../../recommendations.json'),
() =>
({
default: {
extensions: Array.from({ length: 10 }, (_, i) => ({
extensionId: `dummy.id-${i}`,
title: 'dummy title',
description: 'dummy description',
icon: 'data:image/png;base64-icon',
thumbnail: 'data:image/png;base64-thumbnail',
publishDate: '2020-01-01',
})),
registries: [
{
id: 'my.registry.com',
name: 'My Extension',
extensionId: 'my.extensionId',
errors: ['is denied'],
},
],
},
],
},
}));
}) as unknown as typeof Recommendations,
);
const configurationRegistryMock = {
registerConfigurations: registerConfigurationsMock,

View file

@ -19,6 +19,7 @@
import { existsSync } from 'node:fs';
import { readFile, writeFile } from 'node:fs/promises';
import type Electron from 'electron';
import { safeStorage } from 'electron';
import { beforeEach, expect, test, vi } from 'vitest';
@ -27,15 +28,19 @@ import { type Directories } from '/@/plugin/directories.js';
import type { SecretStorageChangeEvent } from './safe-storage-registry.js';
import { SafeStorageRegistry } from './safe-storage-registry.js';
vi.mock('electron', () => ({
safeStorage: {
encryptString: vi.fn(),
decryptString: vi.fn(),
},
}));
vi.mock(
import('electron'),
() =>
({
safeStorage: {
encryptString: vi.fn(),
decryptString: vi.fn(),
},
}) as unknown as typeof Electron,
);
vi.mock('node:fs');
vi.mock('node:fs/promises');
vi.mock(import('node:fs'));
vi.mock(import('node:fs/promises'));
let safeStorageRegistry: SafeStorageRegistry;

View file

@ -17,6 +17,7 @@
***********************************************************************/
import type { ApiSenderType } from '@podman-desktop/core-api/api-sender';
import type Electron from 'electron';
import { assert, beforeEach, expect, test, vi } from 'vitest';
import { Disposable } from '/@/plugin/types/disposable.js';
@ -42,7 +43,7 @@ beforeEach(() => {
vi.resetAllMocks();
});
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
class Notification {
show(): void {}
close(): void {}
@ -50,7 +51,7 @@ vi.mock('electron', async () => {
return {
Notification,
};
} as unknown as typeof Electron;
});
test('expect notification added to the queue', async () => {

View file

@ -28,6 +28,8 @@ import type { LockedConfiguration } from '/@/plugin/locked-configuration.js';
import { TelemetryTrustedValue } from '/@/plugin/types/telemetry.js';
import product from '/@product.json' with { type: 'json' };
// eslint-disable-next-line no-restricted-imports
import type * as TelemetryJSON from '../../../../../telemetry.json';
import type { EventType } from './telemetry.js';
import { Telemetry, TelemetryLoggerImpl } from './telemetry.js';
@ -50,18 +52,22 @@ const lockedConfigurationMock = {
getTelemetryInfo: vi.fn(),
} as unknown as LockedConfiguration;
vi.mock('../../../../../telemetry.json', () => ({
default: {
rules: [
{
event: 'dropMe',
disabled: true,
vi.mock(
import('../../../../../telemetry.json'),
() =>
({
default: {
rules: [
{
event: 'dropMe',
disabled: true,
},
{ event: 'sometimes', ratio: 0.5 },
{ event: 'list', frequency: 'dailyPerInstance' },
],
},
{ event: 'sometimes', ratio: 0.5 },
{ event: 'list', frequency: 'dailyPerInstance' },
],
},
}));
}) as unknown as typeof TelemetryJSON,
);
vi.mock(import('/@product.json'));

View file

@ -24,16 +24,16 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { TempFileService } from './temp-file-service.js';
vi.mock('node:fs/promises', () => ({
vi.mock(import('node:fs/promises'), () => ({
writeFile: vi.fn(),
unlink: vi.fn(),
}));
vi.mock('node:os', () => ({
vi.mock(import('node:os'), () => ({
tmpdir: vi.fn().mockReturnValue('/tmp'),
}));
vi.mock('node:path', () => ({
vi.mock(import('node:path'), () => ({
join: vi.fn().mockImplementation((...args) => args.join('/')),
}));

View file

@ -30,13 +30,13 @@ import { TrayMenuRegistry } from './tray-menu-registry.js';
let menuRegistry: TrayMenuRegistry;
let trayMenu: TrayMenu;
vi.mock('electron', () => {
vi.mock(import('electron'), () => {
return {
ipcMain: {
emit: vi.fn(),
on: vi.fn(),
},
};
} as unknown as typeof Electron;
});
beforeAll(() => {

View file

@ -16,7 +16,8 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import type { IncomingMessage } from 'node:http';
import type { ClientRequest, IncomingMessage, RequestOptions } from 'node:http';
import { get } from 'node:https';
import type { Configuration } from '@podman-desktop/api';
import type { ApiSenderType } from '@podman-desktop/core-api/api-sender';
@ -37,20 +38,26 @@ import * as util from '/@/util.js';
import { isLinux, isMac, isWindows } from '/@/util.js';
import product from '/@product.json' with { type: 'json' };
// eslint-disable-next-line no-restricted-imports
import type PackageJSON from '../../../../package.json';
import type { TaskManager } from './tasks/task-manager.js';
vi.mock('electron', () => ({
app: {
getVersion: vi.fn(),
getPath: vi.fn(),
getAppPath: vi.fn().mockReturnValue('a-custom-appPath'),
},
shell: {
openExternal: vi.fn(),
},
}));
vi.mock(
import('electron'),
() =>
({
app: {
getVersion: vi.fn(),
getPath: vi.fn(),
getAppPath: vi.fn().mockReturnValue('a-custom-appPath'),
},
shell: {
openExternal: vi.fn(),
},
}) as unknown as typeof Electron,
);
vi.mock('electron-updater', () => ({
vi.mock(import('electron-updater'), () => ({
autoUpdater: {
downloadUpdate: vi.fn(),
quitAndInstall: vi.fn(),
@ -58,10 +65,10 @@ vi.mock('electron-updater', () => ({
on: vi.fn(),
autoDownload: true,
disableDifferentialDownload: false,
},
} as unknown as AppUpdater,
}));
vi.mock('/@/util.js', () => ({
vi.mock(import('/@/util.js'), () => ({
isLinux: vi.fn(),
isWindows: vi.fn(),
isMac: vi.fn(),
@ -69,17 +76,12 @@ vi.mock('/@/util.js', () => ({
const getStatusCodeMock = { statusCode: 200 } as IncomingMessage;
vi.mock('https', () => ({
get: (_: string, callback: (_: IncomingMessage) => void): void => {
callback(getStatusCodeMock);
},
}));
vi.mock('../../../../package.json', () => ({
vi.mock(import('node:https'));
vi.mock(import('../../../../package.json'), () => ({
default: {
homepage: 'appHomepage',
repository: 'appRepo',
},
} as unknown as typeof PackageJSON,
}));
vi.mock(import('/@product.json'));
@ -126,10 +128,29 @@ function mockConfiguration(options: Record<string, unknown>): void {
});
}
/**
* The {@link import(`node:https`).get} has two signature.
* We need to make a weird function to be able to typesafely mock it
*/
function getMock(
_: RequestOptions | string | URL,
arg2: RequestOptions | ((res: IncomingMessage) => void),
arg3?: (res: IncomingMessage) => void,
): ClientRequest {
if (typeof arg2 === 'function') {
arg2?.(getStatusCodeMock);
} else if (typeof arg3 === 'function') {
arg3?.(getStatusCodeMock);
}
return {} as unknown as ClientRequest;
}
beforeEach(() => {
vi.useFakeTimers();
vi.resetAllMocks();
vi.mocked(get).mockImplementation(getMock);
// Simulate PROD env
vi.stubEnv('PROD', true);

View file

@ -25,11 +25,11 @@ import { isLinux } from '/@/util.js';
import { DirectoryStrategy } from './directory-strategy.js';
// Mock the external modules
vi.mock('node:fs', () => ({
vi.mock(import('node:fs'), () => ({
existsSync: vi.fn(),
}));
vi.mock('/@/util.js', () => ({
vi.mock(import('/@/util.js'), () => ({
isLinux: vi.fn(),
}));

View file

@ -27,24 +27,14 @@ import type { Mock } from 'vitest';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import type { Proxy } from '/@/plugin/proxy.js';
import * as util from '/@/util.js';
import { isLinux, isMac, isWindows } from '/@/util.js';
import { Exec, getInstallationPath, macosExtraPath } from './exec.js';
// Mock sudo-prompt exec to resolve everytime.
vi.mock(import('@expo/sudo-prompt'), async () => {
return {
exec: vi.fn(),
};
});
vi.mock(import('@expo/sudo-prompt'));
vi.mock(import('/@/util.js'));
vi.mock('child_process', () => {
return {
spawn: vi.fn(),
};
});
vi.mock(import('node:child_process'));
const setEncodingMock = vi.fn();
@ -55,7 +45,6 @@ describe('exec', () => {
beforeEach(() => {
vi.resetAllMocks();
vi.clearAllMocks();
});
const exec = new Exec(proxy);
@ -142,7 +131,7 @@ describe('exec', () => {
test('should reject with an error when the process error event received', async () => {
const command = 'nonexistent-command';
vi.mock('child_process', () => {
vi.mock(import('node:child_process'), () => {
return {
spawn: vi.fn(),
};
@ -210,18 +199,12 @@ describe('exec', () => {
const command = 'echo';
const args = ['Hello, World!'];
const error = new Error('Error message');
(util.isWindows as Mock).mockReturnValue(true);
vi.mocked(isWindows).mockReturnValue(true);
(sudo.exec as Mock).mockImplementation((_command, _options, callback) => {
callback(error);
});
vi.mock('child_process', () => {
return {
spawn: vi.fn(),
};
});
const execResult = exec.exec(command, args, { isAdmin: true });
await expect(execResult).rejects.toThrowError(/Failed to execute command: Error message/);
@ -341,7 +324,7 @@ describe('exec', () => {
const command = 'echo';
const args = ['Hello, "World"!'];
(util.isMac as Mock).mockReturnValue(true);
vi.mocked(isMac).mockReturnValue(true);
const on = vi.fn().mockImplementationOnce((event: string, cb: (arg0: string) => string) => {
if (event === 'data') {
@ -377,7 +360,7 @@ describe('exec', () => {
const command = 'echo';
const args = ['Hello, World!'];
(util.isLinux as Mock).mockReturnValue(true);
vi.mocked(isLinux).mockReturnValue(true);
const on = vi.fn().mockImplementationOnce((event: string, cb: (arg0: string) => string) => {
if (event === 'data') {
@ -410,7 +393,7 @@ describe('exec', () => {
const command = 'echo';
const args = ['Hello, World!'];
(util.isLinux as Mock).mockReturnValue(true);
vi.mocked(isLinux).mockReturnValue(true);
const on = vi.fn().mockImplementationOnce((event: string, cb: (arg0: string) => string) => {
if (event === 'data') {
@ -446,7 +429,7 @@ describe('exec', () => {
test('should run the command with privileges using exec on Windows', async () => {
const command = 'echo';
const args = ['Hello, World!'];
(util.isWindows as Mock).mockReturnValue(true);
vi.mocked(isWindows).mockReturnValue(true);
(sudo.exec as Mock).mockImplementation((_command, _options, callback) => {
callback(undefined);
@ -477,7 +460,7 @@ describe('exec', () => {
test('should run the command with privileges on Windows and remove unsupported environment', async () => {
const command = 'echo';
const args = ['Hello, World!'];
(util.isWindows as Mock).mockReturnValue(true);
vi.mocked(isWindows).mockReturnValue(true);
let options:
| {
env?: { [p: string]: string };
@ -574,7 +557,7 @@ describe('exec', () => {
const command = 'echo';
const args = ['Hello, World!'];
(util.isLinux as Mock).mockReturnValue(true);
vi.mocked(isLinux).mockReturnValue(true);
const on = vi.fn().mockImplementationOnce((event: string, cb: (arg0: string) => string) => {
if (event === 'data') {
@ -610,13 +593,6 @@ describe('exec', () => {
});
});
vi.mock('./util', () => {
return {
isWindows: vi.fn(),
isMac: vi.fn(),
};
});
describe('getInstallationPath', () => {
let originalPath: string | undefined;
@ -634,8 +610,8 @@ describe('getInstallationPath', () => {
skip: platform() !== 'win32',
}, () => {
beforeEach(() => {
vi.spyOn(util, 'isWindows').mockImplementation(() => true);
vi.spyOn(util, 'isMac').mockImplementation(() => false);
vi.mocked(isWindows).mockReturnValue(true);
vi.mocked(isMac).mockReturnValue(false);
});
test('should return the installation paths for Windows', () => {
@ -672,8 +648,8 @@ describe('getInstallationPath', () => {
});
test('should return the installation path for macOS', () => {
vi.spyOn(util, 'isWindows').mockImplementation(() => false);
vi.spyOn(util, 'isMac').mockImplementation(() => true);
vi.mocked(isWindows).mockReturnValue(false);
vi.mocked(isMac).mockReturnValue(true);
process.env['PATH'] = '/usr/bin';
@ -683,8 +659,8 @@ describe('getInstallationPath', () => {
});
test('should return the installation path for macOS with defined param', () => {
vi.spyOn(util, 'isWindows').mockImplementation(() => false);
vi.spyOn(util, 'isMac').mockImplementation(() => true);
vi.mocked(isWindows).mockReturnValue(false);
vi.mocked(isMac).mockReturnValue(true);
process.env['PATH'] = '/usr/bin';
@ -694,8 +670,8 @@ describe('getInstallationPath', () => {
});
test('should return the installation path for other platforms', () => {
vi.spyOn(util, 'isWindows').mockImplementation(() => false);
vi.spyOn(util, 'isMac').mockImplementation(() => false);
vi.mocked(isWindows).mockReturnValue(false);
vi.mocked(isMac).mockReturnValue(false);
process.env['PATH'] = '/usr/bin'; // Example PATH for other platforms
const path = getInstallationPath();
@ -704,8 +680,8 @@ describe('getInstallationPath', () => {
});
test('should return the installation path for other platforms with defined param', () => {
vi.spyOn(util, 'isWindows').mockImplementation(() => false);
vi.spyOn(util, 'isMac').mockImplementation(() => false);
vi.mocked(isWindows).mockReturnValue(false);
vi.mocked(isMac).mockReturnValue(false);
process.env['PATH'] = '/usr/bin'; // Example PATH for other platforms
const path = getInstallationPath('/usr/other');

View file

@ -25,7 +25,7 @@ import { beforeEach, expect, test, vi } from 'vitest';
import { spawnWithPromise } from './spawn-promise.js';
// mock spawn
vi.mock('node:child_process', () => {
vi.mock(import('node:child_process'), () => {
return {
spawn: vi.fn(),
};

View file

@ -23,13 +23,13 @@ import { beforeEach, expect, test, vi } from 'vitest';
import { getSystemInfo } from '/@/plugin/util/sys-info.js';
import { isLinux, isMac, isWindows } from '/@/util.js';
vi.mock('/@/util.js', () => ({
vi.mock(import('/@/util.js'), () => ({
isLinux: vi.fn(),
isMac: vi.fn(),
isWindows: vi.fn(),
}));
vi.mock('node:os', () => ({
vi.mock(import('node:os'), () => ({
arch: vi.fn(),
release: vi.fn(),
version: vi.fn(),

View file

@ -21,14 +21,18 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
import { DevToolsManager } from './devtools-manager.js';
vi.mock('electron', () => ({
webContents: {
fromId: vi.fn(),
},
BrowserWindow: {
getAllWindows: vi.fn(),
},
}));
vi.mock(
import('electron'),
() =>
({
webContents: {
fromId: vi.fn(),
},
BrowserWindow: {
getAllWindows: vi.fn(),
},
}) as unknown as typeof Electron,
);
const mockWebContents = vi.mocked(webContents);
const mockBrowserWindow = vi.mocked(BrowserWindow);

View file

@ -30,20 +30,24 @@ import type { WebviewPanelImpl } from './webview-panel-impl.js';
import { WebviewRegistry } from './webview-registry.js';
// mock node:fs
vi.mock('node:fs');
vi.mock(import('node:fs'));
// mock express dependency and default export
vi.mock('express', () => ({
default: (): typeof express =>
vi.mock(
import('express'),
() =>
({
use: vi.fn(),
listen: vi.fn().mockImplementation((_portNumber, _hostname, func: () => void) => {
func();
return { on: vi.fn() };
}),
on: vi.fn().mockResolvedValue(undefined),
default: (): typeof express =>
({
use: vi.fn(),
listen: vi.fn().mockImplementation((_portNumber, _hostname, func: () => void) => {
func();
return { on: vi.fn() };
}),
on: vi.fn().mockResolvedValue(undefined),
}) as unknown as typeof express,
}) as unknown as typeof express,
}));
);
// provide a custom free port number
vi.mock(import('/@/plugin/util/port.js'), () => ({

View file

@ -27,11 +27,15 @@ import type {
import { shell } from 'electron';
import { beforeEach, describe, expect, test, vi } from 'vitest';
vi.mock('electron', () => ({
shell: {
openExternal: vi.fn(),
},
}));
vi.mock(
import('electron'),
() =>
({
shell: {
openExternal: vi.fn(),
},
}) as unknown as typeof Electron,
);
const ELECTRON_APP_MOCK: ElectronApp = {
on: vi.fn(),

View file

@ -27,22 +27,22 @@ import { MacosStartup } from './macos-startup.js';
type AppGetPathParam = Parameters<typeof app.getPath>[0];
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
app: {
getPath: vi.fn(),
setLoginItemSettings: vi.fn(),
},
};
} as unknown as typeof Electron;
});
vi.mock('node:fs', async () => {
vi.mock(import('node:fs'), async () => {
return {
existsSync: vi.fn(),
};
});
vi.mock('node:fs/promises');
vi.mock('node:path');
vi.mock(import('node:fs/promises'));
vi.mock(import('node:path'));
let macosStartup: MacosStartup;

View file

@ -46,12 +46,12 @@ const browserWindowMock = {
getBounds: vi.fn(),
} as unknown as BrowserWindow;
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
screen: {
getDisplayMatching: vi.fn(),
},
};
} as unknown as typeof Electron;
});
beforeEach(() => {

View file

@ -26,21 +26,16 @@ import type { ConfigurationRegistry } from '/@/plugin/configuration-registry.js'
import { WindowsStartup } from './windows-startup.js';
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
app: {
getPath: vi.fn(),
setLoginItemSettings: vi.fn(),
},
};
} as unknown as typeof Electron;
});
vi.mock('node:fs', async () => {
return {
existsSync: vi.fn(),
unlink: vi.fn(),
};
});
vi.mock(import('node:fs'));
const minimizeOnStatup = vi.fn();
const configurationRegistry = {

View file

@ -45,7 +45,7 @@ const mockNativeImage = vi.hoisted(() => ({
createFromBuffer: vi.fn().mockReturnValue({ isEmpty: () => false }),
}));
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
return {
app: {
getAppPath: (): string => 'a-custom-appPath',
@ -56,14 +56,14 @@ vi.mock('electron', async () => {
shouldUseDarkColors: false,
},
nativeImage: mockNativeImage,
};
} as unknown as typeof Electron;
});
vi.mock('node:fs', () => ({
vi.mock(import('node:fs'), () => ({
readFileSync: vi.fn().mockReturnValue(Buffer.from('')),
}));
vi.mock('./util.js', () => ({
vi.mock(import('./util.js'), () => ({
isMac: vi.fn(),
isWindows: vi.fn(),
}));

View file

@ -29,7 +29,7 @@ import * as util from './util.js';
let trayMenu: TrayMenu;
let tray: Tray;
let animatedTray: AnimatedTray;
vi.mock('electron', async () => {
vi.mock(import('electron'), async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const Menu = {} as unknown as any;
Menu['buildFromTemplate'] = vi.fn();
@ -42,7 +42,7 @@ vi.mock('electron', async () => {
nativeImage: {
createFromDataURL: vi.fn(),
},
};
} as unknown as typeof Electron;
});
beforeAll(() => {

View file

@ -23,7 +23,7 @@ import { createHash, formatName, getBase64Image, requireNonUndefined } from './u
beforeEach(() => {
vi.resetAllMocks();
vi.mock('node:fs');
vi.mock(import('node:fs'));
});
test('getBase64Image - return undefined if path do not exists', () => {