Migrate backend test suite from xUnit v2 to v3
- Directory.Packages.props: xunit 2.9.3 -> xunit.v3 4.0.0, bump xunit.runner.visualstudio to the matching 4.0.0 - All 5 test csproj: xunit -> xunit.v3 package reference, add <OutputType>Exe</OutputType> (v3 test projects are standalone executables) - backend/global.json: opt dotnet test into the new MTP-native mode (.NET 10 SDK removed the old VSTest bridge for MTP-based test projects like xunit v3) - IAsyncLifetime implementations (HandlerTestBase, ApiTestFixture, InfrastructureTestFixture, StorageServiceTests): v3's IAsyncLifetime now IS IAsyncDisposable, so InitializeAsync/DisposeAsync return ValueTask instead of Task. ApiTestFixture specifically now overrides WebApplicationFactory.DisposeAsync instead of implementing IAsyncLifetime.DisposeAsync explicitly, since v3 collapses both to the same single DisposeAsync slot - Replaced CancellationToken.None with TestContext.Current.CancellationToken across the suite (a v3-only API) and added it to every call that was silently omitting a CancellationToken argument, per the new xUnit1051 analyzer warnings that came with the v3 package Verified: dotnet build (0 warnings, 0 errors) and dotnet test, 250/250 passing under the new MTP runner.
This commit is contained in:
@@ -43,14 +43,14 @@ public sealed class CreateTrackCommandHandlerTests : HandlerTestBase
|
||||
|
||||
var command = new CreateTrackCommand(user.Id, "My Song", picture.Id, audio.Id);
|
||||
|
||||
var result = await CreateHandler().Handle(command, CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(command, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("My Song", result.Value.Title);
|
||||
Assert.Equal(user.Id, result.Value.OwnerUserId);
|
||||
await eventBus.Received(1).PublishAsync(Arg.Any<Musify.Application.Events.CreateTrackResourcesEvent>(), Arg.Any<CancellationToken>());
|
||||
|
||||
var stored = await Database.LocalTracks.FindAsync(result.Value.Id);
|
||||
var stored = await Database.LocalTracks.FindAsync([result.Value.Id], TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(stored);
|
||||
Assert.Equal(ProcessingStatus.Pending, stored.Audio.TranscodeStatus);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public sealed class CreateTrackCommandHandlerTests : HandlerTestBase
|
||||
{
|
||||
var command = new CreateTrackCommand(404, "Orphan Song", Guid.NewGuid(), Guid.NewGuid());
|
||||
|
||||
var result = await CreateHandler().Handle(command, CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(command, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public sealed class CreateTrackCommandHandlerTests : HandlerTestBase
|
||||
|
||||
var command = new CreateTrackCommand(user.Id, "My Song", picture.Id, audio.Id);
|
||||
|
||||
var result = await CreateHandler().Handle(command, CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(command, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.True(result.IsError);
|
||||
await eventBus.DidNotReceive().PublishAsync(Arg.Any<Musify.Application.Events.CreateTrackResourcesEvent>(), Arg.Any<CancellationToken>());
|
||||
@@ -91,7 +91,7 @@ public sealed class CreateTrackCommandHandlerTests : HandlerTestBase
|
||||
|
||||
var command = new CreateTrackCommand(user.Id, "My Song", picture.Id, audio.Id);
|
||||
|
||||
var result = await CreateHandler().Handle(command, CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(command, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Conflict, result.FirstError.Type);
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ public sealed class DeleteTrackCommandHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner);
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(owner.Id, track.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(owner.Id, track.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
var stored = await Database.Tracks.FindAsync(track.Id);
|
||||
var stored = await Database.Tracks.FindAsync([track.Id], TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(stored);
|
||||
Assert.Equal(LifeCycleStatus.Removing, stored.LifeCycleStatus);
|
||||
await eventBus.Received(1).PublishAsync(Arg.Any<Musify.Application.Events.DeleteTrackEvent>(), Arg.Any<CancellationToken>());
|
||||
@@ -33,7 +33,7 @@ public sealed class DeleteTrackCommandHandlerTests : HandlerTestBase
|
||||
[Fact]
|
||||
public async Task Handle_TrackMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(1, Guid.NewGuid()), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(1, Guid.NewGuid()), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public sealed class DeleteTrackCommandHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner);
|
||||
await SeedAsync(owner, stranger, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(stranger.Id, track.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(stranger.Id, track.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Unauthorized, result.FirstError.Type);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public sealed class DeleteTrackCommandHandlerTests : HandlerTestBase
|
||||
var externalTrack = TestEntities.ExternalTrack();
|
||||
await SeedAsync(externalTrack);
|
||||
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(1, externalTrack.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(1, externalTrack.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Unauthorized, result.FirstError.Type);
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public sealed class DeleteTrackCommandHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner, audio: TestEntities.PendingAudio());
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(owner.Id, track.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new DeleteTrackCommand(owner.Id, track.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Conflict, result.FirstError.Type);
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ public sealed class GetListeningHistoryQueryHandlerTests : HandlerTestBase
|
||||
TestEntities.ListeningHistory(owner.Id, older.Id, DateTime.UtcNow.AddMinutes(-5)),
|
||||
TestEntities.ListeningHistory(owner.Id, newer.Id, DateTime.UtcNow));
|
||||
|
||||
var result = await CreateHandler().Handle(new GetListeningHistoryQuery(owner.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetListeningHistoryQuery(owner.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(["Newer listen", "Older listen"], result.Select(track => track.Title));
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public sealed class GetListeningHistoryQueryHandlerTests : HandlerTestBase
|
||||
var owner = TestEntities.User();
|
||||
await SeedAsync(owner);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetListeningHistoryQuery(owner.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetListeningHistoryQuery(owner.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public sealed class GetTrackByIdQueryHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner, "My Song");
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTrackByIdQuery(track.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackByIdQuery(track.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("My Song", result.Value.Title);
|
||||
@@ -27,7 +27,7 @@ public sealed class GetTrackByIdQueryHandlerTests : HandlerTestBase
|
||||
[Fact]
|
||||
public async Task Handle_TrackMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateHandler().Handle(new GetTrackByIdQuery(Guid.NewGuid()), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackByIdQuery(Guid.NewGuid()), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed class GetTrackCoverQueryHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner);
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(track.Id, size), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(track.Id, size), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("covers-bucket", result.Value.Bucket);
|
||||
@@ -32,7 +32,7 @@ public sealed class GetTrackCoverQueryHandlerTests : HandlerTestBase
|
||||
[Fact]
|
||||
public async Task Handle_TrackMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(Guid.NewGuid(), "small"), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(Guid.NewGuid(), "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public sealed class GetTrackCoverQueryHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner, pictures: TestEntities.PendingPictures());
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(track.Id, "small"), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(track.Id, "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
|
||||
@@ -33,14 +33,14 @@ public sealed class GetTrackStreamQueryHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner);
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTrackStreamQuery(track.Id, owner.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackStreamQuery(track.Id, owner.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("ticket-token", result.Value.Ticket);
|
||||
Assert.Equal(60, result.Value.ExpiresInSeconds);
|
||||
Assert.Contains("audio-folder", result.Value.ManifestUrl);
|
||||
|
||||
var history = Assert.Single(await Database.ListeningHistories.ToListAsync());
|
||||
var history = Assert.Single(await Database.ListeningHistories.ToListAsync(TestContext.Current.CancellationToken));
|
||||
Assert.Equal(owner.Id, history.UserId);
|
||||
Assert.Equal(track.Id, history.TrackId);
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public sealed class GetTrackStreamQueryHandlerTests : HandlerTestBase
|
||||
[Fact]
|
||||
public async Task Handle_TrackMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateHandler().Handle(new GetTrackStreamQuery(Guid.NewGuid(), 1), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackStreamQuery(Guid.NewGuid(), 1), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public sealed class GetTrackStreamQueryHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner, audio: TestEntities.PendingAudio());
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTrackStreamQuery(track.Id, owner.Id), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTrackStreamQuery(track.Id, owner.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Conflict, result.FirstError.Type);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed class GetTracksByUserIdQueryHandlerTests : HandlerTestBase
|
||||
new UserHasTrack { UserId = owner.Id, TrackId = mine.Id },
|
||||
new UserHasTrack { UserId = other.Id, TrackId = theirs.Id });
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTracksByUserIdQuery(owner.Id, Name: null, PageNumber: 1, PageSize: 10), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTracksByUserIdQuery(owner.Id, Name: null, PageNumber: 1, PageSize: 10), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
var track = Assert.Single(result.Value.Items);
|
||||
@@ -37,7 +37,7 @@ public sealed class GetTracksByUserIdQueryHandlerTests : HandlerTestBase
|
||||
var track = TestEntities.LocalTrack(owner);
|
||||
await SeedAsync(owner, track, new UserHasTrack { UserId = owner.Id, TrackId = track.Id });
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTracksByUserIdQuery(owner.Id, Name: null, PageNumber: requestedPageNumber, PageSize: 10), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTracksByUserIdQuery(owner.Id, Name: null, PageNumber: requestedPageNumber, PageSize: 10), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal(expectedPageNumber, result.Value.PageNumber);
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetTracksQueryHandlerTests : HandlerTestBase
|
||||
new Musify.Domain.Entities.UserHasTrack { UserId = owner.Id, TrackId = trackA.Id },
|
||||
new Musify.Domain.Entities.UserHasTrack { UserId = owner.Id, TrackId = trackB.Id });
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTracksQuery(Name: null, PageNumber: 1, PageSize: 10), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTracksQuery(Name: null, PageNumber: 1, PageSize: 10), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal(2, result.Value.TotalItemCount);
|
||||
@@ -36,7 +36,7 @@ public sealed class GetTracksQueryHandlerTests : HandlerTestBase
|
||||
new Musify.Domain.Entities.UserHasTrack { UserId = owner.Id, TrackId = match.Id },
|
||||
new Musify.Domain.Entities.UserHasTrack { UserId = owner.Id, TrackId = other.Id });
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTracksQuery(Name: "rhapsody", PageNumber: 1, PageSize: 10), CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(new GetTracksQuery(Name: "rhapsody", PageNumber: 1, PageSize: 10), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
var track = Assert.Single(result.Value.Items);
|
||||
|
||||
+5
-5
@@ -39,13 +39,13 @@ public sealed class RequestTrackUploadUrlsCommandHandlerTests : HandlerTestBase
|
||||
|
||||
var command = new RequestTrackUploadUrlsCommand(user.Id, "webp", "image/webp", "mp3", "audio/mpeg");
|
||||
|
||||
var result = await CreateHandler().Handle(command, CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(command, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("https://storage.musify.test/presigned-upload", result.Value.PictureUploadUrl);
|
||||
Assert.Equal("https://storage.musify.test/presigned-upload", result.Value.AudioUploadUrl);
|
||||
|
||||
var intents = await Database.UploadIntents.Where(intent => intent.UserId == user.Id).ToListAsync();
|
||||
var intents = await Database.UploadIntents.Where(intent => intent.UserId == user.Id).ToListAsync(TestContext.Current.CancellationToken);
|
||||
Assert.Equal(2, intents.Count);
|
||||
Assert.Contains(intents, intent => intent.Purpose == UploadIntentPurpose.TrackPicture);
|
||||
Assert.Contains(intents, intent => intent.Purpose == UploadIntentPurpose.TrackAudio);
|
||||
@@ -56,7 +56,7 @@ public sealed class RequestTrackUploadUrlsCommandHandlerTests : HandlerTestBase
|
||||
{
|
||||
var command = new RequestTrackUploadUrlsCommand(404, "webp", "image/webp", "mp3", "audio/mpeg");
|
||||
|
||||
var result = await CreateHandler().Handle(command, CancellationToken.None);
|
||||
var result = await CreateHandler().Handle(command, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -72,9 +72,9 @@ public sealed class RequestTrackUploadUrlsCommandHandlerTests : HandlerTestBase
|
||||
|
||||
var command = new RequestTrackUploadUrlsCommand(user.Id, "webp", "image/webp", "mp3", "audio/mpeg");
|
||||
|
||||
var result = await CreateHandler(config).Handle(command, CancellationToken.None);
|
||||
var result = await CreateHandler(config).Handle(command, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Validation, result.FirstError.Type);
|
||||
Assert.Equal(1, await Database.UploadIntents.CountAsync());
|
||||
Assert.Equal(1, await Database.UploadIntents.CountAsync(TestContext.Current.CancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user