diff --git a/src/BirdsiteLive.Common/Regexes/UserRegexes.cs b/src/BirdsiteLive.Common/Regexes/UserRegexes.cs index ab48a1f..fc4783c 100644 --- a/src/BirdsiteLive.Common/Regexes/UserRegexes.cs +++ b/src/BirdsiteLive.Common/Regexes/UserRegexes.cs @@ -5,6 +5,6 @@ namespace BirdsiteLive.Common.Regexes public class UserRegexes { public static readonly Regex TwitterAccount = new Regex(@"^[a-zA-Z0-9_]+$"); - public static readonly Regex Mention = new Regex(@"(.?)@([a-zA-Z0-9_]+)(\s|$|[\[\]<>,;:'!?/|-]|(. ))"); + public static readonly Regex Mention = new Regex(@"(.?)@([a-zA-Z0-9_]+)(\s|$|[\[\]<>,;:'\.’!?/|-]|(. ))"); } } \ No newline at end of file diff --git a/src/BirdsiteLive.Domain/Tools/StatusExtractor.cs b/src/BirdsiteLive.Domain/Tools/StatusExtractor.cs index 3fcb2e0..9d618d6 100644 --- a/src/BirdsiteLive.Domain/Tools/StatusExtractor.cs +++ b/src/BirdsiteLive.Domain/Tools/StatusExtractor.cs @@ -6,6 +6,7 @@ using BirdsiteLive.Common.Regexes; using BirdsiteLive.Common.Settings; using BirdsiteLive.Twitter; using Microsoft.Extensions.Logging; +using System; namespace BirdsiteLive.Domain.Tools { @@ -35,10 +36,6 @@ namespace BirdsiteLive.Domain.Tools messageContent = Regex.Replace(messageContent, @"\r\n\r\n?|\n\n", "

"); messageContent = Regex.Replace(messageContent, @"\r\n?|\n", "
"); - //// Secure emojis - //var emojiMatch = EmojiRegexes.Emoji.Matches(messageContent); - //foreach (Match m in emojiMatch) - // messageContent = Regex.Replace(messageContent, m.ToString(), $" {m} "); // Extract Urls var urlMatch = UrlRegexes.Url.Matches(messageContent); @@ -110,7 +107,7 @@ namespace BirdsiteLive.Domain.Tools continue; } - var url = $"https://{_instanceSettings.Domain}/users/{mention}"; + var url = $"https://{_instanceSettings.Domain}/users/{mention.ToLower()}"; var name = $"@{mention}"; if (tags.All(x => x.href != url)) @@ -124,7 +121,7 @@ namespace BirdsiteLive.Domain.Tools } messageContent = Regex.Replace(messageContent, Regex.Escape(m.Groups[0].ToString()), - $@"{m.Groups[1]}@{mention}{m.Groups[3]}"); + $@"{m.Groups[1]}@{mention}{m.Groups[3]}"); } } diff --git a/src/Tests/BirdsiteLive.Domain.Tests/Tools/StatusExtractorTests.cs b/src/Tests/BirdsiteLive.Domain.Tests/Tools/StatusExtractorTests.cs index 9717aab..b820e25 100644 --- a/src/Tests/BirdsiteLive.Domain.Tests/Tools/StatusExtractorTests.cs +++ b/src/Tests/BirdsiteLive.Domain.Tests/Tools/StatusExtractorTests.cs @@ -111,6 +111,27 @@ namespace BirdsiteLive.Domain.Tests.Tools Assert.IsTrue(result.content.Contains(@"https://www.eff.org/deeplinks/2020/07/pact-act-not-solution-problem-harmful-online-content")); #endregion } + [TestMethod] + public void Extract_FormatUrl_Long2_Test() + { + #region Stubs + var message = $"https://twitterisgoinggreat.com/#twitters-first-dollar15bn-interest-payment-could-be-due-in-two-weeks"; + #endregion + + #region Mocks + var logger = new Mock>(); + #endregion + + var service = new StatusExtractor(_settings, logger.Object); + var result = service.Extract(message); + + #region Validations + logger.VerifyAll(); + Assert.AreEqual(result.content, @"https://www.eff.org/deeplinks/2020/07/pact-act-not-solution-problem-harmful-online-content"); + Assert.AreEqual(0, result.tags.Length); + + #endregion + } [TestMethod] public void Extract_FormatUrl_Exact_Test() @@ -361,7 +382,37 @@ namespace BirdsiteLive.Domain.Tests.Tools Assert.AreEqual("https://domain.name/users/mynickname", result.tags.First().href); Assert.IsTrue(result.content.Contains("Bla!")); - Assert.IsTrue(result.content.Contains(@"@mynickname")); + Assert.IsTrue(result.content.Contains(@"@mynickname")); + #endregion + } + [TestMethod] + public void Extract_TagsWithPunctuations_Test() + { + #region Stubs + var message = $"this: @amberfloio. @StellantisNA’s"; + #endregion + + #region Mocks + var logger = new Mock>(); + #endregion + + var service = new StatusExtractor(_settings, logger.Object); + var result = service.Extract(message); + + #region Validations + logger.VerifyAll(); + Assert.AreEqual(2, result.tags.Length); + + Assert.AreEqual("@amberfloio", result.tags.First().name); + Assert.AreEqual("Mention", result.tags.First().type); + Assert.AreEqual("https://domain.name/users/amberfloio", result.tags.First().href); + + Assert.AreEqual("@StellantisNA", result.tags.Last().name); + Assert.AreEqual("Mention", result.tags.Last().type); + Assert.AreEqual("https://domain.name/users/stellantisna", result.tags.Last().href); + + Assert.IsTrue(result.content.Contains("this:")); + Assert.IsTrue(result.content.Contains(@"@amberfloio")); #endregion } @@ -384,9 +435,9 @@ namespace BirdsiteLive.Domain.Tests.Tools Assert.AreEqual(4, result.tags.Length); Assert.AreEqual("Mention", result.tags.First().type); - Assert.IsTrue(result.content.Contains(@"@photos_floues")); - Assert.IsTrue(result.content.Contains(@"@KiwixOffline @photos_floues")); - Assert.IsTrue(result.content.Contains(@"Cc @Pyb75 @photos_floues @KiwixOffline")); + Assert.IsTrue(result.content.Contains(@"@photos_floues")); + Assert.IsTrue(result.content.Contains(@"@KiwixOffline @photos_floues")); + Assert.IsTrue(result.content.Contains(@"Cc @Pyb75 @photos_floues @KiwixOffline")); #endregion } @@ -412,7 +463,7 @@ namespace BirdsiteLive.Domain.Tests.Tools Assert.AreEqual("https://domain.name/users/mynickname", result.tags.First().href); Assert.IsTrue(result.content.Contains("Bla!")); - Assert.IsTrue(result.content.Contains(@"@mynickname")); + Assert.IsTrue(result.content.Contains(@"@mynickname")); #endregion } @@ -439,7 +490,7 @@ namespace BirdsiteLive.Domain.Tests.Tools Assert.IsTrue(result.content.Contains("Bla!")); Assert.IsTrue(result.content.Contains("Blo")); - Assert.IsTrue(result.content.Contains(@"@mynickname")); + Assert.IsTrue(result.content.Contains(@"@mynickname")); #endregion } @@ -465,7 +516,7 @@ namespace BirdsiteLive.Domain.Tests.Tools Assert.AreEqual("https://domain.name/users/my___nickname", result.tags.First().href); Assert.IsTrue(result.content.Contains("Bla!")); - Assert.IsTrue(result.content.Contains(@"@my___nickname")); + Assert.IsTrue(result.content.Contains(@"@my___nickname")); #endregion } @@ -491,7 +542,7 @@ namespace BirdsiteLive.Domain.Tests.Tools Assert.AreEqual("https://domain.name/users/my___nickname", result.tags.First().href); Assert.IsTrue(result.content.Contains("Bla!")); - Assert.IsTrue(result.content.Contains(@"@my___nickname")); + Assert.IsTrue(result.content.Contains(@"@my___nickname")); #endregion } @@ -499,7 +550,7 @@ namespace BirdsiteLive.Domain.Tests.Tools public void Extract_SingleMentionTag_AtStart_Test() { #region Stubs - var message = $"@mynickname Bla!"; + var message = $"@myNickName Bla!"; #endregion #region Mocks @@ -512,12 +563,12 @@ namespace BirdsiteLive.Domain.Tests.Tools #region Validations logger.VerifyAll(); Assert.AreEqual(1, result.tags.Length); - Assert.AreEqual("@mynickname", result.tags.First().name); + Assert.AreEqual("@myNickName", result.tags.First().name); Assert.AreEqual("Mention", result.tags.First().type); Assert.AreEqual("https://domain.name/users/mynickname", result.tags.First().href); Assert.IsTrue(result.content.Contains("Bla!")); - Assert.IsTrue(result.content.Contains(@"@mynickname")); + Assert.IsTrue(result.content.Contains(@"@myNickName")); #endregion } @@ -539,10 +590,10 @@ namespace BirdsiteLive.Domain.Tests.Tools logger.VerifyAll(); Assert.AreEqual(4, result.tags.Length); Assert.IsTrue(result.content.Contains("Bla!")); - Assert.IsTrue(result.content.Contains(@"@mynickname")); - Assert.IsTrue(result.content.Contains(@"@mynickname2")); - Assert.IsTrue(result.content.Contains(@"@mynickname3")); - Assert.IsTrue(result.content.Contains(@"@dada")); + Assert.IsTrue(result.content.Contains(@"@mynickname")); + Assert.IsTrue(result.content.Contains(@"@mynickname2")); + Assert.IsTrue(result.content.Contains(@"@mynickname3")); + Assert.IsTrue(result.content.Contains(@"@dada")); #endregion } @@ -564,10 +615,10 @@ namespace BirdsiteLive.Domain.Tests.Tools logger.VerifyAll(); Assert.AreEqual(5, result.tags.Length); Assert.IsTrue(result.content.Contains("Bla!")); - Assert.IsTrue(result.content.Contains(@"@mynickname")); + Assert.IsTrue(result.content.Contains(@"@mynickname")); Assert.IsTrue(result.content.Contains(@"#mytag2")); - Assert.IsTrue(result.content.Contains(@"@mynickname3")); - Assert.IsTrue(result.content.Contains(@"@dada")); + Assert.IsTrue(result.content.Contains(@"@mynickname3")); + Assert.IsTrue(result.content.Contains(@"@dada")); Assert.IsTrue(result.content.Contains(@"#dada")); #endregion } @@ -591,7 +642,7 @@ namespace BirdsiteLive.Domain.Tests.Tools logger.VerifyAll(); Assert.AreEqual(1, result.tags.Length); Assert.IsTrue(result.content.Contains( - @"😤@mynickname")); + @"😤@mynickname")); Assert.IsTrue(result.content.Contains(@"😎😍🤗🤩😘")); #endregion @@ -615,7 +666,7 @@ namespace BirdsiteLive.Domain.Tests.Tools #region Validations logger.VerifyAll(); Assert.AreEqual(1, result.tags.Length); - Assert.IsTrue(result.content.Equals(@"bla (@mynickname test)")); + Assert.IsTrue(result.content.Equals(@"bla (@mynickname test)")); #endregion } }