From 9bb0a46aad25792aeab0bce9a661c294816d57d5 Mon Sep 17 00:00:00 2001 From: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> Date: Thu, 1 Feb 2024 13:05:22 -0800 Subject: [PATCH] Fix PNI normalization in conversation selectors --- package.json | 2 +- ts/state/selectors/conversations.ts | 3 +- ts/test-mock/pnp/accept_gv2_invite_test.ts | 98 ++++++++++++++++++++-- yarn.lock | 8 +- 4 files changed, 99 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 3c96571a65f9..8dba33251b83 100644 --- a/package.json +++ b/package.json @@ -199,7 +199,7 @@ "@electron/notarize": "2.1.0", "@formatjs/intl": "2.6.7", "@mixer/parallel-prettier": "2.0.3", - "@signalapp/mock-server": "4.6.0", + "@signalapp/mock-server": "5.0.0", "@storybook/addon-a11y": "7.4.5", "@storybook/addon-actions": "7.4.5", "@storybook/addon-controls": "7.4.5", diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts index 67dabbac7078..2ca73285784e 100644 --- a/ts/state/selectors/conversations.ts +++ b/ts/state/selectors/conversations.ts @@ -38,6 +38,7 @@ import type { ContactNameColorType } from '../../types/Colors'; import { ContactNameColors } from '../../types/Colors'; import type { AvatarDataType } from '../../types/Avatar'; import type { AciString, ServiceIdString } from '../../types/ServiceId'; +import { normalizeServiceId } from '../../types/ServiceId'; import { isInSystemContacts } from '../../util/isInSystemContacts'; import { isSignalConnection } from '../../util/getSignalConnections'; import { sortByTitle } from '../../util/sortByTitle'; @@ -821,7 +822,7 @@ export const getConversationSelector = createSelector( const onServiceId = getOwn( byServiceId, - id.toLowerCase ? id.toLowerCase() : id + normalizeServiceId(id, 'getConversationSelector') ); if (onServiceId) { return selector(onServiceId); diff --git a/ts/test-mock/pnp/accept_gv2_invite_test.ts b/ts/test-mock/pnp/accept_gv2_invite_test.ts index 95d75e84b4da..fb99dec50757 100644 --- a/ts/test-mock/pnp/accept_gv2_invite_test.ts +++ b/ts/test-mock/pnp/accept_gv2_invite_test.ts @@ -3,10 +3,14 @@ import { assert } from 'chai'; import type { Group, PrimaryDevice } from '@signalapp/mock-server'; -import { Proto, ServiceIdKind } from '@signalapp/mock-server'; +import { Proto, ServiceIdKind, StorageState } from '@signalapp/mock-server'; import createDebug from 'debug'; import * as durations from '../../util/durations'; +import { + parseAndFormatPhoneNumber, + PhoneNumberFormat, +} from '../../util/libphonenumberInstance'; import { Bootstrap } from '../bootstrap'; import type { App } from '../bootstrap'; @@ -19,6 +23,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { let app: App; let group: Group; let unknownContact: PrimaryDevice; + let unknownPniContact: PrimaryDevice; beforeEach(async () => { bootstrap = new Bootstrap({ @@ -27,15 +32,35 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { }); await bootstrap.init(); - const { contacts, unknownContacts } = bootstrap; + const { phone, contacts, unknownContacts } = bootstrap; const [first, second] = contacts; - [unknownContact] = unknownContacts; + [unknownContact, unknownPniContact] = unknownContacts; group = await first.createGroup({ - title: 'Invite by PNI', + title: 'Invited Desktop PNI', members: [first, second, unknownContact], }); + let state = StorageState.getEmpty(); + + state = state.updateAccount({ + profileKey: phone.profileKey.serialize(), + e164: phone.device.number, + }); + + state = state.addContact( + unknownPniContact, + { + identityState: Proto.ContactRecord.IdentityState.DEFAULT, + whitelisted: true, + + serviceE164: unknownPniContact.device.number, + }, + ServiceIdKind.PNI + ); + + await phone.setStorageState(state); + app = await bootstrap.link(); const { desktop } = bootstrap; @@ -300,7 +325,7 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { timestamp: bootstrap.getTimestamp(), // There is no one to receive it so don't bother. - sendInvite: false, + sendUpdateTo: [], }); debug('Sending message to group'); @@ -316,8 +341,9 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { await leftPane.locator(`[data-testid="${group.id}"]`).click(); debug('Accepting remote invite'); - await second.acceptPniInvite(group, desktop, { + await second.acceptPniInvite(group, { timestamp: bootstrap.getTimestamp(), + sendUpdateTo: [{ device: desktop }], }); await window @@ -328,4 +354,64 @@ describe('pnp/accept gv2 invite', function (this: Mocha.Suite) { ) .waitFor(); }); + + it('should display a e164 for a PNI invite', async () => { + const { phone, contacts, desktop } = bootstrap; + + const [first] = contacts; + + debug('Creating new group with Desktop'); + group = await phone.createGroup({ + title: 'Remote Invite', + members: [phone, first], + }); + + debug('Sending message to group'); + await first.sendText(desktop, 'howdy', { + group, + timestamp: bootstrap.getTimestamp(), + }); + + const window = await app.getWindow(); + const leftPane = window.locator('#LeftPane'); + + debug('Opening new group'); + await leftPane.locator(`[data-testid="${group.id}"]`).click(); + + debug('Inviting remote PNI to group'); + group = await phone.inviteToGroup(group, unknownPniContact.device, { + timestamp: bootstrap.getTimestamp(), + + serviceIdKind: ServiceIdKind.PNI, + sendUpdateTo: [{ device: desktop }], + }); + + debug('Waiting for invite notification'); + const parsedE164 = parseAndFormatPhoneNumber( + unknownPniContact.device.number, + '+1', + PhoneNumberFormat.NATIONAL + ); + if (!parsedE164) { + throw new Error('Failed to parse device number'); + } + const { e164 } = parsedE164; + await window + .locator(`.SystemMessage >> text=You invited ${e164} to the group`) + .waitFor(); + + debug('Accepting remote invite'); + await unknownPniContact.acceptPniInvite(group, { + timestamp: bootstrap.getTimestamp(), + sendUpdateTo: [{ device: desktop }], + }); + + debug('Waiting for accept notification'); + await window + .locator( + '.SystemMessage >> ' + + `text=${unknownPniContact.profileName} accepted your invitation to the group` + ) + .waitFor(); + }); }); diff --git a/yarn.lock b/yarn.lock index d64d67f2f59f..df2fd39dcea0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3973,10 +3973,10 @@ type-fest "^3.5.0" uuid "^8.3.0" -"@signalapp/mock-server@4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-4.6.0.tgz#4530ba1cc56fe71be9137ac0434523bec1f1b163" - integrity sha512-2TobdaMERrhXpY0dbwCszNJpcp1YdLOWiDByX4XHnoJ6yyubnW00rfM6h7PzDVIgLpb6fVfHI3sLbQlubxeo5g== +"@signalapp/mock-server@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-5.0.0.tgz#2534925b0e248b6211cda420641508d92c5a97cb" + integrity sha512-HlEgiBKmPp1Rl5ltfg/FmIfH2DQeCzb7lML8SscRvZOQSE83+MRf7JZtwIlDQxg3YmhQo0RmReQNv8yz5KtbVg== dependencies: "@signalapp/libsignal-client" "^0.39.2" debug "^4.3.2"