From d37b39e3ef684236a57b98bc3732f7f59451dbf7 Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Sun, 17 Nov 2024 06:24:14 -0300 Subject: [PATCH 01/10] feat: Creating the project "ShareBook.Test.Integration" --- ShareBook/ShareBook.Api/Startup.cs | 17 ++++++-- .../Setup/ShareBookTestsFixture.cs | 22 ++++++++++ .../Setup/ShareBookWebAppFactory.cs | 40 +++++++++++++++++++ .../ShareBook.Test.Integration.csproj | 31 ++++++++++++++ ShareBook/ShareBook.sln | 12 ++++++ 5 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs create mode 100644 ShareBook/ShareBook.Test.Integration/Setup/ShareBookWebAppFactory.cs create mode 100644 ShareBook/ShareBook.Test.Integration/ShareBook.Test.Integration.csproj diff --git a/ShareBook/ShareBook.Api/Startup.cs b/ShareBook/ShareBook.Api/Startup.cs index 90a2f093..6f572bcf 100644 --- a/ShareBook/ShareBook.Api/Startup.cs +++ b/ShareBook/ShareBook.Api/Startup.cs @@ -29,6 +29,11 @@ namespace ShareBook.Api { public class Startup { + /// + /// Only should be used for integration tests + /// + public static bool IgnoreMigrations = false; + public Startup(IConfiguration configuration) { Configuration = configuration; @@ -164,11 +169,15 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { var scopeServiceProvider = serviceScope.ServiceProvider; var context = serviceScope.ServiceProvider.GetService(); - context.Database.Migrate(); - if (env.IsDevelopment() || env.IsStaging()) + + if (!IgnoreMigrations) { - var sharebookSeeder = new ShareBookSeeder(context); - sharebookSeeder.Seed(); + context.Database.Migrate(); + if (env.IsDevelopment() || env.IsStaging()) + { + var sharebookSeeder = new ShareBookSeeder(context); + sharebookSeeder.Seed(); + } } } } diff --git a/ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs b/ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs new file mode 100644 index 00000000..323f96ad --- /dev/null +++ b/ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.DependencyInjection; +using ShareBook.Repository; + +namespace ShareBook.Test.Integration.Setup; + + +[CollectionDefinition(nameof(ShareBookTestsFixture))] +public class ShareBookTestsFixtureCollection : ICollectionFixture +{ } + +public class ShareBookTestsFixture +{ + public ShareBookWebAppFactory ShareBookWebAppFactory { get; } = new ShareBookWebAppFactory(); + public HttpClient ShareBookApiClient { get; init; } + public ApplicationDbContext ApplicationDbContext { get; init; } + + public ShareBookTestsFixture() + { + ShareBookApiClient = ShareBookWebAppFactory.CreateClient(); + ApplicationDbContext = ShareBookWebAppFactory.Services.GetRequiredService(); + } +} diff --git a/ShareBook/ShareBook.Test.Integration/Setup/ShareBookWebAppFactory.cs b/ShareBook/ShareBook.Test.Integration/Setup/ShareBookWebAppFactory.cs new file mode 100644 index 00000000..c2f4777d --- /dev/null +++ b/ShareBook/ShareBook.Test.Integration/Setup/ShareBookWebAppFactory.cs @@ -0,0 +1,40 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using ShareBook.Api; +using ShareBook.Repository; + +namespace ShareBook.Test.Integration.Setup; + +public class ShareBookWebAppFactory : WebApplicationFactory +{ + protected override IHostBuilder? CreateHostBuilder() + { + return Host.CreateDefaultBuilder() + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } + + protected override void ConfigureWebHost(IWebHostBuilder builder) + { + base.ConfigureWebHost(builder); + Startup.IgnoreMigrations = true; + + builder.ConfigureTestServices(services => + { + var dbOptions = services.FirstOrDefault(x => x.ServiceType == typeof(DbContextOptions)); + if (dbOptions != null) + services.Remove(dbOptions); + + services.AddDbContext(options => + { + options.UseInMemoryDatabase("ShareBookInMemoryDb"); + }); + }); + } +} \ No newline at end of file diff --git a/ShareBook/ShareBook.Test.Integration/ShareBook.Test.Integration.csproj b/ShareBook/ShareBook.Test.Integration/ShareBook.Test.Integration.csproj new file mode 100644 index 00000000..7a1a00c1 --- /dev/null +++ b/ShareBook/ShareBook.Test.Integration/ShareBook.Test.Integration.csproj @@ -0,0 +1,31 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + + + diff --git a/ShareBook/ShareBook.sln b/ShareBook/ShareBook.sln index 90a79562..2a9e056b 100644 --- a/ShareBook/ShareBook.sln +++ b/ShareBook/ShareBook.sln @@ -33,6 +33,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sharebook.Jobs", "Sharebook EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShareBook.Infra.Data", "ShareBook.Repository\ShareBook.Infra.Data.csproj", "{4A07DFF3-3909-4081-8495-714179019A08}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6728E7E5-0D94-4795-9B03-7E6374A19CB8}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShareBook.Test.Integration", "ShareBook.Test.Integration\ShareBook.Test.Integration.csproj", "{51D010F3-DE4C-467E-A35C-19A91768B6A9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,6 +78,10 @@ Global {4A07DFF3-3909-4081-8495-714179019A08}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A07DFF3-3909-4081-8495-714179019A08}.Release|Any CPU.ActiveCfg = Release|Any CPU {4A07DFF3-3909-4081-8495-714179019A08}.Release|Any CPU.Build.0 = Release|Any CPU + {51D010F3-DE4C-467E-A35C-19A91768B6A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51D010F3-DE4C-467E-A35C-19A91768B6A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51D010F3-DE4C-467E-A35C-19A91768B6A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51D010F3-DE4C-467E-A35C-19A91768B6A9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -84,6 +95,7 @@ Global {F51F1D75-DC21-4B49-AE98-8E1292311D2B} = {F4693E98-387E-4804-A818-FEC59FEDD41C} {E59DF563-5B90-479E-9E08-FA99442EEE13} = {CC695E9A-927F-4BCA-B43F-1DD488258B6D} {4A07DFF3-3909-4081-8495-714179019A08} = {F4693E98-387E-4804-A818-FEC59FEDD41C} + {51D010F3-DE4C-467E-A35C-19A91768B6A9} = {4DC3351F-0B20-4D5E-8727-3730DF7A9B88} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FF5BA500-51EA-4DD9-8523-8EE368731B63} From 68252438eb2e5c1b454914511df04db25a7d826b Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Sun, 17 Nov 2024 06:26:30 -0300 Subject: [PATCH 02/10] test: Integration => Adding first Meetups test "AvailableBooks_Empty" --- .../Tests/MeetupTests/MeetupTests.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs diff --git a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs new file mode 100644 index 00000000..0e783225 --- /dev/null +++ b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs @@ -0,0 +1,27 @@ +using FluentAssertions; +using ShareBook.Test.Integration.Setup; +using System.Net; + +namespace ShareBook.Test.Integration.Tests.MeetupTests; + +[Collection(nameof(ShareBookTestsFixture))] +public class MeetupTests +{ + private readonly ShareBookTestsFixture _fixture; + + public MeetupTests(ShareBookTestsFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public async Task AvailableBooks_Empty() + { + var response = await _fixture.ShareBookApiClient.GetAsync("api/book/AvailableBooks"); + + response.Should().NotBeNull(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + string responseAsString = await response.Content.ReadAsStringAsync(); + responseAsString.Should().Be("[]"); + } +} From db43bf31f4d5f6d0550f2511d6c73c7cab8669e8 Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Sun, 17 Nov 2024 06:46:47 -0300 Subject: [PATCH 03/10] test: ShareBook.Test.Integration => Adding the first test for Books ("AvailableBooks_Empty") --- .../GlobalUsings.cs | 2 ++ .../Tests/BookTests/BookTests.cs | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 ShareBook/ShareBook.Test.Integration/GlobalUsings.cs create mode 100644 ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs diff --git a/ShareBook/ShareBook.Test.Integration/GlobalUsings.cs b/ShareBook/ShareBook.Test.Integration/GlobalUsings.cs new file mode 100644 index 00000000..5f70f455 --- /dev/null +++ b/ShareBook/ShareBook.Test.Integration/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using FluentAssertions; +global using ShareBook.Test.Integration.Setup; \ No newline at end of file diff --git a/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs new file mode 100644 index 00000000..a14997f0 --- /dev/null +++ b/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs @@ -0,0 +1,25 @@ +using System.Net; + +namespace ShareBook.Test.Integration.Tests.BookTests; + +[Collection(nameof(ShareBookTestsFixture))] +public class BookTests +{ + private readonly ShareBookTestsFixture _fixture; + + public BookTests(ShareBookTestsFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public async Task AvailableBooks_Empty() + { + var response = await _fixture.ShareBookApiClient.GetAsync("api/book/AvailableBooks"); + + response.Should().NotBeNull(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + string responseAsString = await response.Content.ReadAsStringAsync(); + responseAsString.Should().Be("[]"); + } +} From 8cf3b15ff5962289336e28a42cde0268fca56bd3 Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Mon, 18 Nov 2024 07:41:07 -0300 Subject: [PATCH 04/10] test: Integration => Seeding data before run tests --- .../Setup/ShareBookTestsFixture.cs | 4 ++++ .../Tests/BookTests/BookTests.cs | 10 ++++++++-- .../Tests/MeetupTests/MeetupTests.cs | 15 ++++++++++----- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs b/ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs index 323f96ad..8498719c 100644 --- a/ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs +++ b/ShareBook/ShareBook.Test.Integration/Setup/ShareBookTestsFixture.cs @@ -18,5 +18,9 @@ public ShareBookTestsFixture() { ShareBookApiClient = ShareBookWebAppFactory.CreateClient(); ApplicationDbContext = ShareBookWebAppFactory.Services.GetRequiredService(); + + // Seed data + var sharebookSeeder = new ShareBookSeeder(ApplicationDbContext); + sharebookSeeder.Seed(); } } diff --git a/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs index a14997f0..b4b3f272 100644 --- a/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs +++ b/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs @@ -1,4 +1,6 @@ using System.Net; +using System.Text.Json; +using ShareBook.Api.ViewModels; namespace ShareBook.Test.Integration.Tests.BookTests; @@ -13,13 +15,17 @@ public BookTests(ShareBookTestsFixture fixture) } [Fact] - public async Task AvailableBooks_Empty() + public async Task AvailableBooks_All() { var response = await _fixture.ShareBookApiClient.GetAsync("api/book/AvailableBooks"); response.Should().NotBeNull(); response.StatusCode.Should().Be(HttpStatusCode.OK); string responseAsString = await response.Content.ReadAsStringAsync(); - responseAsString.Should().Be("[]"); + responseAsString.Should().NotBeNullOrWhiteSpace(); + List? books = JsonSerializer.Deserialize>(responseAsString); + books.Should().NotBeNullOrEmpty(); + books!.Count.Should().Be(22); + // TODO: Validate all items have title, author and so on } } diff --git a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs index 0e783225..707434f2 100644 --- a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs +++ b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs @@ -1,6 +1,7 @@ -using FluentAssertions; -using ShareBook.Test.Integration.Setup; using System.Net; +using System.Text.Json; +using ShareBook.Domain; +using ShareBook.Domain.Common; namespace ShareBook.Test.Integration.Tests.MeetupTests; @@ -15,13 +16,17 @@ public MeetupTests(ShareBookTestsFixture fixture) } [Fact] - public async Task AvailableBooks_Empty() + public async Task MeetupList_Empty() { - var response = await _fixture.ShareBookApiClient.GetAsync("api/book/AvailableBooks"); + var response = await _fixture.ShareBookApiClient.GetAsync("api/Meetup"); response.Should().NotBeNull(); response.StatusCode.Should().Be(HttpStatusCode.OK); string responseAsString = await response.Content.ReadAsStringAsync(); - responseAsString.Should().Be("[]"); + responseAsString.Should().NotBeNullOrWhiteSpace(); + PagedList? meetups = JsonSerializer.Deserialize>(responseAsString); + meetups.Should().NotBeNull(); + meetups!.Page.Should().Be(0); + meetups!.Items.Should().BeNull(); } } From e29cacbba53d831f761d332504be4e83cd11ab36 Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Mon, 18 Nov 2024 08:04:45 -0300 Subject: [PATCH 05/10] test: Integration => Turning MeetupTests as theory with different paginations --- .../Tests/MeetupTests/MeetupTests.cs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs index 707434f2..7498633a 100644 --- a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs +++ b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs @@ -1,5 +1,5 @@ using System.Net; -using System.Text.Json; +using Newtonsoft.Json; using ShareBook.Domain; using ShareBook.Domain.Common; @@ -15,18 +15,27 @@ public MeetupTests(ShareBookTestsFixture fixture) _fixture = fixture; } - [Fact] - public async Task MeetupList_Empty() + [Theory] + [InlineData(1, 1, 1)] + [InlineData(1, 10, 8)] + [InlineData(2, 10, 0)] + [InlineData(2, 5, 3)] + [InlineData(3, 3, 2)] + public async Task MeetupList(int page, int pageSize, int expectedQuantity) { - var response = await _fixture.ShareBookApiClient.GetAsync("api/Meetup"); + // TODO: Add tests for upcoming=true + var response = await _fixture.ShareBookApiClient.GetAsync($"api/Meetup?page={page}&pageSize={pageSize}"); response.Should().NotBeNull(); response.StatusCode.Should().Be(HttpStatusCode.OK); string responseAsString = await response.Content.ReadAsStringAsync(); responseAsString.Should().NotBeNullOrWhiteSpace(); - PagedList? meetups = JsonSerializer.Deserialize>(responseAsString); + PagedList? meetups = JsonConvert.DeserializeObject>(responseAsString); meetups.Should().NotBeNull(); - meetups!.Page.Should().Be(0); - meetups!.Items.Should().BeNull(); + meetups!.Page.Should().Be(page); + meetups!.ItemsPerPage.Should().Be(pageSize); + meetups!.Items.Should().HaveCount(expectedQuantity); + // TODO: Validate all items have title, url and so on + meetups!.TotalItems.Should().Be(8); } } From d81e820de08ef96bbe7d0cfc30184173b2e247ff Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Mon, 18 Nov 2024 08:14:37 -0300 Subject: [PATCH 06/10] test: Integration/meetupTests => Adding tests for upcoming=true --- .../ShareBook.Repository/ShareBookSeeder.cs | 15 ++++++++-- .../Tests/MeetupTests/MeetupTests.cs | 28 ++++++++++++------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ShareBook/ShareBook.Repository/ShareBookSeeder.cs b/ShareBook/ShareBook.Repository/ShareBookSeeder.cs index 1412f19c..0ba5c14b 100644 --- a/ShareBook/ShareBook.Repository/ShareBookSeeder.cs +++ b/ShareBook/ShareBook.Repository/ShareBookSeeder.cs @@ -583,7 +583,7 @@ public void Seed() StartDate = DateTime.Parse("2022-09-07T19:00:00"), Cover = "https://www.sharebook.com.br/Images/Meetup/desenvolvimento-de-software-sustentavel.png", YoutubeUrl = null, - SymplaEventUrl = "https://www.sympla.com.br/desenvolvimento-de-software-sustentavel__1709335" + SymplaEventUrl = "https://www.sympla.com.br/desenvolvimento-de-software-sustentavel__1709335", }; var meetup8 = new Meetup() @@ -597,6 +597,17 @@ public void Seed() SymplaEventUrl = "https://www.sympla.com.br/java-spring-boot---criando-uma-api-crud-do-zero---2-de-2__1706178" }; + var meetup9 = new Meetup() + { + SymplaEventId = 2432671, + Title = "GITHUB ACTIONS NA PRÁTICA", + Description = "
O GitHub Actions é uma ferramenta poderosa para automação de fluxos de trabalho de desenvolvimento. Ao permitir que você defina e execute uma série de ações baseadas em eventos específicos do GitHub, como push, pull request ou issues, ele simplifica tarefas complexas, desde a integração contínua até a implantação contínua. Com sua flexibilidade e capacidade de personalização, o GitHub Actions capacita os desenvolvedores a otimizarem seus processos de desenvolvimento, melhorando a qualidade do código, reduzindo erros e aumentando a eficiência geral do projeto. Em um mundo onde cada segundo conta, o GitHub Actions se torna um aliado indispensável na busca pela excelência técnica.

Palestrante: Renan Barbosa
Host: Raffaello Damgaard

Nossa live será transmitida ao vivo via You Tube:
", + StartDate = DateTime.Now.AddDays(7), // Upcoming = true + Cover = "https://www.sharebook.com.br/Images/Meetup/github-actions-na-pratica.png", + YoutubeUrl = "https://www.sharebook.com.br/Images/Meetup/github-actions-na-pratica.png", + SymplaEventUrl = "https://www.sympla.com.br/java-spring-boot---criando-uma-api-crud-do-zero---2-de-2__1706178" + }; + _context.Categories.AddRange(adm, dir, psico, med, eng, geo_his, cien, art); _context.Users.AddRange(grantee, @operator, raffa); _context.Books.AddRange(book1, book2, book3, book4, book5, book6, book7, @@ -604,7 +615,7 @@ public void Seed() book16, book18, book19, book20, book21, book22, book23); _context.BookUser.Add(request); - _context.Meetups.AddRange(meetup1, meetup2, meetup3, meetup4, meetup5, meetup6, meetup7, meetup8); + _context.Meetups.AddRange(meetup1, meetup2, meetup3, meetup4, meetup5, meetup6, meetup7, meetup8, meetup9); _context.SaveChanges(); } diff --git a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs index 7498633a..2b4fdcb4 100644 --- a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs +++ b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs @@ -16,15 +16,16 @@ public MeetupTests(ShareBookTestsFixture fixture) } [Theory] - [InlineData(1, 1, 1)] - [InlineData(1, 10, 8)] - [InlineData(2, 10, 0)] - [InlineData(2, 5, 3)] - [InlineData(3, 3, 2)] - public async Task MeetupList(int page, int pageSize, int expectedQuantity) + [InlineData(1, 1, false, 1)] + [InlineData(1, 10, false, 8)] + [InlineData(2, 10, false, 0)] + [InlineData(2, 5, false, 3)] + [InlineData(3, 3, false, 2)] + [InlineData(1, 5, true, 1)] + [InlineData(2, 5, true, 0)] + public async Task MeetupList(int page, int pageSize, bool upcoming, int expectedQuantity) { - // TODO: Add tests for upcoming=true - var response = await _fixture.ShareBookApiClient.GetAsync($"api/Meetup?page={page}&pageSize={pageSize}"); + var response = await _fixture.ShareBookApiClient.GetAsync($"api/Meetup?page={page}&pageSize={pageSize}&upcoming={upcoming}"); response.Should().NotBeNull(); response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -35,7 +36,14 @@ public async Task MeetupList(int page, int pageSize, int expectedQuantity) meetups!.Page.Should().Be(page); meetups!.ItemsPerPage.Should().Be(pageSize); meetups!.Items.Should().HaveCount(expectedQuantity); - // TODO: Validate all items have title, url and so on - meetups!.TotalItems.Should().Be(8); + meetups!.TotalItems.Should().Be(upcoming ? 1 : 8); + + meetups!.Items.Where(i => + string.IsNullOrWhiteSpace(i.Title) + || string.IsNullOrWhiteSpace(i.Description) + || string.IsNullOrWhiteSpace(i.Cover) + || i.StartDate == default + ).Should().BeEmpty(); + } } From 8373f8c65365845a7e1e134ef749301c4c741e69 Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Wed, 11 Dec 2024 06:15:15 -0300 Subject: [PATCH 07/10] docs: Adding docker command to run SQL Server as docker container on README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 28833056..7ce848f0 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,9 @@ dotnet restore ./ShareBook/ShareBook.sln # build dotnet build ./ShareBook/ShareBook.Api/ShareBook.Api.csproj --verbosity minimal +# Spinning up database (needs docker) +docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=weWkh]6qA3jk" -p 1433:1433 --name=sql-server --hostname=sql-server -d mcr.microsoft.com/mssql/server:2022-latest + # rodar o app com hot reload dotnet watch --project ./ShareBook/ShareBook.Api/ShareBook.Api.csproj From fa60269bd3170cbec5aff99ea449ee12560d87c5 Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Tue, 17 Dec 2024 20:56:42 -0300 Subject: [PATCH 08/10] test: Adding validations to all integration tests --- .../Tests/BookTests/BookTests.cs | 12 +++++++++--- .../Tests/MeetupTests/MeetupTests.cs | 12 ++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs index b4b3f272..9834a084 100644 --- a/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs +++ b/ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs @@ -1,5 +1,5 @@ using System.Net; -using System.Text.Json; +using Newtonsoft.Json; using ShareBook.Api.ViewModels; namespace ShareBook.Test.Integration.Tests.BookTests; @@ -23,9 +23,15 @@ public async Task AvailableBooks_All() response.StatusCode.Should().Be(HttpStatusCode.OK); string responseAsString = await response.Content.ReadAsStringAsync(); responseAsString.Should().NotBeNullOrWhiteSpace(); - List? books = JsonSerializer.Deserialize>(responseAsString); + IList? books = JsonConvert.DeserializeObject>(responseAsString); books.Should().NotBeNullOrEmpty(); books!.Count.Should().Be(22); - // TODO: Validate all items have title, author and so on + + books!.All(i => + !string.IsNullOrWhiteSpace(i.Title) + && !string.IsNullOrWhiteSpace(i.Author) + && !string.IsNullOrWhiteSpace(i.Slug) + && i.CategoryId != default + ).Should().BeTrue(); } } diff --git a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs index 2b4fdcb4..51f5c36f 100644 --- a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs +++ b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs @@ -38,12 +38,12 @@ public async Task MeetupList(int page, int pageSize, bool upcoming, int expected meetups!.Items.Should().HaveCount(expectedQuantity); meetups!.TotalItems.Should().Be(upcoming ? 1 : 8); - meetups!.Items.Where(i => - string.IsNullOrWhiteSpace(i.Title) - || string.IsNullOrWhiteSpace(i.Description) - || string.IsNullOrWhiteSpace(i.Cover) - || i.StartDate == default - ).Should().BeEmpty(); + meetups!.Items.All(i => + !string.IsNullOrWhiteSpace(i.Title) + && !string.IsNullOrWhiteSpace(i.Description) + && !string.IsNullOrWhiteSpace(i.Cover) + && i.StartDate != default + ).Should().BeTrue(); } } From 1804b19adfd41c15de855db042e19c0b0100e05c Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Tue, 17 Dec 2024 21:14:18 -0300 Subject: [PATCH 09/10] test: Adding integration test to api/category --- .../Tests/CategoryTests/CategoryTests.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 ShareBook/ShareBook.Test.Integration/Tests/CategoryTests/CategoryTests.cs diff --git a/ShareBook/ShareBook.Test.Integration/Tests/CategoryTests/CategoryTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/CategoryTests/CategoryTests.cs new file mode 100644 index 00000000..fdb149d9 --- /dev/null +++ b/ShareBook/ShareBook.Test.Integration/Tests/CategoryTests/CategoryTests.cs @@ -0,0 +1,39 @@ +using Newtonsoft.Json; +using ShareBook.Domain; +using ShareBook.Domain.Common; +using System.Net; + +namespace ShareBook.Test.Integration.Tests.CategoryTests; + +[Collection(nameof(ShareBookTestsFixture))] +public class CategoryTests +{ + private readonly ShareBookTestsFixture _fixture; + + public CategoryTests(ShareBookTestsFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public async Task GetCategories() + { + var response = await _fixture.ShareBookApiClient.GetAsync("api/category"); + + response.Should().NotBeNull(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + string responseAsString = await response.Content.ReadAsStringAsync(); + responseAsString.Should().NotBeNullOrWhiteSpace(); + PagedList? categories = JsonConvert.DeserializeObject>(responseAsString); + categories.Should().NotBeNull(); + categories!.Items.Should().NotBeNull(); + categories.Items.Count.Should().Be(10); + categories.ItemsPerPage.Should().Be(50); + categories.Page.Should().Be(1); + + categories.Items.All(i => + !string.IsNullOrWhiteSpace(i.Name) + && i.Id != default + ).Should().BeTrue(); + } +} From 8a8c9ac8cadc85fa3ac93c0c33215018597a5755 Mon Sep 17 00:00:00 2001 From: Henrique Holtz Date: Tue, 17 Dec 2024 21:21:14 -0300 Subject: [PATCH 10/10] test: Adding integration test to "api/Meetup/search?criteria={criteria}" (3x) --- .../Tests/MeetupTests/MeetupTests.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs index 51f5c36f..0b8a856e 100644 --- a/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs +++ b/ShareBook/ShareBook.Test.Integration/Tests/MeetupTests/MeetupTests.cs @@ -44,6 +44,30 @@ public async Task MeetupList(int page, int pageSize, bool upcoming, int expected && !string.IsNullOrWhiteSpace(i.Cover) && i.StartDate != default ).Should().BeTrue(); + } + + [Theory] + [InlineData("Qualidade de vida", 1)] + [InlineData("Azure", 2)] + [InlineData("invalid-nonexist", 0)] + public async Task MeetupSearch(string criteria, int totalExpected) + { + var response = await _fixture.ShareBookApiClient.GetAsync($"api/Meetup/search?criteria={criteria}"); + response.Should().NotBeNull(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + string responseAsString = await response.Content.ReadAsStringAsync(); + responseAsString.Should().NotBeNullOrWhiteSpace(); + IList? meetups = JsonConvert.DeserializeObject>(responseAsString); + meetups.Should().NotBeNull(); + meetups!.Count.Should().Be(totalExpected); + + meetups!.All(i => + !string.IsNullOrWhiteSpace(i.Title) + && i.Title.Contains(criteria, StringComparison.InvariantCultureIgnoreCase) + && !string.IsNullOrWhiteSpace(i.Description) + && !string.IsNullOrWhiteSpace(i.Cover) + && i.StartDate != default + ).Should().BeTrue(); } }