You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
6.7 KiB
214 lines
6.7 KiB
using System.Collections.ObjectModel;
|
|
using Recyclarr.TrashLib.Cache;
|
|
using Recyclarr.TrashLib.Config.Services;
|
|
using Recyclarr.TrashLib.Pipelines.CustomFormat.Models;
|
|
|
|
namespace Recyclarr.TrashLib.Tests.Cache;
|
|
|
|
[TestFixture]
|
|
[Parallelizable(ParallelScope.All)]
|
|
public class ServiceCacheTest
|
|
{
|
|
private sealed class ObjectWithoutAttribute
|
|
{
|
|
}
|
|
|
|
private const string ValidObjectName = "azAZ_09";
|
|
|
|
[CacheObjectName(ValidObjectName)]
|
|
private sealed class ObjectWithAttribute
|
|
{
|
|
public string TestValue { get; init; } = "";
|
|
}
|
|
|
|
[CacheObjectName("invalid+name")]
|
|
private sealed class ObjectWithAttributeInvalidChars
|
|
{
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Load_returns_null_when_file_does_not_exist(
|
|
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
var result = sut.Load<ObjectWithAttribute>(config);
|
|
result.Should().BeNull();
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Loading_with_attribute_parses_correctly(
|
|
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
|
|
[Frozen] ICacheStoragePath storage,
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
const string testJson = @"{'test_value': 'Foo'}";
|
|
|
|
const string testJsonPath = "cacheFile.json";
|
|
fs.AddFile(testJsonPath, new MockFileData(testJson));
|
|
|
|
storage.CalculatePath(default!, default!).ReturnsForAnyArgs(fs.FileInfo.New(testJsonPath));
|
|
|
|
var obj = sut.Load<ObjectWithAttribute>(config);
|
|
|
|
obj.Should().NotBeNull();
|
|
obj!.TestValue.Should().Be("Foo");
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Loading_with_invalid_object_name_throws(
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
Action act = () => sut.Load<ObjectWithAttributeInvalidChars>(config);
|
|
|
|
act.Should()
|
|
.Throw<ArgumentException>()
|
|
.WithMessage("*'invalid+name' has unacceptable characters*");
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Loading_without_attribute_throws(
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
Action act = () => sut.Load<ObjectWithoutAttribute>(config);
|
|
|
|
act.Should()
|
|
.Throw<ArgumentException>()
|
|
.WithMessage("CacheObjectNameAttribute is missing*");
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Properties_are_saved_using_snake_case(
|
|
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
|
|
[Frozen] ICacheStoragePath storage,
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
storage.CalculatePath(default!, default!)
|
|
.ReturnsForAnyArgs(_ => fs.FileInfo.New($"{ValidObjectName}.json"));
|
|
|
|
sut.Save(new ObjectWithAttribute {TestValue = "Foo"}, config);
|
|
|
|
fs.AllFiles.Should().ContainMatch($"*{ValidObjectName}.json");
|
|
|
|
var file = fs.GetFile(storage.CalculatePath(config, "").FullName);
|
|
file.Should().NotBeNull();
|
|
file.TextContents.Should().Contain("\"test_value\"");
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Saving_with_attribute_parses_correctly(
|
|
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
|
|
[Frozen] ICacheStoragePath storage,
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
const string testJsonPath = "cacheFile.json";
|
|
storage.CalculatePath(default!, default!).ReturnsForAnyArgs(fs.FileInfo.New(testJsonPath));
|
|
|
|
sut.Save(new ObjectWithAttribute {TestValue = "Foo"}, config);
|
|
|
|
var expectedFile = fs.GetFile(testJsonPath);
|
|
expectedFile.Should().NotBeNull();
|
|
expectedFile.TextContents.Should().Be(@"{
|
|
""test_value"": ""Foo""
|
|
}");
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Saving_with_invalid_object_name_throws(
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
var act = () => sut.Save(new ObjectWithAttributeInvalidChars(), config);
|
|
|
|
act.Should()
|
|
.Throw<ArgumentException>()
|
|
.WithMessage("*'invalid+name' has unacceptable characters*");
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Saving_without_attribute_throws(
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
var act = () => sut.Save(new ObjectWithoutAttribute(), config);
|
|
|
|
act.Should()
|
|
.Throw<ArgumentException>()
|
|
.WithMessage("CacheObjectNameAttribute is missing*");
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Switching_config_and_base_url_should_yield_different_cache_paths(
|
|
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
|
|
[Frozen] ICacheStoragePath storage,
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
storage.CalculatePath(default!, default!).ReturnsForAnyArgs(fs.FileInfo.New("Foo.json"));
|
|
sut.Save(new ObjectWithAttribute {TestValue = "Foo"}, config);
|
|
|
|
storage.CalculatePath(default!, default!).ReturnsForAnyArgs(fs.FileInfo.New("Bar.json"));
|
|
sut.Save(new ObjectWithAttribute {TestValue = "Bar"}, config);
|
|
|
|
var expectedFiles = new[] {"*Foo.json", "*Bar.json"};
|
|
foreach (var expectedFile in expectedFiles)
|
|
{
|
|
fs.AllFiles.Should().ContainMatch(expectedFile);
|
|
}
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void When_cache_file_is_empty_do_not_throw(
|
|
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
|
|
[Frozen] ICacheStoragePath storage,
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
storage.CalculatePath(default!, default!).ReturnsForAnyArgs(fs.FileInfo.New("cacheFile.json"));
|
|
fs.AddFile("cacheFile.json", new MockFileData(""));
|
|
|
|
Action act = () => sut.Load<ObjectWithAttribute>(config);
|
|
|
|
act.Should().NotThrow();
|
|
}
|
|
|
|
[Test, AutoMockData]
|
|
public void Name_properties_are_set_on_load(
|
|
[Frozen(Matching.ImplementedInterfaces)] MockFileSystem fs,
|
|
[Frozen] ICacheStoragePath storage,
|
|
IServiceConfiguration config,
|
|
ServiceCache sut)
|
|
{
|
|
const string cacheJson = @"
|
|
{
|
|
'version': 1,
|
|
'trash_id_mappings': [
|
|
{
|
|
'custom_format_name': '4K Remaster',
|
|
'trash_id': 'eca37840c13c6ef2dd0262b141a5482f',
|
|
'custom_format_id': 4
|
|
}
|
|
]
|
|
}
|
|
";
|
|
|
|
fs.AddFile("cacheFile.json", new MockFileData(cacheJson));
|
|
storage.CalculatePath(default!, default!).ReturnsForAnyArgs(fs.FileInfo.New("cacheFile.json"));
|
|
|
|
var result = sut.Load<CustomFormatCache>(config);
|
|
|
|
result.Should().BeEquivalentTo(new
|
|
{
|
|
TrashIdMappings = new Collection<TrashIdMapping>
|
|
{
|
|
new("eca37840c13c6ef2dd0262b141a5482f", "4K Remaster", 4)
|
|
}
|
|
});
|
|
}
|
|
}
|