diff --git a/src/models/contact.js b/src/models/contact.js index 9a41bbff0..5a97cded1 100644 --- a/src/models/contact.js +++ b/src/models/contact.js @@ -26,7 +26,7 @@ function isEmpty(value) { export const ContactKindProperties = ['KIND', 'X-ADDRESSBOOKSERVER-KIND'] export const MinimalContactProperties = [ - 'EMAIL', 'UID', 'TEL', 'CATEGORIES', 'FN', 'ORG', 'N', 'X-PHONETIC-FIRST-NAME', 'X-PHONETIC-LAST-NAME', 'X-MANAGERSNAME', 'TITLE', 'NOTE', 'RELATED', + 'EMAIL', 'UID', 'TEL', 'CATEGORIES', 'FN', 'ORG', 'N', 'X-PHONETIC-FIRST-NAME', 'X-PHONETIC-LAST-NAME', 'X-MANAGERSNAME', 'TITLE', 'NOTE', 'RELATED', 'PRONOUNS', ].concat(ContactKindProperties) export function generateContactKey(uid, addressbookId) { diff --git a/src/models/rfcProps.js b/src/models/rfcProps.js index 5acf08905..0c7e1630a 100644 --- a/src/models/rfcProps.js +++ b/src/models/rfcProps.js @@ -362,6 +362,16 @@ const properties = { ], primary: false, }, + pronouns: { + multiple: true, + readableName: t('contacts', 'Pronouns'), + icon: 'icon-gender', + force: 'text', + defaultValue: { + value: '', + }, + primary: false, + }, tz: { readableName: t('contacts', 'Time zone'), force: 'select', @@ -420,6 +430,7 @@ const fieldOrder = [ 'x-phonetic-first-name', 'x-phonetic-last-name', 'gender', + 'pronouns', 'cloud', 'impp', 'geo', diff --git a/tests/javascript/models/contact.test.js b/tests/javascript/models/contact.test.js index 439b0ad5d..9ecf9192d 100644 --- a/tests/javascript/models/contact.test.js +++ b/tests/javascript/models/contact.test.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import Contact from '../../../src/models/contact' +import Contact, { MinimalContactProperties } from '../../../src/models/contact' const getPropertyLines = (property, vcard) => { return vcard.match(new RegExp(`^${property}[;:].*`, 'gmi')) @@ -62,6 +62,10 @@ describe('Test stripping quotes from TYPE', () => { expect(contactWithEmails.hasEmail('third@example.com')).toBe(false) }) + test('Test pronouns are included in the lightweight property list', () => { + expect(MinimalContactProperties).toContain('PRONOUNS') + }) + test('Test stripping quotes from MULTIPLE SPLIT TYPES and MULTIPLE PROPERTIES', () => { const property2 = contact.vCard.addPropertyWithValue('TEl', '+99 876 543 210') property.setParameter('type', ['WORK,VOICE']) diff --git a/tests/javascript/models/rfcProps.test.js b/tests/javascript/models/rfcProps.test.js index 823637c9c..ff56ce517 100644 --- a/tests/javascript/models/rfcProps.test.js +++ b/tests/javascript/models/rfcProps.test.js @@ -29,4 +29,14 @@ describe('RFC props', () => { expect(property.getParameter('type')).toEqual(defaultData.type) expect(contact.vCard.toString()).toMatch(/^IMPP;TYPE=.+:$/m) }) + + test('pronouns is a serializable RFC 9554 text property', () => { + const property = contact.vCard.addPropertyWithValue('pronouns', 'they/them') + + expect(rfcProps.properties.pronouns.readableName).toBe(t('contacts', 'Pronouns')) + expect(rfcProps.properties.pronouns.multiple).toBe(true) + expect(rfcProps.fieldOrder.indexOf('pronouns')).toBeGreaterThan(rfcProps.fieldOrder.indexOf('gender')) + expect(rfcProps.properties.pronouns.force).toBe('text') + expect(contact.vCard.toString()).toMatch(/^PRONOUNS:they\/them$/m) + }) })