Initial GV2 mock tests
This commit is contained in:
parent
34a27accfc
commit
e5ba00b798
7 changed files with 192 additions and 11 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -157,7 +157,7 @@ jobs:
|
|||
env:
|
||||
SIGNAL_ENV: production
|
||||
|
||||
storage-service:
|
||||
mock-tests:
|
||||
needs: lint
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' }}
|
||||
|
@ -198,11 +198,11 @@ jobs:
|
|||
- name: Bundle
|
||||
run: yarn build:webpack
|
||||
|
||||
- name: Run storage service tests
|
||||
- name: Run mock server tests
|
||||
run: |
|
||||
set -o pipefail
|
||||
xvfb-run --auto-servernum yarn test-mock
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
NODE_ENV: production
|
||||
DEBUG: mock:test-storage
|
||||
DEBUG: mock:test:*
|
||||
|
|
|
@ -189,7 +189,7 @@
|
|||
"@chanzuckerberg/axe-storybook-testing": "3.0.2",
|
||||
"@electron/fuses": "1.5.0",
|
||||
"@mixer/parallel-prettier": "2.0.1",
|
||||
"@signalapp/mock-server": "1.3.0",
|
||||
"@signalapp/mock-server": "1.5.0-rc.3",
|
||||
"@storybook/addon-actions": "5.1.11",
|
||||
"@storybook/addon-knobs": "5.1.11",
|
||||
"@storybook/addons": "5.1.11",
|
||||
|
|
|
@ -45,7 +45,7 @@ import type {
|
|||
} from './textsecure/Types.d';
|
||||
import type { RemoveAllConfiguration } from './types/RemoveAllConfiguration';
|
||||
import type { UUIDStringType } from './types/UUID';
|
||||
import { UUID } from './types/UUID';
|
||||
import { UUID, UUIDKind } from './types/UUID';
|
||||
import type { Address } from './types/Address';
|
||||
import type { QualifiedAddressStringType } from './types/QualifiedAddress';
|
||||
import { QualifiedAddress } from './types/QualifiedAddress';
|
||||
|
@ -1682,7 +1682,11 @@ export class SignalProtocolStore extends EventsMixin {
|
|||
const identityRecord = await this.getOrMigrateIdentityRecord(uuid);
|
||||
const id = uuid.toString();
|
||||
|
||||
// When saving a PNI identity - don't create a separate conversation
|
||||
const uuidKind = window.textsecure.storage.user.getOurUuidKind(uuid);
|
||||
if (uuidKind !== UUIDKind.PNI) {
|
||||
window.ConversationController.getOrCreate(id, 'private');
|
||||
}
|
||||
|
||||
const updates: Partial<IdentityKeyType> = {
|
||||
...identityRecord,
|
||||
|
|
|
@ -13,6 +13,8 @@ import { MAX_READ_KEYS as MAX_STORAGE_READ_KEYS } from '../services/storageConst
|
|||
import * as durations from '../util/durations';
|
||||
import { App } from './playwright';
|
||||
|
||||
export { App };
|
||||
|
||||
const debug = createDebug('mock:bootstrap');
|
||||
|
||||
const ELECTRON = path.join(
|
||||
|
|
175
ts/test-mock/gv2/create_test.ts
Normal file
175
ts/test-mock/gv2/create_test.ts
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import type { PrimaryDevice, Group } from '@signalapp/mock-server';
|
||||
import { StorageState, Proto } from '@signalapp/mock-server';
|
||||
import createDebug from 'debug';
|
||||
|
||||
import * as durations from '../../util/durations';
|
||||
import { Bootstrap } from '../bootstrap';
|
||||
import type { App } from '../bootstrap';
|
||||
|
||||
export const debug = createDebug('mock:test:gv2');
|
||||
|
||||
describe('gv2', function needsName() {
|
||||
this.timeout(durations.MINUTE);
|
||||
|
||||
let bootstrap: Bootstrap;
|
||||
let app: App;
|
||||
let pniContact: PrimaryDevice;
|
||||
|
||||
beforeEach(async () => {
|
||||
bootstrap = new Bootstrap();
|
||||
await bootstrap.init();
|
||||
|
||||
const { phone, contacts, server } = bootstrap;
|
||||
|
||||
let state = StorageState.getEmpty();
|
||||
|
||||
state = state.updateAccount({
|
||||
profileKey: phone.profileKey.serialize(),
|
||||
e164: phone.device.number,
|
||||
});
|
||||
|
||||
const [first] = contacts;
|
||||
state = state.addContact(first, {
|
||||
identityState: Proto.ContactRecord.IdentityState.VERIFIED,
|
||||
whitelisted: true,
|
||||
|
||||
identityKey: first.publicKey.serialize(),
|
||||
profileKey: first.profileKey.serialize(),
|
||||
});
|
||||
|
||||
pniContact = await server.createPrimaryDevice({
|
||||
profileName: 'My name is PNI',
|
||||
});
|
||||
state = state.addContact(pniContact, {
|
||||
identityState: Proto.ContactRecord.IdentityState.VERIFIED,
|
||||
whitelisted: true,
|
||||
|
||||
identityKey: pniContact.pniPublicKey.serialize(),
|
||||
|
||||
// Give PNI as the uuid!
|
||||
serviceUuid: pniContact.device.pni,
|
||||
givenName: 'PNI Contact',
|
||||
});
|
||||
|
||||
await phone.setStorageState(state);
|
||||
|
||||
app = await bootstrap.link();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
await bootstrap.teardown();
|
||||
});
|
||||
|
||||
it('should create group and modify it', async () => {
|
||||
const { phone, contacts } = bootstrap;
|
||||
const [first] = contacts;
|
||||
|
||||
let state = await phone.expectStorageState('initial state');
|
||||
|
||||
const window = await app.getWindow();
|
||||
|
||||
const leftPane = window.locator('.left-pane-wrapper');
|
||||
const conversationStack = window.locator('.conversation-stack');
|
||||
|
||||
debug('clicking compose and "New group" buttons');
|
||||
|
||||
await leftPane.locator('.module-main-header__compose-icon').click();
|
||||
|
||||
await leftPane
|
||||
.locator('_react=BaseConversationListItem[title = "New group"]')
|
||||
.click();
|
||||
|
||||
debug('inviting ACI member');
|
||||
|
||||
await leftPane
|
||||
.locator(
|
||||
'_react=BaseConversationListItem' +
|
||||
`[title = ${JSON.stringify(first.profileName)}]`
|
||||
)
|
||||
.click();
|
||||
|
||||
debug('inviting PNI member');
|
||||
|
||||
await leftPane
|
||||
.locator('.module-left-pane__compose-search-form__input')
|
||||
.type('PNI');
|
||||
|
||||
await leftPane
|
||||
.locator('_react=BaseConversationListItem[title = "PNI Contact"]')
|
||||
.click();
|
||||
|
||||
await leftPane
|
||||
.locator('.module-left-pane__footer button >> "Next"')
|
||||
.click();
|
||||
|
||||
debug('entering group title');
|
||||
|
||||
await leftPane.type('My group');
|
||||
|
||||
await leftPane
|
||||
.locator('.module-left-pane__footer button >> "Create"')
|
||||
.click();
|
||||
|
||||
debug('waiting for invitation modal');
|
||||
|
||||
{
|
||||
const modal = window.locator(
|
||||
'.module-GroupDialog:has-text("Invitation sent")'
|
||||
);
|
||||
|
||||
await modal.locator('button >> "Okay"').click();
|
||||
}
|
||||
|
||||
debug('waiting for group data from storage service');
|
||||
|
||||
let group: Group;
|
||||
{
|
||||
state = await phone.waitForStorageState({ after: state });
|
||||
|
||||
const groups = await phone.getAllGroups(state);
|
||||
assert.strictEqual(groups.length, 1);
|
||||
|
||||
[group] = groups;
|
||||
assert.strictEqual(group.title, 'My group');
|
||||
assert.strictEqual(group.revision, 0);
|
||||
assert.strictEqual(group.state.members?.length, 2);
|
||||
assert.strictEqual(group.state.membersPendingProfileKey?.length, 1);
|
||||
}
|
||||
|
||||
debug('opening group settings');
|
||||
|
||||
await conversationStack
|
||||
.locator('button.module-ConversationHeader__button--more')
|
||||
.click();
|
||||
|
||||
await conversationStack
|
||||
.locator('.react-contextmenu-item >> "Group settings"')
|
||||
.click();
|
||||
|
||||
debug('editing group title');
|
||||
{
|
||||
const detailsHeader = conversationStack.locator(
|
||||
'_react=ConversationDetailsHeader'
|
||||
);
|
||||
detailsHeader.locator('button >> "My group"').click();
|
||||
|
||||
const modal = window.locator('.module-Modal:has-text("Edit group")');
|
||||
|
||||
// Group title should be immediately focused.
|
||||
await modal.type(' (v2)');
|
||||
|
||||
await modal.locator('button >> "Save"').click();
|
||||
}
|
||||
|
||||
debug('waiting for the second group update');
|
||||
group = await phone.waitForGroupUpdate(group);
|
||||
|
||||
assert.strictEqual(group.title, 'My group (v2)');
|
||||
assert.strictEqual(group.revision, 1);
|
||||
});
|
||||
});
|
|
@ -8,7 +8,7 @@ import { App } from '../playwright';
|
|||
import { Bootstrap } from '../bootstrap';
|
||||
import type { BootstrapOptions } from '../bootstrap';
|
||||
|
||||
export const debug = createDebug('mock:test-storage');
|
||||
export const debug = createDebug('mock:test:storage');
|
||||
|
||||
export { App, Bootstrap };
|
||||
|
||||
|
|
|
@ -1372,10 +1372,10 @@
|
|||
node-gyp-build "^4.2.3"
|
||||
uuid "^8.3.0"
|
||||
|
||||
"@signalapp/mock-server@1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-1.3.0.tgz#288a994c4f5c26c4c2680289af471e08746ac353"
|
||||
integrity sha512-ix3GO0lytE02nWLj1fKY3UhKM3lCynhvF2LVNHEiMen9wurVyb8mVcmBDb9zRBi63tZmFLAq/IQEYrc1OK3ZJQ==
|
||||
"@signalapp/mock-server@1.5.0-rc.3":
|
||||
version "1.5.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-1.5.0-rc.3.tgz#2bb0d80555e84740bf7c110386da6ec9200785d5"
|
||||
integrity sha512-ShoMNL4XHtvBXDrzgQD2xXpqTDjzzVegQjlA15c9H285Z1qQJhQfnu3A13YDmAYqZ0LbXM8Re5AnWtZJYdGSCA==
|
||||
dependencies:
|
||||
"@signalapp/libsignal-client" "0.15.0"
|
||||
debug "^4.3.2"
|
||||
|
|
Loading…
Reference in a new issue