using PLib.Application.Abstractions; using PLib.Application.Library; using PLib.Domain.Videos; namespace PLib.Tests.Library; /// /// A hand-written double rather than a mock: the scan logic is all about what ends up in the /// repository, so the tests read better when they can just look at the resulting list. /// internal sealed class InMemoryVideoRepository : IVideoRepository { private readonly Dictionary _items = new(LibraryPathComparer.Instance); public int SaveCount { get; private set; } public IReadOnlyCollection Items => _items.Values; public void Seed(params VideoItem[] items) { foreach (var item in items) { _items[item.FullPath] = item; } } public Task> GetAllAsync(CancellationToken cancellationToken = default) => Task.FromResult>([.. _items.Values]); // Labels are held on the entity itself here, so this is the same list. public Task> GetAllWithLabelsAsync(CancellationToken cancellationToken = default) => GetAllAsync(cancellationToken); // Applied sources live on the entity here, so this is the same list again. public Task> GetAllWithMetadataSourcesAsync(CancellationToken cancellationToken = default) => GetAllAsync(cancellationToken); public Task FindByPathAsync(string fullPath, CancellationToken cancellationToken = default) => Task.FromResult(_items.GetValueOrDefault(fullPath)); // Labels are held on the entity itself here, so there is nothing extra to load. public Task FindWithLabelsAsync(Guid id, CancellationToken cancellationToken = default) => Task.FromResult(_items.Values.FirstOrDefault(item => item.Id == id)); public Task AddAsync(VideoItem item, CancellationToken cancellationToken = default) { _items[item.FullPath] = item; return Task.CompletedTask; } public Task RemoveAsync(VideoItem item, CancellationToken cancellationToken = default) { _items.Remove(item.FullPath); return Task.CompletedTask; } public Task SaveChangesAsync(CancellationToken cancellationToken = default) { SaveCount++; return Task.CompletedTask; } }