Skip to content

Commit

Permalink
Use ContactRecord.systemNickname
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny-signal committed Feb 13, 2023
1 parent 949efca commit 1f95c22
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 61 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -192,7 +192,7 @@
"@babel/preset-typescript": "7.17.12",
"@electron/fuses": "1.5.0",
"@mixer/parallel-prettier": "2.0.1",
"@signalapp/mock-server": "2.14.0",
"@signalapp/mock-server": "2.15.0",
"@storybook/addon-a11y": "6.5.6",
"@storybook/addon-actions": "6.5.6",
"@storybook/addon-controls": "6.5.6",
Expand Down
1 change: 1 addition & 0 deletions protos/SignalStorage.proto
Expand Up @@ -95,6 +95,7 @@ message ContactRecord {
optional uint64 unregisteredAtTimestamp = 16;
optional string systemGivenName = 17;
optional string systemFamilyName = 18;
optional string systemNickname = 19;
}

message GroupV1Record {
Expand Down
1 change: 1 addition & 0 deletions ts/model-types.d.ts
Expand Up @@ -327,6 +327,7 @@ export type ConversationAttributesType = {
name?: string;
systemGivenName?: string;
systemFamilyName?: string;
systemNickname?: string;
needsStorageServiceSync?: boolean;
needsVerification?: boolean;
profileSharing?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion ts/models/conversations.ts
Expand Up @@ -352,7 +352,8 @@ export class ConversationModel extends window.Backbone
this.on('newmessage', this.onNewMessage);
this.on('change:profileKey', this.onChangeProfileKey);
this.on(
'change:name change:profileName change:profileFamilyName change:e164',
'change:name change:profileName change:profileFamilyName change:e164 ' +
'change:systemGivenName change:systemFamilyName change:systemNickname',
() => this.maybeClearUsername()
);

Expand Down Expand Up @@ -1910,6 +1911,7 @@ export class ConversationModel extends window.Backbone
name: this.get('name'),
systemGivenName: this.get('systemGivenName'),
systemFamilyName: this.get('systemFamilyName'),
systemNickname: this.get('systemNickname'),
phoneNumber: this.getNumber(),
profileName: this.getProfileName(),
profileSharing: this.get('profileSharing'),
Expand Down
5 changes: 5 additions & 0 deletions ts/services/storageRecordOps.ts
Expand Up @@ -198,6 +198,10 @@ export async function toContactRecord(
if (systemFamilyName) {
contactRecord.systemFamilyName = systemFamilyName;
}
const systemNickname = conversation.get('systemNickname');
if (systemNickname) {
contactRecord.systemNickname = systemNickname;
}
contactRecord.blocked = conversation.isBlocked();
contactRecord.whitelisted = Boolean(conversation.get('profileSharing'));
contactRecord.archived = Boolean(conversation.get('isArchived'));
Expand Down Expand Up @@ -1033,6 +1037,7 @@ export async function mergeContactRecord(
conversation.set({
systemGivenName: dropNull(contactRecord.systemGivenName),
systemFamilyName: dropNull(contactRecord.systemFamilyName),
systemNickname: dropNull(contactRecord.systemNickname),
});

// https://github.com/signalapp/Signal-Android/blob/fc3db538bcaa38dc149712a483d3032c9c1f3998/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt#L921-L936
Expand Down
1 change: 1 addition & 0 deletions ts/state/ducks/conversations.ts
Expand Up @@ -193,6 +193,7 @@ export type ConversationType = ReadonlyDeep<
name?: string;
systemGivenName?: string;
systemFamilyName?: string;
systemNickname?: string;
familyName?: string;
firstName?: string;
profileName?: string;
Expand Down
115 changes: 65 additions & 50 deletions ts/test-mock/pnp/username_test.ts
Expand Up @@ -80,60 +80,75 @@ describe('pnp/username', function needsName() {
await bootstrap.teardown();
});

it('drops username when contact name becomes known', async () => {
const { phone } = bootstrap;

const window = await app.getWindow();
const leftPane = window.locator('.left-pane-wrapper');

debug('find username in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> "${USERNAME}"`
)
.waitFor();

debug('adding profile key for username contact');
let state = await phone.expectStorageState('consistency check');
state = state.updateContact(usernameContact, {
profileKey: usernameContact.profileKey.serialize(),
});
await phone.setStorageState(state);
await phone.sendFetchStorage({
timestamp: bootstrap.getTimestamp(),
});

debug('find profile name in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> ` +
`"${usernameContact.profileName}"`
)
.waitFor();
for (const type of ['profile', 'system']) {
// eslint-disable-next-line no-loop-func
it(`drops username when contact's ${type} name becomes known`, async () => {
const { phone } = bootstrap;

const window = await app.getWindow();
const leftPane = window.locator('.left-pane-wrapper');

debug('find username in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> "${USERNAME}"`
)
.waitFor();

debug('verify that storage service state is updated');
{
const newState = await phone.waitForStorageState({
after: state,
let state = await phone.expectStorageState('consistency check');

if (type === 'profile') {
debug('adding profile key for username contact');
state = state.updateContact(usernameContact, {
profileKey: usernameContact.profileKey.serialize(),
});
} else {
debug('adding nickname for username contact');
state = state.updateContact(usernameContact, {
systemNickname: usernameContact.profileName,
});
}
await phone.setStorageState(state);
await phone.sendFetchStorage({
timestamp: bootstrap.getTimestamp(),
});

const { added, removed } = newState.diff(state);
assert.strictEqual(added.length, 1, 'only one record must be added');
assert.strictEqual(removed.length, 1, 'only one record must be removed');

assert.strictEqual(
added[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(added[0].contact?.username, '');
debug('find profile name in the left pane');
await leftPane
.locator(
`[data-testid="${usernameContact.device.uuid}"] >> ` +
`"${usernameContact.profileName}"`
)
.waitFor();

assert.strictEqual(
removed[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(removed[0].contact?.username, USERNAME);
}
});
debug('verify that storage service state is updated');
{
const newState = await phone.waitForStorageState({
after: state,
});

const { added, removed } = newState.diff(state);
assert.strictEqual(added.length, 1, 'only one record must be added');
assert.strictEqual(
removed.length,
1,
'only one record must be removed'
);

assert.strictEqual(
added[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(added[0].contact?.username, '');

assert.strictEqual(
removed[0].contact?.serviceUuid,
usernameContact.device.uuid
);
assert.strictEqual(removed[0].contact?.username, USERNAME);
}
});
}

it('reserves/confirms/deletes username', async () => {
const { phone, server } = bootstrap;
Expand Down
19 changes: 14 additions & 5 deletions ts/util/getTitle.ts
Expand Up @@ -49,7 +49,16 @@ export function getTitleNoDefault(
export function canHaveUsername(
attributes: Pick<
ConversationAttributesType,
'id' | 'type' | 'name' | 'profileName' | 'profileFamilyName' | 'e164'
| 'id'
| 'type'
| 'name'
| 'profileName'
| 'profileFamilyName'
| 'e164'
| 'systemGivenName'
| 'systemFamilyName'
| 'systemNickname'
| 'type'
>,
ourConversationId: string | undefined
): boolean {
Expand Down Expand Up @@ -84,13 +93,13 @@ export function getProfileName(
export function getSystemName(
attributes: Pick<
ConversationAttributesType,
'systemGivenName' | 'systemFamilyName' | 'type'
'systemGivenName' | 'systemFamilyName' | 'systemNickname' | 'type'
>
): string | undefined {
if (isDirectConversation(attributes)) {
return combineNames(
attributes.systemGivenName,
attributes.systemFamilyName
return (
attributes.systemNickname ||
combineNames(attributes.systemGivenName, attributes.systemFamilyName)
);
}

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -2170,10 +2170,10 @@
node-gyp-build "^4.2.3"
uuid "^8.3.0"

"@signalapp/mock-server@2.14.0":
version "2.14.0"
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-2.14.0.tgz#6309d944cf46e58f6141df45075de882d964ae0a"
integrity sha512-NSLnfjho4HCyrz4Y6cyoIK0f+iuhOrxEFmaabdVUepOaSHPZi1MTyYYo0d6NzD/PGREAQFJuzqNaE+7zhSiPEQ==
"@signalapp/mock-server@2.15.0":
version "2.15.0"
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-2.15.0.tgz#de86ddc4c3f7cbe1e91941832c4b317946e90364"
integrity sha512-bxu4hpnEAAvDT7Yg2LZQNIL/9ciNrGG0hPJlj+dT2iwsHo2AAP8Ej4sLfAiy0O2kYbf2bKcvfTE9C+XwkdAW+w==
dependencies:
"@signalapp/libsignal-client" "^0.22.0"
debug "^4.3.2"
Expand Down

0 comments on commit 1f95c22

Please sign in to comment.