mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-04 06:48:35 +01:00
Merge branch 'master' of github.com:jellyfin/jellyfin into nfo-watched
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
<PackageReference Include="AutoFixture" Version="4.15.0" />
|
||||
<PackageReference Include="AutoFixture.AutoMoq" Version="4.15.0" />
|
||||
<PackageReference Include="AutoFixture.Xunit2" Version="4.15.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Emby.Server.Implementations.HttpServer;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Tests.HttpServer
|
||||
{
|
||||
public class WebSocketConnectionTests
|
||||
{
|
||||
[Fact]
|
||||
public void DeserializeWebSocketMessage_SingleSegment_Success()
|
||||
{
|
||||
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||
var bytes = File.ReadAllBytes("Test Data/HttpServer/ForceKeepAlive.json");
|
||||
con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(bytes), out var bytesConsumed);
|
||||
Assert.Equal(109, bytesConsumed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeWebSocketMessage_MultipleSegments_Success()
|
||||
{
|
||||
const int SplitPos = 64;
|
||||
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||
var bytes = File.ReadAllBytes("Test Data/HttpServer/ForceKeepAlive.json");
|
||||
var seg1 = new BufferSegment(new Memory<byte>(bytes, 0, SplitPos));
|
||||
var seg2 = seg1.Append(new Memory<byte>(bytes, SplitPos, bytes.Length - SplitPos));
|
||||
con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(seg1, 0, seg2, seg2.Memory.Length - 1), out var bytesConsumed);
|
||||
Assert.Equal(109, bytesConsumed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeWebSocketMessage_ValidPartial_Success()
|
||||
{
|
||||
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||
var bytes = File.ReadAllBytes("Test Data/HttpServer/ValidPartial.json");
|
||||
con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(bytes), out var bytesConsumed);
|
||||
Assert.Equal(109, bytesConsumed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeserializeWebSocketMessage_Partial_ThrowJsonException()
|
||||
{
|
||||
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||
var bytes = File.ReadAllBytes("Test Data/HttpServer/Partial.json");
|
||||
Assert.Throws<JsonException>(() => con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(bytes), out var bytesConsumed));
|
||||
}
|
||||
|
||||
internal class BufferSegment : ReadOnlySequenceSegment<byte>
|
||||
{
|
||||
public BufferSegment(Memory<byte> memory)
|
||||
{
|
||||
Memory = memory;
|
||||
}
|
||||
|
||||
public BufferSegment Append(Memory<byte> memory)
|
||||
{
|
||||
var segment = new BufferSegment(memory)
|
||||
{
|
||||
RunningIndex = RunningIndex + Memory.Length
|
||||
};
|
||||
Next = segment;
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,12 @@
|
||||
<RootNamespace>Jellyfin.Server.Implementations.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Test Data\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture" Version="4.15.0" />
|
||||
<PackageReference Include="AutoFixture.AutoMoq" Version="4.15.0" />
|
||||
@@ -35,11 +41,6 @@
|
||||
<ProjectReference Include="..\..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="LiveTv\discover.json" />
|
||||
<EmbeddedResource Include="LiveTv\lineup.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -21,24 +22,15 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
|
||||
|
||||
public HdHomerunHostTests()
|
||||
{
|
||||
const string BaseResourcePath = "Jellyfin.Server.Implementations.Tests.LiveTv.";
|
||||
|
||||
var messageHandler = new Mock<HttpMessageHandler>();
|
||||
messageHandler.Protected()
|
||||
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
|
||||
.Returns<HttpRequestMessage, CancellationToken>(
|
||||
(m, _) =>
|
||||
{
|
||||
var resource = BaseResourcePath + m.RequestUri?.Segments[^1];
|
||||
var stream = typeof(HdHomerunHostTests).Assembly.GetManifestResourceStream(resource);
|
||||
if (stream == null)
|
||||
{
|
||||
throw new NullReferenceException("Resource doesn't exist: " + resource);
|
||||
}
|
||||
|
||||
return Task.FromResult(new HttpResponseMessage()
|
||||
{
|
||||
Content = new StreamContent(stream)
|
||||
Content = new StreamContent(File.OpenRead("Test Data/LiveTv/" + m.RequestUri?.Segments[^1]))
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Emby.Server.Implementations.Plugins;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Tests.Plugins
|
||||
{
|
||||
public class PluginManagerTests
|
||||
{
|
||||
private static readonly string _testPathRoot = Path.Combine(Path.GetTempPath(), "jellyfin-test-data");
|
||||
|
||||
[Fact]
|
||||
public void SaveManifest_RoundTrip_Success()
|
||||
{
|
||||
var pluginManager = new PluginManager(new NullLogger<PluginManager>(), null!, null!, null!, new Version(1, 0));
|
||||
var manifest = new PluginManifest()
|
||||
{
|
||||
Version = "1.0"
|
||||
};
|
||||
|
||||
var tempPath = Path.Combine(_testPathRoot, "manifest-" + Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
Assert.True(pluginManager.SaveManifest(manifest, tempPath));
|
||||
|
||||
var res = pluginManager.LoadManifest(tempPath);
|
||||
|
||||
Assert.Equal(manifest.Category, res.Manifest.Category);
|
||||
Assert.Equal(manifest.Changelog, res.Manifest.Changelog);
|
||||
Assert.Equal(manifest.Description, res.Manifest.Description);
|
||||
Assert.Equal(manifest.Id, res.Manifest.Id);
|
||||
Assert.Equal(manifest.Name, res.Manifest.Name);
|
||||
Assert.Equal(manifest.Overview, res.Manifest.Overview);
|
||||
Assert.Equal(manifest.Owner, res.Manifest.Owner);
|
||||
Assert.Equal(manifest.TargetAbi, res.Manifest.TargetAbi);
|
||||
Assert.Equal(manifest.Timestamp, res.Manifest.Timestamp);
|
||||
Assert.Equal(manifest.Version, res.Manifest.Version);
|
||||
Assert.Equal(manifest.Status, res.Manifest.Status);
|
||||
Assert.Equal(manifest.AutoUpdate, res.Manifest.AutoUpdate);
|
||||
Assert.Equal(manifest.ImagePath, res.Manifest.ImagePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"MessageType":"ForceKeepAlive","MessageId":"00000000-0000-0000-0000-000000000000","ServerId":null,"Data":60}
|
||||
@@ -0,0 +1 @@
|
||||
{"MessageType":"KeepAlive","MessageId":"d29ef449-6965-4000
|
||||
@@ -0,0 +1 @@
|
||||
{"MessageType":"ForceKeepAlive","MessageId":"00000000-0000-0000-0000-000000000000","ServerId":null,"Data":60}{"MessageType":"KeepAlive","MessageId":"d29ef449-6965-4000
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj" />
|
||||
<ProjectReference Include="../../MediaBrowser.Providers/MediaBrowser.Providers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
||||
@@ -8,6 +8,7 @@ using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Providers.Movies;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
@@ -24,8 +25,13 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||
public EpisodeNfoProviderTests()
|
||||
{
|
||||
var providerManager = new Mock<IProviderManager>();
|
||||
|
||||
var imdbExternalId = new ImdbExternalId();
|
||||
var externalIdInfo = new ExternalIdInfo(imdbExternalId.ProviderName, imdbExternalId.Key, imdbExternalId.Type, imdbExternalId.UrlFormatString);
|
||||
|
||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
||||
.Returns(new[] { externalIdInfo });
|
||||
|
||||
var config = new Mock<IConfigurationManager>();
|
||||
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
||||
.Returns(new XbmcMetadataOptions());
|
||||
@@ -60,6 +66,8 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||
Assert.Equal(2017, item.ProductionYear);
|
||||
Assert.Single(item.Studios);
|
||||
Assert.Contains("Starz", item.Studios);
|
||||
Assert.Equal("tt5017734", item.ProviderIds[MetadataProvider.Imdb.ToString()]);
|
||||
Assert.Equal("1276153", item.ProviderIds[MetadataProvider.Tmdb.ToString()]);
|
||||
|
||||
// Credits
|
||||
var writers = result.People.Where(x => x.Type == PersonType.Writer).ToArray();
|
||||
|
||||
@@ -9,6 +9,7 @@ using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Movies;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
@@ -27,8 +28,12 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||
_testUser = new User("Test User", "Auth provider", "Reset provider");
|
||||
|
||||
var providerManager = new Mock<IProviderManager>();
|
||||
|
||||
var tmdbExternalId = new TmdbMovieExternalId();
|
||||
var externalIdInfo = new ExternalIdInfo(tmdbExternalId.ProviderName, tmdbExternalId.Key, tmdbExternalId.Type, tmdbExternalId.UrlFormatString);
|
||||
|
||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
||||
.Returns(new[] { externalIdInfo });
|
||||
|
||||
var nfoConfig = new XbmcMetadataOptions()
|
||||
{
|
||||
@@ -63,7 +68,8 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||
|
||||
Assert.Equal("Justice League", item.OriginalTitle);
|
||||
Assert.Equal("Justice for all.", item.Tagline);
|
||||
Assert.Equal("tt0974015", item.ProviderIds["imdb"]);
|
||||
Assert.Equal("tt0974015", item.ProviderIds[MetadataProvider.Imdb.ToString()]);
|
||||
Assert.Equal("141052", item.ProviderIds[MetadataProvider.Tmdb.ToString()]);
|
||||
|
||||
Assert.Equal(4, item.Genres.Length);
|
||||
Assert.Contains("Action", item.Genres);
|
||||
|
||||
@@ -10,6 +10,8 @@ using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Providers.Music;
|
||||
using MediaBrowser.Providers.Plugins.MusicBrainz;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
@@ -24,8 +26,13 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||
public MusicAlbumNfoProviderTests()
|
||||
{
|
||||
var providerManager = new Mock<IProviderManager>();
|
||||
|
||||
var musicBrainzArtist = new MusicBrainzArtistExternalId();
|
||||
var externalIdInfo = new ExternalIdInfo(musicBrainzArtist.ProviderName, musicBrainzArtist.Key, musicBrainzArtist.Type, "MusicBrainzServer");
|
||||
|
||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
||||
.Returns(new[] { externalIdInfo });
|
||||
|
||||
var config = new Mock<IConfigurationManager>();
|
||||
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
||||
.Returns(new XbmcMetadataOptions());
|
||||
|
||||
@@ -8,6 +8,7 @@ using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Providers.Music;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
@@ -22,8 +23,13 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||
public MusicArtistNfoParserTests()
|
||||
{
|
||||
var providerManager = new Mock<IProviderManager>();
|
||||
|
||||
var musicBrainzArtist = new MusicBrainzArtistExternalId();
|
||||
var externalIdInfo = new ExternalIdInfo(musicBrainzArtist.ProviderName, musicBrainzArtist.Key, musicBrainzArtist.Type, "MusicBrainzServer");
|
||||
|
||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
||||
.Returns(new[] { externalIdInfo });
|
||||
|
||||
var config = new Mock<IConfigurationManager>();
|
||||
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
||||
.Returns(new XbmcMetadataOptions());
|
||||
|
||||
@@ -47,8 +47,8 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||
Assert.Equal("American Gods", item.OriginalTitle);
|
||||
Assert.Equal(string.Empty, item.Tagline);
|
||||
Assert.Equal(0, item.RunTimeTicks);
|
||||
Assert.Equal("46639", item.ProviderIds["tmdb"]);
|
||||
Assert.Equal("253573", item.ProviderIds["tvdb"]);
|
||||
Assert.Equal("46639", item.ProviderIds[MetadataProvider.Tmdb.ToString()]);
|
||||
Assert.Equal("253573", item.ProviderIds[MetadataProvider.Tvdb.ToString()]);
|
||||
|
||||
Assert.Equal(3, item.Genres.Length);
|
||||
Assert.Contains("Drama", item.Genres);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<playcount>2</playcount>
|
||||
<watched>true</watched>
|
||||
<lastplayed>2021-02-11 07:47:23</lastplayed>
|
||||
<tmdbId>141052</tmdbId>
|
||||
<thumb aspect="set.poster" preview="https://assets.fanart.tv/preview/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg">https://assets.fanart.tv/fanart/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg</thumb>
|
||||
<thumb aspect="set.poster" preview="https://assets.fanart.tv/preview/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg">https://assets.fanart.tv/fanart/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg</thumb>
|
||||
<thumb aspect="set.clearlogo" preview="https://assets.fanart.tv/preview/movies/468551/hdmovielogo/justice-league-collection-5ba855ed4239a.png">https://assets.fanart.tv/fanart/movies/468551/hdmovielogo/justice-league-collection-5ba855ed4239a.png</thumb>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<lastplayed></lastplayed>
|
||||
<id>1276153</id>
|
||||
<uniqueid type="tmdb" default="true">1276153</uniqueid>
|
||||
<imdbId>tt5017734</imdbId>
|
||||
<genre>Drama</genre>
|
||||
<genre>Mystery</genre>
|
||||
<genre>Sci-Fi & Fantasy</genre>
|
||||
|
||||
Reference in New Issue
Block a user