Test more contact splitting scenarios

This commit is contained in:
Fedor Indutny 2024-01-31 09:51:09 -08:00 committed by GitHub
parent 304287efef
commit 900b40381c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 93 additions and 81 deletions

View file

@ -1515,7 +1515,7 @@ async function processRemoteRecords(
}); });
// Find remote contact records that: // Find remote contact records that:
// - Have `remote.pni === remote.serviceUuid` and have `remote.serviceE164` // - Have `remote.pni` and have `remote.serviceE164`
// - Match local contact that has `aci`. // - Match local contact that has `aci`.
const splitPNIContacts = new Array<MergeableItemType>(); const splitPNIContacts = new Array<MergeableItemType>();
prunedStorageItems = prunedStorageItems.filter(item => { prunedStorageItems = prunedStorageItems.filter(item => {

View file

@ -229,103 +229,116 @@ describe('pnp/merge', function (this: Mocha.Suite) {
}); });
} }
it('accepts storage service contact splitting', async () => { for (const withPniContact of [false, true]) {
const { phone } = bootstrap; const testName =
'accepts storage service contact splitting ' +
`${withPniContact ? 'with PNI contact' : 'without PNI contact'}`;
debug( // eslint-disable-next-line no-loop-func
'removing both contacts from storage service, adding one combined contact' it(testName, async () => {
); const { phone } = bootstrap;
{
const state = await phone.expectStorageState('consistency check'); debug(
await phone.setStorageState( 'removing both contacts from storage service, adding one combined contact'
state.mergeContact(pniContact, {
identityState: Proto.ContactRecord.IdentityState.DEFAULT,
whitelisted: true,
identityKey: pniContact.publicKey.serialize(),
profileKey: pniContact.profileKey.serialize(),
})
); );
await phone.sendFetchStorage({ {
timestamp: bootstrap.getTimestamp(), const state = await phone.expectStorageState('consistency check');
}); await phone.setStorageState(
} state.mergeContact(pniContact, {
identityState: Proto.ContactRecord.IdentityState.DEFAULT,
whitelisted: true,
identityKey: pniContact.publicKey.serialize(),
profileKey: pniContact.profileKey.serialize(),
})
);
await phone.sendFetchStorage({
timestamp: bootstrap.getTimestamp(),
});
}
const window = await app.getWindow(); const window = await app.getWindow();
const leftPane = window.locator('#LeftPane'); const leftPane = window.locator('#LeftPane');
debug('opening conversation with the merged contact'); debug('opening conversation with the merged contact');
await leftPane await leftPane
.locator( .locator(
`[data-testid="${pniContact.device.aci}"] >> ` + `[data-testid="${pniContact.device.aci}"] >> ` +
`"${pniContact.profileName}"` `"${pniContact.profileName}"`
) )
.click(); .click();
await window.locator('.module-conversation-hero').waitFor(); await window.locator('.module-conversation-hero').waitFor();
debug('Send message to merged contact'); debug('Send message to merged contact');
{ {
const compositionInput = await app.waitForEnabledComposer(); const compositionInput = await app.waitForEnabledComposer();
await compositionInput.type('Hello merged'); await compositionInput.type('Hello merged');
await compositionInput.press('Enter'); await compositionInput.press('Enter');
} }
debug('Split contact and mark ACI as unregistered'); debug('Split contact and mark ACI as unregistered');
{ {
let state = await phone.expectStorageState('consistency check'); let state = await phone.expectStorageState('consistency check');
state = state.updateContact(pniContact, { state = state.updateContact(pniContact, {
pni: undefined, pni: undefined,
serviceE164: undefined, serviceE164: undefined,
unregisteredAtTimestamp: Long.fromNumber(bootstrap.getTimestamp()), unregisteredAtTimestamp: Long.fromNumber(bootstrap.getTimestamp()),
}); });
state = state.addContact( if (withPniContact) {
pniContact, state = state.addContact(
{ pniContact,
identityState: Proto.ContactRecord.IdentityState.DEFAULT, {
whitelisted: true, identityState: Proto.ContactRecord.IdentityState.DEFAULT,
whitelisted: true,
identityKey: pniIdentityKey, identityKey: pniIdentityKey,
serviceE164: pniContact.device.number, serviceE164: pniContact.device.number,
givenName: 'PNI Contact', givenName: 'PNI Contact',
}, },
ServiceIdKind.PNI ServiceIdKind.PNI
); );
}
state = state.pin(pniContact, ServiceIdKind.PNI); state = state.pin(pniContact, ServiceIdKind.PNI);
await phone.setStorageState(state); await phone.setStorageState(state);
await phone.sendFetchStorage({ await phone.sendFetchStorage({
timestamp: bootstrap.getTimestamp(), timestamp: bootstrap.getTimestamp(),
}); });
} }
debug('Wait for pni contact to appear'); debug('Wait for pni contact to appear');
await leftPane await leftPane
.locator(`[data-testid="${pniContact.device.pni}"]`) .locator(`[data-testid="${pniContact.device.pni}"]`)
.waitFor(); .waitFor();
debug('Verify that the message is in the ACI conversation'); debug('Verify that the message is in the ACI conversation');
{ {
// Should have both PNI and ACI messages // Should have both PNI and ACI messages
await window.locator('.module-message__text >> "Hello merged"').waitFor(); await window
.locator('.module-message__text >> "Hello merged"')
.waitFor();
const messages = window.locator('.module-message__text'); const messages = window.locator('.module-message__text');
assert.strictEqual(await messages.count(), 1, 'message count'); assert.strictEqual(await messages.count(), 1, 'message count');
} }
debug('Open PNI conversation'); debug('Open PNI conversation');
await leftPane.locator(`[data-testid="${pniContact.device.pni}"]`).click(); await leftPane
.locator(`[data-testid="${pniContact.device.pni}"]`)
.click();
debug('Verify absence of messages in the PNI conversation'); debug('Verify absence of messages in the PNI conversation');
{ {
const messages = window.locator('.module-message__text'); const messages = window.locator('.module-message__text');
assert.strictEqual(await messages.count(), 0, 'message count'); assert.strictEqual(await messages.count(), 0, 'message count');
} }
}); });
}
it('splits contact when ACI becomes unregistered', async () => { it('splits contact when ACI becomes unregistered', async () => {
const { phone, server } = bootstrap; const { phone, server } = bootstrap;

View file

@ -640,8 +640,7 @@ export type CapabilitiesType = {
pni: boolean; pni: boolean;
}; };
export type CapabilitiesUploadType = { export type CapabilitiesUploadType = {
// true in staging, false in production pni: true;
pni: boolean;
}; };
type StickerPackManifestType = Uint8Array; type StickerPackManifestType = Uint8Array;