Refresh tracked downloads on edit events

This commit is contained in:
Mika Cohen 2026-04-23 15:15:29 -06:00
parent 7cfbc88fb8
commit cce09c916a
No known key found for this signature in database
GPG key ID: D7415E8B2E80D893
2 changed files with 97 additions and 40 deletions

View file

@ -88,38 +88,15 @@ private void GivenTrackedDownloadCanBeMapped()
});
}
[Test]
public void should_reuse_stable_queued_downloading_tracked_download()
[TestCase(DownloadItemStatus.Queued)]
[TestCase(DownloadItemStatus.Paused)]
public void should_reuse_stable_waiting_downloading_tracked_download(DownloadItemStatus status)
{
GivenTrackedDownloadCanBeMapped();
var client = CreateDownloadClient();
var item = CreateDownloadItem(DownloadItemStatus.Queued);
var updatedItem = CreateDownloadItem(DownloadItemStatus.Queued);
updatedItem.RemainingSize = 250;
var trackedDownload = Subject.TrackDownload(client, item);
var refreshedTrackedDownload = Subject.TrackDownload(client, updatedItem);
trackedDownload.State.Should().Be(TrackedDownloadState.Downloading);
refreshedTrackedDownload.Should().BeSameAs(trackedDownload);
refreshedTrackedDownload.DownloadItem.Should().BeSameAs(updatedItem);
Mocker.GetMock<IHistoryService>()
.Verify(s => s.FindByDownloadId(It.IsAny<string>()), Times.Once());
Mocker.GetMock<IParsingService>()
.Verify(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null), Times.Once());
}
[Test]
public void should_reuse_stable_paused_downloading_tracked_download()
{
GivenTrackedDownloadCanBeMapped();
var client = CreateDownloadClient();
var item = CreateDownloadItem(DownloadItemStatus.Paused);
var updatedItem = CreateDownloadItem(DownloadItemStatus.Paused);
var item = CreateDownloadItem(status);
var updatedItem = CreateDownloadItem(status);
updatedItem.RemainingSize = 250;
var trackedDownload = Subject.TrackDownload(client, item);
@ -543,6 +520,74 @@ public void should_not_throw_when_processing_deleted_episodes()
trackedDownloads.First().RemoteEpisode.Should().BeNull();
}
[Test]
public void should_update_tracked_download_when_series_edited()
{
var originalSeries = new Series { Id = 5, TvdbId = 10, Title = "TV Series" };
var updatedSeries = new Series { Id = 5, TvdbId = 10, Title = "TV Series Updated" };
var remoteEpisode = new RemoteEpisode
{
Series = originalSeries,
Episodes = new List<Episode> { new Episode { Id = 4 } },
ParsedEpisodeInfo = new ParsedEpisodeInfo
{
SeriesTitle = "TV Series",
SeasonNumber = 1,
EpisodeNumbers = new[] { 1 }
}
};
var updatedRemoteEpisode = new RemoteEpisode
{
Series = updatedSeries,
Episodes = new List<Episode> { new Episode { Id = 4 } },
ParsedEpisodeInfo = new ParsedEpisodeInfo
{
SeriesTitle = "TV Series",
SeasonNumber = 1,
EpisodeNumbers = new[] { 1 }
}
};
Mocker.GetMock<IParsingService>()
.SetupSequence(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>(), null))
.Returns(remoteEpisode)
.Returns(updatedRemoteEpisode);
Mocker.GetMock<IHistoryService>()
.Setup(s => s.FindByDownloadId(It.IsAny<string>()))
.Returns(new List<EpisodeHistory>());
var client = new DownloadClientDefinition
{
Id = 1,
Protocol = DownloadProtocol.Torrent
};
var item = new DownloadClientItem
{
Title = "TV Series - S01E01",
DownloadId = "12345",
DownloadClientInfo = new DownloadClientItemClientInfo
{
Id = 1,
Type = "Blackhole",
Name = "Blackhole Client",
Protocol = DownloadProtocol.Torrent
}
};
Subject.TrackDownload(client, item);
Subject.Handle(new SeriesEditedEvent(updatedSeries, originalSeries));
var trackedDownloads = Subject.GetTrackedDownloads();
trackedDownloads.Should().HaveCount(1);
trackedDownloads.First().RemoteEpisode.Should().BeSameAs(updatedRemoteEpisode);
trackedDownloads.First().RemoteEpisode.Series.Title.Should().Be("TV Series Updated");
}
[Test]
public void should_not_throw_when_processing_deleted_series()
{

View file

@ -28,6 +28,7 @@ public interface ITrackedDownloadService
public class TrackedDownloadService : ITrackedDownloadService,
IHandle<EpisodeInfoRefreshedEvent>,
IHandle<SeriesEditedEvent>,
IHandle<SeriesAddedEvent>,
IHandle<SeriesDeletedEvent>
{
@ -283,6 +284,16 @@ private void UpdateCachedItem(TrackedDownload trackedDownload)
_aggregationService.Augment(trackedDownload.RemoteEpisode);
}
private void RefreshCachedItems(List<TrackedDownload> cachedItems)
{
if (cachedItems.Any())
{
cachedItems.ForEach(UpdateCachedItem);
_eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(GetTrackedDownloads()));
}
}
private static TrackedDownloadState GetStateFromHistory(DownloadHistoryEventType eventType)
{
switch (eventType)
@ -323,6 +334,17 @@ public void Handle(EpisodeInfoRefreshedEvent message)
}
}
public void Handle(SeriesEditedEvent message)
{
var cachedItems = _cache.Values
.Where(t =>
t.RemoteEpisode?.Series != null &&
(t.RemoteEpisode.Series.Id == message.Series?.Id || t.RemoteEpisode.Series.TvdbId == message.Series?.TvdbId))
.ToList();
RefreshCachedItems(cachedItems);
}
public void Handle(SeriesAddedEvent message)
{
var cachedItems = _cache.Values
@ -331,12 +353,7 @@ public void Handle(SeriesAddedEvent message)
message.Series?.TvdbId == t.RemoteEpisode.Series.TvdbId)
.ToList();
if (cachedItems.Any())
{
cachedItems.ForEach(UpdateCachedItem);
_eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(GetTrackedDownloads()));
}
RefreshCachedItems(cachedItems);
}
public void Handle(SeriesDeletedEvent message)
@ -347,12 +364,7 @@ public void Handle(SeriesDeletedEvent message)
message.Series.Any(s => s.Id == t.RemoteEpisode.Series.Id || s.TvdbId == t.RemoteEpisode.Series.TvdbId))
.ToList();
if (cachedItems.Any())
{
cachedItems.ForEach(UpdateCachedItem);
_eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(GetTrackedDownloads()));
}
RefreshCachedItems(cachedItems);
}
}
}