Initial GV2 mock tests

This commit is contained in:
Fedor Indutny 2022-04-20 12:35:53 -07:00 committed by GitHub
parent 34a27accfc
commit e5ba00b798
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 192 additions and 11 deletions

View File

@ -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:*

View File

@ -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",

View File

@ -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();
window.ConversationController.getOrCreate(id, 'private');
// 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,

View File

@ -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(

View 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);
});
});

View File

@ -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 };

View File

@ -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"