Adapt the refactored web player to the new backend API (id path params, bulk track adds, flat list items, mix kind) and port AddAlbumToPlayList to the backend conventions.
92 lines
4.2 KiB
C#
92 lines
4.2 KiB
C#
using ErrorOr;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Musify.Application.PlayLists;
|
|
using Musify.Application.Tests.TestSupport;
|
|
using Musify.Domain.Entities;
|
|
using Xunit;
|
|
|
|
namespace Musify.Application.Tests.PlayLists
|
|
{
|
|
public sealed class AddAlbumToPlayListCommandHandlerTests : HandlerTestBase
|
|
{
|
|
private AddAlbumToPlayListCommandHandler CreateHandler() => new(Database, NoOpLogger<AddAlbumToPlayListCommandHandler>());
|
|
|
|
[Fact]
|
|
public async Task Handle_AddsAlbumTracksInAlbumOrder()
|
|
{
|
|
var owner = TestEntities.User();
|
|
var playList = TestEntities.PlayList(owner.Id);
|
|
var album = TestEntities.Album(owner.Id);
|
|
var first = TestEntities.Track(owner, "First");
|
|
var second = TestEntities.Track(owner, "Second");
|
|
await SeedAsync(
|
|
owner, playList, album, first, second,
|
|
new AlbumHasTrack { AlbumId = album.Id, TrackId = second.Id, TrackNumber = 2 },
|
|
new AlbumHasTrack { AlbumId = album.Id, TrackId = first.Id, TrackNumber = 1 });
|
|
|
|
var result = await CreateHandler().Handle(new AddAlbumToPlayListCommand(owner.Id, playList.Id, album.Id), TestContext.Current.CancellationToken);
|
|
|
|
Assert.False(result.IsError);
|
|
Assert.Equal(2, result.Value.AddedCount);
|
|
var links = await Database.PlayListHasTracks.OrderBy(link => link.Position).ToListAsync(TestContext.Current.CancellationToken);
|
|
Assert.Equal([first.Id, second.Id], links.Select(link => link.TrackId));
|
|
Assert.Equal([0, 1], links.Select(link => link.Position));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_SkipsTracksAlreadyInPlayList_AndAppendsAfterThem()
|
|
{
|
|
var owner = TestEntities.User();
|
|
var playList = TestEntities.PlayList(owner.Id);
|
|
var album = TestEntities.Album(owner.Id);
|
|
var existing = TestEntities.Track(owner, "Existing");
|
|
var fresh = TestEntities.Track(owner, "Fresh");
|
|
await SeedAsync(
|
|
owner, playList, album, existing, fresh,
|
|
new AlbumHasTrack { AlbumId = album.Id, TrackId = existing.Id, TrackNumber = 1 },
|
|
new AlbumHasTrack { AlbumId = album.Id, TrackId = fresh.Id, TrackNumber = 2 },
|
|
new PlayListHasTrack { PlayListId = playList.Id, TrackId = existing.Id, Position = 4 });
|
|
|
|
var result = await CreateHandler().Handle(new AddAlbumToPlayListCommand(owner.Id, playList.Id, album.Id), TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(1, result.Value.AddedCount);
|
|
var link = await Database.PlayListHasTracks.SingleAsync(l => l.TrackId == fresh.Id, TestContext.Current.CancellationToken);
|
|
Assert.Equal(5, link.Position);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_PlayListMissing_ReturnsNotFound()
|
|
{
|
|
var result = await CreateHandler().Handle(new AddAlbumToPlayListCommand(1, Guid.NewGuid(), Guid.NewGuid()), TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_NotOwner_ReturnsForbidden()
|
|
{
|
|
var owner = TestEntities.User(1, "owner");
|
|
var stranger = TestEntities.User(2, "stranger");
|
|
var playList = TestEntities.PlayList(owner.Id);
|
|
var album = TestEntities.Album(owner.Id);
|
|
await SeedAsync(owner, stranger, playList, album);
|
|
|
|
var result = await CreateHandler().Handle(new AddAlbumToPlayListCommand(stranger.Id, playList.Id, album.Id), TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(ErrorType.Forbidden, result.FirstError.Type);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_AlbumMissing_ReturnsNotFound()
|
|
{
|
|
var owner = TestEntities.User();
|
|
var playList = TestEntities.PlayList(owner.Id);
|
|
await SeedAsync(owner, playList);
|
|
|
|
var result = await CreateHandler().Handle(new AddAlbumToPlayListCommand(owner.Id, playList.Id, Guid.NewGuid()), TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(ErrorType.NotFound, result.FirstError.Type);
|
|
}
|
|
}
|
|
}
|