From 7eba162879f6d1ff04539cac5c0d6372a955d82b Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 28 Dec 2023 14:49:35 -0500 Subject: Move LiveTv tests to separate project --- .../Properties/AssemblyInfo.cs | 1 + Jellyfin.sln | 7 + tests/Jellyfin.LiveTv.Tests/HdHomerunHostTests.cs | 156 ++++++++++ .../Jellyfin.LiveTv.Tests/HdHomerunManagerTests.cs | 326 +++++++++++++++++++++ .../Jellyfin.LiveTv.Tests.csproj | 29 ++ .../Listings/XmlTvListingsProviderTests.cs | 89 ++++++ .../Jellyfin.LiveTv.Tests/RecordingHelperTests.cs | 109 +++++++ .../SchedulesDirectDeserializeTests.cs | 240 +++++++++++++++ .../Test Data/LiveTv/10.10.10.100/discover.json | 1 + .../Test Data/LiveTv/10.10.10.100/lineup.json | 1 + .../Test Data/LiveTv/192.168.1.182/discover.json | 1 + .../Test Data/LiveTv/192.168.1.182/lineup.json | 1 + .../LiveTv/Listings/XmlTv/emptycategory.xml | 6 + .../Test Data/LiveTv/Listings/XmlTv/notitle.xml | 10 + .../SchedulesDirect/headends_response.json | 1 + .../Test Data/SchedulesDirect/lineup_response.json | 1 + .../SchedulesDirect/lineups_response.json | 1 + .../metadata_programs_response.json | 1 + .../SchedulesDirect/programs_response.json | 1 + .../SchedulesDirect/schedules_request.json | 1 + .../SchedulesDirect/schedules_response.json | 1 + .../SchedulesDirect/token_live_response.json | 1 + .../SchedulesDirect/token_offline_response.json | 1 + .../LiveTv/HdHomerunHostTests.cs | 156 ---------- .../LiveTv/HdHomerunManagerTests.cs | 326 --------------------- .../LiveTv/Listings/XmlTvListingsProviderTests.cs | 89 ------ .../LiveTv/RecordingHelperTests.cs | 109 ------- .../SchedulesDirectDeserializeTests.cs | 240 --------------- .../Test Data/LiveTv/10.10.10.100/discover.json | 1 - .../Test Data/LiveTv/10.10.10.100/lineup.json | 1 - .../Test Data/LiveTv/192.168.1.182/discover.json | 1 - .../Test Data/LiveTv/192.168.1.182/lineup.json | 1 - .../LiveTv/Listings/XmlTv/emptycategory.xml | 6 - .../Test Data/LiveTv/Listings/XmlTv/notitle.xml | 10 - .../SchedulesDirect/headends_response.json | 1 - .../Test Data/SchedulesDirect/lineup_response.json | 1 - .../SchedulesDirect/lineups_response.json | 1 - .../metadata_programs_response.json | 1 - .../SchedulesDirect/programs_response.json | 1 - .../SchedulesDirect/schedules_request.json | 1 - .../SchedulesDirect/schedules_response.json | 1 - .../SchedulesDirect/token_live_response.json | 1 - .../SchedulesDirect/token_offline_response.json | 1 - 43 files changed, 986 insertions(+), 949 deletions(-) create mode 100644 tests/Jellyfin.LiveTv.Tests/HdHomerunHostTests.cs create mode 100644 tests/Jellyfin.LiveTv.Tests/HdHomerunManagerTests.cs create mode 100644 tests/Jellyfin.LiveTv.Tests/Jellyfin.LiveTv.Tests.csproj create mode 100644 tests/Jellyfin.LiveTv.Tests/Listings/XmlTvListingsProviderTests.cs create mode 100644 tests/Jellyfin.LiveTv.Tests/RecordingHelperTests.cs create mode 100644 tests/Jellyfin.LiveTv.Tests/SchedulesDirect/SchedulesDirectDeserializeTests.cs create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/discover.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/lineup.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/discover.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/lineup.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/headends_response.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineup_response.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineups_response.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/metadata_programs_response.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/programs_response.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_request.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_response.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_live_response.json create mode 100644 tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_offline_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/LiveTv/Listings/XmlTvListingsProviderTests.cs delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/LiveTv/RecordingHelperTests.cs delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/discover.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/lineup.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/discover.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/lineup.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/headends_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineup_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineups_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/metadata_programs_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/programs_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_request.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_live_response.json delete mode 100644 tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_offline_response.json diff --git a/Emby.Server.Implementations/Properties/AssemblyInfo.cs b/Emby.Server.Implementations/Properties/AssemblyInfo.cs index 41c396ac1..fb7377b1d 100644 --- a/Emby.Server.Implementations/Properties/AssemblyInfo.cs +++ b/Emby.Server.Implementations/Properties/AssemblyInfo.cs @@ -17,6 +17,7 @@ using System.Runtime.InteropServices; [assembly: NeutralResourcesLanguage("en")] [assembly: InternalsVisibleTo("Jellyfin.Server.Implementations.Tests")] [assembly: InternalsVisibleTo("Emby.Server.Implementations.Fuzz")] +[assembly: InternalsVisibleTo("Jellyfin.LiveTv.Tests")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from diff --git a/Jellyfin.sln b/Jellyfin.sln index 4385ac241..31e302d94 100644 --- a/Jellyfin.sln +++ b/Jellyfin.sln @@ -87,6 +87,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Hls. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.MediaEncoding.Keyframes.Tests", "tests\Jellyfin.MediaEncoding.Keyframes.Tests\Jellyfin.MediaEncoding.Keyframes.Tests.csproj", "{24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.LiveTv.Tests", "tests\Jellyfin.LiveTv.Tests\Jellyfin.LiveTv.Tests.csproj", "{C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -233,6 +235,10 @@ Global {24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Release|Any CPU.ActiveCfg = Release|Any CPU {24960660-DE6C-47BF-AEEF-CEE8F19FE6C2}.Release|Any CPU.Build.0 = Release|Any CPU + {C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -259,6 +265,7 @@ Global {08FFF49B-F175-4807-A2B5-73B0EBD9F716} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C} {154872D9-6C12-4007-96E3-8F70A58386CE} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C} {0A3FCC4D-C714-4072-B90F-E374A15F9FF9} = {C9F0AB5D-F4D7-40C8-A353-3305C86D6D4C} + {C4F71272-C6BE-4C30-BE0D-4E6ED651D6D3} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE} diff --git a/tests/Jellyfin.LiveTv.Tests/HdHomerunHostTests.cs b/tests/Jellyfin.LiveTv.Tests/HdHomerunHostTests.cs new file mode 100644 index 000000000..bc4b2da5b --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/HdHomerunHostTests.cs @@ -0,0 +1,156 @@ +using System; +using System.IO; +using System.Net.Http; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; +using Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun; +using MediaBrowser.Model.LiveTv; +using Moq; +using Moq.Protected; +using Xunit; + +namespace Jellyfin.LiveTv.Tests +{ + public class HdHomerunHostTests + { + private readonly Fixture _fixture; + private readonly HdHomerunHost _hdHomerunHost; + + public HdHomerunHostTests() + { + var messageHandler = new Mock(); + messageHandler.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .Returns( + (m, _) => + { + return Task.FromResult(new HttpResponseMessage() + { + Content = new StreamContent(File.OpenRead(Path.Combine("Test Data/LiveTv", m.RequestUri!.Host, m.RequestUri.Segments[^1]))) + }); + }); + + var http = new Mock(); + http.Setup(x => x.CreateClient(It.IsAny())) + .Returns(new HttpClient(messageHandler.Object)); + _fixture = new Fixture(); + _fixture.Customize(new AutoMoqCustomization + { + ConfigureMembers = true + }).Inject(http); + _hdHomerunHost = _fixture.Create(); + } + + [Fact] + public async Task GetModelInfo_Valid_Success() + { + var host = new TunerHostInfo() + { + Url = "192.168.1.182" + }; + + var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None); + Assert.Equal("HDHomeRun PRIME", modelInfo.FriendlyName); + Assert.Equal("HDHR3-CC", modelInfo.ModelNumber); + Assert.Equal("hdhomerun3_cablecard", modelInfo.FirmwareName); + Assert.Equal("20160630atest2", modelInfo.FirmwareVersion); + Assert.Equal("FFFFFFFF", modelInfo.DeviceID); + Assert.Equal("FFFFFFFF", modelInfo.DeviceAuth); + Assert.Equal(3, modelInfo.TunerCount); + Assert.Equal("http://192.168.1.182:80", modelInfo.BaseURL); + Assert.Equal("http://192.168.1.182:80/lineup.json", modelInfo.LineupURL); + } + + [Fact] + public async Task GetModelInfo_Legacy_Success() + { + var host = new TunerHostInfo() + { + Url = "10.10.10.100" + }; + + var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None); + Assert.Equal("HDHomeRun DUAL", modelInfo.FriendlyName); + Assert.Equal("HDHR3-US", modelInfo.ModelNumber); + Assert.Equal("hdhomerun3_atsc", modelInfo.FirmwareName); + Assert.Equal("20200225", modelInfo.FirmwareVersion); + Assert.Equal("10xxxxx5", modelInfo.DeviceID); + Assert.Null(modelInfo.DeviceAuth); + Assert.Equal(2, modelInfo.TunerCount); + Assert.Equal("http://10.10.10.100:80", modelInfo.BaseURL); + Assert.Null(modelInfo.LineupURL); + } + + [Fact] + public async Task GetModelInfo_EmptyUrl_ArgumentException() + { + var host = new TunerHostInfo() + { + Url = string.Empty + }; + + await Assert.ThrowsAsync(() => _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None)); + } + + [Fact] + public async Task GetLineup_Valid_Success() + { + var host = new TunerHostInfo() + { + Url = "192.168.1.182" + }; + + var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None); + Assert.Equal(6, channels.Count); + Assert.Equal("4.1", channels[0].GuideNumber); + Assert.Equal("WCMH-DT", channels[0].GuideName); + Assert.True(channels[0].HD); + Assert.True(channels[0].Favorite); + Assert.Equal("http://192.168.1.111:5004/auto/v4.1", channels[0].URL); + } + + [Fact] + public async Task GetLineup_Legacy_Success() + { + var host = new TunerHostInfo() + { + Url = "10.10.10.100" + }; + + // Placeholder json is invalid, just need to make sure we can reach it + await Assert.ThrowsAsync(() => _hdHomerunHost.GetLineup(host, CancellationToken.None)); + } + + [Fact] + public async Task GetLineup_ImportFavoritesOnly_Success() + { + var host = new TunerHostInfo() + { + Url = "192.168.1.182", + ImportFavoritesOnly = true + }; + + var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None); + Assert.Single(channels); + Assert.Equal("4.1", channels[0].GuideNumber); + Assert.Equal("WCMH-DT", channels[0].GuideName); + Assert.True(channels[0].HD); + Assert.True(channels[0].Favorite); + Assert.Equal("http://192.168.1.111:5004/auto/v4.1", channels[0].URL); + } + + [Fact] + public async Task TryGetTunerHostInfo_Valid_Success() + { + var host = await _hdHomerunHost.TryGetTunerHostInfo("192.168.1.182", CancellationToken.None); + Assert.Equal(_hdHomerunHost.Type, host.Type); + Assert.Equal("192.168.1.182", host.Url); + Assert.Equal("HDHomeRun PRIME", host.FriendlyName); + Assert.Equal("FFFFFFFF", host.DeviceId); + Assert.Equal(3, host.TunerCount); + } + } +} diff --git a/tests/Jellyfin.LiveTv.Tests/HdHomerunManagerTests.cs b/tests/Jellyfin.LiveTv.Tests/HdHomerunManagerTests.cs new file mode 100644 index 000000000..fcebc0ff7 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/HdHomerunManagerTests.cs @@ -0,0 +1,326 @@ +using System; +using System.Text; +using Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun; +using Xunit; + +namespace Jellyfin.LiveTv.Tests +{ + public class HdHomerunManagerTests + { + [Fact] + public void WriteNullTerminatedString_Empty_Success() + { + ReadOnlySpan expected = stackalloc byte[] + { + 1, 0 + }; + + Span buffer = stackalloc byte[128]; + int len = HdHomerunManager.WriteNullTerminatedString(buffer, string.Empty); + + Assert.Equal( + Convert.ToHexString(expected), + Convert.ToHexString(buffer.Slice(0, len))); + } + + [Fact] + public void WriteNullTerminatedString_Valid_Success() + { + ReadOnlySpan expected = stackalloc byte[] + { + 10, (byte)'T', (byte)'h', (byte)'e', (byte)' ', (byte)'q', (byte)'u', (byte)'i', (byte)'c', (byte)'k', 0 + }; + + Span buffer = stackalloc byte[128]; + int len = HdHomerunManager.WriteNullTerminatedString(buffer, "The quick"); + + Assert.Equal( + Convert.ToHexString(expected), + Convert.ToHexString(buffer.Slice(0, len))); + } + + [Fact] + public void WriteGetMessage_Valid_Success() + { + ReadOnlySpan expected = stackalloc byte[] + { + 0, 4, + 0, 12, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 0xc0, 0xc9, 0x87, 0x33 + }; + + Span buffer = stackalloc byte[128]; + int len = HdHomerunManager.WriteGetMessage(buffer, 0, "N"); + + Assert.Equal( + Convert.ToHexString(expected), + Convert.ToHexString(buffer.Slice(0, len))); + } + + [Fact] + public void WriteSetMessage_NoLockKey_Success() + { + ReadOnlySpan expected = stackalloc byte[] + { + 0, 4, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0xa9, 0x49, 0xd0, 0x68 + }; + + Span buffer = stackalloc byte[128]; + int len = HdHomerunManager.WriteSetMessage(buffer, 0, "N", "value", null); + + Assert.Equal( + Convert.ToHexString(expected), + Convert.ToHexString(buffer.Slice(0, len))); + } + + [Fact] + public void WriteSetMessage_LockKey_Success() + { + ReadOnlySpan expected = stackalloc byte[] + { + 0, 4, + 0, 26, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 21, + 4, 0x00, 0x01, 0x38, 0xd5, + 0x8e, 0xb6, 0x06, 0x82 + }; + + Span buffer = stackalloc byte[128]; + int len = HdHomerunManager.WriteSetMessage(buffer, 0, "N", "value", 80085); + + Assert.Equal( + Convert.ToHexString(expected), + Convert.ToHexString(buffer.Slice(0, len))); + } + + [Fact] + public void TryGetReturnValueOfGetSet_Valid_Success() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0x7d, 0xa3, 0xa3, 0xf3 + }; + + Assert.True(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out var value)); + Assert.Equal("value", Encoding.UTF8.GetString(value)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_InvalidCrc_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0x7d, 0xa3, 0xa3, 0xf4 + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_InvalidPacketType_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 4, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0xa9, 0x49, 0xd0, 0x68 + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_InvalidPacket_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 0x7d, 0xa3, 0xa3 + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_TooSmallMessageLength_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 19, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0x25, 0x25, 0x44, 0x9a + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_TooLargeMessageLength_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 21, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0xe3, 0x20, 0x79, 0x6c + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_TooLargeNameLength_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 3, + 20, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0xe1, 0x8e, 0x9c, 0x74 + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_InvalidGetSetNameTag_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 4, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0xee, 0x05, 0xe7, 0x12 + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_InvalidGetSetValueTag_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 3, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0x64, 0xaa, 0x66, 0xf9 + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void TryGetReturnValueOfGetSet_TooLargeValueLength_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 7, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0xc9, 0xa8, 0xd4, 0x55 + }; + + Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); + } + + [Fact] + public void VerifyReturnValueOfGetSet_Valid_True() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0x7d, 0xa3, 0xa3, 0xf3 + }; + + Assert.True(HdHomerunManager.VerifyReturnValueOfGetSet(packet, "value")); + } + + [Fact] + public void VerifyReturnValueOfGetSet_WrongValue_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 5, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0x7d, 0xa3, 0xa3, 0xf3 + }; + + Assert.False(HdHomerunManager.VerifyReturnValueOfGetSet(packet, "none")); + } + + [Fact] + public void VerifyReturnValueOfGetSet_InvalidPacket_False() + { + ReadOnlySpan packet = new byte[] + { + 0, 4, + 0, 20, + 3, + 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, + 4, + 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, + 0x7d, 0xa3, 0xa3, 0xf3 + }; + + Assert.False(HdHomerunManager.VerifyReturnValueOfGetSet(packet, "value")); + } + } +} diff --git a/tests/Jellyfin.LiveTv.Tests/Jellyfin.LiveTv.Tests.csproj b/tests/Jellyfin.LiveTv.Tests/Jellyfin.LiveTv.Tests.csproj new file mode 100644 index 000000000..de448bada --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Jellyfin.LiveTv.Tests.csproj @@ -0,0 +1,29 @@ + + + net8.0 + + + + + PreserveNewest + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/tests/Jellyfin.LiveTv.Tests/Listings/XmlTvListingsProviderTests.cs b/tests/Jellyfin.LiveTv.Tests/Listings/XmlTvListingsProviderTests.cs new file mode 100644 index 000000000..71d135735 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Listings/XmlTvListingsProviderTests.cs @@ -0,0 +1,89 @@ +using System; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; +using Emby.Server.Implementations.LiveTv.Listings; +using MediaBrowser.Model.LiveTv; +using Moq; +using Moq.Protected; +using Xunit; + +namespace Jellyfin.LiveTv.Tests.Listings; + +public class XmlTvListingsProviderTests +{ + private readonly Fixture _fixture; + private readonly XmlTvListingsProvider _xmlTvListingsProvider; + + public XmlTvListingsProviderTests() + { + var messageHandler = new Mock(); + messageHandler.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .Returns( + (m, _) => + { + return Task.FromResult(new HttpResponseMessage() + { + Content = new StreamContent(File.OpenRead(Path.Combine("Test Data/LiveTv/Listings/XmlTv", m.RequestUri!.Segments[^1]))) + }); + }); + + var http = new Mock(); + http.Setup(x => x.CreateClient(It.IsAny())) + .Returns(new HttpClient(messageHandler.Object)); + _fixture = new Fixture(); + _fixture.Customize(new AutoMoqCustomization + { + ConfigureMembers = true + }).Inject(http); + _xmlTvListingsProvider = _fixture.Create(); + } + + [Theory] + [InlineData("Test Data/LiveTv/Listings/XmlTv/notitle.xml")] + [InlineData("https://example.com/notitle.xml")] + public async Task GetProgramsAsync_NoTitle_Success(string path) + { + var info = new ListingsProviderInfo() + { + Path = path + }; + + var startDate = new DateTime(2022, 11, 4); + var programs = await _xmlTvListingsProvider.GetProgramsAsync(info, "3297", startDate, startDate.AddDays(1), CancellationToken.None); + var programsList = programs.ToList(); + Assert.Single(programsList); + var program = programsList[0]; + Assert.Null(program.Name); + Assert.Null(program.SeriesId); + Assert.Null(program.EpisodeTitle); + Assert.True(program.IsSports); + Assert.True(program.HasImage); + Assert.Equal("https://domain.tld/image.png", program.ImageUrl); + Assert.Equal("3297", program.ChannelId); + } + + [Theory] + [InlineData("Test Data/LiveTv/Listings/XmlTv/emptycategory.xml")] + [InlineData("https://example.com/emptycategory.xml")] + public async Task GetProgramsAsync_EmptyCategories_Success(string path) + { + var info = new ListingsProviderInfo() + { + Path = path + }; + + var startDate = new DateTime(2022, 11, 4); + var programs = await _xmlTvListingsProvider.GetProgramsAsync(info, "3297", startDate, startDate.AddDays(1), CancellationToken.None); + var programsList = programs.ToList(); + Assert.Single(programsList); + var program = programsList[0]; + Assert.DoesNotContain(program.Genres, g => string.IsNullOrEmpty(g)); + Assert.Equal("3297", program.ChannelId); + } +} diff --git a/tests/Jellyfin.LiveTv.Tests/RecordingHelperTests.cs b/tests/Jellyfin.LiveTv.Tests/RecordingHelperTests.cs new file mode 100644 index 000000000..a5941e7f0 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/RecordingHelperTests.cs @@ -0,0 +1,109 @@ +using System; +using Emby.Server.Implementations.LiveTv.EmbyTV; +using MediaBrowser.Controller.LiveTv; +using Xunit; + +namespace Jellyfin.LiveTv.Tests +{ + public static class RecordingHelperTests + { + public static TheoryData GetRecordingName_Success_TestData() + { + var data = new TheoryData(); + + data.Add( + "The Incredibles 2020_04_20_21_06_00", + new TimerInfo + { + Name = "The Incredibles", + StartDate = new DateTime(2020, 4, 20, 21, 6, 0, DateTimeKind.Local), + IsMovie = true + }); + + data.Add( + "The Incredibles (2004)", + new TimerInfo + { + Name = "The Incredibles", + IsMovie = true, + ProductionYear = 2004 + }); + data.Add( + "The Big Bang Theory 2020_04_20_21_06_00", + new TimerInfo + { + Name = "The Big Bang Theory", + StartDate = new DateTime(2020, 4, 20, 21, 6, 0, DateTimeKind.Local), + IsProgramSeries = true, + }); + data.Add( + "The Big Bang Theory S12E10", + new TimerInfo + { + Name = "The Big Bang Theory", + IsProgramSeries = true, + SeasonNumber = 12, + EpisodeNumber = 10 + }); + data.Add( + "The Big Bang Theory S12E10 The VCR Illumination", + new TimerInfo + { + Name = "The Big Bang Theory", + IsProgramSeries = true, + SeasonNumber = 12, + EpisodeNumber = 10, + EpisodeTitle = "The VCR Illumination" + }); + data.Add( + "The Big Bang Theory 2018-12-06", + new TimerInfo + { + Name = "The Big Bang Theory", + IsProgramSeries = true, + OriginalAirDate = new DateTime(2018, 12, 6, 0, 0, 0, DateTimeKind.Local) + }); + + data.Add( + "The Big Bang Theory 2018-12-06 - The VCR Illumination", + new TimerInfo + { + Name = "The Big Bang Theory", + IsProgramSeries = true, + OriginalAirDate = new DateTime(2018, 12, 6, 0, 0, 0, DateTimeKind.Local), + EpisodeTitle = "The VCR Illumination" + }); + + data.Add( + "The Big Bang Theory 2018_12_06_21_06_00 - The VCR Illumination", + new TimerInfo + { + Name = "The Big Bang Theory", + StartDate = new DateTime(2018, 12, 6, 21, 6, 0, DateTimeKind.Local), + IsProgramSeries = true, + OriginalAirDate = new DateTime(2018, 12, 6), + EpisodeTitle = "The VCR Illumination" + }); + + data.Add( + "Lorem ipsum dolor sit amet: consect 2018_12_06_21_06_00", + new TimerInfo + { + Name = "Lorem ipsum dolor sit amet: consect", + IsProgramSeries = true, + StartDate = new DateTime(2018, 12, 6, 21, 6, 0, DateTimeKind.Local), + OriginalAirDate = new DateTime(2018, 12, 6), + EpisodeTitle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor" + }); + + return data; + } + + [Theory] + [MemberData(nameof(GetRecordingName_Success_TestData))] + public static void GetRecordingName_Success(string expected, TimerInfo timerInfo) + { + Assert.Equal(expected, RecordingHelper.GetRecordingName(timerInfo)); + } + } +} diff --git a/tests/Jellyfin.LiveTv.Tests/SchedulesDirect/SchedulesDirectDeserializeTests.cs b/tests/Jellyfin.LiveTv.Tests/SchedulesDirect/SchedulesDirectDeserializeTests.cs new file mode 100644 index 000000000..6b1f4d416 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/SchedulesDirect/SchedulesDirectDeserializeTests.cs @@ -0,0 +1,240 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos; +using Jellyfin.Extensions.Json; +using Xunit; + +namespace Jellyfin.LiveTv.Tests.SchedulesDirect +{ + public class SchedulesDirectDeserializeTests + { + private readonly JsonSerializerOptions _jsonOptions; + + public SchedulesDirectDeserializeTests() + { + _jsonOptions = JsonDefaults.Options; + } + + /// + /// /token response. + /// + [Fact] + public void Deserialize_Token_Response_Live_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/token_live_response.json"); + var tokenDto = JsonSerializer.Deserialize(bytes, _jsonOptions); + + Assert.NotNull(tokenDto); + Assert.Equal(0, tokenDto!.Code); + Assert.Equal("OK", tokenDto.Message); + Assert.Equal("AWS-SD-web.1", tokenDto.ServerId); + Assert.Equal(new DateTime(2016, 08, 23, 13, 55, 25, DateTimeKind.Utc), tokenDto.TokenTimestamp); + Assert.Equal("f3fca79989cafe7dead71beefedc812b", tokenDto.Token); + } + + /// + /// /token response. + /// + [Fact] + public void Deserialize_Token_Response_Offline_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/token_offline_response.json"); + var tokenDto = JsonSerializer.Deserialize(bytes, _jsonOptions); + + Assert.NotNull(tokenDto); + Assert.Equal(3_000, tokenDto!.Code); + Assert.Equal("Server offline for maintenance.", tokenDto.Message); + Assert.Equal("20141201.web.1", tokenDto.ServerId); + Assert.Equal(new DateTime(2015, 04, 23, 00, 03, 32, DateTimeKind.Utc), tokenDto.TokenTimestamp); + Assert.Equal("CAFEDEADBEEFCAFEDEADBEEFCAFEDEADBEEFCAFE", tokenDto.Token); + Assert.Equal("SERVICE_OFFLINE", tokenDto.Response); + } + + /// + /// /schedules request. + /// + [Fact] + public void Serialize_Schedule_Request_Success() + { + var expectedString = File.ReadAllText("Test Data/SchedulesDirect/schedules_request.json").Trim(); + + var requestObject = new RequestScheduleForChannelDto[] + { + new RequestScheduleForChannelDto + { + StationId = "20454", + Date = new[] + { + "2015-03-13", + "2015-03-17" + } + }, + new RequestScheduleForChannelDto + { + StationId = "10021", + Date = new[] + { + "2015-03-12", + "2015-03-13" + } + } + }; + + var requestString = JsonSerializer.Serialize(requestObject, _jsonOptions); + Assert.Equal(expectedString, requestString); + } + + /// + /// /schedules response. + /// + [Fact] + public void Deserialize_Schedule_Response_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/schedules_response.json"); + var days = JsonSerializer.Deserialize>(bytes, _jsonOptions); + + Assert.NotNull(days); + Assert.Single(days); + + var dayDto = days[0]; + Assert.Equal("20454", dayDto.StationId); + Assert.Equal(2, dayDto.Programs.Count); + + Assert.Equal("SH005371070000", dayDto.Programs[0].ProgramId); + Assert.Equal(new DateTime(2015, 03, 03, 00, 00, 00, DateTimeKind.Utc), dayDto.Programs[0].AirDateTime); + Assert.Equal(1_800, dayDto.Programs[0].Duration); + Assert.Equal("Sy8HEMBPcuiAx3FBukUhKQ", dayDto.Programs[0].Md5); + Assert.True(dayDto.Programs[0].New); + Assert.Equal(2, dayDto.Programs[0].AudioProperties.Count); + Assert.Equal("stereo", dayDto.Programs[0].AudioProperties[0]); + Assert.Equal("cc", dayDto.Programs[0].AudioProperties[1]); + Assert.Single(dayDto.Programs[0].VideoProperties); + Assert.Equal("hdtv", dayDto.Programs[0].VideoProperties[0]); + } + + /// + /// /programs response. + /// + [Fact] + public void Deserialize_Program_Response_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/programs_response.json"); + var programDtos = JsonSerializer.Deserialize>(bytes, _jsonOptions); + + Assert.NotNull(programDtos); + Assert.Equal(2, programDtos!.Count); + Assert.Equal("EP000000060003", programDtos[0].ProgramId); + Assert.Single(programDtos[0].Titles); + Assert.Equal("'Allo 'Allo!", programDtos[0].Titles[0].Title120); + Assert.Equal("Series", programDtos[0].EventDetails?.SubType); + Assert.Equal("en", programDtos[0].Descriptions?.Description1000[0].DescriptionLanguage); + Assert.Equal("A disguised British Intelligence officer is sent to help the airmen.", programDtos[0].Descriptions?.Description1000[0].Description); + Assert.Equal(new DateTime(1985, 11, 04), programDtos[0].OriginalAirDate); + Assert.Single(programDtos[0].Genres); + Assert.Equal("Sitcom", programDtos[0].Genres[0]); + Assert.Equal("The Poloceman Cometh", programDtos[0].EpisodeTitle150); + Assert.Equal(2, programDtos[0].Metadata[0].Gracenote?.Season); + Assert.Equal(3, programDtos[0].Metadata[0].Gracenote?.Episode); + Assert.Equal(13, programDtos[0].Cast.Count); + Assert.Equal("383774", programDtos[0].Cast[0].PersonId); + Assert.Equal("392649", programDtos[0].Cast[0].NameId); + Assert.Equal("Gorden Kaye", programDtos[0].Cast[0].Name); + Assert.Equal("Actor", programDtos[0].Cast[0].Role); + Assert.Equal("01", programDtos[0].Cast[0].BillingOrder); + Assert.Equal(3, programDtos[0].Crew.Count); + Assert.Equal("354407", programDtos[0].Crew[0].PersonId); + Assert.Equal("363281", programDtos[0].Crew[0].NameId); + Assert.Equal("David Croft", programDtos[0].Crew[0].Name); + Assert.Equal("Director", programDtos[0].Crew[0].Role); + Assert.Equal("01", programDtos[0].Crew[0].BillingOrder); + } + + /// + /// /metadata/programs response. + /// + [Fact] + public void Deserialize_Metadata_Programs_Response_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/metadata_programs_response.json"); + var showImagesDtos = JsonSerializer.Deserialize>(bytes, _jsonOptions); + + Assert.NotNull(showImagesDtos); + Assert.Single(showImagesDtos!); + Assert.Equal("SH00712240", showImagesDtos[0].ProgramId); + Assert.Equal(4, showImagesDtos[0].Data.Count); + Assert.Equal("135", showImagesDtos[0].Data[0].Width); + Assert.Equal("180", showImagesDtos[0].Data[0].Height); + Assert.Equal("assets/p282288_b_v2_aa.jpg", showImagesDtos[0].Data[0].Uri); + Assert.Equal("Sm", showImagesDtos[0].Data[0].Size); + Assert.Equal("3x4", showImagesDtos[0].Data[0].Aspect); + Assert.Equal("Banner-L3", showImagesDtos[0].Data[0].Category); + Assert.Equal("yes", showImagesDtos[0].Data[0].Text); + Assert.Equal("true", showImagesDtos[0].Data[0].Primary); + Assert.Equal("Series", showImagesDtos[0].Data[0].Tier); + } + + /// + /// /headends response. + /// + [Fact] + public void Deserialize_Headends_Response_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/headends_response.json"); + var headendsDtos = JsonSerializer.Deserialize>(bytes, _jsonOptions); + + Assert.NotNull(headendsDtos); + Assert.Equal(8, headendsDtos!.Count); + Assert.Equal("CA00053", headendsDtos[0].Headend); + Assert.Equal("Cable", headendsDtos[0].Transport); + Assert.Equal("Beverly Hills", headendsDtos[0].Location); + Assert.Equal(2, headendsDtos[0].Lineups.Count); + Assert.Equal("Time Warner Cable - Cable", headendsDtos[0].Lineups[0].Name); + Assert.Equal("USA-CA00053-DEFAULT", headendsDtos[0].Lineups[0].Lineup); + Assert.Equal("/20141201/lineups/USA-CA00053-DEFAULT", headendsDtos[0].Lineups[0].Uri); + } + + /// + /// /lineups response. + /// + [Fact] + public void Deserialize_Lineups_Response_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/lineups_response.json"); + var lineupsDto = JsonSerializer.Deserialize(bytes, _jsonOptions); + + Assert.NotNull(lineupsDto); + Assert.Equal(0, lineupsDto!.Code); + Assert.Equal("20141201.web.1", lineupsDto.ServerId); + Assert.Equal(new DateTime(2015, 04, 17, 14, 22, 17, DateTimeKind.Utc), lineupsDto.LineupTimestamp); + Assert.Equal(5, lineupsDto.Lineups.Count); + Assert.Equal("GBR-0001317-DEFAULT", lineupsDto.Lineups[0].Lineup); + Assert.Equal("Freeview - Carlton - LWT (Southeast)", lineupsDto.Lineups[0].Name); + Assert.Equal("DVB-T", lineupsDto.Lineups[0].Transport); + Assert.Equal("London", lineupsDto.Lineups[0].Location); + Assert.Equal("/20141201/lineups/GBR-0001317-DEFAULT", lineupsDto.Lineups[0].Uri); + + Assert.Equal("DELETED LINEUP", lineupsDto.Lineups[4].Name); + Assert.True(lineupsDto.Lineups[4].IsDeleted); + } + + /// + /// /lineup/:id response. + /// + [Fact] + public void Deserialize_Lineup_Response_Success() + { + var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/lineup_response.json"); + var channelDto = JsonSerializer.Deserialize(bytes, _jsonOptions); + + Assert.NotNull(channelDto); + Assert.Equal(2, channelDto!.Map.Count); + Assert.Equal("24326", channelDto.Map[0].StationId); + Assert.Equal("001", channelDto.Map[0].Channel); + Assert.Equal("BBC ONE South", channelDto.Map[0].ProvderCallsign); + Assert.Equal("1", channelDto.Map[0].LogicalChannelNumber); + Assert.Equal("providerCallsign", channelDto.Map[0].MatchType); + } + } +} diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/discover.json b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/discover.json new file mode 100644 index 000000000..a4ad4ed44 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/discover.json @@ -0,0 +1 @@ +{"FriendlyName":"HDHomeRun DUAL","ModelNumber":"HDHR3-US","Legacy":1,"FirmwareName":"hdhomerun3_atsc","FirmwareVersion":"20200225","DeviceID":"10xxxxx5","TunerCount":2,"BaseURL":"http://10.10.10.100:80"} diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/lineup.json b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/lineup.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/10.10.10.100/lineup.json @@ -0,0 +1 @@ +{} diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/discover.json b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/discover.json new file mode 100644 index 000000000..851f17bb2 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/discover.json @@ -0,0 +1 @@ +{"FriendlyName":"HDHomeRun PRIME","ModelNumber":"HDHR3-CC","FirmwareName":"hdhomerun3_cablecard","FirmwareVersion":"20160630atest2","DeviceID":"FFFFFFFF","DeviceAuth":"FFFFFFFF","TunerCount":3,"ConditionalAccess":1,"BaseURL":"http://192.168.1.182:80","LineupURL":"http://192.168.1.182:80/lineup.json"} diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/lineup.json b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/lineup.json new file mode 100644 index 000000000..4cb5ebc8e --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/192.168.1.182/lineup.json @@ -0,0 +1 @@ +[ { "GuideNumber": "4.1", "GuideName": "WCMH-DT", "HD": 1, "Favorite": 1, "URL": "http://192.168.1.111:5004/auto/v4.1" }, { "GuideNumber": "4.2", "GuideName": "MeTV", "URL": "http://192.168.1.111:5004/auto/v4.2" }, { "GuideNumber": "4.3", "GuideName": "ION TV", "URL": "http://192.168.1.111:5004/auto/v4.3" }, { "GuideNumber": "6.1", "GuideName": "WSYX DT", "HD": 1, "URL": "http://192.168.1.111:5004/auto/v6.1" }, { "GuideNumber": "6.2", "GuideName": "MYTV", "URL": "http://192.168.1.111:5004/auto/v6.2" }, { "GuideNumber": "6.3", "GuideName": "ANTENNA", "URL": "http://192.168.1.111:5004/auto/v6.3" } ] diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml new file mode 100644 index 000000000..dd4aa8977 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml @@ -0,0 +1,6 @@ + + + + sports + + diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml new file mode 100644 index 000000000..5a5be7997 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml @@ -0,0 +1,10 @@ + + + sports + 2022-11-04 13:00:00 + + + + diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/headends_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/headends_response.json new file mode 100644 index 000000000..015afeecc --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/headends_response.json @@ -0,0 +1 @@ +[{"headend":"CA00053","transport":"Cable","location":"Beverly Hills","lineups":[{"name":"Time Warner Cable - Cable","lineup":"USA-CA00053-DEFAULT","uri":"/20141201/lineups/USA-CA00053-DEFAULT"},{"name":"Time Warner Cable - Digital","lineup":"USA-CA00053-X","uri":"/20141201/lineups/USA-CA00053-X"}]},{"headend":"CA61222","transport":"Cable","location":"Beverly Hills","lineups":[{"name":"Mulholland Estates - Cable","lineup":"USA-CA61222-DEFAULT","uri":"/20141201/lineups/USA-CA61222-DEFAULT"}]},{"headend":"CA66511","transport":"Cable","location":"Los Angeles","lineups":[{"name":"AT&T U-verse TV - Digital","lineup":"USA-CA66511-X","uri":"/20141201/lineups/USA-CA66511-X"}]},{"headend":"CA67309","transport":"Cable","location":"Westchester","lineups":[{"name":"Time Warner Cable Sherman Oaks - Cable","lineup":"USA-CA67309-DEFAULT","uri":"/20141201/lineups/USA-CA67309-DEFAULT"},{"name":"Time Warner Cable Sherman Oaks - Digital","lineup":"USA-CA67309-X","uri":"/20141201/lineups/USA-CA67309-X"}]},{"headend":"CA67310","transport":"Cable","location":"Eagle Rock","lineups":[{"name":"Time Warner Cable City of Los Angeles - Cable","lineup":"USA-CA67310-DEFAULT","uri":"/20141201/lineups/USA-CA67310-DEFAULT"},{"name":"Time Warner Cable City of Los Angeles - Digital","lineup":"USA-CA67310-X","uri":"/20141201/lineups/USA-CA67310-X"}]},{"headend":"DISH803","transport":"Satellite","location":"Los Angeles","lineups":[{"name":"DISH Los Angeles - Satellite","lineup":"USA-DISH803-DEFAULT","uri":"/20141201/lineups/USA-DISH803-DEFAULT"}]},{"headend":"DITV803","transport":"Satellite","location":"Los Angeles","lineups":[{"name":"DIRECTV Los Angeles - Satellite","lineup":"USA-DITV803-DEFAULT","uri":"/20141201/lineups/USA-DITV803-DEFAULT"}]},{"headend":"90210","transport":"Antenna","location":"90210","lineups":[{"name":"Antenna","lineup":"USA-OTA-90210","uri":"/20141201/lineups/USA-OTA-90210"}]}] diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineup_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineup_response.json new file mode 100644 index 000000000..072089470 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineup_response.json @@ -0,0 +1 @@ +{"map":[{"stationID":"24326","channel":"001","providerCallsign":"BBC ONE South","logicalChannelNumber":"1","matchType":"providerCallsign"},{"stationID":"17154","channel":"002","providerCallsign":"BBC TWO","logicalChannelNumber":"2","matchType":"providerCallsign"}]} diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineups_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineups_response.json new file mode 100644 index 000000000..032a84e59 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/lineups_response.json @@ -0,0 +1 @@ +{"code":0,"serverID":"20141201.web.1","datetime":"2015-04-17T14:22:17Z","lineups":[{"lineup":"GBR-0001317-DEFAULT","name":"Freeview - Carlton - LWT (Southeast)","transport":"DVB-T","location":"London","uri":"/20141201/lineups/GBR-0001317-DEFAULT"},{"lineup":"USA-IL57303-X","name":"Comcast Waukegan/Lake Forest Area - Digital","transport":"Cable","location":"Lake Forest","uri":"/20141201/lineups/USA-IL57303-X"},{"lineup":"USA-NY67791-X","name":"Verizon Fios Queens - Digital","transport":"Cable","location":"Fresh Meadows","uri":"/20141201/lineups/USA-NY67791-X"},{"lineup":"USA-OTA-60030","name":"Local Over the Air Broadcast","transport":"Antenna","location":"60030","uri":"/20141201/lineups/USA-OTA-60030"},{"lineup":"USA-WI61859-DEFAULT","name":"DELETED LINEUP","isDeleted":true}]} diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/metadata_programs_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/metadata_programs_response.json new file mode 100644 index 000000000..78166f09a --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/metadata_programs_response.json @@ -0,0 +1 @@ +[{"programID":"SH00712240","data":[{"width":"135","height":"180","uri":"assets/p282288_b_v2_aa.jpg","size":"Sm","aspect":"3x4","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"},{"width":"720","height":"540","uri":"assets/p282288_b_h6_aa.jpg","size":"Lg","aspect":"4x3","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"},{"width":"960","height":"1440","uri":"assets/p282288_b_v8_aa.jpg","size":"Ms","aspect":"2x3","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"},{"width":"180","height":"135","uri":"assets/p282288_b_h5_aa.jpg","size":"Sm","aspect":"4x3","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"}]}] diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/programs_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/programs_response.json new file mode 100644 index 000000000..fe2a94436 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/programs_response.json @@ -0,0 +1 @@ +[{"programID":"EP000000060003","titles":[{"title120":"'Allo 'Allo!"}],"eventDetails":{"subType":"Series"},"descriptions":{"description1000":[{"descriptionLanguage":"en","description":"A disguised British Intelligence officer is sent to help the airmen."}]},"originalAirDate":"1985-11-04","genres":["Sitcom"],"episodeTitle150":"The Poloceman Cometh","metadata":[{"Gracenote":{"season":2,"episode":3}}],"cast":[{"personId":"383774","nameId":"392649","name":"Gorden Kaye","role":"Actor","billingOrder":"01"},{"personId":"246840","nameId":"250387","name":"Carmen Silvera","role":"Actor","billingOrder":"02"},{"personId":"376955","nameId":"385830","name":"Rose Hill","role":"Actor","billingOrder":"03"},{"personId":"259773","nameId":"263340","name":"Vicki Michelle","role":"Actor","billingOrder":"04"},{"personId":"353113","nameId":"361987","name":"Kirsten Cooke","role":"Actor","billingOrder":"05"},{"personId":"77787","nameId":"77787","name":"Richard Marner","role":"Actor","billingOrder":"06"},{"personId":"230921","nameId":"234193","name":"Guy Siner","role":"Actor","billingOrder":"07"},{"personId":"374934","nameId":"383809","name":"Kim Hartman","role":"Actor","billingOrder":"08"},{"personId":"369151","nameId":"378026","name":"Richard Gibson","role":"Actor","billingOrder":"09"},{"personId":"343690","nameId":"352564","name":"Arthur Bostrom","role":"Actor","billingOrder":"10"},{"personId":"352557","nameId":"361431","name":"John D. Collins","role":"Actor","billingOrder":"11"},{"personId":"605275","nameId":"627734","name":"Nicholas Frankau","role":"Actor","billingOrder":"12"},{"personId":"373394","nameId":"382269","name":"Jack Haig","role":"Actor","billingOrder":"13"}],"crew":[{"personId":"354407","nameId":"363281","name":"David Croft","role":"Director","billingOrder":"01"},{"personId":"354407","nameId":"363281","name":"David Croft","role":"Writer","billingOrder":"02"},{"personId":"105145","nameId":"105145","name":"Jeremy Lloyd","role":"Writer","billingOrder":"03"}],"showType":"Series","hasImageArtwork":true,"md5":"Jo5NKxoo44xRvBCAq8QT2A"},{"programID":"EP000000510142","titles":[{"title120":"A Different World"}],"eventDetails":{"subType":"Series"},"descriptions":{"description1000":[{"descriptionLanguage":"en","description":"Whitley and Dwayne tell new students about their honeymoon in Los Angeles."}]},"originalAirDate":"1992-09-24","genres":["Sitcom"],"episodeTitle150":"Honeymoon in L.A.","metadata":[{"Gracenote":{"season":6,"episode":1}}],"cast":[{"personId":"700","nameId":"700","name":"Jasmine Guy","role":"Actor","billingOrder":"01"},{"personId":"729","nameId":"729","name":"Kadeem Hardison","role":"Actor","billingOrder":"02"},{"personId":"120","nameId":"120","name":"Darryl M. Bell","role":"Actor","billingOrder":"03"},{"personId":"1729","nameId":"1729","name":"Cree Summer","role":"Actor","billingOrder":"04"},{"personId":"217","nameId":"217","name":"Charnele Brown","role":"Actor","billingOrder":"05"},{"personId":"1811","nameId":"1811","name":"Glynn Turman","role":"Actor","billingOrder":"06"},{"personId":"1232","nameId":"1232","name":"Lou Myers","role":"Actor","billingOrder":"07"},{"personId":"1363","nameId":"1363","name":"Jada Pinkett","role":"Guest Star","billingOrder":"08"},{"personId":"222967","nameId":"225536","name":"Ajai Sanders","role":"Guest Star","billingOrder":"09"},{"personId":"181744","nameId":"183292","name":"Karen Malina White","role":"Guest Star","billingOrder":"10"},{"personId":"305017","nameId":"318897","name":"Patrick Y. Malone","role":"Guest Star","billingOrder":"11"},{"personId":"9841","nameId":"9841","name":"Bumper Robinson","role":"Guest Star","billingOrder":"12"},{"personId":"426422","nameId":"435297","name":"Sister Souljah","role":"Guest Star","billingOrder":"13"},{"personId":"25","nameId":"25","name":"Debbie Allen","role":"Guest Star","billingOrder":"14"},{"personId":"668","nameId":"668","name":"Gilbert Gottfried","role":"Guest Star","billingOrder":"15"}],"showType":"Series","hasImageArtwork":true,"md5":"P5kz0QmCeYxIA+yL0H4DWw"}] diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_request.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_request.json new file mode 100644 index 000000000..5ef1bfb1c --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_request.json @@ -0,0 +1 @@ +[{"stationID":"20454","date":["2015-03-13","2015-03-17"]},{"stationID":"10021","date":["2015-03-12","2015-03-13"]}] diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_response.json new file mode 100644 index 000000000..4a97e5517 --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/schedules_response.json @@ -0,0 +1 @@ +[{"stationID":"20454","programs":[{"programID":"SH005371070000","airDateTime":"2015-03-03T00:00:00Z","duration":1800,"md5":"Sy8HEMBPcuiAx3FBukUhKQ","new":true,"audioProperties":["stereo","cc"],"videoProperties":["hdtv"]},{"programID":"EP000014577244","airDateTime":"2015-03-03T00:30:00Z","duration":1800,"md5":"25DNXVXO192JI7Y9vSW9lQ","new":true,"audioProperties":["stereo","cc"],"videoProperties":["hdtv"]}]}] diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_live_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_live_response.json new file mode 100644 index 000000000..e5fb64a6f --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_live_response.json @@ -0,0 +1 @@ +{"code":0,"message":"OK","serverID":"AWS-SD-web.1","datetime":"2016-08-23T13:55:25Z","token":"f3fca79989cafe7dead71beefedc812b"} diff --git a/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_offline_response.json b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_offline_response.json new file mode 100644 index 000000000..b66a4ed0c --- /dev/null +++ b/tests/Jellyfin.LiveTv.Tests/Test Data/SchedulesDirect/token_offline_response.json @@ -0,0 +1 @@ +{"response":"SERVICE_OFFLINE","code":3000,"serverID":"20141201.web.1","message":"Server offline for maintenance.","datetime":"2015-04-23T00:03:32Z","token":"CAFEDEADBEEFCAFEDEADBEEFCAFEDEADBEEFCAFE"} diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs deleted file mode 100644 index 13ac3ddb0..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using System.Text.Json; -using System.Threading; -using System.Threading.Tasks; -using AutoFixture; -using AutoFixture.AutoMoq; -using Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun; -using MediaBrowser.Model.LiveTv; -using Moq; -using Moq.Protected; -using Xunit; - -namespace Jellyfin.Server.Implementations.Tests.LiveTv -{ - public class HdHomerunHostTests - { - private readonly Fixture _fixture; - private readonly HdHomerunHost _hdHomerunHost; - - public HdHomerunHostTests() - { - var messageHandler = new Mock(); - messageHandler.Protected() - .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) - .Returns( - (m, _) => - { - return Task.FromResult(new HttpResponseMessage() - { - Content = new StreamContent(File.OpenRead(Path.Combine("Test Data/LiveTv", m.RequestUri!.Host, m.RequestUri.Segments[^1]))) - }); - }); - - var http = new Mock(); - http.Setup(x => x.CreateClient(It.IsAny())) - .Returns(new HttpClient(messageHandler.Object)); - _fixture = new Fixture(); - _fixture.Customize(new AutoMoqCustomization - { - ConfigureMembers = true - }).Inject(http); - _hdHomerunHost = _fixture.Create(); - } - - [Fact] - public async Task GetModelInfo_Valid_Success() - { - var host = new TunerHostInfo() - { - Url = "192.168.1.182" - }; - - var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None); - Assert.Equal("HDHomeRun PRIME", modelInfo.FriendlyName); - Assert.Equal("HDHR3-CC", modelInfo.ModelNumber); - Assert.Equal("hdhomerun3_cablecard", modelInfo.FirmwareName); - Assert.Equal("20160630atest2", modelInfo.FirmwareVersion); - Assert.Equal("FFFFFFFF", modelInfo.DeviceID); - Assert.Equal("FFFFFFFF", modelInfo.DeviceAuth); - Assert.Equal(3, modelInfo.TunerCount); - Assert.Equal("http://192.168.1.182:80", modelInfo.BaseURL); - Assert.Equal("http://192.168.1.182:80/lineup.json", modelInfo.LineupURL); - } - - [Fact] - public async Task GetModelInfo_Legacy_Success() - { - var host = new TunerHostInfo() - { - Url = "10.10.10.100" - }; - - var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None); - Assert.Equal("HDHomeRun DUAL", modelInfo.FriendlyName); - Assert.Equal("HDHR3-US", modelInfo.ModelNumber); - Assert.Equal("hdhomerun3_atsc", modelInfo.FirmwareName); - Assert.Equal("20200225", modelInfo.FirmwareVersion); - Assert.Equal("10xxxxx5", modelInfo.DeviceID); - Assert.Null(modelInfo.DeviceAuth); - Assert.Equal(2, modelInfo.TunerCount); - Assert.Equal("http://10.10.10.100:80", modelInfo.BaseURL); - Assert.Null(modelInfo.LineupURL); - } - - [Fact] - public async Task GetModelInfo_EmptyUrl_ArgumentException() - { - var host = new TunerHostInfo() - { - Url = string.Empty - }; - - await Assert.ThrowsAsync(() => _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None)); - } - - [Fact] - public async Task GetLineup_Valid_Success() - { - var host = new TunerHostInfo() - { - Url = "192.168.1.182" - }; - - var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None); - Assert.Equal(6, channels.Count); - Assert.Equal("4.1", channels[0].GuideNumber); - Assert.Equal("WCMH-DT", channels[0].GuideName); - Assert.True(channels[0].HD); - Assert.True(channels[0].Favorite); - Assert.Equal("http://192.168.1.111:5004/auto/v4.1", channels[0].URL); - } - - [Fact] - public async Task GetLineup_Legacy_Success() - { - var host = new TunerHostInfo() - { - Url = "10.10.10.100" - }; - - // Placeholder json is invalid, just need to make sure we can reach it - await Assert.ThrowsAsync(() => _hdHomerunHost.GetLineup(host, CancellationToken.None)); - } - - [Fact] - public async Task GetLineup_ImportFavoritesOnly_Success() - { - var host = new TunerHostInfo() - { - Url = "192.168.1.182", - ImportFavoritesOnly = true - }; - - var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None); - Assert.Single(channels); - Assert.Equal("4.1", channels[0].GuideNumber); - Assert.Equal("WCMH-DT", channels[0].GuideName); - Assert.True(channels[0].HD); - Assert.True(channels[0].Favorite); - Assert.Equal("http://192.168.1.111:5004/auto/v4.1", channels[0].URL); - } - - [Fact] - public async Task TryGetTunerHostInfo_Valid_Success() - { - var host = await _hdHomerunHost.TryGetTunerHostInfo("192.168.1.182", CancellationToken.None); - Assert.Equal(_hdHomerunHost.Type, host.Type); - Assert.Equal("192.168.1.182", host.Url); - Assert.Equal("HDHomeRun PRIME", host.FriendlyName); - Assert.Equal("FFFFFFFF", host.DeviceId); - Assert.Equal(3, host.TunerCount); - } - } -} diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs deleted file mode 100644 index fd499d9cf..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs +++ /dev/null @@ -1,326 +0,0 @@ -using System; -using System.Text; -using Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun; -using Xunit; - -namespace Jellyfin.Server.Implementations.Tests.LiveTv -{ - public class HdHomerunManagerTests - { - [Fact] - public void WriteNullTerminatedString_Empty_Success() - { - ReadOnlySpan expected = stackalloc byte[] - { - 1, 0 - }; - - Span buffer = stackalloc byte[128]; - int len = HdHomerunManager.WriteNullTerminatedString(buffer, string.Empty); - - Assert.Equal( - Convert.ToHexString(expected), - Convert.ToHexString(buffer.Slice(0, len))); - } - - [Fact] - public void WriteNullTerminatedString_Valid_Success() - { - ReadOnlySpan expected = stackalloc byte[] - { - 10, (byte)'T', (byte)'h', (byte)'e', (byte)' ', (byte)'q', (byte)'u', (byte)'i', (byte)'c', (byte)'k', 0 - }; - - Span buffer = stackalloc byte[128]; - int len = HdHomerunManager.WriteNullTerminatedString(buffer, "The quick"); - - Assert.Equal( - Convert.ToHexString(expected), - Convert.ToHexString(buffer.Slice(0, len))); - } - - [Fact] - public void WriteGetMessage_Valid_Success() - { - ReadOnlySpan expected = stackalloc byte[] - { - 0, 4, - 0, 12, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 0xc0, 0xc9, 0x87, 0x33 - }; - - Span buffer = stackalloc byte[128]; - int len = HdHomerunManager.WriteGetMessage(buffer, 0, "N"); - - Assert.Equal( - Convert.ToHexString(expected), - Convert.ToHexString(buffer.Slice(0, len))); - } - - [Fact] - public void WriteSetMessage_NoLockKey_Success() - { - ReadOnlySpan expected = stackalloc byte[] - { - 0, 4, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0xa9, 0x49, 0xd0, 0x68 - }; - - Span buffer = stackalloc byte[128]; - int len = HdHomerunManager.WriteSetMessage(buffer, 0, "N", "value", null); - - Assert.Equal( - Convert.ToHexString(expected), - Convert.ToHexString(buffer.Slice(0, len))); - } - - [Fact] - public void WriteSetMessage_LockKey_Success() - { - ReadOnlySpan expected = stackalloc byte[] - { - 0, 4, - 0, 26, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 21, - 4, 0x00, 0x01, 0x38, 0xd5, - 0x8e, 0xb6, 0x06, 0x82 - }; - - Span buffer = stackalloc byte[128]; - int len = HdHomerunManager.WriteSetMessage(buffer, 0, "N", "value", 80085); - - Assert.Equal( - Convert.ToHexString(expected), - Convert.ToHexString(buffer.Slice(0, len))); - } - - [Fact] - public void TryGetReturnValueOfGetSet_Valid_Success() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0x7d, 0xa3, 0xa3, 0xf3 - }; - - Assert.True(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out var value)); - Assert.Equal("value", Encoding.UTF8.GetString(value)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_InvalidCrc_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0x7d, 0xa3, 0xa3, 0xf4 - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_InvalidPacketType_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 4, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0xa9, 0x49, 0xd0, 0x68 - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_InvalidPacket_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 0x7d, 0xa3, 0xa3 - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_TooSmallMessageLength_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 19, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0x25, 0x25, 0x44, 0x9a - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_TooLargeMessageLength_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 21, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0xe3, 0x20, 0x79, 0x6c - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_TooLargeNameLength_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 3, - 20, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0xe1, 0x8e, 0x9c, 0x74 - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_InvalidGetSetNameTag_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 4, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0xee, 0x05, 0xe7, 0x12 - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_InvalidGetSetValueTag_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 3, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0x64, 0xaa, 0x66, 0xf9 - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void TryGetReturnValueOfGetSet_TooLargeValueLength_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 7, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0xc9, 0xa8, 0xd4, 0x55 - }; - - Assert.False(HdHomerunManager.TryGetReturnValueOfGetSet(packet, out _)); - } - - [Fact] - public void VerifyReturnValueOfGetSet_Valid_True() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0x7d, 0xa3, 0xa3, 0xf3 - }; - - Assert.True(HdHomerunManager.VerifyReturnValueOfGetSet(packet, "value")); - } - - [Fact] - public void VerifyReturnValueOfGetSet_WrongValue_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 5, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0x7d, 0xa3, 0xa3, 0xf3 - }; - - Assert.False(HdHomerunManager.VerifyReturnValueOfGetSet(packet, "none")); - } - - [Fact] - public void VerifyReturnValueOfGetSet_InvalidPacket_False() - { - ReadOnlySpan packet = new byte[] - { - 0, 4, - 0, 20, - 3, - 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0, - 4, - 6, (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', 0, - 0x7d, 0xa3, 0xa3, 0xf3 - }; - - Assert.False(HdHomerunManager.VerifyReturnValueOfGetSet(packet, "value")); - } - } -} diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/Listings/XmlTvListingsProviderTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/Listings/XmlTvListingsProviderTests.cs deleted file mode 100644 index 92b4178fd..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/Listings/XmlTvListingsProviderTests.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using AutoFixture; -using AutoFixture.AutoMoq; -using Emby.Server.Implementations.LiveTv.Listings; -using MediaBrowser.Model.LiveTv; -using Moq; -using Moq.Protected; -using Xunit; - -namespace Jellyfin.Server.Implementations.Tests.LiveTv.Listings; - -public class XmlTvListingsProviderTests -{ - private readonly Fixture _fixture; - private readonly XmlTvListingsProvider _xmlTvListingsProvider; - - public XmlTvListingsProviderTests() - { - var messageHandler = new Mock(); - messageHandler.Protected() - .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) - .Returns( - (m, _) => - { - return Task.FromResult(new HttpResponseMessage() - { - Content = new StreamContent(File.OpenRead(Path.Combine("Test Data/LiveTv/Listings/XmlTv", m.RequestUri!.Segments[^1]))) - }); - }); - - var http = new Mock(); - http.Setup(x => x.CreateClient(It.IsAny())) - .Returns(new HttpClient(messageHandler.Object)); - _fixture = new Fixture(); - _fixture.Customize(new AutoMoqCustomization - { - ConfigureMembers = true - }).Inject(http); - _xmlTvListingsProvider = _fixture.Create(); - } - - [Theory] - [InlineData("Test Data/LiveTv/Listings/XmlTv/notitle.xml")] - [InlineData("https://example.com/notitle.xml")] - public async Task GetProgramsAsync_NoTitle_Success(string path) - { - var info = new ListingsProviderInfo() - { - Path = path - }; - - var startDate = new DateTime(2022, 11, 4); - var programs = await _xmlTvListingsProvider.GetProgramsAsync(info, "3297", startDate, startDate.AddDays(1), CancellationToken.None); - var programsList = programs.ToList(); - Assert.Single(programsList); - var program = programsList[0]; - Assert.Null(program.Name); - Assert.Null(program.SeriesId); - Assert.Null(program.EpisodeTitle); - Assert.True(program.IsSports); - Assert.True(program.HasImage); - Assert.Equal("https://domain.tld/image.png", program.ImageUrl); - Assert.Equal("3297", program.ChannelId); - } - - [Theory] - [InlineData("Test Data/LiveTv/Listings/XmlTv/emptycategory.xml")] - [InlineData("https://example.com/emptycategory.xml")] - public async Task GetProgramsAsync_EmptyCategories_Success(string path) - { - var info = new ListingsProviderInfo() - { - Path = path - }; - - var startDate = new DateTime(2022, 11, 4); - var programs = await _xmlTvListingsProvider.GetProgramsAsync(info, "3297", startDate, startDate.AddDays(1), CancellationToken.None); - var programsList = programs.ToList(); - Assert.Single(programsList); - var program = programsList[0]; - Assert.DoesNotContain(program.Genres, g => string.IsNullOrEmpty(g)); - Assert.Equal("3297", program.ChannelId); - } -} diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/RecordingHelperTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/RecordingHelperTests.cs deleted file mode 100644 index f107b1ef9..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/RecordingHelperTests.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using Emby.Server.Implementations.LiveTv.EmbyTV; -using MediaBrowser.Controller.LiveTv; -using Xunit; - -namespace Jellyfin.Server.Implementations.Tests.LiveTv -{ - public static class RecordingHelperTests - { - public static TheoryData GetRecordingName_Success_TestData() - { - var data = new TheoryData(); - - data.Add( - "The Incredibles 2020_04_20_21_06_00", - new TimerInfo - { - Name = "The Incredibles", - StartDate = new DateTime(2020, 4, 20, 21, 6, 0, DateTimeKind.Local), - IsMovie = true - }); - - data.Add( - "The Incredibles (2004)", - new TimerInfo - { - Name = "The Incredibles", - IsMovie = true, - ProductionYear = 2004 - }); - data.Add( - "The Big Bang Theory 2020_04_20_21_06_00", - new TimerInfo - { - Name = "The Big Bang Theory", - StartDate = new DateTime(2020, 4, 20, 21, 6, 0, DateTimeKind.Local), - IsProgramSeries = true, - }); - data.Add( - "The Big Bang Theory S12E10", - new TimerInfo - { - Name = "The Big Bang Theory", - IsProgramSeries = true, - SeasonNumber = 12, - EpisodeNumber = 10 - }); - data.Add( - "The Big Bang Theory S12E10 The VCR Illumination", - new TimerInfo - { - Name = "The Big Bang Theory", - IsProgramSeries = true, - SeasonNumber = 12, - EpisodeNumber = 10, - EpisodeTitle = "The VCR Illumination" - }); - data.Add( - "The Big Bang Theory 2018-12-06", - new TimerInfo - { - Name = "The Big Bang Theory", - IsProgramSeries = true, - OriginalAirDate = new DateTime(2018, 12, 6, 0, 0, 0, DateTimeKind.Local) - }); - - data.Add( - "The Big Bang Theory 2018-12-06 - The VCR Illumination", - new TimerInfo - { - Name = "The Big Bang Theory", - IsProgramSeries = true, - OriginalAirDate = new DateTime(2018, 12, 6, 0, 0, 0, DateTimeKind.Local), - EpisodeTitle = "The VCR Illumination" - }); - - data.Add( - "The Big Bang Theory 2018_12_06_21_06_00 - The VCR Illumination", - new TimerInfo - { - Name = "The Big Bang Theory", - StartDate = new DateTime(2018, 12, 6, 21, 6, 0, DateTimeKind.Local), - IsProgramSeries = true, - OriginalAirDate = new DateTime(2018, 12, 6), - EpisodeTitle = "The VCR Illumination" - }); - - data.Add( - "Lorem ipsum dolor sit amet: consect 2018_12_06_21_06_00", - new TimerInfo - { - Name = "Lorem ipsum dolor sit amet: consect", - IsProgramSeries = true, - StartDate = new DateTime(2018, 12, 6, 21, 6, 0, DateTimeKind.Local), - OriginalAirDate = new DateTime(2018, 12, 6), - EpisodeTitle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor" - }); - - return data; - } - - [Theory] - [MemberData(nameof(GetRecordingName_Success_TestData))] - public static void GetRecordingName_Success(string expected, TimerInfo timerInfo) - { - Assert.Equal(expected, RecordingHelper.GetRecordingName(timerInfo)); - } - } -} diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs deleted file mode 100644 index d4f28f327..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.Json; -using Emby.Server.Implementations.LiveTv.Listings.SchedulesDirectDtos; -using Jellyfin.Extensions.Json; -using Xunit; - -namespace Jellyfin.Server.Implementations.Tests.LiveTv.SchedulesDirect -{ - public class SchedulesDirectDeserializeTests - { - private readonly JsonSerializerOptions _jsonOptions; - - public SchedulesDirectDeserializeTests() - { - _jsonOptions = JsonDefaults.Options; - } - - /// - /// /token response. - /// - [Fact] - public void Deserialize_Token_Response_Live_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/token_live_response.json"); - var tokenDto = JsonSerializer.Deserialize(bytes, _jsonOptions); - - Assert.NotNull(tokenDto); - Assert.Equal(0, tokenDto!.Code); - Assert.Equal("OK", tokenDto.Message); - Assert.Equal("AWS-SD-web.1", tokenDto.ServerId); - Assert.Equal(new DateTime(2016, 08, 23, 13, 55, 25, DateTimeKind.Utc), tokenDto.TokenTimestamp); - Assert.Equal("f3fca79989cafe7dead71beefedc812b", tokenDto.Token); - } - - /// - /// /token response. - /// - [Fact] - public void Deserialize_Token_Response_Offline_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/token_offline_response.json"); - var tokenDto = JsonSerializer.Deserialize(bytes, _jsonOptions); - - Assert.NotNull(tokenDto); - Assert.Equal(3_000, tokenDto!.Code); - Assert.Equal("Server offline for maintenance.", tokenDto.Message); - Assert.Equal("20141201.web.1", tokenDto.ServerId); - Assert.Equal(new DateTime(2015, 04, 23, 00, 03, 32, DateTimeKind.Utc), tokenDto.TokenTimestamp); - Assert.Equal("CAFEDEADBEEFCAFEDEADBEEFCAFEDEADBEEFCAFE", tokenDto.Token); - Assert.Equal("SERVICE_OFFLINE", tokenDto.Response); - } - - /// - /// /schedules request. - /// - [Fact] - public void Serialize_Schedule_Request_Success() - { - var expectedString = File.ReadAllText("Test Data/SchedulesDirect/schedules_request.json").Trim(); - - var requestObject = new RequestScheduleForChannelDto[] - { - new RequestScheduleForChannelDto - { - StationId = "20454", - Date = new[] - { - "2015-03-13", - "2015-03-17" - } - }, - new RequestScheduleForChannelDto - { - StationId = "10021", - Date = new[] - { - "2015-03-12", - "2015-03-13" - } - } - }; - - var requestString = JsonSerializer.Serialize(requestObject, _jsonOptions); - Assert.Equal(expectedString, requestString); - } - - /// - /// /schedules response. - /// - [Fact] - public void Deserialize_Schedule_Response_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/schedules_response.json"); - var days = JsonSerializer.Deserialize>(bytes, _jsonOptions); - - Assert.NotNull(days); - Assert.Single(days); - - var dayDto = days[0]; - Assert.Equal("20454", dayDto.StationId); - Assert.Equal(2, dayDto.Programs.Count); - - Assert.Equal("SH005371070000", dayDto.Programs[0].ProgramId); - Assert.Equal(new DateTime(2015, 03, 03, 00, 00, 00, DateTimeKind.Utc), dayDto.Programs[0].AirDateTime); - Assert.Equal(1_800, dayDto.Programs[0].Duration); - Assert.Equal("Sy8HEMBPcuiAx3FBukUhKQ", dayDto.Programs[0].Md5); - Assert.True(dayDto.Programs[0].New); - Assert.Equal(2, dayDto.Programs[0].AudioProperties.Count); - Assert.Equal("stereo", dayDto.Programs[0].AudioProperties[0]); - Assert.Equal("cc", dayDto.Programs[0].AudioProperties[1]); - Assert.Single(dayDto.Programs[0].VideoProperties); - Assert.Equal("hdtv", dayDto.Programs[0].VideoProperties[0]); - } - - /// - /// /programs response. - /// - [Fact] - public void Deserialize_Program_Response_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/programs_response.json"); - var programDtos = JsonSerializer.Deserialize>(bytes, _jsonOptions); - - Assert.NotNull(programDtos); - Assert.Equal(2, programDtos!.Count); - Assert.Equal("EP000000060003", programDtos[0].ProgramId); - Assert.Single(programDtos[0].Titles); - Assert.Equal("'Allo 'Allo!", programDtos[0].Titles[0].Title120); - Assert.Equal("Series", programDtos[0].EventDetails?.SubType); - Assert.Equal("en", programDtos[0].Descriptions?.Description1000[0].DescriptionLanguage); - Assert.Equal("A disguised British Intelligence officer is sent to help the airmen.", programDtos[0].Descriptions?.Description1000[0].Description); - Assert.Equal(new DateTime(1985, 11, 04), programDtos[0].OriginalAirDate); - Assert.Single(programDtos[0].Genres); - Assert.Equal("Sitcom", programDtos[0].Genres[0]); - Assert.Equal("The Poloceman Cometh", programDtos[0].EpisodeTitle150); - Assert.Equal(2, programDtos[0].Metadata[0].Gracenote?.Season); - Assert.Equal(3, programDtos[0].Metadata[0].Gracenote?.Episode); - Assert.Equal(13, programDtos[0].Cast.Count); - Assert.Equal("383774", programDtos[0].Cast[0].PersonId); - Assert.Equal("392649", programDtos[0].Cast[0].NameId); - Assert.Equal("Gorden Kaye", programDtos[0].Cast[0].Name); - Assert.Equal("Actor", programDtos[0].Cast[0].Role); - Assert.Equal("01", programDtos[0].Cast[0].BillingOrder); - Assert.Equal(3, programDtos[0].Crew.Count); - Assert.Equal("354407", programDtos[0].Crew[0].PersonId); - Assert.Equal("363281", programDtos[0].Crew[0].NameId); - Assert.Equal("David Croft", programDtos[0].Crew[0].Name); - Assert.Equal("Director", programDtos[0].Crew[0].Role); - Assert.Equal("01", programDtos[0].Crew[0].BillingOrder); - } - - /// - /// /metadata/programs response. - /// - [Fact] - public void Deserialize_Metadata_Programs_Response_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/metadata_programs_response.json"); - var showImagesDtos = JsonSerializer.Deserialize>(bytes, _jsonOptions); - - Assert.NotNull(showImagesDtos); - Assert.Single(showImagesDtos!); - Assert.Equal("SH00712240", showImagesDtos[0].ProgramId); - Assert.Equal(4, showImagesDtos[0].Data.Count); - Assert.Equal("135", showImagesDtos[0].Data[0].Width); - Assert.Equal("180", showImagesDtos[0].Data[0].Height); - Assert.Equal("assets/p282288_b_v2_aa.jpg", showImagesDtos[0].Data[0].Uri); - Assert.Equal("Sm", showImagesDtos[0].Data[0].Size); - Assert.Equal("3x4", showImagesDtos[0].Data[0].Aspect); - Assert.Equal("Banner-L3", showImagesDtos[0].Data[0].Category); - Assert.Equal("yes", showImagesDtos[0].Data[0].Text); - Assert.Equal("true", showImagesDtos[0].Data[0].Primary); - Assert.Equal("Series", showImagesDtos[0].Data[0].Tier); - } - - /// - /// /headends response. - /// - [Fact] - public void Deserialize_Headends_Response_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/headends_response.json"); - var headendsDtos = JsonSerializer.Deserialize>(bytes, _jsonOptions); - - Assert.NotNull(headendsDtos); - Assert.Equal(8, headendsDtos!.Count); - Assert.Equal("CA00053", headendsDtos[0].Headend); - Assert.Equal("Cable", headendsDtos[0].Transport); - Assert.Equal("Beverly Hills", headendsDtos[0].Location); - Assert.Equal(2, headendsDtos[0].Lineups.Count); - Assert.Equal("Time Warner Cable - Cable", headendsDtos[0].Lineups[0].Name); - Assert.Equal("USA-CA00053-DEFAULT", headendsDtos[0].Lineups[0].Lineup); - Assert.Equal("/20141201/lineups/USA-CA00053-DEFAULT", headendsDtos[0].Lineups[0].Uri); - } - - /// - /// /lineups response. - /// - [Fact] - public void Deserialize_Lineups_Response_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/lineups_response.json"); - var lineupsDto = JsonSerializer.Deserialize(bytes, _jsonOptions); - - Assert.NotNull(lineupsDto); - Assert.Equal(0, lineupsDto!.Code); - Assert.Equal("20141201.web.1", lineupsDto.ServerId); - Assert.Equal(new DateTime(2015, 04, 17, 14, 22, 17, DateTimeKind.Utc), lineupsDto.LineupTimestamp); - Assert.Equal(5, lineupsDto.Lineups.Count); - Assert.Equal("GBR-0001317-DEFAULT", lineupsDto.Lineups[0].Lineup); - Assert.Equal("Freeview - Carlton - LWT (Southeast)", lineupsDto.Lineups[0].Name); - Assert.Equal("DVB-T", lineupsDto.Lineups[0].Transport); - Assert.Equal("London", lineupsDto.Lineups[0].Location); - Assert.Equal("/20141201/lineups/GBR-0001317-DEFAULT", lineupsDto.Lineups[0].Uri); - - Assert.Equal("DELETED LINEUP", lineupsDto.Lineups[4].Name); - Assert.True(lineupsDto.Lineups[4].IsDeleted); - } - - /// - /// /lineup/:id response. - /// - [Fact] - public void Deserialize_Lineup_Response_Success() - { - var bytes = File.ReadAllBytes("Test Data/SchedulesDirect/lineup_response.json"); - var channelDto = JsonSerializer.Deserialize(bytes, _jsonOptions); - - Assert.NotNull(channelDto); - Assert.Equal(2, channelDto!.Map.Count); - Assert.Equal("24326", channelDto.Map[0].StationId); - Assert.Equal("001", channelDto.Map[0].Channel); - Assert.Equal("BBC ONE South", channelDto.Map[0].ProvderCallsign); - Assert.Equal("1", channelDto.Map[0].LogicalChannelNumber); - Assert.Equal("providerCallsign", channelDto.Map[0].MatchType); - } - } -} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/discover.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/discover.json deleted file mode 100644 index a4ad4ed44..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/discover.json +++ /dev/null @@ -1 +0,0 @@ -{"FriendlyName":"HDHomeRun DUAL","ModelNumber":"HDHR3-US","Legacy":1,"FirmwareName":"hdhomerun3_atsc","FirmwareVersion":"20200225","DeviceID":"10xxxxx5","TunerCount":2,"BaseURL":"http://10.10.10.100:80"} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/lineup.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/lineup.json deleted file mode 100644 index 0967ef424..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/10.10.10.100/lineup.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/discover.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/discover.json deleted file mode 100644 index 851f17bb2..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/discover.json +++ /dev/null @@ -1 +0,0 @@ -{"FriendlyName":"HDHomeRun PRIME","ModelNumber":"HDHR3-CC","FirmwareName":"hdhomerun3_cablecard","FirmwareVersion":"20160630atest2","DeviceID":"FFFFFFFF","DeviceAuth":"FFFFFFFF","TunerCount":3,"ConditionalAccess":1,"BaseURL":"http://192.168.1.182:80","LineupURL":"http://192.168.1.182:80/lineup.json"} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/lineup.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/lineup.json deleted file mode 100644 index 4cb5ebc8e..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/192.168.1.182/lineup.json +++ /dev/null @@ -1 +0,0 @@ -[ { "GuideNumber": "4.1", "GuideName": "WCMH-DT", "HD": 1, "Favorite": 1, "URL": "http://192.168.1.111:5004/auto/v4.1" }, { "GuideNumber": "4.2", "GuideName": "MeTV", "URL": "http://192.168.1.111:5004/auto/v4.2" }, { "GuideNumber": "4.3", "GuideName": "ION TV", "URL": "http://192.168.1.111:5004/auto/v4.3" }, { "GuideNumber": "6.1", "GuideName": "WSYX DT", "HD": 1, "URL": "http://192.168.1.111:5004/auto/v6.1" }, { "GuideNumber": "6.2", "GuideName": "MYTV", "URL": "http://192.168.1.111:5004/auto/v6.2" }, { "GuideNumber": "6.3", "GuideName": "ANTENNA", "URL": "http://192.168.1.111:5004/auto/v6.3" } ] diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml b/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml deleted file mode 100644 index dd4aa8977..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/emptycategory.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - sports - - diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml b/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml deleted file mode 100644 index 5a5be7997..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/LiveTv/Listings/XmlTv/notitle.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - sports - 2022-11-04 13:00:00 - - - - diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/headends_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/headends_response.json deleted file mode 100644 index 015afeecc..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/headends_response.json +++ /dev/null @@ -1 +0,0 @@ -[{"headend":"CA00053","transport":"Cable","location":"Beverly Hills","lineups":[{"name":"Time Warner Cable - Cable","lineup":"USA-CA00053-DEFAULT","uri":"/20141201/lineups/USA-CA00053-DEFAULT"},{"name":"Time Warner Cable - Digital","lineup":"USA-CA00053-X","uri":"/20141201/lineups/USA-CA00053-X"}]},{"headend":"CA61222","transport":"Cable","location":"Beverly Hills","lineups":[{"name":"Mulholland Estates - Cable","lineup":"USA-CA61222-DEFAULT","uri":"/20141201/lineups/USA-CA61222-DEFAULT"}]},{"headend":"CA66511","transport":"Cable","location":"Los Angeles","lineups":[{"name":"AT&T U-verse TV - Digital","lineup":"USA-CA66511-X","uri":"/20141201/lineups/USA-CA66511-X"}]},{"headend":"CA67309","transport":"Cable","location":"Westchester","lineups":[{"name":"Time Warner Cable Sherman Oaks - Cable","lineup":"USA-CA67309-DEFAULT","uri":"/20141201/lineups/USA-CA67309-DEFAULT"},{"name":"Time Warner Cable Sherman Oaks - Digital","lineup":"USA-CA67309-X","uri":"/20141201/lineups/USA-CA67309-X"}]},{"headend":"CA67310","transport":"Cable","location":"Eagle Rock","lineups":[{"name":"Time Warner Cable City of Los Angeles - Cable","lineup":"USA-CA67310-DEFAULT","uri":"/20141201/lineups/USA-CA67310-DEFAULT"},{"name":"Time Warner Cable City of Los Angeles - Digital","lineup":"USA-CA67310-X","uri":"/20141201/lineups/USA-CA67310-X"}]},{"headend":"DISH803","transport":"Satellite","location":"Los Angeles","lineups":[{"name":"DISH Los Angeles - Satellite","lineup":"USA-DISH803-DEFAULT","uri":"/20141201/lineups/USA-DISH803-DEFAULT"}]},{"headend":"DITV803","transport":"Satellite","location":"Los Angeles","lineups":[{"name":"DIRECTV Los Angeles - Satellite","lineup":"USA-DITV803-DEFAULT","uri":"/20141201/lineups/USA-DITV803-DEFAULT"}]},{"headend":"90210","transport":"Antenna","location":"90210","lineups":[{"name":"Antenna","lineup":"USA-OTA-90210","uri":"/20141201/lineups/USA-OTA-90210"}]}] diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineup_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineup_response.json deleted file mode 100644 index 072089470..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineup_response.json +++ /dev/null @@ -1 +0,0 @@ -{"map":[{"stationID":"24326","channel":"001","providerCallsign":"BBC ONE South","logicalChannelNumber":"1","matchType":"providerCallsign"},{"stationID":"17154","channel":"002","providerCallsign":"BBC TWO","logicalChannelNumber":"2","matchType":"providerCallsign"}]} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineups_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineups_response.json deleted file mode 100644 index 032a84e59..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/lineups_response.json +++ /dev/null @@ -1 +0,0 @@ -{"code":0,"serverID":"20141201.web.1","datetime":"2015-04-17T14:22:17Z","lineups":[{"lineup":"GBR-0001317-DEFAULT","name":"Freeview - Carlton - LWT (Southeast)","transport":"DVB-T","location":"London","uri":"/20141201/lineups/GBR-0001317-DEFAULT"},{"lineup":"USA-IL57303-X","name":"Comcast Waukegan/Lake Forest Area - Digital","transport":"Cable","location":"Lake Forest","uri":"/20141201/lineups/USA-IL57303-X"},{"lineup":"USA-NY67791-X","name":"Verizon Fios Queens - Digital","transport":"Cable","location":"Fresh Meadows","uri":"/20141201/lineups/USA-NY67791-X"},{"lineup":"USA-OTA-60030","name":"Local Over the Air Broadcast","transport":"Antenna","location":"60030","uri":"/20141201/lineups/USA-OTA-60030"},{"lineup":"USA-WI61859-DEFAULT","name":"DELETED LINEUP","isDeleted":true}]} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/metadata_programs_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/metadata_programs_response.json deleted file mode 100644 index 78166f09a..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/metadata_programs_response.json +++ /dev/null @@ -1 +0,0 @@ -[{"programID":"SH00712240","data":[{"width":"135","height":"180","uri":"assets/p282288_b_v2_aa.jpg","size":"Sm","aspect":"3x4","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"},{"width":"720","height":"540","uri":"assets/p282288_b_h6_aa.jpg","size":"Lg","aspect":"4x3","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"},{"width":"960","height":"1440","uri":"assets/p282288_b_v8_aa.jpg","size":"Ms","aspect":"2x3","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"},{"width":"180","height":"135","uri":"assets/p282288_b_h5_aa.jpg","size":"Sm","aspect":"4x3","category":"Banner-L3","text":"yes","primary":"true","tier":"Series"}]}] diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/programs_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/programs_response.json deleted file mode 100644 index fe2a94436..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/programs_response.json +++ /dev/null @@ -1 +0,0 @@ -[{"programID":"EP000000060003","titles":[{"title120":"'Allo 'Allo!"}],"eventDetails":{"subType":"Series"},"descriptions":{"description1000":[{"descriptionLanguage":"en","description":"A disguised British Intelligence officer is sent to help the airmen."}]},"originalAirDate":"1985-11-04","genres":["Sitcom"],"episodeTitle150":"The Poloceman Cometh","metadata":[{"Gracenote":{"season":2,"episode":3}}],"cast":[{"personId":"383774","nameId":"392649","name":"Gorden Kaye","role":"Actor","billingOrder":"01"},{"personId":"246840","nameId":"250387","name":"Carmen Silvera","role":"Actor","billingOrder":"02"},{"personId":"376955","nameId":"385830","name":"Rose Hill","role":"Actor","billingOrder":"03"},{"personId":"259773","nameId":"263340","name":"Vicki Michelle","role":"Actor","billingOrder":"04"},{"personId":"353113","nameId":"361987","name":"Kirsten Cooke","role":"Actor","billingOrder":"05"},{"personId":"77787","nameId":"77787","name":"Richard Marner","role":"Actor","billingOrder":"06"},{"personId":"230921","nameId":"234193","name":"Guy Siner","role":"Actor","billingOrder":"07"},{"personId":"374934","nameId":"383809","name":"Kim Hartman","role":"Actor","billingOrder":"08"},{"personId":"369151","nameId":"378026","name":"Richard Gibson","role":"Actor","billingOrder":"09"},{"personId":"343690","nameId":"352564","name":"Arthur Bostrom","role":"Actor","billingOrder":"10"},{"personId":"352557","nameId":"361431","name":"John D. Collins","role":"Actor","billingOrder":"11"},{"personId":"605275","nameId":"627734","name":"Nicholas Frankau","role":"Actor","billingOrder":"12"},{"personId":"373394","nameId":"382269","name":"Jack Haig","role":"Actor","billingOrder":"13"}],"crew":[{"personId":"354407","nameId":"363281","name":"David Croft","role":"Director","billingOrder":"01"},{"personId":"354407","nameId":"363281","name":"David Croft","role":"Writer","billingOrder":"02"},{"personId":"105145","nameId":"105145","name":"Jeremy Lloyd","role":"Writer","billingOrder":"03"}],"showType":"Series","hasImageArtwork":true,"md5":"Jo5NKxoo44xRvBCAq8QT2A"},{"programID":"EP000000510142","titles":[{"title120":"A Different World"}],"eventDetails":{"subType":"Series"},"descriptions":{"description1000":[{"descriptionLanguage":"en","description":"Whitley and Dwayne tell new students about their honeymoon in Los Angeles."}]},"originalAirDate":"1992-09-24","genres":["Sitcom"],"episodeTitle150":"Honeymoon in L.A.","metadata":[{"Gracenote":{"season":6,"episode":1}}],"cast":[{"personId":"700","nameId":"700","name":"Jasmine Guy","role":"Actor","billingOrder":"01"},{"personId":"729","nameId":"729","name":"Kadeem Hardison","role":"Actor","billingOrder":"02"},{"personId":"120","nameId":"120","name":"Darryl M. Bell","role":"Actor","billingOrder":"03"},{"personId":"1729","nameId":"1729","name":"Cree Summer","role":"Actor","billingOrder":"04"},{"personId":"217","nameId":"217","name":"Charnele Brown","role":"Actor","billingOrder":"05"},{"personId":"1811","nameId":"1811","name":"Glynn Turman","role":"Actor","billingOrder":"06"},{"personId":"1232","nameId":"1232","name":"Lou Myers","role":"Actor","billingOrder":"07"},{"personId":"1363","nameId":"1363","name":"Jada Pinkett","role":"Guest Star","billingOrder":"08"},{"personId":"222967","nameId":"225536","name":"Ajai Sanders","role":"Guest Star","billingOrder":"09"},{"personId":"181744","nameId":"183292","name":"Karen Malina White","role":"Guest Star","billingOrder":"10"},{"personId":"305017","nameId":"318897","name":"Patrick Y. Malone","role":"Guest Star","billingOrder":"11"},{"personId":"9841","nameId":"9841","name":"Bumper Robinson","role":"Guest Star","billingOrder":"12"},{"personId":"426422","nameId":"435297","name":"Sister Souljah","role":"Guest Star","billingOrder":"13"},{"personId":"25","nameId":"25","name":"Debbie Allen","role":"Guest Star","billingOrder":"14"},{"personId":"668","nameId":"668","name":"Gilbert Gottfried","role":"Guest Star","billingOrder":"15"}],"showType":"Series","hasImageArtwork":true,"md5":"P5kz0QmCeYxIA+yL0H4DWw"}] diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_request.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_request.json deleted file mode 100644 index 5ef1bfb1c..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_request.json +++ /dev/null @@ -1 +0,0 @@ -[{"stationID":"20454","date":["2015-03-13","2015-03-17"]},{"stationID":"10021","date":["2015-03-12","2015-03-13"]}] diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_response.json deleted file mode 100644 index 4a97e5517..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/schedules_response.json +++ /dev/null @@ -1 +0,0 @@ -[{"stationID":"20454","programs":[{"programID":"SH005371070000","airDateTime":"2015-03-03T00:00:00Z","duration":1800,"md5":"Sy8HEMBPcuiAx3FBukUhKQ","new":true,"audioProperties":["stereo","cc"],"videoProperties":["hdtv"]},{"programID":"EP000014577244","airDateTime":"2015-03-03T00:30:00Z","duration":1800,"md5":"25DNXVXO192JI7Y9vSW9lQ","new":true,"audioProperties":["stereo","cc"],"videoProperties":["hdtv"]}]}] diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_live_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_live_response.json deleted file mode 100644 index e5fb64a6f..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_live_response.json +++ /dev/null @@ -1 +0,0 @@ -{"code":0,"message":"OK","serverID":"AWS-SD-web.1","datetime":"2016-08-23T13:55:25Z","token":"f3fca79989cafe7dead71beefedc812b"} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_offline_response.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_offline_response.json deleted file mode 100644 index b66a4ed0c..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/SchedulesDirect/token_offline_response.json +++ /dev/null @@ -1 +0,0 @@ -{"response":"SERVICE_OFFLINE","code":3000,"serverID":"20141201.web.1","message":"Server offline for maintenance.","datetime":"2015-04-23T00:03:32Z","token":"CAFEDEADBEEFCAFEDEADBEEFCAFEDEADBEEFCAFE"} -- cgit v1.2.3