Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating first few integration tests #571

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 13 additions & 4 deletions ShareBook/ShareBook.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ namespace ShareBook.Api
{
public class Startup
{
/// <summary>
/// Only should be used for integration tests
/// </summary>
public static bool IgnoreMigrations = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pode falar um pouco desse cara? Em que contexto ele fica true?


public Startup(IConfiguration configuration)
{
Configuration = configuration;
Expand Down Expand Up @@ -164,11 +169,15 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var scopeServiceProvider = serviceScope.ServiceProvider;
var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
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();
}
}
}
}
Expand Down
15 changes: 13 additions & 2 deletions ShareBook/ShareBook.Repository/ShareBookSeeder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -597,14 +597,25 @@ 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 = "<div>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.</div><div><br></div><div><b>Palestrante</b>: Renan Barbosa</div><div><b>Host</b>: Raffaello Damgaard</div><div><br></div><div><b>Nossa live será transmitida ao vivo via You Tube</b>:</div><div><a href=\"https://www.youtube.com/watch?v=2d7PchqkRVQ\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://www.youtube.com/watch?v=2d7PchqkRVQ</a><br></div>",
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,
book8, book9, book10, book11, book12, book13, book14, book15, book16,
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();
}
Expand Down
2 changes: 2 additions & 0 deletions ShareBook/ShareBook.Test.Integration/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
global using FluentAssertions;
global using ShareBook.Test.Integration.Setup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using ShareBook.Repository;

namespace ShareBook.Test.Integration.Setup;


[CollectionDefinition(nameof(ShareBookTestsFixture))]
public class ShareBookTestsFixtureCollection : ICollectionFixture<ShareBookTestsFixture>
{ }

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<ApplicationDbContext>();

// Seed data
var sharebookSeeder = new ShareBookSeeder(ApplicationDbContext);
sharebookSeeder.Seed();
}
}
Original file line number Diff line number Diff line change
@@ -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<Program>
{
protected override IHostBuilder? CreateHostBuilder()
{
return Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
Startup.IgnoreMigrations = true;

builder.ConfigureTestServices(services =>
{
var dbOptions = services.FirstOrDefault(x => x.ServiceType == typeof(DbContextOptions<ApplicationDbContext>));
if (dbOptions != null)
services.Remove(dbOptions);

services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase("ShareBookInMemoryDb");
});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="FluentAssertions" Version="4.14.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ShareBook.Api\ShareBook.Api.csproj" />
<ProjectReference Include="..\ShareBook.Repository\ShareBook.Infra.Data.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>
37 changes: 37 additions & 0 deletions ShareBook/ShareBook.Test.Integration/Tests/BookTests/BookTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Net;
using Newtonsoft.Json;
using ShareBook.Api.ViewModels;

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_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().NotBeNullOrWhiteSpace();
IList<BookVM>? books = JsonConvert.DeserializeObject<IList<BookVM>>(responseAsString);
books.Should().NotBeNullOrEmpty();
books!.Count.Should().Be(22);

books!.All(i =>
!string.IsNullOrWhiteSpace(i.Title)
&& !string.IsNullOrWhiteSpace(i.Author)
&& !string.IsNullOrWhiteSpace(i.Slug)
&& i.CategoryId != default
).Should().BeTrue();
}
}
Original file line number Diff line number Diff line change
@@ -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<Category>? categories = JsonConvert.DeserializeObject<PagedList<Category>>(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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System.Net;
using Newtonsoft.Json;
using ShareBook.Domain;
using ShareBook.Domain.Common;

namespace ShareBook.Test.Integration.Tests.MeetupTests;

[Collection(nameof(ShareBookTestsFixture))]
public class MeetupTests
{
private readonly ShareBookTestsFixture _fixture;

public MeetupTests(ShareBookTestsFixture fixture)
{
_fixture = fixture;
}

[Theory]
[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)
{
var response = await _fixture.ShareBookApiClient.GetAsync($"api/Meetup?page={page}&pageSize={pageSize}&upcoming={upcoming}");

response.Should().NotBeNull();
response.StatusCode.Should().Be(HttpStatusCode.OK);
string responseAsString = await response.Content.ReadAsStringAsync();
responseAsString.Should().NotBeNullOrWhiteSpace();
PagedList<Meetup>? meetups = JsonConvert.DeserializeObject<PagedList<Meetup>>(responseAsString);
meetups.Should().NotBeNull();
meetups!.Page.Should().Be(page);
meetups!.ItemsPerPage.Should().Be(pageSize);
meetups!.Items.Should().HaveCount(expectedQuantity);
meetups!.TotalItems.Should().Be(upcoming ? 1 : 8);

meetups!.Items.All(i =>
!string.IsNullOrWhiteSpace(i.Title)
&& !string.IsNullOrWhiteSpace(i.Description)
&& !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<Meetup>? meetups = JsonConvert.DeserializeObject<IList<Meetup>>(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();
}
}
7 changes: 7 additions & 0 deletions ShareBook/ShareBook.sln
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.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
Expand Down Expand Up @@ -76,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
Expand All @@ -89,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}
Expand Down
Loading