Deduplicate-emails (#10355)

Following User request to remove duplicate emails

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Guillim
2025-02-20 15:40:49 +01:00
committed by GitHub
parent d4aba8d1ff
commit 04a62e9749
5 changed files with 75 additions and 2 deletions

View File

@ -21,6 +21,7 @@ import {
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { lowercaseDomain } from 'src/engine/api/graphql/workspace-query-runner/utils/query-runner-links.util';
import {
RichTextV2Metadata,
richTextV2ValueSchema,
@ -230,6 +231,37 @@ export class QueryRunnerArgsFactory {
return [key, valueInBothFormats];
}
case FieldMetadataType.LINKS: {
const newPrimaryLinkUrl = lowercaseDomain(value?.primaryLinkUrl);
return [key, { ...value, primaryLinkUrl: newPrimaryLinkUrl }];
}
case FieldMetadataType.EMAILS: {
let additionalEmails = value?.additionalEmails;
const primaryEmail = value?.primaryEmail
? value.primaryEmail.toLowerCase()
: '';
if (additionalEmails) {
try {
const emailArray = JSON.parse(additionalEmails) as string[];
additionalEmails = JSON.stringify(
emailArray.map((email) => email.toLowerCase()),
);
} catch {
/* empty */
}
}
return [
key,
{
primaryEmail,
additionalEmails,
},
];
}
default:
return [key, value];
}

View File

@ -0,0 +1,17 @@
import { lowercaseDomain } from 'src/engine/api/graphql/workspace-query-runner/utils/query-runner-links.util';
describe('queryRunner LINKS util', () => {
it('should leave lowcased domain unchanged', () => {
const primaryLinkUrl = 'https://www.example.com/test';
const result = lowercaseDomain(primaryLinkUrl);
expect(result).toBe('https://www.example.com/test');
});
it('should lowercase the domain of the primary link url', () => {
const primaryLinkUrl = 'htTps://wwW.exAmple.coM/TEST';
const result = lowercaseDomain(primaryLinkUrl);
expect(result).toBe('https://www.example.com/TEST');
});
});

View File

@ -0,0 +1,7 @@
export const lowercaseDomain = (url: string) => {
try {
return new URL(url).toString();
} catch {
return url;
}
};

View File

@ -29,4 +29,17 @@ describe('getUniqueContactsAndHandles', () => {
'jane@twenty.com',
]);
});
it('should deduplicate handles when they are in different cases', () => {
const contacts: Contact[] = [
{ handle: 'john@twenty.com', displayName: 'John Doe' },
{ handle: 'John@twenty.com', displayName: 'John Doe' },
];
const result = getUniqueContactsAndHandles(contacts);
expect(result.uniqueContacts).toEqual([
{ handle: 'john@twenty.com', displayName: 'John Doe' },
]);
expect(result.uniqueHandles).toEqual(['john@twenty.com']);
});
});

View File

@ -11,9 +11,13 @@ export function getUniqueContactsAndHandles(contacts: Contact[]): {
return { uniqueContacts: [], uniqueHandles: [] };
}
const uniqueHandles = uniq(contacts.map((participant) => participant.handle));
const uniqueHandles = uniq(
contacts.map((participant) => participant.handle.toLocaleLowerCase()),
);
const uniqueContacts = uniqBy(contacts, 'handle');
const uniqueContacts = uniqBy(contacts, (contact) =>
contact.handle.toLocaleLowerCase(),
);
return { uniqueContacts, uniqueHandles };
}