Files
pgsql-jellyfin/tests/Jellyfin.Providers.Tests/MediaInfo/VideoImageProviderTests.cs
wjones af1152b001 Refactor: standardize namespace and using directive style
Refactored all C# test files to use explicit namespace declarations and moved all using directives inside the namespace block for consistency. Updated assembly info and cache files to reflect the new build. Adjusted MvcTestingAppManifest.json to use fully qualified assembly names. No functional changes; all updates are related to code style, organization, and project metadata.
2026-02-20 16:26:53 -05:00

131 lines
6.2 KiB
C#

// <copyright file="VideoImageProviderTests.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace Jellyfin.Providers.Tests.MediaInfo
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Providers.MediaInfo;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Xunit;
public class VideoImageProviderTests
{
public static TheoryData<Video> GetImage_UnsupportedInput_ReturnsNoImage_TestData()
{
return new()
{
new Movie { IsPlaceHolder = true },
new Movie { DefaultVideoStreamIndex = null },
// set a default index but don't put anything there (invalid input, but provider shouldn't break)
new Movie { DefaultVideoStreamIndex = 0 }
};
}
[Theory]
[MemberData(nameof(GetImage_UnsupportedInput_ReturnsNoImage_TestData))]
public async Task GetImage_UnsupportedInput_ReturnsNoImage(Video input)
{
var mediaSourceManager = GetMediaSourceManager(input, null, new List<MediaStream>());
var videoImageProvider = new VideoImageProvider(mediaSourceManager, Mock.Of<IMediaEncoder>(), new NullLogger<VideoImageProvider>());
var actual = await videoImageProvider.GetImage(input, ImageType.Primary, CancellationToken.None);
Assert.NotNull(actual);
Assert.False(actual.HasImage);
}
[Theory]
[InlineData(1, 1)] // default not first stream
[InlineData(5, 0)] // default out of valid range
public async Task GetImage_DefaultVideoStreams_ReturnsCorrectStreamImage(int defaultIndex, int targetIndex)
{
var input = new Movie { DefaultVideoStreamIndex = defaultIndex };
string targetPath = "path.jpg";
var mediaStreams = new List<MediaStream>();
var mediaEncoder = new Mock<IMediaEncoder>(MockBehavior.Strict);
for (int i = 0; i <= targetIndex; i++)
{
var mediaStream = new MediaStream { Type = MediaStreamType.Video, Index = i };
mediaStreams.Add(mediaStream);
var path = i == targetIndex ? targetPath : "wrong stream called!";
mediaEncoder.Setup(encoder => encoder.ExtractVideoImage(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MediaSourceInfo>(), mediaStream, It.IsAny<Video3DFormat?>(), It.IsAny<TimeSpan?>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(path));
}
var defaultStream = defaultIndex < mediaStreams.Count ? mediaStreams[targetIndex] : null;
var mediaSourceManager = GetMediaSourceManager(input, defaultStream, mediaStreams);
var videoImageProvider = new VideoImageProvider(mediaSourceManager, mediaEncoder.Object, new NullLogger<VideoImageProvider>());
var actual = await videoImageProvider.GetImage(input, ImageType.Primary, CancellationToken.None);
Assert.NotNull(actual);
Assert.True(actual.HasImage);
Assert.Equal(targetPath, actual.Path);
Assert.Equal(ImageFormat.Jpg, actual.Format);
}
[Theory]
[InlineData(null, 10)] // default time
[InlineData(500, 50)] // calculated time
public async Task GetImage_TimeSpan_SelectsCorrectTime(int? runTimeSeconds, long expectedSeconds)
{
MediaStream targetStream = new() { Type = MediaStreamType.Video, Index = 0 };
var input = new Movie
{
DefaultVideoStreamIndex = 0,
RunTimeTicks = runTimeSeconds * TimeSpan.TicksPerSecond
};
var mediaSourceManager = GetMediaSourceManager(input, targetStream, new List<MediaStream> { targetStream });
// use a callback to catch the actual value
// provides more information on failure than verifying a specific input was called on the mock
TimeSpan? actualTimeSpan = null;
var mediaEncoder = new Mock<IMediaEncoder>(MockBehavior.Strict);
mediaEncoder.Setup(encoder => encoder.ExtractVideoImage(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MediaSourceInfo>(), It.IsAny<MediaStream>(), It.IsAny<Video3DFormat?>(), It.IsAny<TimeSpan?>(), CancellationToken.None))
.Callback<string, string, MediaSourceInfo, MediaStream, Video3DFormat?, TimeSpan?, CancellationToken>((_, _, _, _, _, timeSpan, _) => actualTimeSpan = timeSpan)
.Returns(Task.FromResult("path"));
var videoImageProvider = new VideoImageProvider(mediaSourceManager, mediaEncoder.Object, new NullLogger<VideoImageProvider>());
// not testing return, just verifying what gets requested for time span
await videoImageProvider.GetImage(input, ImageType.Primary, CancellationToken.None);
Assert.Equal(TimeSpan.FromSeconds(expectedSeconds), actualTimeSpan);
}
private static IMediaSourceManager GetMediaSourceManager(Video item, MediaStream? defaultStream, List<MediaStream> mediaStreams)
{
var defaultStreamList = new List<MediaStream>();
if (defaultStream is not null)
{
defaultStreamList.Add(defaultStream);
}
var mediaSourceManager = new Mock<IMediaSourceManager>(MockBehavior.Strict);
mediaSourceManager.Setup(i => i.GetMediaStreams(It.Is<MediaStreamQuery>(q => q.ItemId.Equals(item.Id) && q.Index == item.DefaultVideoStreamIndex)))
.Returns(defaultStreamList);
mediaSourceManager.Setup(i => i.GetMediaStreams(It.Is<MediaStreamQuery>(q => q.ItemId.Equals(item.Id) && q.Type == MediaStreamType.Video)))
.Returns(mediaStreams);
return mediaSourceManager.Object;
}
}
}