From 575864c917dbbe6b58d3e4534c3015327f2cb088 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Tue, 5 Sep 2017 12:39:07 -0400 Subject: PLT-7474 Stopped requiring confirmation for mentions in code blocks (#7375) * PLT-7474 Stopped requiring confirmation for mentions in code blocks * Stopped mentioning people from code blocks using ~~~ --- app/notification.go | 4 +-- app/notification_test.go | 6 ++++ webapp/tests/utils/post_utils.test.jsx | 54 ++++++++++++++++++++++++++++++++-- webapp/utils/post_utils.jsx | 12 +++++++- 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/app/notification.go b/app/notification.go index b0a5d83ad..c86e1669f 100644 --- a/app/notification.go +++ b/app/notification.go @@ -839,14 +839,14 @@ func GetExplicitMentions(message string, keywords map[string][]string) (map[stri // Matches a line containing only ``` and a potential language definition, any number of lines not containing ```, // and then either a line containing only ``` or the end of the text -var codeBlockPattern = regexp.MustCompile("(?m)^[^\\S\n]*\\`\\`\\`.*$[\\s\\S]+?(^[^\\S\n]*\\`\\`\\`$|\\z)") +var codeBlockPattern = regexp.MustCompile("(?m)^[^\\S\n]*[\\`~]{3}.*$[\\s\\S]+?(^[^\\S\n]*[`~]{3}$|\\z)") // Matches a backquote, either some text or any number of non-empty lines, and then a final backquote var inlineCodePattern = regexp.MustCompile("(?m)\\`+(?:.+?|.*?\n(.*?\\S.*?\n)*.*?)\\`+") // Strips pre-formatted text and code blocks from a Markdown string by replacing them with whitespace func removeCodeFromMessage(message string) string { - if strings.Contains(message, "```") { + if strings.Contains(message, "```") || strings.Contains(message, "~~~") { message = codeBlockPattern.ReplaceAllString(message, "") } diff --git a/app/notification_test.go b/app/notification_test.go index 02b6e1db0..e0c1a54e6 100644 --- a/app/notification_test.go +++ b/app/notification_test.go @@ -399,6 +399,12 @@ func TestRemoveCodeFromMessage(t *testing.T) { if actual := removeCodeFromMessage(input); actual != expected { t.Fatalf("received incorrect output\n\nGot:\n%v\n\nExpected:\n%v\n", actual, expected) } + + input = "this is text with\n~~~\na code block\n~~~\nin it" + expected = "this is text with\n\nin it" + if actual := removeCodeFromMessage(input); actual != expected { + t.Fatalf("received incorrect output\n\nGot:\n%v\n\nExpected:\n%v\n", actual, expected) + } } func TestGetMentionKeywords(t *testing.T) { diff --git a/webapp/tests/utils/post_utils.test.jsx b/webapp/tests/utils/post_utils.test.jsx index 0546d5bea..bcb5c039e 100644 --- a/webapp/tests/utils/post_utils.test.jsx +++ b/webapp/tests/utils/post_utils.test.jsx @@ -4,8 +4,8 @@ describe('PostUtils.containsAtMention', function() { test('should return correct @all (same for @channel)', function() { for (const data of [ { - text: undefined, //eslint-disable-line no-undefined - key: undefined, //eslint-disable-line no-undefined + text: undefined, // eslint-disable-line no-undefined + key: undefined, // eslint-disable-line no-undefined result: false }, { @@ -87,6 +87,56 @@ describe('PostUtils.containsAtMention', function() { text: 'hey @ALL:+1:', key: '@all', result: true + }, + { + text: '`@all`', + key: '@all', + result: false + }, + { + text: '@someone `@all`', + key: '@all', + result: false + }, + { + text: '@someone `@all`', + key: '@someone', + result: true + }, + { + text: '``@all``', + key: '@all', + result: false + }, + { + text: '```@all```', + key: '@all', + result: false + }, + { + text: '```\n@all\n```', + key: '@all', + result: false + }, + { + text: '```````\n@all\n```````', + key: '@all', + result: false + }, + { + text: '```code\n@all\n```', + key: '@all', + result: false + }, + { + text: '~~~@all~~~', + key: '@all', + result: true + }, + { + text: '~~~\n@all\n~~~', + key: '@all', + result: false } ]) { const containsAtMention = PostUtils.containsAtMention(data.text, data.key); diff --git a/webapp/utils/post_utils.jsx b/webapp/utils/post_utils.jsx index 1ff16a5ab..d37e6c26d 100644 --- a/webapp/utils/post_utils.jsx +++ b/webapp/utils/post_utils.jsx @@ -113,5 +113,15 @@ export function containsAtMention(text, key) { } // This doesn't work for at mentions containing periods or hyphens - return new RegExp(`\\B${key}\\b`, 'i').test(text); + return new RegExp(`\\B${key}\\b`, 'i').test(removeCode(text)); +} + +// Returns a given text string with all Markdown code replaced with whitespace. +export function removeCode(text) { + // These patterns should match the ones in app/notification.go, except JavaScript doesn't + // support \z for the end of the text in multiline mode, so we use $(?![\r\n]) + const codeBlockPattern = /^[^\S\n]*[`~]{3}.*$[\s\S]+?(^[^\S\n]*[`~]{3}$|$(?![\r\n]))/m; + const inlineCodePattern = /`+(?:.+?|.*?\n(.*?\S.*?\n)*.*?)`+/m; + + return text.replace(codeBlockPattern, '').replace(inlineCodePattern, ' '); } -- cgit v1.2.3-1-g7c22