Deduplicate picture flows: shared upload issuer, cover query and picture source change
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Net.Http.Json;
|
||||
using Musify.Api.DataTransferObjects.Albums;
|
||||
using Musify.Api.Tests.TestSupport;
|
||||
using Musify.Application.Albums.Responses;
|
||||
using Musify.Application.Pictures.Responses;
|
||||
using Musify.Application.Contracts;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
@@ -29,7 +30,7 @@ public sealed class AlbumEndpointsTests(ApiTestFixture fixture)
|
||||
TestContext.Current.CancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var body = await response.Content.ReadFromJsonAsync<AlbumPictureUploadResponse>(TestContext.Current.CancellationToken);
|
||||
var body = await response.Content.ReadFromJsonAsync<PictureUploadResponse>(TestContext.Current.CancellationToken);
|
||||
return body!.IntentId;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,9 @@ public sealed class CreateAlbumCommandHandlerTests : HandlerTestBase
|
||||
private CreateAlbumCommandHandler CreateHandler() => new(
|
||||
eventBus,
|
||||
Database,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
new UploadIntentValidator(Database, storageService, TestConfigurations.UploadIntent()),
|
||||
NoOpLogger<CreateAlbumCommandHandler>(),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.Album(),
|
||||
TestConfigurations.UploadIntent());
|
||||
TestConfigurations.Album());
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_ValidPictureIntent_CreatesAlbumAndPublishesResourcesEvent()
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
using ErrorOr;
|
||||
using Musify.Application.Albums;
|
||||
using Musify.Application.Tests.TestSupport;
|
||||
using Xunit;
|
||||
|
||||
namespace Musify.Application.Tests.Albums;
|
||||
|
||||
public sealed class GetAlbumCoverQueryHandlerTests : HandlerTestBase
|
||||
{
|
||||
private GetAlbumCoverQueryHandler CreateHandler() =>
|
||||
new(Database, TestConfigurations.Storage("covers-bucket"), TestConfigurations.Album());
|
||||
|
||||
[Theory]
|
||||
[InlineData("small", "small.webp")]
|
||||
[InlineData("large", "large.webp")]
|
||||
[InlineData("medium", "medium.webp")]
|
||||
public async Task Handle_ExistingAlbum_ReturnsRequestedSize(string size, string expectedFileName)
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var album = TestEntities.Album(owner.Id);
|
||||
await SeedAsync(owner, album);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetAlbumCoverQuery(album.Id, size), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("covers-bucket", result.Value.Bucket);
|
||||
Assert.EndsWith(expectedFileName, result.Value.Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_AlbumMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateHandler().Handle(new GetAlbumCoverQuery(Guid.NewGuid(), "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_PicturesStillProcessing_FallsBackToTheOriginal()
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var album = TestEntities.Album(owner.Id, pictures: Musify.Domain.ValueObjects.EntityPictures.Pending("original.png"));
|
||||
await SeedAsync(owner, album);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetAlbumCoverQuery(album.Id, "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Contains($"{owner.Id}", result.Value.Key);
|
||||
Assert.EndsWith("original.png", result.Value.Key);
|
||||
Assert.Equal("image/png", result.Value.ContentType);
|
||||
}
|
||||
}
|
||||
+10
-7
@@ -20,14 +20,17 @@ public sealed class RequestAlbumPictureUploadCommandHandlerTests : HandlerTestBa
|
||||
.GetUploadUrlAsync(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<TimeSpan>(), Arg.Any<CancellationToken>())
|
||||
.Returns("https://storage.musify.test/presigned-upload");
|
||||
|
||||
var config = uploadIntentConfig ?? TestConfigurations.UploadIntent();
|
||||
|
||||
return new RequestAlbumPictureUploadCommandHandler(
|
||||
Database,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
storageService,
|
||||
NoOpLogger<RequestAlbumPictureUploadCommandHandler>(),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.Album(),
|
||||
uploadIntentConfig ?? TestConfigurations.UploadIntent());
|
||||
new UploadIntentIssuer(
|
||||
Database,
|
||||
storageService,
|
||||
new UploadIntentValidator(Database, storageService, config),
|
||||
TestConfigurations.Storage(),
|
||||
config,
|
||||
NoOpLogger<UploadIntentIssuer>()),
|
||||
TestConfigurations.Album());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -16,11 +16,9 @@ public sealed class UpdateAlbumCommandHandlerTests : HandlerTestBase
|
||||
private UpdateAlbumCommandHandler CreateHandler() => new(
|
||||
eventBus,
|
||||
Database,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
new UploadIntentValidator(Database, storageService, TestConfigurations.UploadIntent()),
|
||||
NoOpLogger<UpdateAlbumCommandHandler>(),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.Album(),
|
||||
TestConfigurations.UploadIntent());
|
||||
TestConfigurations.Album());
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_Owner_UpdatesTitleDescriptionAndReleaseYear()
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
using ErrorOr;
|
||||
using Musify.Application.Configuration;
|
||||
using Musify.Application.Pictures;
|
||||
using Musify.Application.Tests.TestSupport;
|
||||
using Musify.Domain.ValueObjects;
|
||||
using Xunit;
|
||||
|
||||
namespace Musify.Application.Tests.Pictures;
|
||||
|
||||
public sealed class GetCoverQueryHandlerTests : HandlerTestBase
|
||||
{
|
||||
private GetCoverQueryHandler CreateHandler() => new(
|
||||
Database,
|
||||
TestConfigurations.Storage("covers-bucket"),
|
||||
TestConfigurations.Track(),
|
||||
TestConfigurations.Album(),
|
||||
TestConfigurations.PlayList());
|
||||
|
||||
[Theory]
|
||||
[InlineData(PictureSize.Small, "small.webp")]
|
||||
[InlineData(PictureSize.Medium, "medium.webp")]
|
||||
[InlineData(PictureSize.Large, "large.webp")]
|
||||
public async Task Handle_ProcessedTrack_ReturnsRequestedSize(PictureSize size, string expectedFileName)
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var track = TestEntities.Track(owner);
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetCoverQuery(CoverOwner.Track, track.Id, size), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("covers-bucket", result.Value.Bucket);
|
||||
Assert.EndsWith(expectedFileName, result.Value.Key);
|
||||
Assert.Equal("image/webp", result.Value.ContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(PictureSize.Small, "small.webp")]
|
||||
[InlineData(PictureSize.Medium, "medium.webp")]
|
||||
[InlineData(PictureSize.Large, "large.webp")]
|
||||
public async Task Handle_ProcessedAlbum_ReturnsRequestedSize(PictureSize size, string expectedFileName)
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var album = TestEntities.Album(owner.Id);
|
||||
await SeedAsync(owner, album);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetCoverQuery(CoverOwner.Album, album.Id, size), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.EndsWith(expectedFileName, result.Value.Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_ProcessedPlayList_ReturnsRequestedSize()
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var playList = TestEntities.PlayList(owner.Id);
|
||||
await SeedAsync(owner, playList);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetCoverQuery(CoverOwner.PlayList, playList.Id, PictureSize.Large), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.EndsWith("large.webp", result.Value.Key);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(CoverOwner.Track)]
|
||||
[InlineData(CoverOwner.Album)]
|
||||
[InlineData(CoverOwner.PlayList)]
|
||||
public async Task Handle_EntityMissing_ReturnsNotFound(CoverOwner owner)
|
||||
{
|
||||
var result = await CreateHandler().Handle(new GetCoverQuery(owner, Guid.NewGuid()), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_AlbumPicturesStillProcessing_FallsBackToTheOriginal()
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var album = TestEntities.Album(owner.Id, pictures: EntityPictures.Pending("original.png"));
|
||||
await SeedAsync(owner, album);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetCoverQuery(CoverOwner.Album, album.Id, PictureSize.Small), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Contains($"{owner.Id}", result.Value.Key);
|
||||
Assert.EndsWith("original.png", result.Value.Key);
|
||||
Assert.Equal("image/png", result.Value.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_RemovingAlbum_ReturnsNotFound()
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var album = TestEntities.Album(owner.Id);
|
||||
album.LifeCycleStatus = LifeCycleStatus.Removing;
|
||||
await SeedAsync(owner, album);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetCoverQuery(CoverOwner.Album, album.Id), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -16,11 +16,9 @@ public sealed class CreatePlayListCommandHandlerTests : HandlerTestBase
|
||||
private CreatePlayListCommandHandler CreateHandler() => new(
|
||||
eventBus,
|
||||
Database,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
new UploadIntentValidator(Database, storageService, TestConfigurations.UploadIntent()),
|
||||
NoOpLogger<CreatePlayListCommandHandler>(),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.PlayList(),
|
||||
TestConfigurations.UploadIntent());
|
||||
TestConfigurations.PlayList());
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_NoPictureIntent_CreatesPlayListWithoutPictures()
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
using ErrorOr;
|
||||
using Musify.Application.PlayLists;
|
||||
using Musify.Application.Tests.TestSupport;
|
||||
using Xunit;
|
||||
|
||||
namespace Musify.Application.Tests.PlayLists;
|
||||
|
||||
public sealed class GetPlayListCoverQueryHandlerTests : HandlerTestBase
|
||||
{
|
||||
private GetPlayListCoverQueryHandler CreateHandler() =>
|
||||
new(Database, TestConfigurations.Storage("covers-bucket"), TestConfigurations.PlayList());
|
||||
|
||||
[Theory]
|
||||
[InlineData("small", "small.webp")]
|
||||
[InlineData("large", "large.webp")]
|
||||
[InlineData("medium", "medium.webp")]
|
||||
public async Task Handle_ExistingPlayList_ReturnsRequestedSize(string size, string expectedFileName)
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var playList = TestEntities.PlayList(owner.Id);
|
||||
await SeedAsync(owner, playList);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetPlayListCoverQuery(playList.Id, size), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("covers-bucket", result.Value.Bucket);
|
||||
Assert.EndsWith(expectedFileName, result.Value.Key);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_PlayListMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateHandler().Handle(new GetPlayListCoverQuery(Guid.NewGuid(), "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_PlayListWithoutPictures_ReturnsNotFound()
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var playList = TestEntities.PlayList(owner.Id);
|
||||
playList.Pictures = null;
|
||||
await SeedAsync(owner, playList);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetPlayListCoverQuery(playList.Id, "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
}
|
||||
+10
-7
@@ -20,14 +20,17 @@ public sealed class RequestPlayListPictureUploadCommandHandlerTests : HandlerTes
|
||||
.GetUploadUrlAsync(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<TimeSpan>(), Arg.Any<CancellationToken>())
|
||||
.Returns("https://storage.musify.test/presigned-upload");
|
||||
|
||||
var config = uploadIntentConfig ?? TestConfigurations.UploadIntent();
|
||||
|
||||
return new RequestPlayListPictureUploadCommandHandler(
|
||||
Database,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
storageService,
|
||||
NoOpLogger<RequestPlayListPictureUploadCommandHandler>(),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.PlayList(),
|
||||
uploadIntentConfig ?? TestConfigurations.UploadIntent());
|
||||
new UploadIntentIssuer(
|
||||
Database,
|
||||
storageService,
|
||||
new UploadIntentValidator(Database, storageService, config),
|
||||
TestConfigurations.Storage(),
|
||||
config,
|
||||
NoOpLogger<UploadIntentIssuer>()),
|
||||
TestConfigurations.PlayList());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+2
-4
@@ -16,11 +16,9 @@ public sealed class UpdatePlayListCommandHandlerTests : HandlerTestBase
|
||||
private UpdatePlayListCommandHandler CreateHandler() => new(
|
||||
eventBus,
|
||||
Database,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
new UploadIntentValidator(Database, storageService, TestConfigurations.UploadIntent()),
|
||||
NoOpLogger<UpdatePlayListCommandHandler>(),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.PlayList(),
|
||||
TestConfigurations.UploadIntent());
|
||||
TestConfigurations.PlayList());
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_Owner_RenamesPlayList()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ErrorOr;
|
||||
using Musify.Application.Configuration;
|
||||
using Musify.Application.Contracts;
|
||||
using Musify.Application.Services;
|
||||
using Musify.Application.Tests.TestSupport;
|
||||
@@ -13,7 +14,8 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
private readonly IStorageService storageService = Substitute.For<IStorageService>();
|
||||
private readonly Domain.Entities.User owner = TestEntities.User();
|
||||
|
||||
private UploadIntentValidator CreateValidator() => new(Database, storageService);
|
||||
private UploadIntentValidator CreateValidator(UploadIntentConfiguration? config = null) =>
|
||||
new(Database, storageService, config ?? TestConfigurations.UploadIntent());
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateAndLoadAsync_UploadedObjectWithinLimits_ReturnsTheIntent()
|
||||
@@ -25,7 +27,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
var intent = TestEntities.UploadIntent(owner.Id, bucket: "bucket", key: "temp/object.webp");
|
||||
await SeedAsync(owner, intent);
|
||||
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(TestConfigurations.UploadIntent(), intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal(intent.Id, result.Value.Id);
|
||||
@@ -37,7 +39,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
var intent = TestEntities.UploadIntent(owner.Id, UploadIntentPurpose.TrackAudio);
|
||||
await SeedAsync(owner, intent);
|
||||
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(TestConfigurations.UploadIntent(), intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Validation, result.FirstError.Type);
|
||||
}
|
||||
@@ -45,7 +47,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
[Fact]
|
||||
public async Task ValidateAndLoadAsync_IntentMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(TestConfigurations.UploadIntent(), Guid.NewGuid(), owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(Guid.NewGuid(), owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -57,7 +59,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
var intent = TestEntities.UploadIntent(owner.Id);
|
||||
await SeedAsync(owner, stranger, intent);
|
||||
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(TestConfigurations.UploadIntent(), intent.Id, stranger.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(intent.Id, stranger.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -68,7 +70,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
var intent = TestEntities.UploadIntent(owner.Id, status: UploadIntentStatus.Consumed);
|
||||
await SeedAsync(owner, intent);
|
||||
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(TestConfigurations.UploadIntent(), intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Conflict, result.FirstError.Type);
|
||||
}
|
||||
@@ -79,7 +81,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
var intent = TestEntities.UploadIntent(owner.Id, expiresAt: DateTime.UtcNow.AddMinutes(-1));
|
||||
await SeedAsync(owner, intent);
|
||||
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(TestConfigurations.UploadIntent(), intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Validation, result.FirstError.Type);
|
||||
}
|
||||
@@ -94,7 +96,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
var intent = TestEntities.UploadIntent(owner.Id);
|
||||
await SeedAsync(owner, intent);
|
||||
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(TestConfigurations.UploadIntent(), intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
@@ -112,7 +114,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
var intent = TestEntities.UploadIntent(owner.Id);
|
||||
await SeedAsync(owner, intent);
|
||||
|
||||
var result = await CreateValidator().ValidateAndLoadAsync(config, intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator(config).ValidateAndLoadAsync(intent.Id, owner.Id, UploadIntentPurpose.TrackPicture, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Validation, result.FirstError.Type);
|
||||
}
|
||||
@@ -122,7 +124,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
{
|
||||
await SeedAsync(owner);
|
||||
|
||||
var result = await CreateValidator().CheckQuotaAsync(TestConfigurations.UploadIntent(), owner.Id, requiredBytes: 1024, requiredIntentCount: 1, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator().CheckQuotaAsync(owner.Id, requiredBytes: 1024, requiredIntentCount: 1, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
}
|
||||
@@ -134,7 +136,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
config.MaxActiveUploadIntentsPerUser = 1;
|
||||
await SeedAsync(owner, TestEntities.UploadIntent(owner.Id));
|
||||
|
||||
var result = await CreateValidator().CheckQuotaAsync(config, owner.Id, requiredBytes: 1, requiredIntentCount: 1, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator(config).CheckQuotaAsync(owner.Id, requiredBytes: 1, requiredIntentCount: 1, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.Validation, result.FirstError.Type);
|
||||
}
|
||||
@@ -149,7 +151,7 @@ public sealed class UploadIntentValidatorTests : HandlerTestBase
|
||||
TestEntities.UploadIntent(owner.Id, status: UploadIntentStatus.Expired),
|
||||
TestEntities.UploadIntent(owner.Id, status: UploadIntentStatus.Consumed));
|
||||
|
||||
var result = await CreateValidator().CheckQuotaAsync(config, owner.Id, requiredBytes: 1, requiredIntentCount: 1, TestContext.Current.CancellationToken);
|
||||
var result = await CreateValidator(config).CheckQuotaAsync(owner.Id, requiredBytes: 1, requiredIntentCount: 1, TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
}
|
||||
|
||||
@@ -24,11 +24,9 @@ public sealed class CreateTrackCommandHandlerTests : HandlerTestBase
|
||||
return new CreateTrackCommandHandler(
|
||||
Database,
|
||||
eventBus,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
new UploadIntentValidator(Database, storageService, TestConfigurations.UploadIntent()),
|
||||
NoOpLogger<CreateTrackCommandHandler>(),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.Track(),
|
||||
TestConfigurations.UploadIntent());
|
||||
TestConfigurations.Track());
|
||||
}
|
||||
|
||||
private static (Domain.Entities.UploadIntent Picture, Domain.Entities.UploadIntent Audio) SeedIntents(long userId) =>
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
using ErrorOr;
|
||||
using Musify.Application.Tests.TestSupport;
|
||||
using Musify.Application.Tracks;
|
||||
using Xunit;
|
||||
|
||||
namespace Musify.Application.Tests.Tracks;
|
||||
|
||||
public sealed class GetTrackCoverQueryHandlerTests : HandlerTestBase
|
||||
{
|
||||
private GetTrackCoverQueryHandler CreateHandler() =>
|
||||
new(Database, TestConfigurations.Storage("covers-bucket"), TestConfigurations.Track());
|
||||
|
||||
[Theory]
|
||||
[InlineData("small", "small.webp")]
|
||||
[InlineData("medium", "medium.webp")]
|
||||
[InlineData("large", "large.webp")]
|
||||
[InlineData("unknown-size-falls-back-to-medium", "medium.webp")]
|
||||
public async Task Handle_ProcessedTrack_ReturnsRequestedSize(string size, string expectedFileName)
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var track = TestEntities.Track(owner);
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(track.Id, size), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.False(result.IsError);
|
||||
Assert.Equal("covers-bucket", result.Value.Bucket);
|
||||
Assert.EndsWith(expectedFileName, result.Value.Key);
|
||||
Assert.Equal("image/webp", result.Value.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_TrackMissing_ReturnsNotFound()
|
||||
{
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(Guid.NewGuid(), "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_PictureNotProcessedYet_ReturnsNotFound()
|
||||
{
|
||||
var owner = TestEntities.User();
|
||||
var track = TestEntities.Track(owner, pictures: TestEntities.PendingPictures());
|
||||
await SeedAsync(owner, track);
|
||||
|
||||
var result = await CreateHandler().Handle(new GetTrackCoverQuery(track.Id, "small"), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
||||
}
|
||||
}
|
||||
+10
-5
@@ -21,14 +21,19 @@ public sealed class RequestTrackUploadUrlsCommandHandlerTests : HandlerTestBase
|
||||
.GetUploadUrlAsync(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<TimeSpan>(), Arg.Any<CancellationToken>())
|
||||
.Returns("https://storage.musify.test/presigned-upload");
|
||||
|
||||
var config = uploadIntentConfig ?? TestConfigurations.UploadIntent();
|
||||
|
||||
return new RequestTrackUploadUrlsCommandHandler(
|
||||
Database,
|
||||
new UploadIntentValidator(Database, storageService),
|
||||
storageService,
|
||||
NoOpLogger<RequestTrackUploadUrlsCommandHandler>(),
|
||||
new UploadIntentIssuer(
|
||||
Database,
|
||||
storageService,
|
||||
new UploadIntentValidator(Database, storageService, config),
|
||||
TestConfigurations.Storage(),
|
||||
config,
|
||||
NoOpLogger<UploadIntentIssuer>()),
|
||||
TestConfigurations.Storage(),
|
||||
TestConfigurations.Track(),
|
||||
uploadIntentConfig ?? TestConfigurations.UploadIntent());
|
||||
config);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user