Expand integration coverage and fix settings UI

This commit is contained in:
ajp_anton
2026-07-21 00:42:44 +00:00
parent 25088ce91d
commit 094d5ad9f0
26 changed files with 1665 additions and 66 deletions
@@ -0,0 +1,85 @@
using System.Net;
using Jellyfin.Plugin.Multilang.Data;
using Jellyfin.Plugin.Multilang.Services.Assets;
namespace Jellyfin.Plugin.Multilang.Tests;
public sealed class AssetStorageServiceTests
{
[Fact]
public async Task LocalStorageDownloadsAStableAssetPathAndServesIt()
{
var root = TestPaths.CreateRoot();
try
{
var store = new TranslationStore(new TestApplicationPaths(root));
var factory = new TestHttpClientFactory(_ => new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent([1, 2, 3])
});
var service = new AssetStorageService(factory, store);
var path = await service.StoreAsync("item", "fi", "poster", "https://images.example/poster.jpg", true, CancellationToken.None);
Assert.NotNull(path);
Assert.StartsWith(TranslationStore.LocalAssetUrlPrefix, path, StringComparison.Ordinal);
Assert.True(store.TryNormalizeLocalAssetPath(path, out var fullPath));
Assert.Equal([1, 2, 3], await File.ReadAllBytesAsync(fullPath));
Assert.True(service.TryResolveLocalAsset(path[TranslationStore.LocalAssetUrlPrefix.Length..], out var resolved, out var contentType));
Assert.Equal(fullPath, resolved);
Assert.Equal("image/jpeg", contentType);
}
finally
{
TestPaths.DeleteRoot(root);
}
}
[Fact]
public async Task UrlStorageDoesNotFetchOrWriteAnAsset()
{
var root = TestPaths.CreateRoot();
try
{
var store = new TranslationStore(new TestApplicationPaths(root));
var factory = new TestHttpClientFactory(_ => throw new InvalidOperationException("URL storage must not fetch."));
var service = new AssetStorageService(factory, store);
const string url = "https://images.example/poster.webp";
var result = await service.StoreAsync("item", "fi", "poster", url, false, CancellationToken.None);
Assert.Equal(url, result);
Assert.Empty(factory.Requests);
Assert.Empty(Directory.EnumerateFiles(store.AssetsDirectory, "*", SearchOption.AllDirectories));
}
finally
{
TestPaths.DeleteRoot(root);
}
}
[Fact]
public async Task LocalStorageRejectsAnOversizedResponseBeforeWritingIt()
{
var root = TestPaths.CreateRoot();
try
{
var store = new TranslationStore(new TestApplicationPaths(root));
var factory = new TestHttpClientFactory(_ =>
{
var content = new ByteArrayContent([1]);
content.Headers.ContentLength = 51L * 1024L * 1024L;
return new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
});
var service = new AssetStorageService(factory, store);
await Assert.ThrowsAsync<InvalidOperationException>(() => service.StoreAsync("item", "fi", "poster", "https://images.example/poster.jpg", true, CancellationToken.None));
Assert.Empty(Directory.EnumerateFiles(store.AssetsDirectory, "*", SearchOption.AllDirectories));
}
finally
{
TestPaths.DeleteRoot(root);
}
}
}