diff --git a/src/BirdsiteLive.sln b/src/BirdsiteLive.sln
index ba118c6..4b0cfc1 100644
--- a/src/BirdsiteLive.sln
+++ b/src/BirdsiteLive.sln
@@ -47,7 +47,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Moderation.Tes
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Common.Tests", "Tests\BirdsiteLive.Common.Tests\BirdsiteLive.Common.Tests.csproj", "{C69F7582-6050-44DC-BAAB-7C8F0BDA525C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BSLManager", "BSLManager\BSLManager.csproj", "{4A84D351-E91B-4E58-8E20-211F0F4991D7}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BSLManager", "BSLManager\BSLManager.csproj", "{4A84D351-E91B-4E58-8E20-211F0F4991D7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BSLManager.Tests", "Tests\BSLManager.Tests\BSLManager.Tests.csproj", "{D4457271-620E-465A-B08E-7FC63C99A2F6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -131,6 +133,10 @@ Global
{4A84D351-E91B-4E58-8E20-211F0F4991D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A84D351-E91B-4E58-8E20-211F0F4991D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A84D351-E91B-4E58-8E20-211F0F4991D7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D4457271-620E-465A-B08E-7FC63C99A2F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D4457271-620E-465A-B08E-7FC63C99A2F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D4457271-620E-465A-B08E-7FC63C99A2F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D4457271-620E-465A-B08E-7FC63C99A2F6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -153,6 +159,7 @@ Global
{4BE541AC-8A93-4FA3-98AC-956CC2D5B748} = {DA3C160C-4811-4E26-A5AD-42B81FAF2D7C}
{0A311BF3-4FD9-4303-940A-A3778890561C} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94}
{C69F7582-6050-44DC-BAAB-7C8F0BDA525C} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94}
+ {D4457271-620E-465A-B08E-7FC63C99A2F6} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {69E8DCAD-4C37-4010-858F-5F94E6FBABCE}
diff --git a/src/Tests/BSLManager.Tests/BSLManager.Tests.csproj b/src/Tests/BSLManager.Tests/BSLManager.Tests.csproj
new file mode 100644
index 0000000..033cfe1
--- /dev/null
+++ b/src/Tests/BSLManager.Tests/BSLManager.Tests.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Tests/BSLManager.Tests/Domain/FollowersListStateTests.cs b/src/Tests/BSLManager.Tests/Domain/FollowersListStateTests.cs
new file mode 100644
index 0000000..a0171a4
--- /dev/null
+++ b/src/Tests/BSLManager.Tests/Domain/FollowersListStateTests.cs
@@ -0,0 +1,307 @@
+using System.Collections.Generic;
+using System.Linq;
+using BirdsiteLive.DAL.Models;
+using BSLManager.Domain;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace BSLManager.Tests
+{
+ [TestClass]
+ public class FollowersListStateTests
+ {
+ [TestMethod]
+ public void FilterBy()
+ {
+ #region Stub
+ var followers = new List
+ {
+ new Follower
+ {
+ Id = 0,
+ Acct = "test",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 1,
+ Acct = "test",
+ Host = "host2",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 2,
+ Acct = "user1",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 3,
+ Acct = "user2",
+ Host = "host1",
+ Followings = new List()
+ }
+ };
+ #endregion
+
+ var state = new FollowersListState();
+ state.Load(followers);
+
+ state.FilterBy("test");
+
+ #region Validate
+ Assert.AreEqual(2, state.GetDisplayableList().Count);
+ #endregion
+ }
+
+ [TestMethod]
+ public void FilterBy_GetElement()
+ {
+ #region Stub
+ var followers = new List
+ {
+ new Follower
+ {
+ Id = 0,
+ Acct = "test",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 1,
+ Acct = "test",
+ Host = "host2",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 2,
+ Acct = "user1",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 3,
+ Acct = "user2",
+ Host = "host1",
+ Followings = new List()
+ }
+ };
+ #endregion
+
+ var state = new FollowersListState();
+ state.Load(followers);
+
+ state.FilterBy("test");
+ var el = state.GetElementAt(1);
+
+ #region Validate
+ Assert.AreEqual(followers[1].Id, el.Id);
+ #endregion
+ }
+
+ [TestMethod]
+ public void GetElement()
+ {
+ #region Stub
+ var followers = new List
+ {
+ new Follower
+ {
+ Id = 0,
+ Acct = "test",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 1,
+ Acct = "test",
+ Host = "host2",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 2,
+ Acct = "user1",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 3,
+ Acct = "user2",
+ Host = "host1",
+ Followings = new List()
+ }
+ };
+ #endregion
+
+ var state = new FollowersListState();
+ state.Load(followers);
+
+ var el = state.GetElementAt(2);
+
+ #region Validate
+ Assert.AreEqual(followers[2].Id, el.Id);
+ #endregion
+ }
+
+ [TestMethod]
+ public void FilterBy_RemoveAt()
+ {
+ #region Stub
+ var followers = new List
+ {
+ new Follower
+ {
+ Id = 0,
+ Acct = "test",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 1,
+ Acct = "test",
+ Host = "host2",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 2,
+ Acct = "user1",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 3,
+ Acct = "user2",
+ Host = "host1",
+ Followings = new List()
+ }
+ };
+ #endregion
+
+ var state = new FollowersListState();
+ state.Load(followers.ToList());
+
+ state.FilterBy("test");
+ state.RemoveAt(1);
+
+ var list = state.GetDisplayableList();
+
+ #region Validate
+ Assert.AreEqual(1, list.Count);
+ Assert.IsTrue(list[0].Contains("@test@host1"));
+ #endregion
+ }
+
+ [TestMethod]
+ public void RemoveAt()
+ {
+ #region Stub
+ var followers = new List
+ {
+ new Follower
+ {
+ Id = 0,
+ Acct = "test",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 1,
+ Acct = "test",
+ Host = "host2",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 2,
+ Acct = "user1",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 3,
+ Acct = "user2",
+ Host = "host1",
+ Followings = new List()
+ }
+ };
+ #endregion
+
+ var state = new FollowersListState();
+ state.Load(followers.ToList());
+
+ state.RemoveAt(1);
+
+ var list = state.GetDisplayableList();
+
+ #region Validate
+ Assert.AreEqual(3, list.Count);
+ Assert.IsTrue(list[0].Contains("@test@host1"));
+ Assert.IsFalse(list[1].Contains("@test@host2"));
+ #endregion
+ }
+
+ [TestMethod]
+ public void FilterBy_ResetFilter()
+ {
+ #region Stub
+ var followers = new List
+ {
+ new Follower
+ {
+ Id = 0,
+ Acct = "test",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 1,
+ Acct = "test",
+ Host = "host2",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 2,
+ Acct = "user1",
+ Host = "host1",
+ Followings = new List()
+ },
+ new Follower
+ {
+ Id = 3,
+ Acct = "user2",
+ Host = "host1",
+ Followings = new List()
+ }
+ };
+ #endregion
+
+ var state = new FollowersListState();
+ state.Load(followers.ToList());
+
+ #region Validate
+ state.FilterBy("data");
+ var list = state.GetDisplayableList();
+ Assert.AreEqual(0, list.Count);
+
+ state.FilterBy(string.Empty);
+ list = state.GetDisplayableList();
+ Assert.AreEqual(4, list.Count);
+ #endregion
+ }
+ }
+}