diff --git a/__tests__/ExpensiMark-HTML-test.js b/__tests__/ExpensiMark-HTML-test.js index 84036cb7..49280829 100644 --- a/__tests__/ExpensiMark-HTML-test.js +++ b/__tests__/ExpensiMark-HTML-test.js @@ -1063,3 +1063,63 @@ test('Skip rendering invalid markdown',() => { testString = '> *This is multiline\nbold text*'; expect(parser.replace(testString)).toBe('
*This is multiline
bold text*'); }); + +test('Test for email with test+1@gmail.com@gmail.com', () => { + const testString = 'test+1@gmail.com@gmail.com'; + const resultString = 'test+1@gmail.com@gmail.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test for email with test@gmail.com@gmail.com', () => { + const testString = 'test@gmail.com@gmail.com'; + const resultString = 'test@gmail.com@gmail.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test for email with test@here@gmail.com', () => { + const testString = 'test@here@gmail.com'; + const resultString = 'test@here@gmail.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test for email with test+1@here@gmail.com', () => { + const testString = 'test+1@here@gmail.com'; + const resultString = 'test+1@here@gmail.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test user mention with @here@here.com', () => { + const testString = '@here@here.com'; + const resultString = '@here@here.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test user mention with @abc_@here.com', () => { + const testString = '@abc_@here.com'; + const resultString = '@abc_@here.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test user mention with @here_@here.com', () => { + const testString = '@here_@here.com'; + const resultString = '@here_@here.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test here mention with @here_@here_.com', () => { + const testString = '@here_@here_.com'; + const resultString = '@here@here.com'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test here mention with @here@', () => { + const testString = '@here@'; + const resultString = '@here@'; + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test here mention with @here@here', () => { + const testString = '@here@here'; + const resultString = '@here@here'; + expect(parser.replace(testString)).toBe(resultString); +}); \ No newline at end of file diff --git a/__tests__/Str-test.js b/__tests__/Str-test.js index a8d92a2a..c8d1a386 100644 --- a/__tests__/Str-test.js +++ b/__tests__/Str-test.js @@ -77,7 +77,6 @@ describe('Str.isValidMention', () => { expect(Str.isValidMention('*@username@expensify.com*')).toBeTruthy(); expect(Str.isValidMention(' @username@expensify.com')).toBeTruthy(); expect(Str.isValidMention('~@username@expensify.com~')).toBeTruthy(); - expect(Str.isValidMention('#@username@expensify.com')).toBeTruthy(); expect(Str.isValidMention('_@username@expensify.com_')).toBeTruthy(); expect(Str.isValidMention('`@username@expensify.com`')).toBeFalsy(); expect(Str.isValidMention('\'@username@expensify.com\'')).toBeTruthy(); diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 418cc6d3..8d2186f7 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -92,12 +92,12 @@ export default class ExpensiMark { */ { name: 'hereMentions', - regex: /[`.a-zA-Z]?@here(?=_\b|\b)(?!((?:(?!|[^<]*(<\/pre>|<\/code>))/gm, - replacement: (match) => { + regex: /([a-zA-Z0-9.!$%&+/=?^`{|}_-]?)(@here)([a-zA-Z0-9.!$%&+/=?^`{|}_-]?)(?=\b)(?!(@[a-zA-Z0-9-]+?(\.[a-zA-Z]+)+)|((?:(?!|[^<]*(<\/pre>|<\/code>))/gm, + replacement: (match, g1, g2, g3) => { if (!Str.isValidMention(match)) { return match; } - return `${match}`; + return `${g1}${g2}${g3}`; }, }, @@ -110,7 +110,7 @@ export default class ExpensiMark { */ { name: 'userMentions', - regex: new RegExp(`[\`.a-zA-Z]?@+${CONST.REG_EXP.EMAIL_PART}(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gm'), + regex: new RegExp(`[a-zA-Z0-9.!$%&+/=?^\`{|}-]?@+${CONST.REG_EXP.EMAIL_PART}(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gm'), replacement: (match) => { if (!Str.isValidMention(match)) { return match; diff --git a/lib/str.js b/lib/str.js index 14a582f0..ad48560e 100644 --- a/lib/str.js +++ b/lib/str.js @@ -943,8 +943,16 @@ const Str = { * @returns {bool} */ isValidMention(mention) { - // A valid mention starts with a space, *, _, #, ', ", or @ (with no preceding characters). - return /[\s*~_#'"@]/g.test(mention.charAt(0)); + // Mentions can start @ proceeded by a space, eg "ping @user@domain.tld" + if (/[\s@]/g.test(mention.charAt(0))) { + return true; + } + + // Mentions can also start and end with a *, _, ~, ', or " (with no other preceding characters) + // eg "ping *@user@domain.tld*" + const firstChar = mention.charAt(0); + const lastChar = mention.charAt(mention.length - 1); + return /[*~_'"]/g.test(firstChar) && /[*~_'"]/g.test(lastChar) && firstChar === lastChar; }, /**