diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config
index 67f8ea0..58b08e6 100644
--- a/.nuget/NuGet.Config
+++ b/.nuget/NuGet.Config
@@ -3,4 +3,7 @@
+
+
+
\ No newline at end of file
diff --git a/ContentConsole.Test.Unit/BannedWordCounterServiceTests.cs b/ContentConsole.Test.Unit/BannedWordCounterServiceTests.cs
new file mode 100644
index 0000000..b76786b
--- /dev/null
+++ b/ContentConsole.Test.Unit/BannedWordCounterServiceTests.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ContentConsole.Helpers;
+using ContentConsole.Services;
+using Moq;
+using NUnit.Framework;
+
+namespace ContentConsole.Test.Unit
+{
+ [TestFixture]
+ public class BannedWordCounterServiceTests
+ {
+ [Test]
+ public void CountBannedWords_OnLowercaseContentwithUppercaseBannedWord_CountsBannedWords()
+ {
+ const string upperBannedWord = "BANNED";
+ const string lowercaseContent = "banned content";
+ var lowercaseRetrievedBannedWordsService = new Mock();
+ lowercaseRetrievedBannedWordsService
+ .Setup(service => service.GetBannedWords())
+ .Returns(new List { upperBannedWord });
+
+ IBannedWordCounterService bannedWordCounterService
+ = new BannedWordCounterService(lowercaseRetrievedBannedWordsService.Object, new PhraseMatcher());
+
+ Assert.AreEqual(bannedWordCounterService.CountBannedWords(lowercaseContent), 1);
+ }
+
+ [Test]
+ public void CountBannedWords_OnUppercaseContentwithLowercaseBannedWord_CountsBannedWords()
+ {
+ const string lowercaseBannedWord = "banned";
+ const string uppercaseContent = "BANNED CONTENT";
+ var lowercaseRetrievedBannedWordsService = new Mock();
+ lowercaseRetrievedBannedWordsService
+ .Setup(service => service.GetBannedWords())
+ .Returns(new List { lowercaseBannedWord });
+
+ IBannedWordCounterService bannedWordCounterService
+ = new BannedWordCounterService(lowercaseRetrievedBannedWordsService.Object, new PhraseMatcher());
+
+ Assert.AreEqual(bannedWordCounterService.CountBannedWords(uppercaseContent), 1);
+ }
+
+ [Test]
+ public void CountBannedWords_BannedWordAtSentenceEndNoPunctuation_CountsBannedWords()
+ {
+ const string lowercaseBannedWord = "banned";
+ const string uppercaseContent = "This word is banned";
+ var lowercaseRetrievedBannedWordsService = new Mock();
+ lowercaseRetrievedBannedWordsService
+ .Setup(service => service.GetBannedWords())
+ .Returns(new List { lowercaseBannedWord });
+
+ IBannedWordCounterService bannedWordCounterService
+ = new BannedWordCounterService(lowercaseRetrievedBannedWordsService.Object, new PhraseMatcher());
+
+ Assert.AreEqual(bannedWordCounterService.CountBannedWords(uppercaseContent), 1);
+ }
+
+ [Test]
+ public void CountBannedWords_BannedWordAtSentenceEndWithPunctuation_CountsBannedWords()
+ {
+ const string lowercaseBannedWord = "banned";
+ const string uppercaseContent = "This word is banned.";
+ var lowercaseRetrievedBannedWordsService = new Mock();
+ lowercaseRetrievedBannedWordsService
+ .Setup(service => service.GetBannedWords())
+ .Returns(new List { lowercaseBannedWord });
+
+ IBannedWordCounterService bannedWordCounterService
+ = new BannedWordCounterService(lowercaseRetrievedBannedWordsService.Object, new PhraseMatcher());
+
+ Assert.AreEqual(bannedWordCounterService.CountBannedWords(uppercaseContent), 1);
+ }
+
+ [Test]
+ public void CountBannedWords_BannedWordAtSentenceStartAndEnd_CountsBannedWords()
+ {
+ const string lowercaseBannedWord = "banned";
+ const string uppercaseContent = "banned words are banned";
+ var lowercaseRetrievedBannedWordsService = new Mock();
+ lowercaseRetrievedBannedWordsService
+ .Setup(service => service.GetBannedWords())
+ .Returns(new List { lowercaseBannedWord });
+
+ IBannedWordCounterService bannedWordCounterService
+ = new BannedWordCounterService(lowercaseRetrievedBannedWordsService.Object, new PhraseMatcher());
+
+ Assert.AreEqual(bannedWordCounterService.CountBannedWords(uppercaseContent), 2);
+ }
+
+ [Test]
+ public void CountBannedWords_BannedWordAtSentenceStart_CountsBannedWords()
+ {
+ const string lowercaseBannedWord = "banned";
+ const string uppercaseContent = "banned words";
+ var lowercaseRetrievedBannedWordsService = new Mock();
+ lowercaseRetrievedBannedWordsService
+ .Setup(service => service.GetBannedWords())
+ .Returns(new List { lowercaseBannedWord });
+
+ IBannedWordCounterService bannedWordCounterService
+ = new BannedWordCounterService(lowercaseRetrievedBannedWordsService.Object, new PhraseMatcher());
+
+ Assert.AreEqual(bannedWordCounterService.CountBannedWords(uppercaseContent), 1);
+ }
+ }
+}
diff --git a/ContentConsole.Test.Unit/BannedWordFile.txt b/ContentConsole.Test.Unit/BannedWordFile.txt
new file mode 100644
index 0000000..541f0ce
--- /dev/null
+++ b/ContentConsole.Test.Unit/BannedWordFile.txt
@@ -0,0 +1,8 @@
+
+ b1
+b2
+
+b3
+B3
+
+
diff --git a/ContentConsole.Test.Unit/BannedWordFileRepositoryTests.cs b/ContentConsole.Test.Unit/BannedWordFileRepositoryTests.cs
new file mode 100644
index 0000000..9df3546
--- /dev/null
+++ b/ContentConsole.Test.Unit/BannedWordFileRepositoryTests.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ContentConsole.DataRepository;
+using NUnit.Framework;
+
+namespace ContentConsole.Test.Unit
+{
+ [TestFixture]
+ public class BannedWordFileRepositoryTests
+ {
+ [Test]
+ public void Initialize_GivenFileThatDoesNotExist_ThrowsFileNotFoundException()
+ {
+ Assert.Throws(typeof(ArgumentException),
+ delegate { throw new ArgumentException(); });
+ Assert.Throws(() => new BannedWordFileRepository("NotABannedWordFile.txt"));
+ }
+
+ [Test]
+ public void Initialize_GivenFileThatExists_DoesNotThrowException()
+ {
+ IBannedWordRepository repository = new BannedWordFileRepository("../../BannedWordFile.txt");
+ }
+
+ [Test]
+ public void Initialize_GivenFileThatExists_ReadsFileWords()
+ {
+ IBannedWordRepository repository = new BannedWordFileRepository("../../BannedWordFile.txt");
+
+ Assert.IsTrue(repository.Contains("b1"));
+ Assert.IsTrue(repository.Contains("b2"));
+ Assert.IsTrue(repository.Contains("b3"));
+ Assert.IsTrue(repository.Contains("B3"));
+
+ Assert.AreEqual(repository.GetAll().Count(), 3);
+ }
+ }
+}
diff --git a/ContentConsole.Test.Unit/BannedWordReplacementServiceTests.cs b/ContentConsole.Test.Unit/BannedWordReplacementServiceTests.cs
new file mode 100644
index 0000000..3044cf3
--- /dev/null
+++ b/ContentConsole.Test.Unit/BannedWordReplacementServiceTests.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ContentConsole.Helpers;
+using ContentConsole.Services;
+using Moq;
+using NUnit.Framework;
+
+namespace ContentConsole.Test.Unit
+{
+ [TestFixture]
+ public class BannedWordReplacementServiceTests
+ {
+
+ private IBannedWordRetrievalService CreatedMockBannedWordRetrievalService()
+ {
+ var mockRetrievalService = new Mock();
+ mockRetrievalService.Setup(service => service.GetBannedWords())
+ .Returns(new List { "a", "an", "banned", "WORD", "bad" });
+ return mockRetrievalService.Object;
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenNullContent_ReturnsNull()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ Assert.IsNull(replacementService.ReplaceBannedWords(null));
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenEmptyContent_ReturnsEmptyString()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ Assert.AreEqual("", replacementService.ReplaceBannedWords(""));
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenEmptyPaddedContent_ReturnsEmptyOriginalPaddedInput()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ const string testContent = "\t\n ";
+ Assert.AreEqual(testContent, replacementService.ReplaceBannedWords(testContent), testContent);
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenBannedWordContentLower_ReplacesBannedWordsWithOriginalCapitalization()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ const string testContent = "lower case banned word ";
+ const string expectedReplacement = "lower case b####d w##d ";
+ Assert.AreEqual(expectedReplacement, replacementService.ReplaceBannedWords(testContent));
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenBannedWordContentUpper_ReplacesBannedWordsWithOriginalCapitalization()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ const string testContent = "UPPER CASE BANNED WORD ";
+ const string expectedReplacement = "UPPER CASE B####D W##D ";
+ Assert.AreEqual(expectedReplacement, replacementService.ReplaceBannedWords(testContent));
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenSingleLetterBannedWord_HidesEntireBannedWord()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ const string testContent = "a lower case banned word ";
+ const string expectedReplacement = "# lower case b####d w##d ";
+ Assert.AreEqual(expectedReplacement, replacementService.ReplaceBannedWords(testContent));
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenTwoLetterBannedWord_HidesEntireBannedWord()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ const string testContent = "AN UPPER CASE BANNED WORD ";
+ const string expectedReplacement = "## UPPER CASE B####D W##D ";
+ Assert.AreEqual(expectedReplacement, replacementService.ReplaceBannedWords(testContent));
+ }
+
+ [Test]
+ public void ReplaceBannedWords_OnGivenThreeLetterBannedWord_HidesMiddleLetterOfBannedWord()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ const string testContent = "The weather in Manchester in winter is bad.It rains all the time -it must be horrible for people visiting.";
+ const string expectedReplacement = "The weather in Manchester in winter is b#d.It rains all the time -it must be horrible for people visiting.";
+ Assert.AreEqual(expectedReplacement, replacementService.ReplaceBannedWords(testContent));
+ }
+
+ // We might want to check for this, but for now don't check for pluralization and skip the word.
+ [Test]
+ public void ReplaceBannedWords_OnGivenBadWordPluralized_DoesNotReplacePluralizedBannedWord()
+ {
+ IBannedWordReplacementService replacementService =
+ new BannedWordReplacementService(CreatedMockBannedWordRetrievalService(), new PhraseMatcher());
+ const string testContent = "UPPER CASE BANNED WORDS ";
+ const string expectedReplacement = "UPPER CASE B####D WORDS ";
+ Assert.AreEqual(expectedReplacement, replacementService.ReplaceBannedWords(testContent));
+ }
+ }
+}
diff --git a/ContentConsole.Test.Unit/BannedWordRepositoryTests.cs b/ContentConsole.Test.Unit/BannedWordRepositoryTests.cs
new file mode 100644
index 0000000..51b3683
--- /dev/null
+++ b/ContentConsole.Test.Unit/BannedWordRepositoryTests.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ContentConsole.DataRepository;
+using NUnit.Framework;
+namespace ContentConsole.Test.Unit
+{
+ [TestFixture]
+ public class BannedWordRepositoryTests
+ {
+ [Test]
+ public void GetAll_OnInitialization_ReturnsEmptyNonNullEnumerable()
+ {
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+ IEnumerable bannedWords = bannedWordRepository.GetAll();
+
+ Assert.IsNotNull(bannedWords);
+ Assert.AreEqual(bannedWords.Count(), 0);
+ }
+
+ [Test]
+ public void Add_OnInitialization_AddsNewWordToRepository()
+ {
+ string bannedWord = "banned";
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+
+ bannedWordRepository.Add(bannedWord);
+
+ IEnumerable bannedWords = bannedWordRepository.GetAll();
+ Assert.IsNotNull(bannedWords);
+ Assert.AreEqual(bannedWords.Count(), 1);
+ Assert.AreEqual(bannedWords.First(), bannedWord);
+ }
+
+ [Test]
+ public void Add_OnAddingNull_DoesNotAddNewWord()
+ {
+ string bannedWord = "banned";
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+
+ // Add null
+ bannedWordRepository.Add(null);
+ bannedWordRepository.Add(bannedWord);
+
+ IEnumerable bannedWords = bannedWordRepository.GetAll();
+ Assert.IsNotNull(bannedWords);
+ Assert.AreEqual(bannedWords.Count(), 1);
+ Assert.AreEqual(bannedWords.First(), bannedWord);
+ }
+
+ [Test]
+ public void Add_OnAddingEmpty_DoesNotAddNewWord()
+ {
+ string bannedWord = "banned";
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+
+ // Add null
+ bannedWordRepository.Add("");
+ bannedWordRepository.Add(bannedWord);
+
+ IEnumerable bannedWords = bannedWordRepository.GetAll();
+ Assert.IsNotNull(bannedWords);
+ Assert.AreEqual(bannedWords.Count(), 1);
+ Assert.AreEqual(bannedWords.First(), bannedWord);
+ }
+
+ [Test]
+ public void Add_OnAddingDuplicateWordWithPaddedWhiteSpace_DoesNotAddDuplicate()
+ {
+ string bannedWord = "banned";
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+
+ // Add duplicate word with padding
+ bannedWordRepository.Add(bannedWord);
+ bannedWordRepository.Add(" \t" + bannedWord + "\n");
+
+ IEnumerable bannedWords = bannedWordRepository.GetAll();
+ Assert.IsNotNull(bannedWords);
+ Assert.AreEqual(bannedWords.Count(), 1);
+ Assert.AreEqual(bannedWords.First(), bannedWord);
+ }
+
+ [Test]
+ public void Contains_OnInitialization_ReturnsFalse()
+ {
+ string bannedWord = "banned";
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+ Assert.IsFalse(bannedWordRepository.Contains(bannedWord));
+ }
+
+ [Test]
+ public void Contains_OnGivenNull_ReturnsFalse()
+ {
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+ Assert.IsFalse(bannedWordRepository.Contains(null));
+ }
+
+ [Test]
+ public void Contains_OnGivenEmptyWord_ReturnsFalse()
+ {
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+ Assert.IsFalse(bannedWordRepository.Contains(""));
+ }
+
+ [Test]
+ public void Contains_AddingLowercaseWordAndCheckingUppercaseContains_ReturnsTrueOnMatch()
+ {
+ string bannedWord = "banned";
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+
+ bannedWordRepository.Add(bannedWord);
+ Assert.IsTrue(bannedWordRepository.Contains(bannedWord));
+ }
+
+ [Test]
+ public void Contains_ContainsIgnoresWhiteSpace_DoesNotAddDuplicate()
+ {
+ string bannedWord = "banned";
+ IBannedWordRepository bannedWordRepository = new BannedWordRepository();
+
+ // Add original word with padding
+ bannedWordRepository.Add(" \t" + bannedWord + "\n");
+
+ // check original word is contained, as well as padded variations
+ Assert.IsTrue(bannedWordRepository.Contains(bannedWord));
+ Assert.IsTrue(bannedWordRepository.Contains(" " + bannedWord));
+ Assert.IsTrue(bannedWordRepository.Contains("\t" + bannedWord + "\n"));
+ }
+ }
+}
diff --git a/ContentConsole.Test.Unit/BannedWordRetrievalServiceTests.cs b/ContentConsole.Test.Unit/BannedWordRetrievalServiceTests.cs
new file mode 100644
index 0000000..0f18185
--- /dev/null
+++ b/ContentConsole.Test.Unit/BannedWordRetrievalServiceTests.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ContentConsole.DataRepository;
+using ContentConsole.Services;
+using Moq;
+using NUnit.Framework;
+
+namespace ContentConsole.Test.Unit
+{
+ [TestFixture]
+ public class BannedWordRetrievalServiceTests
+ {
+ [Test]
+ public void GetBannedWords_InitializedWithEmptyRepo_ReturnsEmptyList()
+ {
+ var mockRepo = new Mock();
+ mockRepo.Setup(repo => repo.GetAll())
+ .Returns(new List());
+
+ IBannedWordRetrievalService bannedWordRetrievalService = new BannedWordRetrievalService(mockRepo.Object);
+
+ Assert.AreSame(bannedWordRetrievalService.GetBannedWords(), mockRepo.Object.GetAll());
+ }
+
+ [Test]
+ public void GetBannedWords_InitializedWithRepo_ReturnsMatchingList()
+ {
+ var mockRepo = new Mock();
+ mockRepo.Setup(repo => repo.GetAll())
+ .Returns(new List() { "banned", "word" });
+
+ IBannedWordRetrievalService bannedWordRetrievalService = new BannedWordRetrievalService(mockRepo.Object);
+ IEnumerable serviceBannedWords = bannedWordRetrievalService.GetBannedWords();
+
+ Assert.AreEqual(serviceBannedWords.Count(), 2);
+ Assert.IsTrue(serviceBannedWords.Contains("banned"));
+ Assert.IsTrue(serviceBannedWords.Contains("word"));
+ }
+ }
+}
diff --git a/ContentConsole.Test.Unit/ContentConsole.Test.Unit.csproj b/ContentConsole.Test.Unit/ContentConsole.Test.Unit.csproj
index f1b05c0..6db05f3 100644
--- a/ContentConsole.Test.Unit/ContentConsole.Test.Unit.csproj
+++ b/ContentConsole.Test.Unit/ContentConsole.Test.Unit.csproj
@@ -35,9 +35,25 @@
..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll
+ False
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll
+ False
+
..\packages\NUnit.2.6.3\lib\nunit.framework.dll
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll
+ False
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll
+ False
+
@@ -47,11 +63,29 @@
+
+
+
+
+
+
+
+
+
+
+
+ {70da2b36-ebf3-4438-9f95-ecc828a64527}
+ ContentConsole
+
+
+
+
+