diff --git a/src/StreamFeed.cs b/src/StreamFeed.cs index c675527..eab310a 100644 --- a/src/StreamFeed.cs +++ b/src/StreamFeed.cs @@ -131,6 +131,10 @@ public async Task UpdateActivityToTargetsAsync(ForeignI IEnumerable newTargets = null, IEnumerable removed = null) { + adds?.ForEach(FeedIdValidator.ThrowIfFeedIdIsInvalid); + newTargets?.ForEach(FeedIdValidator.ThrowIfFeedIdIsInvalid); + removed?.ForEach(FeedIdValidator.ThrowIfFeedIdIsInvalid); + var payload = new { foreign_id = foreignIdTime.ForeignId, diff --git a/src/Utils/FeedIdValidator.cs b/src/Utils/FeedIdValidator.cs new file mode 100644 index 0000000..e629e1a --- /dev/null +++ b/src/Utils/FeedIdValidator.cs @@ -0,0 +1,61 @@ +using System; + +namespace Stream.Utils +{ + public static class FeedIdValidator + { + /// + /// Validates a fully qualified feed identifier. It should look like this: flat:myfeedname + /// We could use a Regex but that has a performance impact + /// so let's just iterate through the string and check for the correct format. + /// + public static void ThrowIfFeedIdIsInvalid(string feedId) + { + if (string.IsNullOrWhiteSpace(feedId)) + { + throw new InvalidFeedIdException(feedId); + } + + var foundColon = false; + var colonIndex = 0; + var index = 0; + + foreach (var character in feedId) + { + if (character == ':') + { + if (foundColon) + { + throw new InvalidFeedIdException(feedId); + } + + if (index == 0 || index == feedId.Length - 1) + { + throw new InvalidFeedIdException(feedId); + } + + foundColon = true; + colonIndex = index; + } + + index++; + } + + if (!foundColon) + { + throw new InvalidFeedIdException(feedId); + } + } + } + + /// + /// Exception thrown when a feed identifier is invalid. + /// The feed identifier should have a single colon. Example: flat:myfeedname + /// + public class InvalidFeedIdException : Exception + { + public InvalidFeedIdException(string feedId) : base($"Invalid feed id: {feedId}. It should look like this: flat:myfeedname") + { + } + } +} \ No newline at end of file diff --git a/tests/FeedIdValidatorTests.cs b/tests/FeedIdValidatorTests.cs new file mode 100644 index 0000000..ce5bbbe --- /dev/null +++ b/tests/FeedIdValidatorTests.cs @@ -0,0 +1,22 @@ +using NUnit.Framework; +using Stream.Utils; + +public class FeedIdValidatorTests +{ + [Test] + public void TestFeedIdValidator() + { + var invalidFeedIds = new[] { "nocolon", ":beginning", "ending:", "mul:tip:le:colons" }; + var valifFeedIds = new[] { "flat:myfeedname" }; + + foreach (var feedId in invalidFeedIds) + { + Assert.Throws(() => FeedIdValidator.ThrowIfFeedIdIsInvalid(feedId)); + } + + foreach (var feedId in valifFeedIds) + { + Assert.DoesNotThrow(() => FeedIdValidator.ThrowIfFeedIdIsInvalid(feedId)); + } + } +} \ No newline at end of file