2021-06-01 23:30:25 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
import { assert } from 'chai';
|
|
|
|
import { getDefaultConversation } from '../helpers/getDefaultConversation';
|
|
|
|
|
|
|
|
import {
|
|
|
|
dehydrateCollisionsWithConversations,
|
|
|
|
getCollisionsFromMemberships,
|
|
|
|
hasUnacknowledgedCollisions,
|
|
|
|
invertIdsByTitle,
|
|
|
|
} from '../../util/groupMemberNameCollisions';
|
|
|
|
|
|
|
|
describe('group member name collision utilities', () => {
|
|
|
|
describe('dehydrateCollisionsWithConversations', () => {
|
|
|
|
it('turns conversations into "plain" IDs', () => {
|
|
|
|
const conversation1 = getDefaultConversation();
|
|
|
|
const conversation2 = getDefaultConversation();
|
|
|
|
const conversation3 = getDefaultConversation();
|
|
|
|
const conversation4 = getDefaultConversation();
|
|
|
|
|
|
|
|
const result = dehydrateCollisionsWithConversations({
|
|
|
|
Alice: [conversation1, conversation2],
|
|
|
|
Bob: [conversation3, conversation4],
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.deepEqual(result, {
|
|
|
|
Alice: [conversation1.id, conversation2.id],
|
|
|
|
Bob: [conversation3.id, conversation4.id],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('getCollisionsFromMemberships', () => {
|
|
|
|
it('finds collisions by title, omitting some conversations', () => {
|
|
|
|
const alice1 = getDefaultConversation({
|
|
|
|
profileName: 'Alice',
|
|
|
|
title: 'Alice',
|
|
|
|
});
|
|
|
|
const alice2 = getDefaultConversation({
|
|
|
|
profileName: 'Alice',
|
|
|
|
title: 'Alice',
|
|
|
|
});
|
|
|
|
const bob1 = getDefaultConversation({
|
|
|
|
profileName: 'Bob',
|
|
|
|
title: 'Bob',
|
|
|
|
});
|
|
|
|
const bob2 = getDefaultConversation({
|
2021-06-02 17:24:22 +00:00
|
|
|
name: 'Bob In Your Contacts',
|
2021-06-01 23:30:25 +00:00
|
|
|
profileName: 'Bob',
|
|
|
|
title: 'Bob',
|
|
|
|
});
|
|
|
|
const bob3 = getDefaultConversation({
|
|
|
|
profileName: 'Bob',
|
|
|
|
title: 'Bob',
|
|
|
|
});
|
2021-06-02 17:24:22 +00:00
|
|
|
|
|
|
|
// Ignored, because Bob is not in your contacts (lacks `name`), has no profile name,
|
|
|
|
// and has no E164.
|
2021-06-01 23:30:25 +00:00
|
|
|
const ignoredBob = getDefaultConversation({
|
|
|
|
e164: undefined,
|
|
|
|
title: 'Bob',
|
|
|
|
});
|
2021-06-02 17:24:22 +00:00
|
|
|
|
|
|
|
// Ignored, because there's only one Charlie.
|
2021-06-01 23:30:25 +00:00
|
|
|
const charlie = getDefaultConversation({
|
|
|
|
profileName: 'Charlie',
|
|
|
|
title: 'Charlie',
|
|
|
|
});
|
2021-06-02 17:24:22 +00:00
|
|
|
|
|
|
|
// Ignored, because all Donnas are in your contacts (they have a `name`).
|
|
|
|
const donna1 = getDefaultConversation({
|
|
|
|
name: 'Donna One',
|
|
|
|
profileName: 'Donna',
|
|
|
|
title: 'Donna',
|
|
|
|
});
|
|
|
|
const donna2 = getDefaultConversation({
|
|
|
|
name: 'Donna Two',
|
|
|
|
profileName: 'Donna',
|
|
|
|
title: 'Donna',
|
|
|
|
});
|
|
|
|
const donna3 = getDefaultConversation({
|
|
|
|
name: 'Donna Three',
|
|
|
|
profileName: 'Donna',
|
|
|
|
title: 'Donna',
|
|
|
|
});
|
|
|
|
|
|
|
|
// Ignored, because you're not included.
|
2021-06-01 23:30:25 +00:00
|
|
|
const me = getDefaultConversation({
|
|
|
|
isMe: true,
|
|
|
|
profileName: 'Alice',
|
|
|
|
title: 'Alice',
|
|
|
|
});
|
2021-06-02 17:24:22 +00:00
|
|
|
|
2021-06-01 23:30:25 +00:00
|
|
|
const memberships = [
|
|
|
|
alice1,
|
|
|
|
alice2,
|
|
|
|
bob1,
|
|
|
|
bob2,
|
|
|
|
bob3,
|
|
|
|
ignoredBob,
|
|
|
|
charlie,
|
2021-06-02 17:24:22 +00:00
|
|
|
donna1,
|
|
|
|
donna2,
|
|
|
|
donna3,
|
2021-06-01 23:30:25 +00:00
|
|
|
me,
|
|
|
|
].map(member => ({ member }));
|
|
|
|
|
|
|
|
const result = getCollisionsFromMemberships(memberships);
|
|
|
|
|
|
|
|
assert.deepEqual(result, {
|
|
|
|
Alice: [alice1, alice2],
|
|
|
|
Bob: [bob1, bob2, bob3],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('hasUnacknowledgedCollisions', () => {
|
|
|
|
it('returns false if the collisions are identical', () => {
|
|
|
|
assert.isFalse(hasUnacknowledgedCollisions({}, {}));
|
|
|
|
assert.isFalse(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def'] },
|
|
|
|
{ Alice: ['abc', 'def'] }
|
|
|
|
)
|
|
|
|
);
|
|
|
|
assert.isFalse(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def'] },
|
|
|
|
{ Alice: ['def', 'abc'] }
|
|
|
|
)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns false if the acknowledged collisions are a superset of the current collisions', () => {
|
|
|
|
assert.isFalse(
|
|
|
|
hasUnacknowledgedCollisions({ Alice: ['abc', 'def'] }, {})
|
|
|
|
);
|
|
|
|
assert.isFalse(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def', 'geh'] },
|
|
|
|
{ Alice: ['abc', 'geh'] }
|
|
|
|
)
|
|
|
|
);
|
|
|
|
assert.isFalse(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def'], Bob: ['ghi', 'jkl'] },
|
|
|
|
{ Alice: ['abc', 'def'] }
|
|
|
|
)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns true if the current collisions has a title that was not acknowledged', () => {
|
|
|
|
assert.isTrue(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def'], Bob: ['ghi', 'jkl'] },
|
|
|
|
{
|
|
|
|
Alice: ['abc', 'def'],
|
|
|
|
Bob: ['ghi', 'jkl'],
|
|
|
|
Charlie: ['mno', 'pqr'],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
assert.isTrue(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def'], Bob: ['ghi', 'jkl'] },
|
|
|
|
{
|
|
|
|
Alice: ['abc', 'def'],
|
|
|
|
Charlie: ['mno', 'pqr'],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns true if any title has a new ID', () => {
|
|
|
|
assert.isTrue(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def'] },
|
|
|
|
{ Alice: ['abc', 'def', 'ghi'] }
|
|
|
|
)
|
|
|
|
);
|
|
|
|
assert.isTrue(
|
|
|
|
hasUnacknowledgedCollisions(
|
|
|
|
{ Alice: ['abc', 'def'] },
|
|
|
|
{ Alice: ['abc', 'ghi'] }
|
|
|
|
)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('invertIdsByTitle', () => {
|
|
|
|
it('returns an empty object if passed no IDs', () => {
|
|
|
|
assert.deepEqual(invertIdsByTitle({}), {});
|
|
|
|
assert.deepEqual(invertIdsByTitle({ Alice: [] }), {});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns an object with ID keys and title values', () => {
|
|
|
|
assert.deepEqual(
|
|
|
|
invertIdsByTitle({ Alice: ['abc', 'def'], Bob: ['ghi', 'jkl', 'mno'] }),
|
|
|
|
{
|
|
|
|
abc: 'Alice',
|
|
|
|
def: 'Alice',
|
|
|
|
ghi: 'Bob',
|
|
|
|
jkl: 'Bob',
|
|
|
|
mno: 'Bob',
|
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|