refactor: rename file to match class name

recyclarr
Robert Dailey 4 years ago
parent 50195b8cfd
commit 2f3c56783c

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
application continues as if there was no cache at all. application continues as if there was no cache at all.
- Fix a bug that resulted in certain custom formats not having their scores set in quality - Fix a bug that resulted in certain custom formats not having their scores set in quality
profiles. profiles.
- Fixed an issue where multiple instance configuration was not working.
### Changed ### Changed

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Abstractions; using System.IO.Abstractions;
using FluentAssertions; using FluentAssertions;
@ -21,12 +22,17 @@ namespace Trash.Tests.Cache
{ {
Filesystem = fs ?? Substitute.For<IFileSystem>(); Filesystem = fs ?? Substitute.For<IFileSystem>();
StoragePath = Substitute.For<ICacheStoragePath>(); StoragePath = Substitute.For<ICacheStoragePath>();
ServiceConfig = Substitute.For<IServiceConfiguration>(); ConfigProvider = Substitute.For<IConfigurationProvider>();
Cache = new ServiceCache(Filesystem, StoragePath, ServiceConfig, Substitute.For<ILogger>());
// Set up a default for the active config's base URL. This is used to generate part of the path
ConfigProvider.ActiveConfiguration = Substitute.For<IServiceConfiguration>();
ConfigProvider.ActiveConfiguration.BaseUrl.Returns("http://localhost:1234");
Cache = new ServiceCache(Filesystem, StoragePath, ConfigProvider, Substitute.For<ILogger>());
} }
public ServiceCache Cache { get; } public ServiceCache Cache { get; }
public IServiceConfiguration ServiceConfig { get; } public IConfigurationProvider ConfigProvider { get; }
public ICacheStoragePath StoragePath { get; } public ICacheStoragePath StoragePath { get; }
public IFileSystem Filesystem { get; } public IFileSystem Filesystem { get; }
} }
@ -74,7 +80,7 @@ namespace Trash.Tests.Cache
obj.Should().NotBeNull(); obj.Should().NotBeNull();
obj!.TestValue.Should().Be("Foo"); obj!.TestValue.Should().Be("Foo");
ctx.Filesystem.File.Received().ReadAllText(Path.Combine("testpath", "c59d1c81", $"{ValidObjectName}.json")); ctx.Filesystem.File.Received().ReadAllText(Path.Combine("testpath", "be8fbc8f", $"{ValidObjectName}.json"));
} }
[Test] [Test]
@ -110,7 +116,7 @@ namespace Trash.Tests.Cache
ctx.Cache.Save(new ObjectWithAttribute {TestValue = "Foo"}); ctx.Cache.Save(new ObjectWithAttribute {TestValue = "Foo"});
var expectedParentDirectory = Path.Combine("testpath", "c59d1c81"); var expectedParentDirectory = Path.Combine("testpath", "be8fbc8f");
ctx.Filesystem.Directory.Received().CreateDirectory(expectedParentDirectory); ctx.Filesystem.Directory.Received().CreateDirectory(expectedParentDirectory);
dynamic expectedJson = new {TestValue = "Foo"}; dynamic expectedJson = new {TestValue = "Foo"};
@ -143,6 +149,31 @@ namespace Trash.Tests.Cache
.WithMessage("CacheObjectNameAttribute is missing*"); .WithMessage("CacheObjectNameAttribute is missing*");
} }
[Test]
public void Switching_config_and_base_url_should_yield_different_cache_paths()
{
var ctx = new Context();
ctx.StoragePath.Path.Returns("testpath");
var actualPaths = new List<string>();
dynamic testJson = new {TestValue = "Foo"};
ctx.Filesystem.File.Exists(Arg.Any<string>()).Returns(true);
ctx.Filesystem.File.ReadAllText(Arg.Do<string>(s => actualPaths.Add(s)))
.Returns(_ => JsonConvert.SerializeObject(testJson));
ctx.Cache.Load<ObjectWithAttribute>();
// Change the active config & base URL so we get a different path
ctx.ConfigProvider.ActiveConfiguration = Substitute.For<IServiceConfiguration>();
ctx.ConfigProvider.ActiveConfiguration.BaseUrl.Returns("http://localhost:5678");
ctx.Cache.Load<ObjectWithAttribute>();
actualPaths.Count.Should().Be(2);
actualPaths.Should().OnlyHaveUniqueItems();
}
[Test] [Test]
public void When_cache_file_is_empty_do_not_throw() public void When_cache_file_is_empty_do_not_throw()
{ {

@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using Trash.Config;
using Trash.Radarr; using Trash.Radarr;
using Trash.Radarr.CustomFormat.Api; using Trash.Radarr.CustomFormat.Api;
using Trash.Radarr.CustomFormat.Models; using Trash.Radarr.CustomFormat.Models;
@ -22,13 +23,15 @@ namespace Trash.Tests.Radarr.CustomFormat.Processors
var steps = Substitute.For<IPersistenceProcessorSteps>(); var steps = Substitute.For<IPersistenceProcessorSteps>();
var cfApi = Substitute.For<ICustomFormatService>(); var cfApi = Substitute.For<ICustomFormatService>();
var qpApi = Substitute.For<IQualityProfileService>(); var qpApi = Substitute.For<IQualityProfileService>();
var config = new RadarrConfiguration {DeleteOldCustomFormats = true};
var configProvider = Substitute.For<IConfigurationProvider>();
configProvider.ActiveConfiguration = new RadarrConfiguration {DeleteOldCustomFormats = true};
var guideCfs = Array.Empty<ProcessedCustomFormatData>(); var guideCfs = Array.Empty<ProcessedCustomFormatData>();
var deletedCfsInCache = new Collection<TrashIdMapping>(); var deletedCfsInCache = new Collection<TrashIdMapping>();
var profileScores = new Dictionary<string, List<QualityProfileCustomFormatScoreEntry>>(); var profileScores = new Dictionary<string, List<QualityProfileCustomFormatScoreEntry>>();
var processor = new PersistenceProcessor(cfApi, qpApi, config, () => steps); var processor = new PersistenceProcessor(cfApi, qpApi, configProvider, () => steps);
processor.PersistCustomFormats(guideCfs, deletedCfsInCache, profileScores); processor.PersistCustomFormats(guideCfs, deletedCfsInCache, profileScores);
steps.JsonTransactionStep.Received().RecordDeletions(Arg.Is(deletedCfsInCache), Arg.Any<List<JObject>>()); steps.JsonTransactionStep.Received().RecordDeletions(Arg.Is(deletedCfsInCache), Arg.Any<List<JObject>>());
@ -40,17 +43,43 @@ namespace Trash.Tests.Radarr.CustomFormat.Processors
var steps = Substitute.For<IPersistenceProcessorSteps>(); var steps = Substitute.For<IPersistenceProcessorSteps>();
var cfApi = Substitute.For<ICustomFormatService>(); var cfApi = Substitute.For<ICustomFormatService>();
var qpApi = Substitute.For<IQualityProfileService>(); var qpApi = Substitute.For<IQualityProfileService>();
var config = new RadarrConfiguration(); // DeleteOldCustomFormats should default to false
var configProvider = Substitute.For<IConfigurationProvider>();
configProvider.ActiveConfiguration = new RadarrConfiguration {DeleteOldCustomFormats = false};
var guideCfs = Array.Empty<ProcessedCustomFormatData>(); var guideCfs = Array.Empty<ProcessedCustomFormatData>();
var deletedCfsInCache = Array.Empty<TrashIdMapping>(); var deletedCfsInCache = Array.Empty<TrashIdMapping>();
var profileScores = new Dictionary<string, List<QualityProfileCustomFormatScoreEntry>>(); var profileScores = new Dictionary<string, List<QualityProfileCustomFormatScoreEntry>>();
var processor = new PersistenceProcessor(cfApi, qpApi, config, () => steps); var processor = new PersistenceProcessor(cfApi, qpApi, configProvider, () => steps);
processor.PersistCustomFormats(guideCfs, deletedCfsInCache, profileScores); processor.PersistCustomFormats(guideCfs, deletedCfsInCache, profileScores);
steps.JsonTransactionStep.DidNotReceive() steps.JsonTransactionStep.DidNotReceive()
.RecordDeletions(Arg.Any<IEnumerable<TrashIdMapping>>(), Arg.Any<List<JObject>>()); .RecordDeletions(Arg.Any<IEnumerable<TrashIdMapping>>(), Arg.Any<List<JObject>>());
} }
[Test]
public void Different_active_configuration_is_properly_used()
{
var steps = Substitute.For<IPersistenceProcessorSteps>();
var cfApi = Substitute.For<ICustomFormatService>();
var qpApi = Substitute.For<IQualityProfileService>();
var configProvider = Substitute.For<IConfigurationProvider>();
var guideCfs = Array.Empty<ProcessedCustomFormatData>();
var deletedCfsInCache = Array.Empty<TrashIdMapping>();
var profileScores = new Dictionary<string, List<QualityProfileCustomFormatScoreEntry>>();
var processor = new PersistenceProcessor(cfApi, qpApi, configProvider, () => steps);
configProvider.ActiveConfiguration = new RadarrConfiguration {DeleteOldCustomFormats = false};
processor.PersistCustomFormats(guideCfs, deletedCfsInCache, profileScores);
configProvider.ActiveConfiguration = new RadarrConfiguration {DeleteOldCustomFormats = true};
processor.PersistCustomFormats(guideCfs, deletedCfsInCache, profileScores);
steps.JsonTransactionStep.Received(1)
.RecordDeletions(Arg.Any<IEnumerable<TrashIdMapping>>(), Arg.Any<List<JObject>>());
}
} }
} }

@ -15,17 +15,18 @@ namespace Trash.Cache
public class ServiceCache : IServiceCache public class ServiceCache : IServiceCache
{ {
private static readonly Regex AllowedObjectNameCharacters = new(@"^[\w-]+$", RegexOptions.Compiled); private static readonly Regex AllowedObjectNameCharacters = new(@"^[\w-]+$", RegexOptions.Compiled);
private readonly IServiceConfiguration _config; private readonly IConfigurationProvider _configProvider;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly IFNV1a _hash; private readonly IFNV1a _hash;
private readonly ICacheStoragePath _storagePath; private readonly ICacheStoragePath _storagePath;
public ServiceCache(IFileSystem fileSystem, ICacheStoragePath storagePath, IServiceConfiguration config, public ServiceCache(IFileSystem fileSystem, ICacheStoragePath storagePath,
IConfigurationProvider configProvider,
ILogger log) ILogger log)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
_storagePath = storagePath; _storagePath = storagePath;
_config = config; _configProvider = configProvider;
Log = log; Log = log;
_hash = FNV1aFactory.Instance.Create(FNVConfig.GetPredefinedConfig(32)); _hash = FNV1aFactory.Instance.Create(FNVConfig.GetPredefinedConfig(32));
} }
@ -74,7 +75,8 @@ namespace Trash.Cache
private string BuildServiceGuid() private string BuildServiceGuid()
{ {
return _hash.ComputeHash(Encoding.ASCII.GetBytes(_config.BaseUrl)).AsHexString(); return _hash.ComputeHash(Encoding.ASCII.GetBytes(_configProvider.ActiveConfiguration.BaseUrl))
.AsHexString();
} }
private string PathFromAttribute<T>() private string PathFromAttribute<T>()

@ -95,8 +95,10 @@ namespace Trash
.As<IConfigurationProvider>() .As<IConfigurationProvider>()
.SingleInstance(); .SingleInstance();
builder.Register(c => c.Resolve<IConfigurationProvider>().ActiveConfiguration) // note: Do not allow consumers to resolve IServiceConfiguration directly; if this gets cached
.As<IServiceConfiguration>(); // they end up using the wrong configuration when multiple instances are used.
// builder.Register(c => c.Resolve<IConfigurationProvider>().ActiveConfiguration)
// .As<IServiceConfiguration>();
} }
private static void CommandRegistrations(ContainerBuilder builder) private static void CommandRegistrations(ContainerBuilder builder)

@ -10,11 +10,11 @@ namespace Trash.Radarr.CustomFormat.Api
{ {
internal class CustomFormatService : ICustomFormatService internal class CustomFormatService : ICustomFormatService
{ {
private readonly IServiceConfiguration _serviceConfig; private readonly IConfigurationProvider _configProvider;
public CustomFormatService(IServiceConfiguration serviceConfig) public CustomFormatService(IConfigurationProvider configProvider)
{ {
_serviceConfig = serviceConfig; _configProvider = configProvider;
} }
public async Task<List<JObject>> GetCustomFormats() public async Task<List<JObject>> GetCustomFormats()
@ -51,7 +51,7 @@ namespace Trash.Radarr.CustomFormat.Api
private string BaseUrl() private string BaseUrl()
{ {
return _serviceConfig.BuildUrl(); return _configProvider.ActiveConfiguration.BuildUrl();
} }
} }
} }

@ -9,14 +9,14 @@ namespace Trash.Radarr.CustomFormat.Api
{ {
internal class QualityProfileService : IQualityProfileService internal class QualityProfileService : IQualityProfileService
{ {
private readonly IServiceConfiguration _serviceConfig; private readonly IConfigurationProvider _configProvider;
public QualityProfileService(IServiceConfiguration serviceConfig) public QualityProfileService(IConfigurationProvider configProvider)
{ {
_serviceConfig = serviceConfig; _configProvider = configProvider;
} }
private string BaseUrl => _serviceConfig.BuildUrl(); private string BaseUrl => _configProvider.ActiveConfiguration.BuildUrl();
public async Task<List<JObject>> GetQualityProfiles() public async Task<List<JObject>> GetQualityProfiles()
{ {

@ -18,7 +18,7 @@ namespace Trash.Radarr.CustomFormat.Processors
internal class PersistenceProcessor : IPersistenceProcessor internal class PersistenceProcessor : IPersistenceProcessor
{ {
private readonly RadarrConfiguration _config; private readonly IConfigurationProvider _configProvider;
private readonly ICustomFormatService _customFormatService; private readonly ICustomFormatService _customFormatService;
private readonly IQualityProfileService _qualityProfileService; private readonly IQualityProfileService _qualityProfileService;
private readonly Func<IPersistenceProcessorSteps> _stepsFactory; private readonly Func<IPersistenceProcessorSteps> _stepsFactory;
@ -27,13 +27,13 @@ namespace Trash.Radarr.CustomFormat.Processors
public PersistenceProcessor( public PersistenceProcessor(
ICustomFormatService customFormatService, ICustomFormatService customFormatService,
IQualityProfileService qualityProfileService, IQualityProfileService qualityProfileService,
IServiceConfiguration config, IConfigurationProvider configProvider,
Func<IPersistenceProcessorSteps> stepsFactory) Func<IPersistenceProcessorSteps> stepsFactory)
{ {
_customFormatService = customFormatService; _customFormatService = customFormatService;
_qualityProfileService = qualityProfileService; _qualityProfileService = qualityProfileService;
_stepsFactory = stepsFactory; _stepsFactory = stepsFactory;
_config = (RadarrConfiguration) config; _configProvider = configProvider;
_steps = _stepsFactory(); _steps = _stepsFactory();
} }
@ -63,7 +63,8 @@ namespace Trash.Radarr.CustomFormat.Processors
_steps.JsonTransactionStep.Process(guideCfs, radarrCfs); _steps.JsonTransactionStep.Process(guideCfs, radarrCfs);
// Step 1.1: Optionally record deletions of custom formats in cache but not in the guide // Step 1.1: Optionally record deletions of custom formats in cache but not in the guide
if (_config.DeleteOldCustomFormats) var config = (RadarrConfiguration) _configProvider.ActiveConfiguration;
if (config.DeleteOldCustomFormats)
{ {
_steps.JsonTransactionStep.RecordDeletions(deletedCfsInCache, radarrCfs); _steps.JsonTransactionStep.RecordDeletions(deletedCfsInCache, radarrCfs);
} }

@ -21,8 +21,7 @@ namespace Trash.Radarr.CustomFormat.Processors.PersistenceSteps
IDictionary<string, List<QualityProfileCustomFormatScoreEntry>> cfScores) IDictionary<string, List<QualityProfileCustomFormatScoreEntry>> cfScores)
{ {
var radarrProfiles = (await api.GetQualityProfiles()) var radarrProfiles = (await api.GetQualityProfiles())
.Select(p => (Name: p["name"].ToString(), Json: p)) .Select(p => (Name: p["name"].ToString(), Json: p));
.ToList();
var profileScores = cfScores var profileScores = cfScores
.GroupJoin(radarrProfiles, .GroupJoin(radarrProfiles,

@ -9,14 +9,14 @@ namespace Trash.Radarr.QualityDefinition.Api
{ {
public class QualityDefinitionService : IQualityDefinitionService public class QualityDefinitionService : IQualityDefinitionService
{ {
private readonly IServiceConfiguration _serviceConfig; private readonly IConfigurationProvider _configProvider;
public QualityDefinitionService(IServiceConfiguration serviceConfig) public QualityDefinitionService(IConfigurationProvider configProvider)
{ {
_serviceConfig = serviceConfig; _configProvider = configProvider;
} }
private string BaseUrl => _serviceConfig.BuildUrl(); private string BaseUrl => _configProvider.ActiveConfiguration.BuildUrl();
public async Task<List<RadarrQualityDefinitionItem>> GetQualityDefinition() public async Task<List<RadarrQualityDefinitionItem>> GetQualityDefinition()
{ {

@ -10,11 +10,11 @@ namespace Trash.Sonarr.Api
{ {
public class SonarrApi : ISonarrApi public class SonarrApi : ISonarrApi
{ {
private readonly IServiceConfiguration _config; private readonly IConfigurationProvider _configProvider;
public SonarrApi(IServiceConfiguration config) public SonarrApi(IConfigurationProvider configProvider)
{ {
_config = config; _configProvider = configProvider;
} }
public async Task<Version> GetVersion() public async Task<Version> GetVersion()
@ -78,9 +78,6 @@ namespace Trash.Sonarr.Api
.ReceiveJson<List<SonarrQualityDefinitionItem>>(); .ReceiveJson<List<SonarrQualityDefinitionItem>>();
} }
private string BaseUrl() private string BaseUrl() => _configProvider.ActiveConfiguration.BaseUrl;
{
return _config.BuildUrl();
}
} }
} }

Loading…
Cancel
Save