diff --git a/ts/groups.ts b/ts/groups.ts index 63c7e8170..3e73bcfc5 100644 --- a/ts/groups.ts +++ b/ts/groups.ts @@ -5464,7 +5464,7 @@ function profileKeyHasChanged( function hasProfileKey(userId: ServiceIdString) { const conversation = window.ConversationController.get(userId); if (!conversation) { - return true; + return false; } const existingBase64 = conversation.get('profileKey'); diff --git a/ts/test-mock/bootstrap.ts b/ts/test-mock/bootstrap.ts index 86e889397..127e43c34 100644 --- a/ts/test-mock/bootstrap.ts +++ b/ts/test-mock/bootstrap.ts @@ -72,6 +72,7 @@ export type BootstrapOptions = Readonly<{ linkedDevices?: number; contactCount?: number; contactsWithoutProfileKey?: number; + unknownContactCount?: number; contactNames?: ReadonlyArray; contactPreKeyCount?: number; }>; @@ -82,6 +83,7 @@ type BootstrapInternalOptions = Pick & linkedDevices: number; contactCount: number; contactsWithoutProfileKey: number; + unknownContactCount: number; contactNames: ReadonlyArray; }>; @@ -116,6 +118,7 @@ export class Bootstrap { private readonly options: BootstrapInternalOptions; private privContacts?: ReadonlyArray; private privContactsWithoutProfileKey?: ReadonlyArray; + private privUnknownContacts?: ReadonlyArray; private privPhone?: PrimaryDevice; private privDesktop?: Device; private storagePath?: string; @@ -132,6 +135,7 @@ export class Bootstrap { linkedDevices: 5, contactCount: MAX_CONTACTS, contactsWithoutProfileKey: 0, + unknownContactCount: 0, contactNames: CONTACT_NAMES, benchmark: false, @@ -139,7 +143,9 @@ export class Bootstrap { }; assert( - this.options.contactCount + this.options.contactsWithoutProfileKey <= + this.options.contactCount + + this.options.contactsWithoutProfileKey + + this.options.unknownContactCount <= this.options.contactNames.length ); } @@ -152,13 +158,8 @@ export class Bootstrap { const { port } = this.server.address(); debug('started server on port=%d', port); - const contactNames = this.options.contactNames.slice( - 0, - this.options.contactCount + this.options.contactsWithoutProfileKey - ); - const allContacts = await Promise.all( - contactNames.map(async profileName => { + this.options.contactNames.map(async profileName => { const primary = await this.server.createPrimaryDevice({ profileName, }); @@ -172,9 +173,14 @@ export class Bootstrap { }) ); - this.privContacts = allContacts.slice(0, this.options.contactCount); - this.privContactsWithoutProfileKey = allContacts.slice( - this.contacts.length + this.privContacts = allContacts.splice(0, this.options.contactCount); + this.privContactsWithoutProfileKey = allContacts.splice( + 0, + this.options.contactsWithoutProfileKey + ); + this.privUnknownContacts = allContacts.splice( + 0, + this.options.unknownContactCount ); this.privPhone = await this.server.createPrimaryDevice({ @@ -386,9 +392,20 @@ export class Bootstrap { ); return this.privContactsWithoutProfileKey; } + public get unknownContacts(): ReadonlyArray { + assert( + this.privUnknownContacts, + 'Bootstrap has to be initialized first, see: bootstrap.init()' + ); + return this.privUnknownContacts; + } public get allContacts(): ReadonlyArray { - return [...this.contacts, ...this.contactsWithoutProfileKey]; + return [ + ...this.contacts, + ...this.contactsWithoutProfileKey, + ...this.unknownContacts, + ]; } // diff --git a/ts/test-mock/messaging/unknown_contact_test.ts b/ts/test-mock/messaging/unknown_contact_test.ts index b47c01913..976a3e1ac 100644 --- a/ts/test-mock/messaging/unknown_contact_test.ts +++ b/ts/test-mock/messaging/unknown_contact_test.ts @@ -22,18 +22,13 @@ describe('unknown contacts', function (this: Mocha.Suite) { let unknownContact: PrimaryDevice; beforeEach(async () => { - bootstrap = new Bootstrap(); + bootstrap = new Bootstrap({ contactCount: 1, unknownContactCount: 1 }); await bootstrap.init(); app = await bootstrap.link(); page = await app.getWindow(); - const { server, desktop } = bootstrap; - unknownContact = await server.createPrimaryDevice({ - profileName: 'Hugh Ameye', - }); - - const ourKey = await desktop.popSingleUseKey(); - await unknownContact.addSingleUseKey(desktop, ourKey); + const { unknownContacts } = bootstrap; + [unknownContact] = unknownContacts; }); afterEach(async function (this: Mocha.Context) { diff --git a/ts/test-mock/pnp/accept_gv2_invite_test.ts b/ts/test-mock/pnp/accept_gv2_invite_test.ts index 4f0757557..a80609ba4 100644 --- a/ts/test-mock/pnp/accept_gv2_invite_test.ts +++ b/ts/test-mock/pnp/accept_gv2_invite_test.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import { assert } from 'chai'; -import type { Group } from '@signalapp/mock-server'; +import type { Group, PrimaryDevice } from '@signalapp/mock-server'; import { Proto, ServiceIdKind } from '@signalapp/mock-server'; import createDebug from 'debug'; @@ -19,18 +19,22 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { let bootstrap: Bootstrap; let app: App; let group: Group; + let unknownContact: PrimaryDevice; beforeEach(async () => { - bootstrap = new Bootstrap(); + bootstrap = new Bootstrap({ + contactCount: 10, + unknownContactCount: 3, + }); await bootstrap.init(); - const { contacts } = bootstrap; - + const { contacts, unknownContacts } = bootstrap; const [first, second] = contacts; + [unknownContact] = unknownContacts; group = await first.createGroup({ title: 'Invite by PNI', - members: [first, second], + members: [first, second, unknownContact], }); app = await bootstrap.link(); @@ -42,7 +46,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { }); // Verify that created group has pending member - assert.strictEqual(group.state?.members?.length, 2); + assert.strictEqual(group.state?.members?.length, 3); assert(!group.getMemberByServiceId(desktop.aci)); assert(!group.getMemberByServiceId(desktop.pni)); assert(!group.getPendingMemberByServiceId(desktop.aci)); @@ -77,7 +81,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { group = await phone.waitForGroupUpdate(group); assert.strictEqual(group.revision, 2); - assert.strictEqual(group.state?.members?.length, 3); + assert.strictEqual(group.state?.members?.length, 4); assert(group.getMemberByServiceId(desktop.aci)); assert(!group.getMemberByServiceId(desktop.pni)); assert(!group.getPendingMemberByServiceId(desktop.aci)); @@ -109,13 +113,22 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { .locator('.module-message-request-actions button >> "Accept"') .waitFor({ state: 'hidden' }); - debug('Leave the group through settings'); await window .locator('button.module-ConversationHeader__button--more') .click(); await window.locator('.react-contextmenu-item >> "Group settings"').click(); + debug( + 'Checking that we see all members of group, including (previously) unknown contact' + ); + await window + .locator('.ConversationDetails-panel-section__title >> "4 members"') + .waitFor(); + await window.getByText(unknownContact.profileName).waitFor(); + + debug('Leave the group through settings'); + await conversationStack .locator('.conversation-details-panel >> "Leave group"') .click(); @@ -125,7 +138,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { debug('Waiting for final group update'); group = await phone.waitForGroupUpdate(group); assert.strictEqual(group.revision, 4); - assert.strictEqual(group.state?.members?.length, 2); + assert.strictEqual(group.state?.members?.length, 3); assert(!group.getMemberByServiceId(desktop.aci)); assert(!group.getMemberByServiceId(desktop.pni)); assert(!group.getPendingMemberByServiceId(desktop.aci)); @@ -149,7 +162,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { group = await phone.waitForGroupUpdate(group); assert.strictEqual(group.revision, 2); - assert.strictEqual(group.state?.members?.length, 2); + assert.strictEqual(group.state?.members?.length, 3); assert(!group.getMemberByServiceId(desktop.aci)); assert(!group.getMemberByServiceId(desktop.pni)); assert(!group.getPendingMemberByServiceId(desktop.aci)); @@ -209,7 +222,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { group = await phone.waitForGroupUpdate(group); assert.strictEqual(group.revision, 3); - assert.strictEqual(group.state?.members?.length, 3); + assert.strictEqual(group.state?.members?.length, 4); assert(group.getMemberByServiceId(desktop.aci)); assert(!group.getMemberByServiceId(desktop.pni)); assert(!group.getPendingMemberByServiceId(desktop.aci)); @@ -261,7 +274,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { group = await phone.waitForGroupUpdate(group); assert.strictEqual(group.revision, 3); - assert.strictEqual(group.state?.members?.length, 2); + assert.strictEqual(group.state?.members?.length, 3); assert(!group.getMemberByServiceId(desktop.aci)); assert(!group.getMemberByServiceId(desktop.pni)); assert(!group.getPendingMemberByServiceId(desktop.aci));