Adapt bootstrap to support two clients
This commit is contained in:
parent
5044b3ca3b
commit
9963daf3bf
4 changed files with 128 additions and 21 deletions
|
@ -222,7 +222,7 @@
|
|||
"@indutny/parallel-prettier": "3.0.0",
|
||||
"@indutny/rezip-electron": "2.0.1",
|
||||
"@napi-rs/canvas": "0.1.61",
|
||||
"@signalapp/mock-server": "13.0.1",
|
||||
"@signalapp/mock-server": "13.1.0",
|
||||
"@storybook/addon-a11y": "8.4.4",
|
||||
"@storybook/addon-actions": "8.4.4",
|
||||
"@storybook/addon-controls": "8.4.4",
|
||||
|
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
|
@ -430,8 +430,8 @@ importers:
|
|||
specifier: 0.1.61
|
||||
version: 0.1.61
|
||||
'@signalapp/mock-server':
|
||||
specifier: 13.0.1
|
||||
version: 13.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
|
||||
specifier: 13.1.0
|
||||
version: 13.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
|
||||
'@storybook/addon-a11y':
|
||||
specifier: 8.4.4
|
||||
version: 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.3.3)(utf-8-validate@5.0.10))
|
||||
|
@ -2770,8 +2770,8 @@ packages:
|
|||
'@signalapp/libsignal-client@0.76.0':
|
||||
resolution: {integrity: sha512-wQZFC79GAUeee8pf+aDK5Gii0HbQoCAv/oTn1Ht7d5mFq2pw/L0jRcv3j9DgVYodzCOlnanfto3apfA6eN/Whw==}
|
||||
|
||||
'@signalapp/mock-server@13.0.1':
|
||||
resolution: {integrity: sha512-1rT0fYyqEad64GnZRrFVhNsgKpPS+pvyyk8iOGUHqnqnf818yLIYHblS/5m/cNcvHyC/BBqdtgRHAsfGNqkuZw==}
|
||||
'@signalapp/mock-server@13.1.0':
|
||||
resolution: {integrity: sha512-CuDNLNEBMzwIs5jr7Lx9F4YFoRD62s7WgPGtm3qpaggixSQtabjMC7AKSR0xvaHcZpYZtBU5jcGK8Roguo9nuw==}
|
||||
|
||||
'@signalapp/parchment-cjs@3.0.1':
|
||||
resolution: {integrity: sha512-hSBMQ1M7wE4GcC8ZeNtvpJF+DAJg3eIRRf1SiHS3I3Algav/sgJJNm6HIYm6muHuK7IJmuEjkL3ILSXgmu0RfQ==}
|
||||
|
@ -12466,7 +12466,7 @@ snapshots:
|
|||
type-fest: 4.26.1
|
||||
uuid: 11.0.2
|
||||
|
||||
'@signalapp/mock-server@13.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)':
|
||||
'@signalapp/mock-server@13.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)':
|
||||
dependencies:
|
||||
'@indutny/parallel-prettier': 3.0.0(prettier@3.3.3)
|
||||
'@signalapp/libsignal-client': 0.60.2
|
||||
|
|
|
@ -117,6 +117,9 @@ export type BootstrapOptions = Readonly<{
|
|||
contactPreKeyCount?: number;
|
||||
|
||||
useLegacyStorageEncryption?: boolean;
|
||||
|
||||
// Optional. specify a server to use instead of creating and initializing one.
|
||||
server?: Server;
|
||||
}>;
|
||||
|
||||
export type EphemeralBackupType = Readonly<
|
||||
|
@ -207,7 +210,7 @@ const DEFAULT_REMOTE_CONFIG = [
|
|||
//
|
||||
export class Bootstrap {
|
||||
public readonly server: Server;
|
||||
public readonly cdn3Path: string;
|
||||
public readonly cdn3Path?: string;
|
||||
|
||||
readonly #options: BootstrapInternalOptions;
|
||||
#privContacts?: ReadonlyArray<PrimaryDevice>;
|
||||
|
@ -221,16 +224,18 @@ export class Bootstrap {
|
|||
readonly #randomId = crypto.randomBytes(8).toString('hex');
|
||||
|
||||
constructor(options: BootstrapOptions = {}) {
|
||||
this.cdn3Path = path.join(
|
||||
os.tmpdir(),
|
||||
`mock-signal-cdn3-${this.#randomId}`
|
||||
);
|
||||
this.server = new Server({
|
||||
// Limit number of storage read keys for easier testing
|
||||
maxStorageReadKeys: MAX_STORAGE_READ_KEYS,
|
||||
cdn3Path: this.cdn3Path,
|
||||
updates2Path: path.join(__dirname, 'updates-data'),
|
||||
});
|
||||
this.cdn3Path =
|
||||
options.server === undefined
|
||||
? path.join(os.tmpdir(), `mock-signal-cdn3-${this.#randomId}`)
|
||||
: undefined;
|
||||
this.server =
|
||||
options.server ??
|
||||
new Server({
|
||||
// Limit number of storage read keys for easier testing
|
||||
maxStorageReadKeys: MAX_STORAGE_READ_KEYS,
|
||||
cdn3Path: this.cdn3Path,
|
||||
updates2Path: path.join(__dirname, 'updates-data'),
|
||||
});
|
||||
|
||||
this.#options = {
|
||||
linkedDevices: 5,
|
||||
|
@ -254,10 +259,14 @@ export class Bootstrap {
|
|||
public async init(): Promise<void> {
|
||||
debug('initializing');
|
||||
|
||||
await this.server.listen(0);
|
||||
if (this.#options.server === undefined) {
|
||||
await this.server.listen(0);
|
||||
|
||||
const { port } = this.server.address();
|
||||
debug('started server on port=%d', port);
|
||||
const { port } = this.server.address();
|
||||
debug('started server on port=%d', port);
|
||||
} else {
|
||||
debug('existing server listening on port = ', this.server.address().port);
|
||||
}
|
||||
|
||||
const totalContactCount =
|
||||
this.#options.contactCount +
|
||||
|
@ -367,7 +376,9 @@ export class Bootstrap {
|
|||
...[this.#storagePath, this.cdn3Path].map(tmpPath =>
|
||||
tmpPath ? fs.rm(tmpPath, { recursive: true }) : Promise.resolve()
|
||||
),
|
||||
this.server.close(),
|
||||
this.#options.server === undefined
|
||||
? this.server.close()
|
||||
: Promise.resolve(),
|
||||
this.#lastApp?.close(),
|
||||
]),
|
||||
new Promise(resolve => setTimeout(resolve, CLOSE_TIMEOUT).unref()),
|
||||
|
|
96
ts/test-mock/calling/callMessages_test.ts
Normal file
96
ts/test-mock/calling/callMessages_test.ts
Normal file
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { StorageState } from '@signalapp/mock-server';
|
||||
import * as durations from '../../util/durations';
|
||||
import type { App } from '../playwright';
|
||||
import { Bootstrap } from '../bootstrap';
|
||||
import { typeIntoInput, waitForEnabledComposer } from '../helpers';
|
||||
|
||||
describe('callMessages', function (this: Mocha.Suite) {
|
||||
this.timeout(durations.MINUTE);
|
||||
|
||||
let bootstrap1: Bootstrap;
|
||||
let bootstrap2: Bootstrap;
|
||||
let app1: App;
|
||||
let app2: App;
|
||||
|
||||
beforeEach(async () => {
|
||||
bootstrap1 = new Bootstrap();
|
||||
await bootstrap1.init();
|
||||
|
||||
bootstrap2 = new Bootstrap({ server: bootstrap1.server });
|
||||
await bootstrap2.init();
|
||||
|
||||
let state1 = StorageState.getEmpty();
|
||||
state1 = state1.updateAccount({
|
||||
profileKey: bootstrap1.phone.profileKey.serialize(),
|
||||
});
|
||||
|
||||
state1 = state1.addContact(bootstrap2.phone, {
|
||||
whitelisted: true,
|
||||
profileKey: bootstrap2.phone.profileKey.serialize(),
|
||||
givenName: 'Contact2',
|
||||
});
|
||||
|
||||
state1 = state1.pin(bootstrap2.phone);
|
||||
|
||||
await bootstrap1.phone.setStorageState(state1);
|
||||
|
||||
app1 = await bootstrap1.link();
|
||||
|
||||
let state2 = StorageState.getEmpty();
|
||||
state2 = state2.updateAccount({
|
||||
profileKey: bootstrap2.phone.profileKey.serialize(),
|
||||
});
|
||||
|
||||
state2 = state2.addContact(bootstrap1.phone, {
|
||||
whitelisted: true,
|
||||
profileKey: bootstrap1.phone.profileKey.serialize(),
|
||||
givenName: 'Contact1',
|
||||
});
|
||||
|
||||
state2 = state2.pin(bootstrap1.phone);
|
||||
await bootstrap2.phone.setStorageState(state2);
|
||||
|
||||
app2 = await bootstrap2.link();
|
||||
});
|
||||
|
||||
afterEach(async function (this: Mocha.Context) {
|
||||
if (!bootstrap1) {
|
||||
return;
|
||||
}
|
||||
await bootstrap2.maybeSaveLogs(this.currentTest, app2);
|
||||
await bootstrap1.maybeSaveLogs(this.currentTest, app1);
|
||||
|
||||
await app2.close();
|
||||
await app1.close();
|
||||
|
||||
await bootstrap2.teardown();
|
||||
await bootstrap1.teardown();
|
||||
});
|
||||
|
||||
it('can send a message from one client to another', async () => {
|
||||
const window1 = await app1.getWindow();
|
||||
const leftPane1 = window1.locator('#LeftPane');
|
||||
|
||||
await leftPane1
|
||||
.locator(`[data-testid="${bootstrap2.phone.device.aci}"]`)
|
||||
.click();
|
||||
const window2 = await app2.getWindow();
|
||||
|
||||
const messageBody = 'Hello world';
|
||||
const compositionInput = await waitForEnabledComposer(window1);
|
||||
await typeIntoInput(compositionInput, messageBody, '');
|
||||
await compositionInput.press('Enter');
|
||||
|
||||
const leftPane = window2.locator('#LeftPane');
|
||||
await leftPane
|
||||
.locator(`[data-testid="${bootstrap1.phone.device.aci}"]`)
|
||||
.click();
|
||||
|
||||
await window2
|
||||
.locator(`.module-message__text >> "${messageBody}"`)
|
||||
.waitFor();
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue