Files
allstarr/allstarr.Tests/JellyfinResponseBuilderTests.cs
Josh Patra e18840cddf feat: Fork octo-fiestarr as allstarr with Jellyfin proxy improvements
Major changes:
- Rename project from octo-fiesta to allstarr
- Add Jellyfin proxy support alongside Subsonic/Navidrome
- Implement fuzzy search with relevance scoring and Levenshtein distance
- Add POST body logging for debugging playback progress issues
- Separate local and external artists in search results
- Add +5 score boost for external results to prioritize larger catalog(probably gonna reverse it)
- Create FuzzyMatcher utility for intelligent search result scoring
- Add ConvertPlaylistToJellyfinItem method for playlist support
- Rename keys folder to apis and update gitignore
- Filter search results by relevance score (>= 40)
- Add Redis caching support with configurable settings
- Update environment configuration with backend selection
- Improve external provider integration (SquidWTF, Deezer, Qobuz)
- Add tests for all services
2026-01-29 17:36:53 -05:00

293 lines
8.5 KiB
C#

using Microsoft.AspNetCore.Mvc;
using allstarr.Models.Domain;
using allstarr.Models.Subsonic;
using allstarr.Services.Jellyfin;
namespace allstarr.Tests;
public class JellyfinResponseBuilderTests
{
private readonly JellyfinResponseBuilder _builder;
public JellyfinResponseBuilderTests()
{
_builder = new JellyfinResponseBuilder();
}
[Fact]
public void ConvertSongToJellyfinItem_SetsCorrectFields()
{
// Arrange
var song = new Song
{
Id = "song-123",
Title = "Test Track",
Artist = "Test Artist",
Album = "Test Album",
AlbumId = "album-456",
ArtistId = "artist-789",
Duration = 245,
Track = 3,
DiscNumber = 1,
Year = 2023,
Genre = "Rock",
IsLocal = true
};
// Act
var result = _builder.ConvertSongToJellyfinItem(song);
// Assert
Assert.Equal("song-123", result["Id"]);
Assert.Equal("Test Track", result["Name"]);
Assert.Equal("Audio", result["Type"]);
Assert.Equal("Test Album", result["Album"]);
Assert.Equal("album-456", result["AlbumId"]);
Assert.Equal(3, result["IndexNumber"]);
Assert.Equal(1, result["ParentIndexNumber"]);
Assert.Equal(2023, result["ProductionYear"]);
Assert.Equal(245 * TimeSpan.TicksPerSecond, result["RunTimeTicks"]);
}
[Fact]
public void ConvertSongToJellyfinItem_ExternalSong_IncludesProviderIds()
{
// Arrange
var song = new Song
{
Id = "ext-deezer-song-12345",
Title = "External Track",
Artist = "External Artist",
IsLocal = false,
ExternalProvider = "deezer",
ExternalId = "12345",
Isrc = "USRC12345678"
};
// Act
var result = _builder.ConvertSongToJellyfinItem(song);
// Assert
Assert.True(result.ContainsKey("ProviderIds"));
var providerIds = result["ProviderIds"] as Dictionary<string, string>;
Assert.NotNull(providerIds);
Assert.Equal("12345", providerIds["deezer"]);
Assert.Equal("USRC12345678", providerIds["ISRC"]);
}
[Fact]
public void ConvertAlbumToJellyfinItem_SetsCorrectFields()
{
// Arrange
var album = new Album
{
Id = "album-456",
Title = "Greatest Hits",
Artist = "Famous Band",
ArtistId = "artist-123",
Year = 2020,
SongCount = 12,
Genre = "Pop",
IsLocal = true
};
// Act
var result = _builder.ConvertAlbumToJellyfinItem(album);
// Assert
Assert.Equal("album-456", result["Id"]);
Assert.Equal("Greatest Hits", result["Name"]);
Assert.Equal("MusicAlbum", result["Type"]);
Assert.Equal(true, result["IsFolder"]);
Assert.Equal("Famous Band", result["AlbumArtist"]);
Assert.Equal(2020, result["ProductionYear"]);
Assert.Equal(12, result["ChildCount"]);
}
[Fact]
public void ConvertArtistToJellyfinItem_SetsCorrectFields()
{
// Arrange
var artist = new Artist
{
Id = "artist-789",
Name = "The Rockers",
AlbumCount = 5,
IsLocal = true
};
// Act
var result = _builder.ConvertArtistToJellyfinItem(artist);
// Assert
Assert.Equal("artist-789", result["Id"]);
Assert.Equal("The Rockers", result["Name"]);
Assert.Equal("MusicArtist", result["Type"]);
Assert.Equal(true, result["IsFolder"]);
Assert.Equal(5, result["AlbumCount"]);
}
[Fact]
public void ConvertPlaylistToAlbumItem_SetsPlaylistType()
{
// Arrange
var playlist = new ExternalPlaylist
{
Id = "ext-playlist-deezer-999",
ExternalId = "999",
Name = "Summer Vibes",
Provider = "deezer",
CuratorName = "DJ Cool",
TrackCount = 50,
Duration = 3600,
CreatedDate = new DateTime(2023, 6, 15)
};
// Act
var result = _builder.ConvertPlaylistToAlbumItem(playlist);
// Assert
Assert.Equal("ext-playlist-deezer-999", result["Id"]);
Assert.Equal("Summer Vibes", result["Name"]);
Assert.Equal("Playlist", result["Type"]);
Assert.Equal("DJ Cool", result["AlbumArtist"]);
Assert.Equal(50, result["ChildCount"]);
Assert.Equal(2023, result["ProductionYear"]);
}
[Fact]
public void ConvertPlaylistToAlbumItem_NoCurator_UsesProvider()
{
// Arrange
var playlist = new ExternalPlaylist
{
Id = "ext-playlist-deezer-888",
ExternalId = "888",
Name = "Top Hits",
Provider = "deezer",
CuratorName = null,
TrackCount = 30
};
// Act
var result = _builder.ConvertPlaylistToAlbumItem(playlist);
// Assert
Assert.Equal("deezer", result["AlbumArtist"]);
}
[Fact]
public void CreateItemsResponse_ReturnsPaginatedResult()
{
// Arrange
var songs = new List<Song>
{
new() { Id = "1", Title = "Song One", Artist = "Artist", Duration = 200 },
new() { Id = "2", Title = "Song Two", Artist = "Artist", Duration = 180 }
};
// Act
var result = _builder.CreateItemsResponse(songs);
// Assert
var jsonResult = Assert.IsType<JsonResult>(result);
Assert.NotNull(jsonResult.Value);
}
[Fact]
public void CreateSearchHintsResponse_IncludesAllTypes()
{
// Arrange
var songs = new List<Song> { new() { Id = "s1", Title = "Track", Artist = "A" } };
var albums = new List<Album> { new() { Id = "a1", Title = "Album", Artist = "A" } };
var artists = new List<Artist> { new() { Id = "ar1", Name = "Artist" } };
// Act
var result = _builder.CreateSearchHintsResponse(songs, albums, artists);
// Assert
var jsonResult = Assert.IsType<JsonResult>(result);
Assert.NotNull(jsonResult.Value);
}
[Fact]
public void CreateError_Returns404ForNotFound()
{
// Act
var result = _builder.CreateError(404, "Item not found");
// Assert
var objectResult = Assert.IsType<ObjectResult>(result);
Assert.Equal(404, objectResult.StatusCode);
}
[Fact]
public void CreateAlbumResponse_IncludesChildrenForSongs()
{
// Arrange
var album = new Album
{
Id = "album-1",
Title = "Full Album",
Artist = "Artist",
Songs = new List<Song>
{
new() { Id = "t1", Title = "Track 1", Artist = "Artist", Track = 1 },
new() { Id = "t2", Title = "Track 2", Artist = "Artist", Track = 2 }
}
};
// Act
var result = _builder.CreateAlbumResponse(album);
// Assert
var jsonResult = Assert.IsType<JsonResult>(result);
Assert.NotNull(jsonResult.Value);
}
[Fact]
public void CreateArtistResponse_IncludesAlbumsList()
{
// Arrange
var artist = new Artist { Id = "art-1", Name = "Test Artist" };
var albums = new List<Album>
{
new() { Id = "alb-1", Title = "First Album", Artist = "Test Artist" },
new() { Id = "alb-2", Title = "Second Album", Artist = "Test Artist" }
};
// Act
var result = _builder.CreateArtistResponse(artist, albums);
// Assert
var jsonResult = Assert.IsType<JsonResult>(result);
Assert.NotNull(jsonResult.Value);
}
[Fact]
public void CreatePlaylistAsAlbumResponse_CalculatesTotalDuration()
{
// Arrange
var playlist = new ExternalPlaylist
{
Id = "pl-1",
Name = "My Playlist",
Provider = "deezer",
ExternalId = "123"
};
var tracks = new List<Song>
{
new() { Id = "t1", Title = "Song 1", Duration = 180 },
new() { Id = "t2", Title = "Song 2", Duration = 240 },
new() { Id = "t3", Title = "Song 3", Duration = 200 }
};
// Act
var result = _builder.CreatePlaylistAsAlbumResponse(playlist, tracks);
// Assert
var jsonResult = Assert.IsType<JsonResult>(result);
Assert.NotNull(jsonResult.Value);
}
}