From e96d78bd213d694aeaffad9336e9774488bcd0bf Mon Sep 17 00:00:00 2001 From: Alex Hyett Date: Fri, 7 Jul 2023 14:27:35 +0100 Subject: [PATCH] Added Integration test that uses Refit --- GitHubActionsDemo.sln | 11 ++- .../Books/IBookApi.cs | 2 +- .../GitHubActionsDemo.Api.Sdk.csproj | 2 +- .../Models/Validators/BookRequestValidator.cs | 4 +- .../DbContext.cs | 2 +- .../Models/NotFound.cs | 6 -- ...ubActionsDemo.Api.Integration.Tests.csproj | 30 +++++++ .../IntegrationTests.cs | 78 +++++++++++++++++++ .../Usings.cs | 1 + .../AuthorsControllerTests.cs | 2 +- .../GitHubActionsDemo.Api.Unit.Tests.csproj} | 0 .../Usings.cs | 0 ...tHubActionsDemo.Service.Unit.Tests.csproj} | 0 .../LibraryServiceTests.cs | 2 +- .../Usings.cs | 0 15 files changed, 124 insertions(+), 16 deletions(-) delete mode 100644 src/GitHubActionsDemo.Service/Models/NotFound.cs create mode 100644 test/GitHubActionsDemo.Api.Integration.Tests/GitHubActionsDemo.Api.Integration.Tests.csproj create mode 100644 test/GitHubActionsDemo.Api.Integration.Tests/IntegrationTests.cs create mode 100644 test/GitHubActionsDemo.Api.Integration.Tests/Usings.cs rename test/{GitHubActionsDemo.Api.Tests => GitHubActionsDemo.Api.Unit.Tests}/AuthorsControllerTests.cs (96%) rename test/{GitHubActionsDemo.Api.Tests/GitHubActionsDemo.Api.Tests.csproj => GitHubActionsDemo.Api.Unit.Tests/GitHubActionsDemo.Api.Unit.Tests.csproj} (100%) rename test/{GitHubActionsDemo.Api.Tests => GitHubActionsDemo.Api.Unit.Tests}/Usings.cs (100%) rename test/{GitHubActionsDemo.Service.Tests/GitHubActionsDemo.Service.Tests.csproj => GitHubActionsDemo.Service.Unit.Tests/GitHubActionsDemo.Service.Unit.Tests.csproj} (100%) rename test/{GitHubActionsDemo.Service.Tests => GitHubActionsDemo.Service.Unit.Tests}/LibraryServiceTests.cs (95%) rename test/{GitHubActionsDemo.Service.Tests => GitHubActionsDemo.Service.Unit.Tests}/Usings.cs (100%) diff --git a/GitHubActionsDemo.sln b/GitHubActionsDemo.sln index 8b770c8..6452fa7 100644 --- a/GitHubActionsDemo.sln +++ b/GitHubActionsDemo.sln @@ -13,9 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Persistan EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{015E0E24-CD73-48C7-8565-5A566F5DAB87}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Api.Tests", "test\GitHubActionsDemo.Api.Tests\GitHubActionsDemo.Api.Tests.csproj", "{AA6299AC-C10C-49CD-89A3-33122123AE7A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Api.Unit.Tests", "test\GitHubActionsDemo.Api.Unit.Tests\GitHubActionsDemo.Api.Unit.Tests.csproj", "{AA6299AC-C10C-49CD-89A3-33122123AE7A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Service.Tests", "test\GitHubActionsDemo.Service.Tests\GitHubActionsDemo.Service.Tests.csproj", "{957CACE1-E456-48DA-84A7-02A81B9F0371}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Service.Unit.Tests", "test\GitHubActionsDemo.Service.Unit.Tests\GitHubActionsDemo.Service.Unit.Tests.csproj", "{957CACE1-E456-48DA-84A7-02A81B9F0371}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubActionsDemo.Api.Integration.Tests", "test\GitHubActionsDemo.Api.Integration.Tests\GitHubActionsDemo.Api.Integration.Tests.csproj", "{F846BF32-3117-468E-8A90-6692D498BB40}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -46,6 +48,10 @@ Global {957CACE1-E456-48DA-84A7-02A81B9F0371}.Debug|Any CPU.Build.0 = Debug|Any CPU {957CACE1-E456-48DA-84A7-02A81B9F0371}.Release|Any CPU.ActiveCfg = Release|Any CPU {957CACE1-E456-48DA-84A7-02A81B9F0371}.Release|Any CPU.Build.0 = Release|Any CPU + {F846BF32-3117-468E-8A90-6692D498BB40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F846BF32-3117-468E-8A90-6692D498BB40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F846BF32-3117-468E-8A90-6692D498BB40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F846BF32-3117-468E-8A90-6692D498BB40}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {E3C34F79-B74E-44A4-99F0-B0B3C2D7CCB2} = {53A44CCA-C5C6-4D98-91B8-D331D68BF7B0} @@ -53,5 +59,6 @@ Global {339301B3-E9BD-45D1-B6A9-94F41367DF16} = {53A44CCA-C5C6-4D98-91B8-D331D68BF7B0} {AA6299AC-C10C-49CD-89A3-33122123AE7A} = {015E0E24-CD73-48C7-8565-5A566F5DAB87} {957CACE1-E456-48DA-84A7-02A81B9F0371} = {015E0E24-CD73-48C7-8565-5A566F5DAB87} + {F846BF32-3117-468E-8A90-6692D498BB40} = {015E0E24-CD73-48C7-8565-5A566F5DAB87} EndGlobalSection EndGlobal diff --git a/src/GitHubActionsDemo.Api.Sdk/Books/IBookApi.cs b/src/GitHubActionsDemo.Api.Sdk/Books/IBookApi.cs index 4f09cf4..db5ba22 100644 --- a/src/GitHubActionsDemo.Api.Sdk/Books/IBookApi.cs +++ b/src/GitHubActionsDemo.Api.Sdk/Books/IBookApi.cs @@ -12,5 +12,5 @@ public interface IBookApi Task GetBookAsync(int bookId); [Post("/books/")] - Task> CreateBookAsync([Body] BookRequest request); + Task CreateBookAsync([Body] BookRequest request); } diff --git a/src/GitHubActionsDemo.Api.Sdk/GitHubActionsDemo.Api.Sdk.csproj b/src/GitHubActionsDemo.Api.Sdk/GitHubActionsDemo.Api.Sdk.csproj index e0cfd6c..da3d35e 100644 --- a/src/GitHubActionsDemo.Api.Sdk/GitHubActionsDemo.Api.Sdk.csproj +++ b/src/GitHubActionsDemo.Api.Sdk/GitHubActionsDemo.Api.Sdk.csproj @@ -3,7 +3,7 @@ net7.0 enable - enable + disable diff --git a/src/GitHubActionsDemo.Api/Models/Validators/BookRequestValidator.cs b/src/GitHubActionsDemo.Api/Models/Validators/BookRequestValidator.cs index 7c8288b..363c066 100644 --- a/src/GitHubActionsDemo.Api/Models/Validators/BookRequestValidator.cs +++ b/src/GitHubActionsDemo.Api/Models/Validators/BookRequestValidator.cs @@ -11,9 +11,7 @@ public class BookRequestValidator : AbstractValidator RuleFor(x => x.Isbn) .NotEmpty() - .MinimumLength(10) - .MaximumLength(17) - .Matches(@"^(?:ISBN(?:-1[03])?:? )?(?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})[- 0 - 9X]{ 13}$| 97[89][0 - 9]{ 10}$| (?= (?:[0 - 9] +[- ]){ 4})[- 0 - 9]{ 17}$)(?: 97[89][- ] ?)?[0 - 9]{ 1,5}[- ]?[0 - 9]+[- ]?[0 - 9] +[- ]?[0 - 9X]$"); + .Matches(@"^(?=(?:\D*\d){10}(?:(?:\D*\d){3})?$)[\d-]+$"); RuleFor(x => x.DatePublished) .NotEmpty(); diff --git a/src/GitHubActionsDemo.Persistance/DbContext.cs b/src/GitHubActionsDemo.Persistance/DbContext.cs index 15c6d41..b70872d 100644 --- a/src/GitHubActionsDemo.Persistance/DbContext.cs +++ b/src/GitHubActionsDemo.Persistance/DbContext.cs @@ -63,7 +63,7 @@ public class DbContext : IDbContext book_id INT NOT NULL AUTO_INCREMENT, title VARCHAR(255), author_id INT NOT NULL, - isbn VARCHAR(13) NOT NULL, + isbn VARCHAR(20) NOT NULL, date_published DATETIME NOT NULL, date_created DATETIME NOT NULL, date_modified DATETIME NOT NULL, diff --git a/src/GitHubActionsDemo.Service/Models/NotFound.cs b/src/GitHubActionsDemo.Service/Models/NotFound.cs deleted file mode 100644 index 6ea7b8c..0000000 --- a/src/GitHubActionsDemo.Service/Models/NotFound.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace GitHubActionsDemo.Service.Models; - -public class NotFound -{ - -} \ No newline at end of file diff --git a/test/GitHubActionsDemo.Api.Integration.Tests/GitHubActionsDemo.Api.Integration.Tests.csproj b/test/GitHubActionsDemo.Api.Integration.Tests/GitHubActionsDemo.Api.Integration.Tests.csproj new file mode 100644 index 0000000..77ed7ee --- /dev/null +++ b/test/GitHubActionsDemo.Api.Integration.Tests/GitHubActionsDemo.Api.Integration.Tests.csproj @@ -0,0 +1,30 @@ + + + + net7.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/test/GitHubActionsDemo.Api.Integration.Tests/IntegrationTests.cs b/test/GitHubActionsDemo.Api.Integration.Tests/IntegrationTests.cs new file mode 100644 index 0000000..9a1eeef --- /dev/null +++ b/test/GitHubActionsDemo.Api.Integration.Tests/IntegrationTests.cs @@ -0,0 +1,78 @@ + +using GitHubActionsDemo.Api.Sdk.Authors; +using GitHubActionsDemo.Api.Sdk.Books; +using Refit; +using Shouldly; + +namespace GitHubActionsDemo.Api.Integration.Tests; + +public class IntegrationTests +{ + private const string BaseUri = "http://localhost:5275"; + private readonly IAuthorApi _authorApi = RestService.For(BaseUri); + private readonly IBookApi _bookApi = RestService.For(BaseUri); + + [Fact] + public async Task Given_valid_author_should_create_author() + { + var request = new AuthorRequest + { + FirstName = $"{Guid.NewGuid()}", + LastName = $"{Guid.NewGuid()}" + }; + + var author = await _authorApi.CreateAuthorAsync(request); + author.AuthorId.ShouldNotBe(0); + author.FirstName.ShouldBe(request.FirstName); + author.LastName.ShouldBe(request.LastName); + author.DateCreated.ShouldBeInRange(DateTime.UtcNow.AddSeconds(-5), DateTime.UtcNow.AddSeconds(5)); + author.DateModified.ShouldBeInRange(DateTime.UtcNow.AddSeconds(-5), DateTime.UtcNow.AddSeconds(5)); + } + + [Fact] + public async Task Given_created_author_should_return_author_on_get() + { + var request = new AuthorRequest + { + FirstName = $"{Guid.NewGuid()}", + LastName = $"{Guid.NewGuid()}" + }; + + var createdAuthor = await _authorApi.CreateAuthorAsync(request); + + var author = await _authorApi.GetAuthorAsync(createdAuthor.AuthorId); + author.AuthorId.ShouldBe(createdAuthor.AuthorId); + author.FirstName.ShouldBe(request.FirstName); + author.LastName.ShouldBe(request.LastName); + author.DateCreated.ShouldBeInRange(DateTime.UtcNow.AddSeconds(-5), DateTime.UtcNow.AddSeconds(5)); + author.DateModified.ShouldBeInRange(DateTime.UtcNow.AddSeconds(-5), DateTime.UtcNow.AddSeconds(5)); + } + + + [Fact] + public async Task Given_valid_book_should_return_book() + { + var authorRequest = new AuthorRequest + { + FirstName = $"{Guid.NewGuid()}", + LastName = $"{Guid.NewGuid()}" + }; + + var createdAuthor = await _authorApi.CreateAuthorAsync(authorRequest); + + var bookRequest = new BookRequest + { + AuthorId = createdAuthor.AuthorId, + Title = "Once upon a time", + Isbn = "978-93-5489-3896", + DatePublished = new DateTime(2020, 01, 01) + }; + + var createdBook = await _bookApi.CreateBookAsync(bookRequest); + createdBook.Title.ShouldBe(bookRequest.Title); + createdBook.Isbn.ShouldBe(bookRequest.Isbn); + createdBook.Author.AuthorId.ShouldBe(createdAuthor.AuthorId); + createdBook.Author.FirstName.ShouldBe(authorRequest.FirstName); + createdBook.Author.LastName.ShouldBe(authorRequest.LastName); + } +} \ No newline at end of file diff --git a/test/GitHubActionsDemo.Api.Integration.Tests/Usings.cs b/test/GitHubActionsDemo.Api.Integration.Tests/Usings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/test/GitHubActionsDemo.Api.Integration.Tests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/test/GitHubActionsDemo.Api.Tests/AuthorsControllerTests.cs b/test/GitHubActionsDemo.Api.Unit.Tests/AuthorsControllerTests.cs similarity index 96% rename from test/GitHubActionsDemo.Api.Tests/AuthorsControllerTests.cs rename to test/GitHubActionsDemo.Api.Unit.Tests/AuthorsControllerTests.cs index de39f22..ef3464a 100644 --- a/test/GitHubActionsDemo.Api.Tests/AuthorsControllerTests.cs +++ b/test/GitHubActionsDemo.Api.Unit.Tests/AuthorsControllerTests.cs @@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Http.HttpResults; using GitHubActionsDemo.Api.Sdk.Authors; using GitHubActionsDemo.Api.Sdk.Shared; -namespace GitHubActionsDemo.Api.Tests; +namespace GitHubActionsDemo.Api.Unit.Tests; public class AuthorsControllerTests { diff --git a/test/GitHubActionsDemo.Api.Tests/GitHubActionsDemo.Api.Tests.csproj b/test/GitHubActionsDemo.Api.Unit.Tests/GitHubActionsDemo.Api.Unit.Tests.csproj similarity index 100% rename from test/GitHubActionsDemo.Api.Tests/GitHubActionsDemo.Api.Tests.csproj rename to test/GitHubActionsDemo.Api.Unit.Tests/GitHubActionsDemo.Api.Unit.Tests.csproj diff --git a/test/GitHubActionsDemo.Api.Tests/Usings.cs b/test/GitHubActionsDemo.Api.Unit.Tests/Usings.cs similarity index 100% rename from test/GitHubActionsDemo.Api.Tests/Usings.cs rename to test/GitHubActionsDemo.Api.Unit.Tests/Usings.cs diff --git a/test/GitHubActionsDemo.Service.Tests/GitHubActionsDemo.Service.Tests.csproj b/test/GitHubActionsDemo.Service.Unit.Tests/GitHubActionsDemo.Service.Unit.Tests.csproj similarity index 100% rename from test/GitHubActionsDemo.Service.Tests/GitHubActionsDemo.Service.Tests.csproj rename to test/GitHubActionsDemo.Service.Unit.Tests/GitHubActionsDemo.Service.Unit.Tests.csproj diff --git a/test/GitHubActionsDemo.Service.Tests/LibraryServiceTests.cs b/test/GitHubActionsDemo.Service.Unit.Tests/LibraryServiceTests.cs similarity index 95% rename from test/GitHubActionsDemo.Service.Tests/LibraryServiceTests.cs rename to test/GitHubActionsDemo.Service.Unit.Tests/LibraryServiceTests.cs index 3c0adbd..5aa2440 100644 --- a/test/GitHubActionsDemo.Service.Tests/LibraryServiceTests.cs +++ b/test/GitHubActionsDemo.Service.Unit.Tests/LibraryServiceTests.cs @@ -4,7 +4,7 @@ using GitHubActionsDemo.Persistance.Models; using GitHubActionsDemo.Service.Models; using Microsoft.Extensions.Logging; -namespace GitHubActionsDemo.Service.Tests; +namespace GitHubActionsDemo.Service.Unit.Tests; public class LibraryServiceTests { diff --git a/test/GitHubActionsDemo.Service.Tests/Usings.cs b/test/GitHubActionsDemo.Service.Unit.Tests/Usings.cs similarity index 100% rename from test/GitHubActionsDemo.Service.Tests/Usings.cs rename to test/GitHubActionsDemo.Service.Unit.Tests/Usings.cs