-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Lowercase email #17775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lowercase email #17775
Changes from 19 commits
b5fc31e
e7b4496
56fda44
7c38dee
33331b2
7a2383a
66b6b73
04bc29c
92eff2d
ec516b8
89e0717
ab0cd23
1730f75
29dced8
fd6238b
ec90f2e
77c9101
b1d53ff
3c37bbf
35be69a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import { inspect } from 'util'; | ||
|
|
||
| import { msg } from '@lingui/core/macro'; | ||
| import { isNull } from '@sniptt/guards'; | ||
|
|
||
| import { validateEmailsPrimaryEmailSubfieldOrThrow } from 'src/engine/api/common/common-args-processors/data-arg-processor/validator-utils/validate-emails-primary-email-subfield-or-throw.util'; | ||
| import { | ||
| CommonQueryRunnerException, | ||
| CommonQueryRunnerExceptionCode, | ||
| } from 'src/engine/api/common/common-query-runners/errors/common-query-runner.exception'; | ||
|
|
||
| export const validateEmailsAdditionalEmailsSubfieldOrThrow = ( | ||
| value: unknown, | ||
| fieldName: string, | ||
| ): string | string[] | null => { | ||
| if (isNull(value)) return null; | ||
|
|
||
| if (typeof value === 'string') { | ||
| return validateEmailsPrimaryEmailSubfieldOrThrow(value, fieldName); | ||
| } | ||
|
|
||
| if ( | ||
| !Array.isArray(value) || | ||
| value.some((item) => | ||
| isNull(validateEmailsPrimaryEmailSubfieldOrThrow(item, fieldName)), | ||
| ) | ||
| ) { | ||
| const inspectedValue = inspect(value); | ||
|
|
||
| throw new CommonQueryRunnerException( | ||
| `Invalid value ${inspectedValue} for field "${fieldName} - Array values need to be string"`, | ||
| CommonQueryRunnerExceptionCode.INVALID_ARGS_DATA, | ||
| { userFriendlyMessage: msg`Invalid value: "${inspectedValue}"` }, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: userFriendlyMessage repeats inspected technical details; per guidance it should stay generic and avoid duplicating the internal error. Prompt for AI agents |
||
| ); | ||
| } | ||
|
|
||
| return value; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { inspect } from 'util'; | ||
|
|
||
| import { msg } from '@lingui/core/macro'; | ||
| import { isNonEmptyString, isNull } from '@sniptt/guards'; | ||
| import { z } from 'zod'; | ||
|
|
||
| import { | ||
| CommonQueryRunnerException, | ||
| CommonQueryRunnerExceptionCode, | ||
| } from 'src/engine/api/common/common-query-runners/errors/common-query-runner.exception'; | ||
|
|
||
| export const validateEmailsPrimaryEmailSubfieldOrThrow = ( | ||
| value: unknown, | ||
| fieldName: string, | ||
| ): string | null => { | ||
| if (isNull(value) || !isNonEmptyString(value)) return null; | ||
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if (typeof value !== 'string') { | ||
| const inspectedValue = inspect(value); | ||
|
|
||
| throw new CommonQueryRunnerException( | ||
| `Invalid string value ${inspectedValue} for email field "${fieldName}"`, | ||
| CommonQueryRunnerExceptionCode.INVALID_ARGS_DATA, | ||
| { userFriendlyMessage: msg`Invalid value: "${inspectedValue}"` }, | ||
| ); | ||
| } | ||
|
|
||
| if (!z.email({ pattern: z.regexes.unicodeEmail }).safeParse(value).success) { | ||
| const inspectedValue = inspect(value); | ||
|
|
||
| throw new CommonQueryRunnerException( | ||
| `Invalid string value ${inspectedValue} for email field "${fieldName}"`, | ||
| CommonQueryRunnerExceptionCode.INVALID_ARGS_DATA, | ||
| { userFriendlyMessage: msg`Invalid value: "${inspectedValue}"` }, | ||
| ); | ||
| } | ||
|
|
||
| return value; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| import { transformEmailsValue } from 'src/engine/core-modules/record-transformer/utils/transform-emails-value.util'; | ||
|
|
||
| describe('transformEmailsValue', () => { | ||
| it('should return undefined when value is undefined', () => { | ||
| const result = transformEmailsValue(undefined); | ||
|
|
||
| expect(result).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('should return null when value is null', () => { | ||
| const result = transformEmailsValue(null); | ||
|
|
||
| expect(result).toBeNull(); | ||
| }); | ||
|
|
||
| it('should convert primaryEmail to lowercase', () => { | ||
| const value = { | ||
| primaryEmail: 'TEST@EXAMPLE.COM', | ||
| additionalEmails: null, | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.primaryEmail).toBe('test@example.com'); | ||
| }); | ||
|
|
||
| it('should return null for primaryEmail when it is empty string', () => { | ||
| const value = { | ||
| primaryEmail: '', | ||
| additionalEmails: null, | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.primaryEmail).toBeNull(); | ||
| }); | ||
|
|
||
| it('should return null for primaryEmail when it is null', () => { | ||
| const value = { | ||
| primaryEmail: null, | ||
| additionalEmails: null, | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.primaryEmail).toBeNull(); | ||
| }); | ||
|
|
||
| it('should return null for primaryEmail when it is undefined', () => { | ||
| const value = { | ||
| additionalEmails: null, | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.primaryEmail).toBeNull(); | ||
| }); | ||
|
|
||
| it('should convert additionalEmails array to lowercase JSON string', () => { | ||
| const value = { | ||
| primaryEmail: 'test@example.com', | ||
| additionalEmails: ['USER1@EXAMPLE.COM', 'USER2@EXAMPLE.COM'], | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.additionalEmails).toBe( | ||
| '["user1@example.com","user2@example.com"]', | ||
| ); | ||
| }); | ||
|
|
||
| it('should parse and convert additionalEmails JSON string to lowercase', () => { | ||
| const value = { | ||
| primaryEmail: 'test@example.com', | ||
| additionalEmails: '["USER1@EXAMPLE.COM","USER2@EXAMPLE.COM"]', | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.additionalEmails).toBe( | ||
| '["user1@example.com","user2@example.com"]', | ||
| ); | ||
| }); | ||
|
|
||
| it('should return null for additionalEmails when it is an empty array', () => { | ||
| const value = { | ||
| primaryEmail: 'test@example.com', | ||
| additionalEmails: [], | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.additionalEmails).toBeNull(); | ||
| }); | ||
|
|
||
| it('should return null for additionalEmails when it is null', () => { | ||
| const value = { | ||
| primaryEmail: 'test@example.com', | ||
| additionalEmails: null, | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.additionalEmails).toBeNull(); | ||
| }); | ||
|
|
||
| it('should handle mixed case emails in additionalEmails array', () => { | ||
| const value = { | ||
| primaryEmail: 'test@example.com', | ||
| additionalEmails: ['Test1@Example.COM', 'TEST2@example.com'], | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result.additionalEmails).toBe( | ||
| '["test1@example.com","test2@example.com"]', | ||
| ); | ||
| }); | ||
|
|
||
| it('should transform both primaryEmail and additionalEmails correctly', () => { | ||
| const value = { | ||
| primaryEmail: 'PRIMARY@EXAMPLE.COM', | ||
| additionalEmails: ['ADDITIONAL1@EXAMPLE.COM', 'ADDITIONAL2@EXAMPLE.COM'], | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result).toEqual({ | ||
| primaryEmail: 'primary@example.com', | ||
| additionalEmails: '["additional1@example.com","additional2@example.com"]', | ||
| }); | ||
| }); | ||
|
|
||
| it('should handle case where primaryEmail is null and additionalEmails exist', () => { | ||
| const value = { | ||
| primaryEmail: null, | ||
| additionalEmails: ['USER@EXAMPLE.COM'], | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result).toEqual({ | ||
| primaryEmail: null, | ||
| additionalEmails: '["user@example.com"]', | ||
| }); | ||
| }); | ||
|
|
||
| it('should handle case where primaryEmail exists and additionalEmails is null', () => { | ||
| const value = { | ||
| primaryEmail: 'USER@EXAMPLE.COM', | ||
| additionalEmails: null, | ||
| }; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result).toEqual({ | ||
| primaryEmail: 'user@example.com', | ||
| additionalEmails: null, | ||
| }); | ||
| }); | ||
|
|
||
| it('should handle empty value object', () => { | ||
| const value = {}; | ||
|
|
||
| const result = transformEmailsValue(value); | ||
|
|
||
| expect(result).toEqual({ | ||
| primaryEmail: null, | ||
| additionalEmails: undefined, | ||
| }); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,4 +2,28 @@ | |
|
|
||
| exports[`Create input validation - EMAILS Gql create input - failure EMAILS - should fail with : {"emailsField":"not-an-email"} 1`] = `"Expected type "EmailsCreateInput" to be an object."`; | ||
|
|
||
| exports[`Create input validation - EMAILS Gql create input - failure EMAILS - should fail with : {"emailsField":{"additionalEmails":"not-an-email"}} 1`] = `"Invalid string value 'not-an-email' for email field "emailsField.additionalEmails""`; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please write down a command I can run to check if test is OK? I don't have such dropdown in my IDE
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! |
||
|
|
||
| exports[`Create input validation - EMAILS Gql create input - failure EMAILS - should fail with : {"emailsField":{"additionalEmails":["not-an-email","additional@email.com"]}} 1`] = `"Invalid string value 'not-an-email' for email field "emailsField.additionalEmails""`; | ||
|
|
||
| exports[`Create input validation - EMAILS Gql create input - failure EMAILS - should fail with : {"emailsField":{"additionalEmails":["not-an-email"]}} 1`] = `"Invalid string value 'not-an-email' for email field "emailsField.additionalEmails""`; | ||
|
|
||
| exports[`Create input validation - EMAILS Gql create input - failure EMAILS - should fail with : {"emailsField":{"primaryEmail":"email@email.com","additionalEmails":["not-an-email"]}} 1`] = `"Invalid string value 'not-an-email' for email field "emailsField.additionalEmails""`; | ||
|
|
||
| exports[`Create input validation - EMAILS Gql create input - failure EMAILS - should fail with : {"emailsField":{"primaryEmail":"not-an-email","additionalEmails":["additional@email.com"]}} 1`] = `"Invalid string value 'not-an-email' for email field "emailsField.primaryEmail""`; | ||
|
|
||
| exports[`Create input validation - EMAILS Gql create input - failure EMAILS - should fail with : {"emailsField":{"primaryEmail":"not-an-email"}} 1`] = `"Invalid string value 'not-an-email' for email field "emailsField.primaryEmail""`; | ||
|
|
||
| exports[`Create input validation - EMAILS Rest create input - failure EMAILS - should fail with : {"emailsField":"not-an-email"} 1`] = `"["Invalid object value 'not-an-email' for field \\"emailsField\\""]"`; | ||
|
|
||
| exports[`Create input validation - EMAILS Rest create input - failure EMAILS - should fail with : {"emailsField":{"additionalEmails":"not-an-email"}} 1`] = `"["Invalid string value 'not-an-email' for email field \\"emailsField.additionalEmails\\""]"`; | ||
|
|
||
| exports[`Create input validation - EMAILS Rest create input - failure EMAILS - should fail with : {"emailsField":{"additionalEmails":["not-an-email","additional@email.com"]}} 1`] = `"["Invalid string value 'not-an-email' for email field \\"emailsField.additionalEmails\\""]"`; | ||
|
|
||
| exports[`Create input validation - EMAILS Rest create input - failure EMAILS - should fail with : {"emailsField":{"additionalEmails":["not-an-email"]}} 1`] = `"["Invalid string value 'not-an-email' for email field \\"emailsField.additionalEmails\\""]"`; | ||
|
|
||
| exports[`Create input validation - EMAILS Rest create input - failure EMAILS - should fail with : {"emailsField":{"primaryEmail":"email@email.com","additionalEmails":["not-an-email"]}} 1`] = `"["Invalid string value 'not-an-email' for email field \\"emailsField.additionalEmails\\""]"`; | ||
|
|
||
| exports[`Create input validation - EMAILS Rest create input - failure EMAILS - should fail with : {"emailsField":{"primaryEmail":"not-an-email","additionalEmails":["additional@email.com"]}} 1`] = `"["Invalid string value 'not-an-email' for email field \\"emailsField.primaryEmail\\""]"`; | ||
|
|
||
| exports[`Create input validation - EMAILS Rest create input - failure EMAILS - should fail with : {"emailsField":{"primaryEmail":"not-an-email"}} 1`] = `"["Invalid string value 'not-an-email' for email field \\"emailsField.primaryEmail\\""]"`; | ||

Uh oh!
There was an error while loading. Please reload this page.