From 96553c3e2bab8e1adb8e6f6b3b2d1aae1295d366 Mon Sep 17 00:00:00 2001 From: Neil Brommer Date: Wed, 20 Apr 2022 15:34:13 -0700 Subject: [PATCH] Add some service unit tests; add base for Fluxor tests --- .../MockApis/MockBookmarkContainersApi.cs | 29 +++++ .../Client/MockApis/MockBookmarkGroupsApi.cs | 23 ++++ .../Client/MockApis/MockBookmarksApi.cs | 23 ++++ .../Client/Store/ContainerListTests.cs | 25 ++++ .../Client/Store/UnitTestWithFluxor.cs | 37 ++++++ Start_Tests/Server/BookmarkServiceTests.cs | 117 ++++++++++++++++++ Start_Tests/{ => Server}/UnitTestWithDb.cs | 20 ++- Start_Tests/Start_Tests.csproj | 18 +++ Start_Tests/UnitTest1.cs | 20 --- 9 files changed, 289 insertions(+), 23 deletions(-) create mode 100644 Start_Tests/Client/MockApis/MockBookmarkContainersApi.cs create mode 100644 Start_Tests/Client/MockApis/MockBookmarkGroupsApi.cs create mode 100644 Start_Tests/Client/MockApis/MockBookmarksApi.cs create mode 100644 Start_Tests/Client/Store/ContainerListTests.cs create mode 100644 Start_Tests/Client/Store/UnitTestWithFluxor.cs create mode 100644 Start_Tests/Server/BookmarkServiceTests.cs rename Start_Tests/{ => Server}/UnitTestWithDb.cs (78%) delete mode 100644 Start_Tests/UnitTest1.cs diff --git a/Start_Tests/Client/MockApis/MockBookmarkContainersApi.cs b/Start_Tests/Client/MockApis/MockBookmarkContainersApi.cs new file mode 100644 index 0000000..9fedf05 --- /dev/null +++ b/Start_Tests/Client/MockApis/MockBookmarkContainersApi.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Refit; +using Start.Shared; +using Start.Shared.Api; + +namespace Start_Tests.Client.MockApis { + public class MockBookmarkContainersApi : IBookmarkContainersApi { + public Task>> GetAllBookmarkContainers() { + throw new NotImplementedException(); + } + + public Task> GetBookmarkContainer( + int bookmarkContainerId) { + throw new NotImplementedException(); + } + + public Task> CreateBookmarkContainer(string title, + int sortOrder) { + throw new NotImplementedException(); + } + + public Task DeleteBookmarkContainer(int bookmarkContainerId) { + throw new NotImplementedException(); + } + } +} diff --git a/Start_Tests/Client/MockApis/MockBookmarkGroupsApi.cs b/Start_Tests/Client/MockApis/MockBookmarkGroupsApi.cs new file mode 100644 index 0000000..0619d09 --- /dev/null +++ b/Start_Tests/Client/MockApis/MockBookmarkGroupsApi.cs @@ -0,0 +1,23 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Refit; +using Start.Shared; +using Start.Shared.Api; + +namespace Start_Tests.Client.MockApis { + public class MockBookmarkGroupsApi : IBookmarkGroupsApi { + public Task> GetBookmarkGroup(int bookmarkGroupId) { + throw new NotImplementedException(); + } + + public Task> CreateBookmarkGroup(string title, string color, + int sortOrder, int bookmarkContainerId) { + throw new NotImplementedException(); + } + + public Task DeleteBookmarkGroup(int bookmarkGroupId) { + throw new NotImplementedException(); + } + } +} diff --git a/Start_Tests/Client/MockApis/MockBookmarksApi.cs b/Start_Tests/Client/MockApis/MockBookmarksApi.cs new file mode 100644 index 0000000..3d2b0eb --- /dev/null +++ b/Start_Tests/Client/MockApis/MockBookmarksApi.cs @@ -0,0 +1,23 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Refit; +using Start.Shared; +using Start.Shared.Api; + +namespace Start_Tests.Client.MockApis { + public class MockBookmarksApi : IBookmarksApi { + public Task> GetBookmark(int bookmarkId) { + throw new NotImplementedException(); + } + + public Task> CreateBookmark(string title, string url, + string notes, int sortOrder, int bookmarkGroupId) { + throw new NotImplementedException(); + } + + public Task DeleteBookmark(int bookmarkId) { + throw new NotImplementedException(); + } + } +} diff --git a/Start_Tests/Client/Store/ContainerListTests.cs b/Start_Tests/Client/Store/ContainerListTests.cs new file mode 100644 index 0000000..9e1cd6c --- /dev/null +++ b/Start_Tests/Client/Store/ContainerListTests.cs @@ -0,0 +1,25 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Start.Client.Store.Features.ContainersList; + +namespace Start_Tests.Client.Store { + [TestClass] + public class ContainerListTests : UnitTestWithFluxor { + public TestContext TestContext { get; set; } + // Only RootState is needed, so no need to get child objects + + [TestMethod] + public void OnFetchContainersList() { + base.Store.Dispatch(new FetchContainerListAction()); + + Assert.IsTrue(base.State.Value.ContainerListState.IsLoadingContainersList); + Assert.AreEqual(0, this.State.Value.ContainerListState.Containers.Count); + } + + [TestInitialize] + public void InitializeState() { + TestContext.WriteLine("Resetting Fluxor state"); + base.ResetState(); + } + } +} diff --git a/Start_Tests/Client/Store/UnitTestWithFluxor.cs b/Start_Tests/Client/Store/UnitTestWithFluxor.cs new file mode 100644 index 0000000..a820a9a --- /dev/null +++ b/Start_Tests/Client/Store/UnitTestWithFluxor.cs @@ -0,0 +1,37 @@ +using System; +using Blazored.LocalStorage; +using Fluxor; +using Microsoft.Extensions.DependencyInjection; +using Start.Client.Store.State; +using Start.Shared.Api; +using Start_Tests.Client.MockApis; + +namespace Start_Tests.Client.Store { + public abstract class UnitTestWithFluxor { + protected IServiceProvider ServiceProvider { get; set; } + protected IStore Store { get; set; } + protected IState State { get; set; } + // Add child states in the individual tests + + protected Bunit.TestContext BunitTc { get; set; } + + public UnitTestWithFluxor() { + this.ResetState(); + } + + public void ResetState() { + this.BunitTc = new Bunit.TestContext(); + + BunitTc.Services.AddBlazoredLocalStorage(); + BunitTc.Services.AddFluxor(config => config.ScanAssemblies(typeof(RootState).Assembly)); + BunitTc.Services.AddScoped(sp => new MockBookmarksApi()); + BunitTc.Services.AddScoped(sp => new MockBookmarkGroupsApi()); + BunitTc.Services + .AddScoped(sp => new MockBookmarkContainersApi()); + + this.Store = this.BunitTc.Services.GetRequiredService(); + this.State = this.BunitTc.Services.GetRequiredService>(); + this.Store.InitializeAsync().Wait(); + } + } +} diff --git a/Start_Tests/Server/BookmarkServiceTests.cs b/Start_Tests/Server/BookmarkServiceTests.cs new file mode 100644 index 0000000..f9d3dc4 --- /dev/null +++ b/Start_Tests/Server/BookmarkServiceTests.cs @@ -0,0 +1,117 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Start.Server.Data.Services; +using Start.Server.Models; + +namespace Start_Tests.Server { + [TestClass] + public class BookmarkServiceTests : UnitTestWithDb { + public TestContext TestContext { get; set; } + public BookmarkService BookmarkService { get; set; } + + public BookmarkServiceTests() { + this.BookmarkService = new BookmarkService(_db); + } + + [TestMethod] + public override void TestDatabaseOK() { + base.TestDatabaseOK(); + } + + #region CreateBookmark + + [TestMethod] + public async Task CreateBookmark_Valid() { + int initialCount = _db.Bookmarks.Count(); + + await this.BookmarkService.CreateBookmark(base.TestUserId, + "Bookmark Service Test Title", "http://example.com", null, 1, + this.TestBookmarkGroup.BookmarkGroupId); + + int updatedCount = _db.Bookmarks.Count(); + Assert.AreEqual(initialCount + 1, updatedCount); + } + + [TestMethod] + [ExpectedException(typeof(DbUpdateException))] + public async Task CreateBookmark_InvalidTitle() { + await this.BookmarkService.CreateBookmark(base.TestUserId, + null, "http://example.com", null, 1, + this.TestBookmarkGroup.BookmarkGroupId); + } + + [TestMethod] + [ExpectedException(typeof(DbUpdateException))] + public async Task CreateBookmark_InvalidUrl() { + await this.BookmarkService.CreateBookmark(base.TestUserId, + "Bookmark Service Test Title", null, null, 1, + this.TestBookmarkGroup.BookmarkGroupId); + } + + #endregion + + #region GetBookmark + + [TestMethod] + public async Task GetBookmark_CorrectUser() { + Bookmark bookmark = await this.BookmarkService + .GetBookmark(base.TestUserId,base.TestBookmark.BookmarkId); + + Assert.IsNotNull(bookmark); + Assert.AreEqual(bookmark.BookmarkId, base.TestBookmark.BookmarkId); + Assert.AreEqual(bookmark.Url, base.TestBookmark.Url); + } + + [TestMethod] + public async Task GetBookmark_WrongUser() { + Bookmark bookmark = await this.BookmarkService + .GetBookmark(base.InvalidUserId, base.TestBookmark.BookmarkId); + + // Should return null if the user doesn't own the bookmark + Assert.IsNull(bookmark); + } + + [TestMethod] + public async Task GetBookmark_WrongId() { + // Ensure that we use an invalid ID by going past the highest ID value + + int maxBookmarkId = _db.Bookmarks.Max(b => b.BookmarkId); + + Bookmark bookmark = await this.BookmarkService + .GetBookmark(base.TestUserId, maxBookmarkId + 1); + + Assert.IsNull(bookmark); + } + + #endregion + + #region UpdateBookmark + + [TestMethod] + public async Task UpdateBookmark_ValidTitle() { + string testTitleUpdate = "Update bookkmark test title"; + + base.TestBookmark.Title = testTitleUpdate; + Bookmark updatedBookmark = await this.BookmarkService + .UpdateBookmark(base.TestUserId, base.TestBookmark); + + Assert.IsNotNull(updatedBookmark); + Assert.AreEqual(updatedBookmark.Title, testTitleUpdate); + + Bookmark fromDb = _db.Bookmarks.Single(b => b.BookmarkId == TestBookmark.BookmarkId); + + Assert.AreEqual(fromDb.Title, testTitleUpdate); + } + + #endregion + + [TestInitialize] + public void ResetDatabase() { + TestContext.WriteLine("Reseting test DB for the next test"); + base.ResetAndFillDb(); + } + } +} diff --git a/Start_Tests/UnitTestWithDb.cs b/Start_Tests/Server/UnitTestWithDb.cs similarity index 78% rename from Start_Tests/UnitTestWithDb.cs rename to Start_Tests/Server/UnitTestWithDb.cs index 1c8e318..25a77e8 100644 --- a/Start_Tests/UnitTestWithDb.cs +++ b/Start_Tests/Server/UnitTestWithDb.cs @@ -7,11 +7,17 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Start.Server.Data; using Start.Server.Models; -namespace Start_Tests { +namespace Start_Tests.Server { public class UnitTestWithDb : IDisposable { private const string InMemoryConnectionString = "DataSource=:memory:"; private SqliteConnection _connection; + protected string TestUserId { get; } = "test_user"; + protected string InvalidUserId { get; } = "invalid_user"; + protected BookmarkContainer TestBookmarkContainer { get; set; } + protected BookmarkGroup TestBookmarkGroup { get; set; } + protected Bookmark TestBookmark { get; set; } + protected readonly ApplicationDbContext _db; public UnitTestWithDb() { @@ -34,8 +40,8 @@ namespace Start_Tests { protected void FillDbTestData() { ApplicationUser testUser = new ApplicationUser { - Id = "test_user", - UserName = "test_user" + Id = this.TestUserId, + UserName = "test_user_name" }; _db.Users.Add(testUser); _db.SaveChanges(); @@ -44,16 +50,24 @@ namespace Start_Tests { 0); _db.BookmarkContainers.Add(testContainer); _db.SaveChanges(); + this.TestBookmarkContainer = testContainer; BookmarkGroup testGroup = new BookmarkGroup("Test Group", "#000000", 0, testContainer.BookmarkContainerId); _db.BookmarkGroups.Add(testGroup); _db.SaveChanges(); + this.TestBookmarkGroup = testGroup; Bookmark testBookmark = new Bookmark("Test Bookmark", "http://example.com", "Test Notes", 0, testGroup.BookmarkGroupId); _db.Bookmarks.Add(testBookmark); _db.SaveChanges(); + this.TestBookmark = testBookmark; + } + + protected void ResetAndFillDb() { + this.ResetDb(); + this.FillDbTestData(); } /// diff --git a/Start_Tests/Start_Tests.csproj b/Start_Tests/Start_Tests.csproj index 1223883..b969c26 100644 --- a/Start_Tests/Start_Tests.csproj +++ b/Start_Tests/Start_Tests.csproj @@ -11,10 +11,28 @@ + + + + + + + + + + + + + + + + + + diff --git a/Start_Tests/UnitTest1.cs b/Start_Tests/UnitTest1.cs deleted file mode 100644 index 73d56f9..0000000 --- a/Start_Tests/UnitTest1.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Start.Server.Models; - -namespace Start_Tests { - [TestClass] - public class UnitTest1 : UnitTestWithDb { - public TestContext TestContext { get; set; } - - [TestMethod] - public override void TestDatabaseOK() { - base.TestDatabaseOK(); - } - - [TestMethod] - public void TestMethod1() { - TestContext.WriteLine("Running TestMethod1 from TestContext"); - } - } -}