Small changes

This commit is contained in:
2026-05-29 13:49:49 +02:00
parent b931958b16
commit 48662d6adf
5 changed files with 12 additions and 16 deletions
@@ -38,8 +38,9 @@ public sealed class ApiIntegrationTests(MusifyApiFactory factory)
var get = await _client.GetAsync($"/users/{id}"); var get = await _client.GetAsync($"/users/{id}");
get.StatusCode.Should().Be(HttpStatusCode.OK); get.StatusCode.Should().Be(HttpStatusCode.OK);
var user = await get.Content.ReadFromJsonAsync<UserApplicationResponse>(); UserApplicationResponse user = await get.Content.ReadFromJsonAsync<UserApplicationResponse>()
user!.Id.Should().Be(id); ?? throw new InvalidOperationException("The response body was null.");
user.Id.Should().Be(id);
user.Name.Should().Be("Alice"); user.Name.Should().Be("Alice");
} }
@@ -49,8 +50,9 @@ public sealed class ApiIntegrationTests(MusifyApiFactory factory)
var response = await _client.PostAsJsonAsync("/users/", new CreateUserRequest(Guid.Empty, "", null, null)); var response = await _client.PostAsJsonAsync("/users/", new CreateUserRequest(Guid.Empty, "", null, null));
response.StatusCode.Should().Be(HttpStatusCode.BadRequest); response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var problem = await response.Content.ReadFromJsonAsync<ValidationProblemResponse>(); ValidationProblemResponse problem = await response.Content.ReadFromJsonAsync<ValidationProblemResponse>()
problem!.Errors.Should().ContainKey(nameof(CreateUserRequest.Name)); ?? throw new InvalidOperationException("The response body was null.");
problem.Errors.Should().ContainKey(nameof(CreateUserRequest.Name));
} }
[Fact] [Fact]
@@ -80,8 +82,9 @@ public sealed class ApiIntegrationTests(MusifyApiFactory factory)
new CreatePlayListRequest("My Mix", "A description", null)); new CreatePlayListRequest("My Mix", "A description", null));
response.StatusCode.Should().Be(HttpStatusCode.Created); response.StatusCode.Should().Be(HttpStatusCode.Created);
var playList = await response.Content.ReadFromJsonAsync<PlayListApplicationResponse>(); PlayListApplicationResponse playList = await response.Content.ReadFromJsonAsync<PlayListApplicationResponse>()
playList!.Name.Should().Be("My Mix"); ?? throw new InvalidOperationException("The response body was null.");
playList.Name.Should().Be("My Mix");
var get = await _client.GetAsync($"/playLists/{playList.Id}"); var get = await _client.GetAsync($"/playLists/{playList.Id}");
get.StatusCode.Should().Be(HttpStatusCode.OK); get.StatusCode.Should().Be(HttpStatusCode.OK);
@@ -129,8 +132,9 @@ public sealed class ApiIntegrationTests(MusifyApiFactory factory)
new RequestTrackUploadUrlsRequest("png", "image/png", "mp3", "audio/mpeg")); new RequestTrackUploadUrlsRequest("png", "image/png", "mp3", "audio/mpeg"));
response.StatusCode.Should().Be(HttpStatusCode.OK); response.StatusCode.Should().Be(HttpStatusCode.OK);
var body = await response.Content.ReadFromJsonAsync<TrackUploadUrlsLikeResponse>(); TrackUploadUrlsLikeResponse body = await response.Content.ReadFromJsonAsync<TrackUploadUrlsLikeResponse>()
body!.PictureUploadUrl.Should().Be("https://signed.example/put"); ?? throw new InvalidOperationException("The response body was null.");
body.PictureUploadUrl.Should().Be("https://signed.example/put");
body.AudioUploadUrl.Should().Be("https://signed.example/put"); body.AudioUploadUrl.Should().Be("https://signed.example/put");
} }
} }
@@ -47,12 +47,10 @@ public sealed class MusifyApiFactory : WebApplicationFactory<Program>
builder.ConfigureTestServices(services => builder.ConfigureTestServices(services =>
{ {
// Never start the RabbitMQ bus, EF outbox delivery or OTLP exporter in tests.
services.RemoveAll<IHostedService>(); services.RemoveAll<IHostedService>();
_connection.Open(); _connection.Open();
// Replace the Npgsql-backed IDatabase with a shared SQLite TestDatabase.
services.RemoveAll<IDatabase>(); services.RemoveAll<IDatabase>();
services.AddScoped<IDatabase>(_ => services.AddScoped<IDatabase>(_ =>
{ {
@@ -64,7 +62,6 @@ public sealed class MusifyApiFactory : WebApplicationFactory<Program>
return db; return db;
}); });
// Replace S3 and MassTransit with controllable test doubles.
services.RemoveAll<IStorageService>(); services.RemoveAll<IStorageService>();
services.AddScoped(_ => Storage); services.AddScoped(_ => Storage);
@@ -8,8 +8,6 @@
<RootNamespace>Musify.WebApi.Tests</RootNamespace> <RootNamespace>Musify.WebApi.Tests</RootNamespace>
</PropertyGroup> </PropertyGroup>
<!-- ResultHttpExtensions returns Microsoft.AspNetCore.Http.IResult, so the test project
needs the ASP.NET Core shared framework to inspect the produced result types. -->
<ItemGroup> <ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" /> <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>
@@ -30,7 +28,6 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\WebApi\WebApi.csproj" /> <ProjectReference Include="..\..\WebApi\WebApi.csproj" />
<!-- Reuse TestDatabase / TestData helpers from the Application test project. -->
<ProjectReference Include="..\..\..\MusifyBackend\Tests\Musify.Application.Tests\Musify.Application.Tests.csproj" /> <ProjectReference Include="..\..\..\MusifyBackend\Tests\Musify.Application.Tests\Musify.Application.Tests.csproj" />
</ItemGroup> </ItemGroup>
@@ -142,7 +142,6 @@ public sealed class UpdatePlayListRequestValidatorTests
[Fact] [Fact]
public void Empty_string_name_is_allowed_by_length_rule() public void Empty_string_name_is_allowed_by_length_rule()
{ {
// Only a MaximumLength rule applies, so an empty (non-null) string passes.
var model = new UpdatePlayListRequest("", null, null); var model = new UpdatePlayListRequest("", null, null);
_validator.TestValidate(model).ShouldNotHaveValidationErrorFor(x => x.NewName); _validator.TestValidate(model).ShouldNotHaveValidationErrorFor(x => x.NewName);
} }
-1
View File
@@ -24,5 +24,4 @@ app
app.Run(); app.Run();
// Exposed so WebApplicationFactory<Program> can bootstrap the app in integration tests.
public partial class Program { } public partial class Program { }