Test more contact splitting scenarios
This commit is contained in:
parent
304287efef
commit
900b40381c
3 changed files with 93 additions and 81 deletions
|
@ -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 => {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue