Skip to content

Commit

Permalink
spec: add initial tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MarshallOfSound committed Sep 22, 2022
1 parent b9293a7 commit b460c20
Show file tree
Hide file tree
Showing 6 changed files with 2,656 additions and 52 deletions.
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testTimeout: 60000,
globalSetup: './jest.global.ts'
};
19 changes: 19 additions & 0 deletions jest.global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { downloadArtifact } from '@electron/get';
import { supportedPlatforms } from './test/helpers';

module.exports = async () => {
console.log('\nDownloading all Electron binaries required for testing...');

await Promise.all(
supportedPlatforms.map(async ([platform, arch]) => {
return downloadArtifact({
version: '20.0.0',
platform,
arch,
artifactName: 'electron',
});
}),
);

console.log('Done...');
};
13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@
"build": "tsc"
},
"devDependencies": {
"@electron/get": "^2.0.1",
"@electron/universal": "^1.3.0",
"@types/fs-extra": "^9.0.1",
"@types/jest": "^29.0.3",
"@types/minimist": "^1.2.1",
"@types/node": "^14.11.2",
"extract-zip": "^2.0.1",
"husky": "^4.3.0",
"jest": "^29.0.3",
"lint-staged": "^10.4.0",
"prettier": "^2.1.2",
"typescript": "^4.0.3"
"ts-jest": "^29.0.1",
"typescript": "^4.3.3"
},
"lint-staged": {
"*.ts": [
Expand All @@ -42,7 +48,10 @@
"type": "git",
"url": "git+https://github.com/electron/fuses.git"
},
"keywords": [ "electron", "fuses"],
"keywords": [
"electron",
"fuses"
],
"author": "Electron Community",
"bugs": {
"url": "https://github.com/electron/fuses/issues"
Expand Down
56 changes: 56 additions & 0 deletions test/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { downloadArtifact } from '@electron/get';
import * as extractZip from 'extract-zip';
import * as fs from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import { FuseConfig, FuseV1Options } from '../src';
import { FuseState } from '../src/constants';

export const supportedPlatforms = [
['darwin', 'x64'],
['darwin', 'arm64'],
['win32', 'ia32'],
['win32', 'x64'],
['win32', 'arm64'],
['linux', 'arm64'],
['linux', 'x64'],
];

export const tmpPaths: string[] = [];

export async function getTmpDir() {
const tmpDir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-fuses-'));
tmpPaths.push(tmpDir);
return tmpDir;
}

export async function getElectronLocally(version: string, platform: string, arch: string) {
const electronZip = await downloadArtifact({
version,
platform,
arch,
artifactName: 'electron',
});
const tmpDir = await getTmpDir();
await extractZip(electronZip, {
dir: tmpDir,
});

if (platform === 'darwin' || platform === 'mas') {
return path.resolve(tmpDir, 'Electron.app');
} else if (platform === 'win32') {
return path.resolve(tmpDir, 'electron.exe');
} else {
return path.resolve(tmpDir, 'electron');
}
}

export function readableFuseWire(config: FuseConfig<FuseState>) {
const cloned: any = { ...config };
for (const key of Object.keys(cloned).filter((k) => k !== 'version')) {
cloned[(FuseV1Options as any)[key]] = (FuseState as any)[cloned[key]];
delete cloned[key];
}

return cloned;
}
107 changes: 107 additions & 0 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { makeUniversalApp } from '@electron/universal';
import * as fs from 'fs-extra';
import * as path from 'path';

import { FuseState } from '../src/constants';
import { flipFuses, FuseV1Options, FuseVersion, getCurrentFuseWire } from '../src/index';
import {
getElectronLocally,
getTmpDir,
readableFuseWire,
supportedPlatforms,
tmpPaths,
} from './helpers';

describe('getCurrentFuseWire()', () => {
afterEach(async () => {
while (tmpPaths.length) {
await fs.remove(tmpPaths.pop()!);
}
});

it('should return the expected defaults for Electron v20.0.0', async () => {
const electronPath = await getElectronLocally('20.0.0', 'darwin', 'x64');
expect(readableFuseWire(await getCurrentFuseWire(electronPath))).toMatchInlineSnapshot(`
{
"EnableCookieEncryption": "DISABLE",
"EnableEmbeddedAsarIntegrityValidation": "DISABLE",
"EnableNodeCliInspectArguments": "ENABLE",
"EnableNodeOptionsEnvironmentVariable": "ENABLE",
"OnlyLoadAppFromAsar": "DISABLE",
"RunAsNode": "ENABLE",
"version": "1",
}
`);
});

for (const [platform, arch] of supportedPlatforms) {
it(`should work on ${platform}/${arch}`, async () => {
const electronPath = await getElectronLocally('20.0.0', platform, arch);
await expect(getCurrentFuseWire(electronPath)).resolves.toBeTruthy();
});
}
});

describe('flipFuses()', () => {
it('should allow toggling a single fuse', async () => {
const electronPath = await getElectronLocally('20.0.0', 'darwin', 'x64');
expect((await getCurrentFuseWire(electronPath))[FuseV1Options.EnableCookieEncryption]).toEqual(
FuseState.DISABLE,
);
const sentinels = await flipFuses(electronPath, {
version: FuseVersion.V1,
[FuseV1Options.EnableCookieEncryption]: true,
});
expect(sentinels).toEqual(1);
expect((await getCurrentFuseWire(electronPath))[FuseV1Options.EnableCookieEncryption]).toEqual(
FuseState.ENABLE,
);
});

it('should allow toggling multiple fuses', async () => {
const electronPath = await getElectronLocally('20.0.0', 'darwin', 'x64');
expect((await getCurrentFuseWire(electronPath))[FuseV1Options.EnableCookieEncryption]).toEqual(
FuseState.DISABLE,
);
expect(
(await getCurrentFuseWire(electronPath))[FuseV1Options.EnableEmbeddedAsarIntegrityValidation],
).toEqual(FuseState.DISABLE);
await flipFuses(electronPath, {
version: FuseVersion.V1,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
});
expect((await getCurrentFuseWire(electronPath))[FuseV1Options.EnableCookieEncryption]).toEqual(
FuseState.ENABLE,
);
expect(
(await getCurrentFuseWire(electronPath))[FuseV1Options.EnableEmbeddedAsarIntegrityValidation],
).toEqual(FuseState.ENABLE);
});

if (process.platform === 'darwin') {
it('should work on universal macOS applications', async () => {
const electronPathX64 = await getElectronLocally('20.0.0', 'darwin', 'x64');
const electronPathArm64 = await getElectronLocally('20.0.0', 'darwin', 'arm64');
for (const electronPath of [electronPathArm64, electronPathX64]) {
await fs.move(
path.resolve(electronPath, 'Contents', 'Resources', 'default_app.asar'),
path.resolve(electronPath, 'Contents', 'Resources', 'app.asar'),
);
}
const electronPathUniversal = path.resolve(await getTmpDir(), 'Electron.app');
await makeUniversalApp({
x64AppPath: electronPathX64,
arm64AppPath: electronPathArm64,
outAppPath: electronPathUniversal,
force: false,
});

const sentinels = await flipFuses(electronPathUniversal, {
version: FuseVersion.V1,
[FuseV1Options.EnableCookieEncryption]: true,
});
expect(sentinels).toEqual(2);
});
}
});
Loading

0 comments on commit b460c20

Please sign in to comment.