Enhance video library management in PLib by introducing folder change tracking and improving video item metadata handling. Update IVideoRepository to include a method for loading video items with labels. Revise VideoPlayerViewModel to manage playback progress and integrate new UI elements for displaying watched status and resume options. Update MainWindowViewModel to observe folder changes for automatic rescanning. Enhance README.md to document these new features and usage instructions.
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
using PLib.Domain.Videos;
|
||||
using Shouldly;
|
||||
|
||||
namespace PLib.Tests.Domain;
|
||||
|
||||
public sealed class WatchProgressTests
|
||||
{
|
||||
private static VideoItem CreateHourLongVideo()
|
||||
{
|
||||
var item = new VideoItem(@"C:\videos\film.mp4", "film", 1_000, DateTimeOffset.UnixEpoch);
|
||||
item.ApplyTechnicalInfo(new VideoTechnicalInfo(TimeSpan.FromHours(1), 1920, 1080, "h264"));
|
||||
return item;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_position_worth_returning_to_is_remembered()
|
||||
{
|
||||
var item = CreateHourLongVideo();
|
||||
|
||||
item.RememberProgress(TimeSpan.FromMinutes(20));
|
||||
|
||||
item.ResumePosition.ShouldBe(TimeSpan.FromMinutes(20));
|
||||
item.WatchedFraction.ShouldBe(1.0 / 3, 0.01);
|
||||
item.PlayCount.ShouldBe(0);
|
||||
item.LastPlayedAt.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Stopping_in_the_first_seconds_leaves_nothing_to_resume()
|
||||
{
|
||||
var item = CreateHourLongVideo();
|
||||
|
||||
item.RememberProgress(TimeSpan.FromSeconds(5));
|
||||
|
||||
item.ResumePosition.ShouldBeNull();
|
||||
item.PlayCount.ShouldBe(0);
|
||||
|
||||
// It still counts as opened, which is what recently-played ordering uses.
|
||||
item.LastPlayedAt.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Reaching_the_credits_counts_as_watched_rather_than_as_a_resume_point()
|
||||
{
|
||||
var item = CreateHourLongVideo();
|
||||
|
||||
// Inside the end-of-playback slack: the viewer is done, not paused.
|
||||
item.RememberProgress(TimeSpan.FromMinutes(60) - TimeSpan.FromSeconds(5));
|
||||
|
||||
item.ResumePosition.ShouldBeNull();
|
||||
item.PlayCount.ShouldBe(1);
|
||||
item.WatchedFraction.ShouldBe(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Watching_again_after_finishing_starts_a_fresh_resume_point()
|
||||
{
|
||||
var item = CreateHourLongVideo();
|
||||
item.RememberProgress(TimeSpan.FromMinutes(60));
|
||||
item.RememberProgress(TimeSpan.FromMinutes(3));
|
||||
|
||||
item.PlayCount.ShouldBe(1);
|
||||
item.ResumePosition.ShouldBe(TimeSpan.FromMinutes(3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_video_of_unknown_length_still_remembers_where_it_stopped()
|
||||
{
|
||||
var item = new VideoItem(@"C:\videos\odd.mkv", "odd", 1_000, DateTimeOffset.UnixEpoch);
|
||||
|
||||
item.RememberProgress(TimeSpan.FromMinutes(5));
|
||||
|
||||
item.ResumePosition.ShouldBe(TimeSpan.FromMinutes(5));
|
||||
|
||||
// Without a duration there is no fraction to draw.
|
||||
item.WatchedFraction.ShouldBe(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user