Skip to content

Commit

Permalink
experiment
Browse files Browse the repository at this point in the history
  • Loading branch information
skrasekmichael committed Mar 11, 2024
1 parent 2ba9889 commit 7f94364
Show file tree
Hide file tree
Showing 33 changed files with 107 additions and 83 deletions.
22 changes: 11 additions & 11 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,30 @@
<PackageVersion Include="FluentAssertions.Web" Version="1.2.5" />
<PackageVersion Include="FluentValidation" Version="11.9.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.0" />
<PackageVersion Include="MailKit" Version="4.3.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" />
<PackageVersion Include="MailKit" Version="4.4.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.2" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Identity.Stores" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Identity.Stores" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
<PackageVersion Include="Microsoft.IdentityModel.Tokens" Version="7.3.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="MediatR" Version="12.2.0" />
<PackageVersion Include="NetArchTest.Rules" Version="1.3.2" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
<PackageVersion Include="Quartz" Version="3.8.0" />
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.8.0" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
<PackageVersion Include="Quartz" Version="3.8.1" />
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.8.1" />
<PackageVersion Include="Respawn" Version="6.2.1" />
<PackageVersion Include="Riok.Mapperly" Version="3.3.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="7.3.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="7.4.0" />
<PackageVersion Include="Testcontainers" Version="3.7.0" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="3.7.0" />
<PackageVersion Include="xunit" Version="2.6.6" />
Expand Down
3 changes: 3 additions & 0 deletions src/TeamUp.Infrastructure/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("TeamUp.Tests.EndToEnd")]
2 changes: 2 additions & 0 deletions src/TeamUp.Infrastructure/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi
services.AddQuartzHostedService(options =>
{
options.WaitForJobsToComplete = true;
options.AwaitApplicationStarted = true;
options.StartDelay = TimeSpan.FromMilliseconds(500);
});
services.AddQuartz(configurator =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

using Npgsql;

using Respawn;
using Respawn.Graph;

using TeamUp.Common.Abstractions;
using TeamUp.Infrastructure.Processing.Outbox;
Expand All @@ -18,9 +20,9 @@
namespace TeamUp.Tests.EndToEnd;

[CollectionDefinition(nameof(AppCollectionFixture))]
public sealed class AppCollectionFixture : ICollectionFixture<EndpointTestsWebAppFactory>;
public sealed class AppCollectionFixture : ICollectionFixture<AppFixture>;

public sealed class EndpointTestsWebAppFactory : WebApplicationFactory<Program>, IAsyncLifetime
public sealed class AppFixture : IAsyncLifetime
{
private readonly PostgreSqlContainer _dbContainer = new PostgreSqlBuilder()
.WithDatabase("POSTGRES")
Expand All @@ -30,11 +32,15 @@ public sealed class EndpointTestsWebAppFactory : WebApplicationFactory<Program>,
.WithCleanUp(true)
.Build();

public const string HTTPS_PORT = "8181";
private Factory Fact { get; set; } = null!;
private Respawner Respawner { get; set; } = null!;

public string HttpsPort => Factory.HttpsPort;
public string ConnectionString => _dbContainer.GetConnectionString();

public Respawner Respawner { get; private set; } = null!;
public IServiceProvider Services => Fact.Services;

public EndpointTestsWebAppFactory()
public AppFixture()
{
Randomizer.Seed = new Random(420_069);
Faker.DefaultStrictMode = true;
Expand All @@ -44,24 +50,56 @@ public async Task InitializeAsync()
{
await _dbContainer.StartAsync();

await using var scope = Services.CreateAsyncScope();
using var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseNpgsql(ConnectionString)
.Options;

var logger = scope.ServiceProvider.GetRequiredService<ILogger<EndpointTestsWebAppFactory>>();
logger.LogCritical("Start migrating, pending count {pendingCount}", dbContext.Database.GetPendingMigrations().Count());
await using var dbContext = new ApplicationDbContext(options);

await dbContext.Database.MigrateAsync();
var pending = await dbContext.Database.GetPendingMigrationsAsync();
Console.WriteLine(" --- start migrating, pending count {0}", pending.Count());

await using (var transaction = dbContext.Database.BeginTransaction())
{
await dbContext.Database.MigrateAsync();
await transaction.CommitAsync();
}

logger.LogCritical("Migrations Applied, pending count {pendingCount}", dbContext.Database.GetPendingMigrations().Count());
pending = await dbContext.Database.GetPendingMigrationsAsync();
Console.WriteLine(" --- migrations applied, pending count {0}", pending.Count());

await using var connection = dbContext.Database.GetDbConnection();
await connection.OpenAsync();

Respawner = await Respawner.CreateAsync(connection, new()
{
DbAdapter = DbAdapter.Postgres
DbAdapter = DbAdapter.Postgres,
TablesToIgnore = [new Table("public", "__EFMigrationsHistory")]
});

Fact = new Factory(ConnectionString);
}

public async Task DisposeAsync()
{
await Fact.DisposeAsync();
await _dbContainer.DisposeAsync();
}

public HttpClient CreateClient() => Fact.CreateClient();
public HttpClient CreateClient(WebApplicationFactoryClientOptions options) => Fact.CreateClient(options);

public async Task ResetDatabaseAsync()
{
await using var connection = new NpgsqlConnection(ConnectionString);
await connection.OpenAsync();
await Respawner.ResetAsync(connection);
}
}

public sealed class Factory(string connectionString) : WebApplicationFactory<Program>
{
public static string HttpsPort => "8181";

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
Expand All @@ -73,7 +111,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
services.RemoveAll<ApplicationDbContext>();
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseNpgsql(ConnectionString);
options.UseNpgsql(connectionString);
});

//email
Expand All @@ -89,10 +127,6 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
});

builder.UseEnvironment(Environments.Production);
builder.UseSetting("https_port", HTTPS_PORT);
builder.UseSetting("https_port", HttpsPort);
}

public new Task DisposeAsync() => _dbContainer.DisposeAsync().AsTask();

public string ConnectionString => _dbContainer.GetConnectionString();
}
12 changes: 4 additions & 8 deletions tests/TeamUp.Tests.EndToEnd/EndpointTests/BaseEndpointTests.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
using System.Net.Http.Headers;

using Npgsql;

using TeamUp.Application.Users;
using TeamUp.Common.Abstractions;
using TeamUp.Tests.EndToEnd.Mocks;

namespace TeamUp.Tests.EndToEnd.EndpointTests;

[Collection(nameof(AppCollectionFixture))]
public abstract class BaseEndpointTests(EndpointTestsWebAppFactory app) : IAsyncLifetime
public abstract class BaseEndpointTests(AppFixture app) : IAsyncLifetime
{
protected static Faker F => FakerExtensions.F;

protected EndpointTestsWebAppFactory App { get; } = app;
protected AppFixture App { get; } = app;
protected HttpClient Client { get; private set; } = null!;
internal MailInbox Inbox { get; private set; } = null!;
internal BackgroundCallback BackgroundCallback { get; private set; } = null!;
Expand All @@ -22,12 +20,10 @@ public abstract class BaseEndpointTests(EndpointTestsWebAppFactory app) : IAsync

public async Task InitializeAsync()
{
await using var connection = new NpgsqlConnection(App.ConnectionString);
await connection.OpenAsync();
await App.Respawner.ResetAsync(connection);
await App.ResetDatabaseAsync();

Client = App.CreateClient();
Client.BaseAddress = new Uri($"https://{Client.BaseAddress?.Host}:{EndpointTestsWebAppFactory.HTTPS_PORT}");
Client.BaseAddress = new Uri($"https://{Client.BaseAddress?.Host}:{App.HttpsPort}");

Inbox = App.Services.GetRequiredService<MailInbox>();
BackgroundCallback = App.Services.GetRequiredService<OutboxBackgroundCallback>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Events;

public sealed class CreateEventTests(EndpointTestsWebAppFactory app) : EventTests(app)
public sealed class CreateEventTests(AppFixture app) : EventTests(app)
{
public static string GetUrl(TeamId teamId) => GetUrl(teamId.Value);
public static string GetUrl(Guid teamId) => $"/api/v1/teams/{teamId}/events";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TeamUp.Tests.EndToEnd.EndpointTests.Events;

public sealed class GetEventTests(EndpointTestsWebAppFactory app) : EventTests(app)
public sealed class GetEventTests(AppFixture app) : EventTests(app)
{
public static string GetUrl(TeamId teamId, EventId eventId) => GetUrl(teamId.Value, eventId.Value);
public static string GetUrl(Guid teamId, Guid eventId) => $"/api/v1/teams/{teamId}/events/{eventId}";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Events;

public sealed class GetEventsTests(EndpointTestsWebAppFactory app) : EventTests(app)
public sealed class GetEventsTests(AppFixture app) : EventTests(app)
{
public static string GetUrl(TeamId teamId, DateTime? from) => GetUrl(teamId.Value, from);
public static string GetUrl(Guid teamId, DateTime? from) => from switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace TeamUp.Tests.EndToEnd.EndpointTests.Events;

public sealed class UpsertEventReplyTests(EndpointTestsWebAppFactory app) : EventTests(app)
public sealed class UpsertEventReplyTests(AppFixture app) : EventTests(app)
{
public static string GetUrl(TeamId teamId, EventId eventId) => GetUrl(teamId.Value, eventId.Value);
public static string GetUrl(Guid teamId, Guid eventId) => $"/api/v1/teams/{teamId}/events/{eventId}";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Events;

public abstract class EventTests(EndpointTestsWebAppFactory app) : BaseEndpointTests(app)
public abstract class EventTests(AppFixture app) : BaseEndpointTests(app)
{
protected static bool ResponseHasCorrectReply(EventResponseResponse err, Event @event)
{
Expand Down
16 changes: 6 additions & 10 deletions tests/TeamUp.Tests.EndToEnd/EndpointTests/HttpsRedirectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,24 @@

using Microsoft.AspNetCore.Mvc.Testing;

using Npgsql;

using TeamUp.Application.Users;

namespace TeamUp.Tests.EndToEnd.EndpointTests;

[Collection(nameof(AppCollectionFixture))]
public sealed class HttpsRedirectionTests(EndpointTestsWebAppFactory app) : IAsyncLifetime
public sealed class HttpsRedirectionTests(AppFixture app) : IAsyncLifetime
{
private EndpointTestsWebAppFactory App { get; } = app;
private AppFixture App { get; } = app;
private HttpClient Client { get; set; } = null!;

public async Task InitializeAsync()
public Task InitializeAsync()
{
await using var connection = new NpgsqlConnection(App.ConnectionString);
await connection.OpenAsync();
await App.Respawner.ResetAsync(connection);

Client = App.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});

return Task.CompletedTask;
}

private void Authenticate(User user)
Expand All @@ -38,7 +34,7 @@ private void Authenticate(User user)
public async Task HttpRequest_ToHealthCheckEndpoint_Should_RedirectToHttps()
{
//arrange
var expectedLocation = $"https://{Client.BaseAddress?.Host}:{EndpointTestsWebAppFactory.HTTPS_PORT}/_health";
var expectedLocation = $"https://{Client.BaseAddress?.Host}:{App.HttpsPort}/_health";

//act
var response = await Client.GetAsync("/_health");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TeamUp.Tests.EndToEnd.EndpointTests.Invitations;

public sealed class AcceptInvitationTests(EndpointTestsWebAppFactory app) : InvitationTests(app)
public sealed class AcceptInvitationTests(AppFixture app) : InvitationTests(app)
{
public static string GetUrl(InvitationId invitationId) => GetUrl(invitationId.Value);
public static string GetUrl(Guid invitationId) => $"/api/v1/invitations/{invitationId}/accept";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Invitations;

public sealed class GetMyInvitationsTests(EndpointTestsWebAppFactory app) : InvitationTests(app)
public sealed class GetMyInvitationsTests(AppFixture app) : InvitationTests(app)
{
public const string URL = "/api/v1/invitations";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Invitations;

public sealed class GetTeamInvitationsTests(EndpointTestsWebAppFactory app) : InvitationTests(app)
public sealed class GetTeamInvitationsTests(AppFixture app) : InvitationTests(app)
{
public static string GetUrl(TeamId teamId) => GetUrl(teamId.Value);
public static string GetUrl(Guid teamId) => $"/api/v1/invitations/teams/{teamId}";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Invitations;

public sealed class InviteUserTests(EndpointTestsWebAppFactory app) : InvitationTests(app)
public sealed class InviteUserTests(AppFixture app) : InvitationTests(app)
{
public const string URL = "/api/v1/invitations";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Invitations;

public sealed class RemoveInvitationTests(EndpointTestsWebAppFactory app) : InvitationTests(app)
public sealed class RemoveInvitationTests(AppFixture app) : InvitationTests(app)
{
public static string GetUrl(InvitationId invitationId) => GetUrl(invitationId.Value);
public static string GetUrl(Guid invitationId) => $"/api/v1/invitations/{invitationId}";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Invitations;

public abstract class InvitationTests(EndpointTestsWebAppFactory app) : BaseEndpointTests(app);
public abstract class InvitationTests(AppFixture app) : BaseEndpointTests(app);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TeamUp.Tests.EndToEnd.EndpointTests.Teams;

public sealed class ChangeNicknameTests(EndpointTestsWebAppFactory app) : TeamTests(app)
public sealed class ChangeNicknameTests(AppFixture app) : TeamTests(app)
{
public static string GetUrl(TeamId teamId) => GetUrl(teamId.Value);
public static string GetUrl(Guid teamId) => $"/api/v1/teams/{teamId}/nickname";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TeamUp.Tests.EndToEnd.EndpointTests.Teams;

public sealed class ChangeOwnershipTests(EndpointTestsWebAppFactory app) : TeamTests(app)
public sealed class ChangeOwnershipTests(AppFixture app) : TeamTests(app)
{
public static string GetUrl(TeamId teamId) => GetUrl(teamId.Value);
public static string GetUrl(Guid teamId) => $"/api/v1/teams/{teamId}/owner";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TeamUp.Tests.EndToEnd.EndpointTests.Teams;

public sealed class CreateEventTypeTests(EndpointTestsWebAppFactory app) : TeamTests(app)
public sealed class CreateEventTypeTests(AppFixture app) : TeamTests(app)
{
public static string GetUrl(TeamId teamId) => GetUrl(teamId.Value);
public static string GetUrl(Guid teamId) => $"/api/v1/teams/{teamId}/event-types";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TeamUp.Tests.EndToEnd.EndpointTests.Teams;

public sealed class CreateTeamTests(EndpointTestsWebAppFactory app) : TeamTests(app)
public sealed class CreateTeamTests(AppFixture app) : TeamTests(app)
{
public const string URL = "/api/v1/teams";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace TeamUp.Tests.EndToEnd.EndpointTests.Teams;

public sealed class DeleteTeamTests(EndpointTestsWebAppFactory app) : TeamTests(app)
public sealed class DeleteTeamTests(AppFixture app) : TeamTests(app)
{
public static string GetUrl(TeamId teamId) => GetUrl(teamId.Value);
public static string GetUrl(Guid teamId) => $"/api/v1/teams/{teamId}";
Expand Down
Loading

0 comments on commit 7f94364

Please # to comment.