mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
test(electron): add unit tests for updater (#5439)
This commit is contained in:
50
packages/frontend/electron/test/main/fixtures/feeds.txt
Normal file
50
packages/frontend/electron/test/main/fixtures/feeds.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
|
||||
<id>tag:github.com,2008:https://github.com/toeverything/AFFiNE/releases</id>
|
||||
<link type="text/html" rel="alternate" href="https://github.com/toeverything/AFFiNE/releases"/>
|
||||
<link type="application/atom+xml" rel="self" href="https://github.com/toeverything/AFFiNE/releases.atom"/>
|
||||
<title>Release notes from AFFiNE</title>
|
||||
<updated>2023-12-28T16:36:36+08:00</updated>
|
||||
<entry>
|
||||
<id>tag:github.com,2008:Repository/519859998/0.11.0-nightly-202312280901-e11e827</id>
|
||||
<updated>2023-12-28T17:23:15+08:00</updated>
|
||||
<link rel="alternate" type="text/html" href="https://github.com/toeverything/AFFiNE/releases/tag/0.11.0-nightly-202312280901-e11e827"/>
|
||||
<title>0.11.0-nightly-202312280901-e11e827</title>
|
||||
<content>No content.</content>
|
||||
<author>
|
||||
<name>github-actions[bot]</name>
|
||||
</author>
|
||||
<media:thumbnail height="30" width="30" url="https://avatars.githubusercontent.com/in/15368?s=60&v=4"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:github.com,2008:Repository/519859998/v0.11.1</id>
|
||||
<updated>2023-12-27T19:40:15+08:00</updated>
|
||||
<link rel="alternate" type="text/html" href="https://github.com/toeverything/AFFiNE/releases/tag/v0.11.1"/>
|
||||
<title>0.11.1</title>
|
||||
<author>
|
||||
<name>github-actions[bot]</name>
|
||||
</author>
|
||||
<media:thumbnail height="30" width="30" url="https://avatars.githubusercontent.com/in/15368?s=60&v=4"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:github.com,2008:Repository/519859998/v0.11.1-beta.1</id>
|
||||
<updated>2023-12-27T18:30:52+08:00</updated>
|
||||
<link rel="alternate" type="text/html" href="https://github.com/toeverything/AFFiNE/releases/tag/v0.11.1-beta.1"/>
|
||||
<title>0.11.1-beta.1</title>
|
||||
<author>
|
||||
<name>github-actions[bot]</name>
|
||||
</author>
|
||||
<media:thumbnail height="30" width="30" url="https://avatars.githubusercontent.com/in/15368?s=60&v=4"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:github.com,2008:Repository/519859998/v0.11.1-canary.1</id>
|
||||
<updated>2023-12-27T10:47:52+08:00</updated>
|
||||
<link rel="alternate" type="text/html" href="https://github.com/toeverything/AFFiNE/releases/tag/v0.11.1-canary.1"/>
|
||||
<title>0.11.1-canary.1</title>
|
||||
<content type="html"></content>
|
||||
<author>
|
||||
<name>github-actions[bot]</name>
|
||||
</author>
|
||||
<media:thumbnail height="30" width="30" url="https://avatars.githubusercontent.com/in/15368?s=60&v=4"/>
|
||||
</entry>
|
||||
</feed>
|
||||
@@ -0,0 +1,20 @@
|
||||
version: 0.11.1-beta.1
|
||||
files:
|
||||
- url: affine-beta-windows-x64.exe
|
||||
sha512: uQdF7bEZteCMp/bT7vwCjlEcAf6osW9zZ+Q5grEkmbHPpcqCCzLudguXqHIwohO4GGq9pS8H4kJzG0LZc+SmXg==
|
||||
size: 179515752
|
||||
- url: affine-beta-macos-arm64.dmg
|
||||
sha512: gRsi4XO4+kREQuLX2CnS2V9vvUmBMmoGR6MvoB6TEFm1WiC8k8v69DRKYQ0Vjlom/j9HZlBEYUTqcW7IsMgrpw==
|
||||
size: 169726061
|
||||
- url: affine-beta-macos-arm64.zip
|
||||
sha512: +aXkjJfQnp2dUz3Y0i5cL6V5Hm1OkYVlwM/KAcZfLlvLoU3zQ0zSZvJ6+H2IlIhOebSq56Ip76H5NP8fe7UnOw==
|
||||
size: 169007175
|
||||
- url: affine-beta-macos-x64.dmg
|
||||
sha512: i5V95dLx3iWFpNj89wFU40THT3Oeow8g706Z6/mG1zYOIR3kXUkIpp6+wJmlfe9g4iwNmRd0rgI4HAG5LaQagg==
|
||||
size: 175712730
|
||||
- url: affine-beta-macos-x64.zip
|
||||
sha512: DnRUHcj+4FluII5kTbUuEAQI2CIRufd1Z0P98pwa/uX5hk2iOj1QzMD8WM+MTbFNC6rZvMtMlos8GyVLsZmK0w==
|
||||
size: 175235583
|
||||
path: affine-beta-windows-x64.exe
|
||||
sha512: uQdF7bEZteCMp/bT7vwCjlEcAf6osW9zZ+Q5grEkmbHPpcqCCzLudguXqHIwohO4GGq9pS8H4kJzG0LZc+SmXg==
|
||||
releaseDate: 2023-12-27T08:59:31.826Z
|
||||
@@ -0,0 +1,20 @@
|
||||
version: 0.11.1-canary.1
|
||||
files:
|
||||
- url: affine-canary-windows-x64.exe
|
||||
sha512: qbK4N6+axVO2dA/iPzfhANWxCZXY1S3ci9qYIT1v/h0oCjc6vqpXU+2KRGL5mplL6wmVgJAOpqrfnq9gHMsfDg==
|
||||
size: 179526504
|
||||
- url: affine-canary-macos-arm64.dmg
|
||||
sha512: ++LAGuxTmFAVd65k8UpKKfU19iisvXHKDDfPkGlTVC000QP3foeS21BmTgYnM1ZuhEC6KGzSGrqvUDVDNYnRmA==
|
||||
size: 169903530
|
||||
- url: affine-canary-macos-arm64.zip
|
||||
sha512: IAWbCpVqPPVVzDowGKGnKZzHN2jPgAW40v+bUZR2tdgDrqIAVy4YdamYz8WmEwpg1TXmi0ueSsWgGFPgBIr0iA==
|
||||
size: 169085665
|
||||
- url: affine-canary-macos-x64.dmg
|
||||
sha512: 4y4/KkmkmFmZ94ntRAN0lSX7aZzgEd4Wg7f85Tff296P3x85sbPF4FFIp++Zx/cgBZBUQwMWe9xeGlefompQ/g==
|
||||
size: 175920978
|
||||
- url: affine-canary-macos-x64.zip
|
||||
sha512: S1MuMHooMOQ9eJ+coRYmyz6k5lnWIMqHotSrywxGGo7sFXBY+O5F4PeKgNREJtwXjAIxv0GxZVvbe5jc+onw9w==
|
||||
size: 175315484
|
||||
path: affine-canary-windows-x64.exe
|
||||
sha512: qbK4N6+axVO2dA/iPzfhANWxCZXY1S3ci9qYIT1v/h0oCjc6vqpXU+2KRGL5mplL6wmVgJAOpqrfnq9gHMsfDg==
|
||||
releaseDate: 2023-12-26T13:24:28.221Z
|
||||
@@ -0,0 +1,20 @@
|
||||
version: 0.11.1
|
||||
files:
|
||||
- url: affine-stable-windows-x64.exe
|
||||
sha512: qHRO31Fb8F+Q/hiGiJJ2WH+PpSC5iUIPtWujUoI+XNMz7UfhCGxoVW9U38CTE9LecILS119SZN0rrHkmu+nQiw==
|
||||
size: 179504488
|
||||
- url: affine-stable-macos-arm64.dmg
|
||||
sha512: uDS7bZusoU5p2t4bi1k/IdvChj3BRIWbOLanbhAfIjwBmf9FM3553wgeUzQLRMRuD5wavsw/aA1BaqFJIbwkyQ==
|
||||
size: 169793193
|
||||
- url: affine-stable-macos-arm64.zip
|
||||
sha512: n4CrOgNPd70WqPfe0ZEKzmyOdqOlVnFvQqylIlt92eqKrUb8jcxVThQY+GU2Jy3jVjvKqUvubodDbIkQhXQ1xQ==
|
||||
size: 169014676
|
||||
- url: affine-stable-macos-x64.dmg
|
||||
sha512: xFy1kt1025h1wqBjHt+IoPweC40UqAZvZLI2XD3LIlPG60jZ03+QM75UwaXYuVYEqe3kO9a3WeFcrfGdoj4Hzw==
|
||||
size: 175720872
|
||||
- url: affine-stable-macos-x64.zip
|
||||
sha512: FfgX22ytleb8fv35odzhDyFsmiUVPdI4XQjTB4uDmkhQ719i+W4yctUnP5TSCpymYC0HgVRFSVg4Jkuuli+8ug==
|
||||
size: 175244411
|
||||
path: affine-stable-windows-x64.exe
|
||||
sha512: qHRO31Fb8F+Q/hiGiJJ2WH+PpSC5iUIPtWujUoI+XNMz7UfhCGxoVW9U38CTE9LecILS119SZN0rrHkmu+nQiw==
|
||||
releaseDate: 2023-12-27T11:04:53.014Z
|
||||
34
packages/frontend/electron/test/main/mocks/app-adapter.ts
Normal file
34
packages/frontend/electron/test/main/mocks/app-adapter.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import type { AppAdapter } from 'electron-updater/out/AppAdapter';
|
||||
|
||||
/**
|
||||
* For testing and same as:
|
||||
* https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/src/ElectronAppAdapter.ts
|
||||
*/
|
||||
export class MockedAppAdapter implements AppAdapter {
|
||||
version: string;
|
||||
name = 'AFFiNE-testing';
|
||||
isPackaged = true;
|
||||
appUpdateConfigPath = '';
|
||||
userDataPath = '';
|
||||
baseCachePath = '';
|
||||
|
||||
constructor(version: string) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
whenReady() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
relaunch() {
|
||||
return;
|
||||
}
|
||||
|
||||
quit() {
|
||||
return;
|
||||
}
|
||||
|
||||
onQuit(_handler: (exitCode: number) => void) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
26
packages/frontend/electron/test/main/mocks/http-executor.ts
Normal file
26
packages/frontend/electron/test/main/mocks/http-executor.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import http from 'node:https';
|
||||
|
||||
import { HttpExecutor } from 'builder-util-runtime';
|
||||
import type { ClientRequest } from 'electron';
|
||||
|
||||
/**
|
||||
* For testing and same as:
|
||||
* https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/src/electronHttpExecutor.ts
|
||||
*/
|
||||
export class MockedHttpExecutor extends HttpExecutor<ClientRequest> {
|
||||
createRequest(
|
||||
options: any,
|
||||
callback: (response: any) => void
|
||||
): ClientRequest {
|
||||
if (options.headers && options.headers.Host) {
|
||||
// set host value from headers.Host
|
||||
options.host = options.headers.Host;
|
||||
// remove header property 'Host', if not removed causes net::ERR_INVALID_ARGUMENT exception
|
||||
delete options.headers.Host;
|
||||
}
|
||||
|
||||
const request = http.request(options);
|
||||
request.on('response', callback);
|
||||
return request as unknown as ClientRequest;
|
||||
}
|
||||
}
|
||||
3
packages/frontend/electron/test/main/mocks/index.ts
Normal file
3
packages/frontend/electron/test/main/mocks/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './app-adapter';
|
||||
export * from './http-executor';
|
||||
export * from './updater';
|
||||
37
packages/frontend/electron/test/main/mocks/updater.ts
Normal file
37
packages/frontend/electron/test/main/mocks/updater.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'electron-updater'; // Prevent BaseUpdater is undefined.
|
||||
|
||||
import { type AllPublishOptions, UUID } from 'builder-util-runtime';
|
||||
import { randomBytes } from 'crypto';
|
||||
import type { AppAdapter } from 'electron-updater/out/AppAdapter';
|
||||
import type { DownloadUpdateOptions } from 'electron-updater/out/AppUpdater';
|
||||
import type { InstallOptions } from 'electron-updater/out/BaseUpdater';
|
||||
import { BaseUpdater } from 'electron-updater/out/BaseUpdater';
|
||||
|
||||
import { MockedHttpExecutor } from './http-executor';
|
||||
|
||||
/**
|
||||
* For testing, like:
|
||||
* https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/src/MacUpdater.ts
|
||||
*/
|
||||
export class MockedUpdater extends BaseUpdater {
|
||||
httpExecutor: MockedHttpExecutor;
|
||||
|
||||
constructor(options?: AllPublishOptions | null, app?: AppAdapter) {
|
||||
super(options, app);
|
||||
|
||||
this.httpExecutor = new MockedHttpExecutor();
|
||||
Object.assign(this, {
|
||||
getOrCreateStagingUserId: () => {
|
||||
const id = UUID.v5(randomBytes(4096), UUID.OID);
|
||||
return id;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
doInstall(_options: InstallOptions) {
|
||||
return true;
|
||||
}
|
||||
doDownloadUpdate(_options: DownloadUpdateOptions): Promise<string[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
}
|
||||
104
packages/frontend/electron/test/main/updater.spec.ts
Normal file
104
packages/frontend/electron/test/main/updater.spec.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import nodePath from 'node:path';
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import { flatten } from 'lodash-es';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { compare } from 'semver';
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
import { CustomGitHubProvider } from '../../src/main/updater/custom-github-provider';
|
||||
import { MockedAppAdapter, MockedUpdater } from './mocks';
|
||||
|
||||
const platformTail = (() => {
|
||||
// https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/src/providers/Provider.ts#L30
|
||||
const platform = process.platform;
|
||||
if (platform === 'linux') {
|
||||
const arch = process.env['TEST_UPDATER_ARCH'] || process.arch;
|
||||
const archSuffix = arch === 'x64' ? '' : `-${arch}`;
|
||||
return '-linux' + archSuffix;
|
||||
} else {
|
||||
return platform === 'darwin' ? '-mac' : '';
|
||||
}
|
||||
})();
|
||||
|
||||
describe('testing for client update', () => {
|
||||
const expectReleaseList = [
|
||||
{ buildType: 'stable', version: '0.11.1' },
|
||||
{ buildType: 'beta', version: '0.11.1-beta.1' },
|
||||
{ buildType: 'canary', version: '0.11.1-canary.1' },
|
||||
];
|
||||
|
||||
const restHandlers = [
|
||||
http.get(
|
||||
'https://github.com/toeverything/AFFiNE/releases.atom',
|
||||
async () => {
|
||||
const buffer = await fs.readFile(
|
||||
nodePath.join(__dirname, 'fixtures', 'feeds.txt')
|
||||
);
|
||||
const content = buffer.toString();
|
||||
return HttpResponse.xml(content);
|
||||
}
|
||||
),
|
||||
...flatten(
|
||||
expectReleaseList.map(({ version, buildType }) => {
|
||||
function response404() {
|
||||
return HttpResponse.text('Not Found', { status: 404 });
|
||||
}
|
||||
|
||||
return [
|
||||
http.get(
|
||||
`https://github.com/toeverything/AFFiNE/releases/download/v${version}/latest${platformTail}.yml`,
|
||||
async function responseContent() {
|
||||
const buffer = await fs.readFile(
|
||||
nodePath.join(
|
||||
__dirname,
|
||||
'fixtures',
|
||||
'releases',
|
||||
`${version}.txt`
|
||||
)
|
||||
);
|
||||
const content = buffer.toString();
|
||||
return HttpResponse.text(content);
|
||||
}
|
||||
),
|
||||
http.get(
|
||||
`https://github.com/toeverything/AFFiNE/releases/download/v${version}/${buildType}${platformTail}.yml`,
|
||||
response404
|
||||
),
|
||||
];
|
||||
})
|
||||
),
|
||||
];
|
||||
|
||||
const server = setupServer(...restHandlers);
|
||||
|
||||
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
|
||||
afterAll(() => server.close());
|
||||
afterEach(() => server.resetHandlers());
|
||||
|
||||
for (const { buildType } of expectReleaseList) {
|
||||
it(`check update for ${buildType} channel successfully`, async () => {
|
||||
const app = new MockedAppAdapter('0.10.0');
|
||||
const updater = new MockedUpdater(null, app);
|
||||
updater.allowPrerelease = buildType !== 'stable';
|
||||
|
||||
const feedUrl: Parameters<typeof updater.setFeedURL>[0] = {
|
||||
channel: buildType,
|
||||
// hack for custom provider
|
||||
provider: 'custom' as 'github',
|
||||
repo: 'AFFiNE',
|
||||
owner: 'toeverything',
|
||||
releaseType: buildType === 'stable' ? 'release' : 'prerelease',
|
||||
// @ts-expect-error hack for custom provider
|
||||
updateProvider: CustomGitHubProvider,
|
||||
};
|
||||
|
||||
updater.setFeedURL(feedUrl);
|
||||
|
||||
const info = await updater.checkForUpdates();
|
||||
expect(info).not.toBe(null);
|
||||
expect(compare(info!.updateInfo.version, '0.10.0')).toBe(1);
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user