Refactor media source handling and update collection options
- Updated `IMediaSourceCatalog` to support user-added media sources, allowing dynamic editing and management of sources. - Removed the `UrlListSource` class as its functionality is now integrated into the new catalog structure. - Enhanced `CollectOptions` to default `RequireProxy` to true, ensuring stricter handling of proxy requirements. - Improved error handling in `ParseError` to include a `Subject` field for better context on failures. - Adjusted dependency injection to reflect changes in media source management, removing old source registrations. - Introduced background proxy checks to ensure a more robust proxy pool management during collection processes. These changes streamline the media collection process and improve the overall user experience by providing clearer error reporting and more flexible source management.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
using AvParser.Core.Collecting;
|
||||
using AvParser.Core.Collecting.Sources;
|
||||
|
||||
namespace AvParser.Core.Tests.Collecting;
|
||||
|
||||
public class MediaSourceCatalogTests
|
||||
{
|
||||
private sealed class FakeStore(IEnumerable<PatternSourceConfig>? seed = null) : IUserSourceStore
|
||||
{
|
||||
private readonly List<PatternSourceConfig> _configs = seed?.ToList() ?? [];
|
||||
|
||||
public event EventHandler? Changed;
|
||||
|
||||
public IReadOnlyList<PatternSourceConfig> List() => [.. _configs];
|
||||
|
||||
public Task<PatternSourceConfig> AddAsync(
|
||||
PatternSourceConfig config,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
_configs.Add(config);
|
||||
Changed?.Invoke(this, EventArgs.Empty);
|
||||
return Task.FromResult(config);
|
||||
}
|
||||
|
||||
public Task<bool> UpdateAsync(PatternSourceConfig config, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var index = _configs.FindIndex(c => c.Id == config.Id);
|
||||
if (index < 0)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
_configs[index] = config;
|
||||
Changed?.Invoke(this, EventArgs.Empty);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task<bool> RemoveAsync(string id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var removed = _configs.RemoveAll(c => c.Id == id) > 0;
|
||||
if (removed)
|
||||
{
|
||||
Changed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
return Task.FromResult(removed);
|
||||
}
|
||||
}
|
||||
|
||||
private static PatternSourceConfig Config(string id, string name)
|
||||
{
|
||||
PatternSourceConfig.TryCreate(
|
||||
name,
|
||||
"https://h/x/",
|
||||
6,
|
||||
8,
|
||||
IdAlphabet.Digits,
|
||||
null,
|
||||
null,
|
||||
allowDirectConnection: false,
|
||||
out var config,
|
||||
id
|
||||
);
|
||||
return config!;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_empty_store_is_a_valid_empty_catalog()
|
||||
{
|
||||
using var catalog = new MediaSourceCatalog(new FakeStore());
|
||||
|
||||
catalog.Sources.ShouldBeEmpty();
|
||||
catalog.Find("anything").ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Sources_are_materialised_from_the_stored_configs()
|
||||
{
|
||||
using var catalog = new MediaSourceCatalog(new FakeStore([Config("s1", "Beta"), Config("s2", "Alpha")]));
|
||||
|
||||
// Ordered by display name.
|
||||
catalog.Sources.Select(s => s.Id).ShouldBe(["s2", "s1"]);
|
||||
catalog.Find("s1").ShouldNotBeNull().DisplayName.ShouldBe("Beta");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Adding_through_the_catalog_rebuilds_and_signals()
|
||||
{
|
||||
var store = new FakeStore();
|
||||
using var catalog = new MediaSourceCatalog(store);
|
||||
var changed = 0;
|
||||
catalog.Changed += (_, _) => changed++;
|
||||
|
||||
await catalog.AddAsync(Config("s1", "One"), TestContext.Current.CancellationToken);
|
||||
|
||||
changed.ShouldBe(1);
|
||||
catalog.Sources.ShouldHaveSingleItem().Id.ShouldBe("s1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Removing_through_the_catalog_drops_the_source()
|
||||
{
|
||||
using var catalog = new MediaSourceCatalog(new FakeStore([Config("s1", "One")]));
|
||||
|
||||
await catalog.RemoveAsync("s1", TestContext.Current.CancellationToken);
|
||||
|
||||
catalog.Sources.ShouldBeEmpty();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user