diff options
18 files changed, 266 insertions, 151 deletions
diff --git a/.github/workflows/automation.yml b/.github/workflows/automation.yml index db34693cc..d5d308185 100644 --- a/.github/workflows/automation.yml +++ b/.github/workflows/automation.yml @@ -16,7 +16,7 @@ jobs: label: stable backport - name: Remove from 'Current Release' project - uses: alex-page/github-project-automation-plus@v0.5.1 + uses: alex-page/github-project-automation-plus@v0.6.0 if: (github.event.pull_request || github.event.issue.pull_request) && !steps.checkLabel.outputs.hasLabel continue-on-error: true with: @@ -25,7 +25,7 @@ jobs: repo-token: ${{ secrets.GH_TOKEN }} - name: Add to 'Release Next' project - uses: alex-page/github-project-automation-plus@v0.5.1 + uses: alex-page/github-project-automation-plus@v0.6.0 if: (github.event.pull_request || github.event.issue.pull_request) && github.event.action == 'opened' continue-on-error: true with: @@ -34,7 +34,7 @@ jobs: repo-token: ${{ secrets.GH_TOKEN }} - name: Add to 'Current Release' project - uses: alex-page/github-project-automation-plus@v0.5.1 + uses: alex-page/github-project-automation-plus@v0.6.0 if: (github.event.pull_request || github.event.issue.pull_request) && steps.checkLabel.outputs.hasLabel continue-on-error: true with: @@ -48,7 +48,7 @@ jobs: run: echo "::set-output name=number::$(curl -s ${{ github.event.issue.comments_url }} | jq '.[] | select(.author_association == "MEMBER") | .author_association' | wc -l)" - name: Move issue to needs triage - uses: alex-page/github-project-automation-plus@v0.5.1 + uses: alex-page/github-project-automation-plus@v0.6.0 if: github.event.issue.pull_request == '' && github.event.comment.author_association == 'MEMBER' && steps.member_comments.outputs.number <= 1 continue-on-error: true with: @@ -57,7 +57,7 @@ jobs: repo-token: ${{ secrets.GH_TOKEN }} - name: Add issue to triage project - uses: alex-page/github-project-automation-plus@v0.5.1 + uses: alex-page/github-project-automation-plus@v0.6.0 if: github.event.issue.pull_request == '' && github.event.action == 'opened' continue-on-error: true with: diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 3417076dc..5f2be07cf 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -111,7 +111,7 @@ namespace Emby.Dlna if (profile != null) { - _logger.LogDebug("Found matching device profile: {0}", profile.Name); + _logger.LogDebug("Found matching device profile: {ProfileName}", profile.Name); } else { @@ -138,80 +138,45 @@ namespace Emby.Dlna _logger.LogInformation(builder.ToString()); } - private bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo) + /// <summary> + /// Attempts to match a device with a profile. + /// Rules: + /// - If the profile field has no value, the field matches irregardless of its contents. + /// - the profile field can be an exact match, or a reg exp. + /// </summary> + /// <param name="deviceInfo">The <see cref="DeviceIdentification"/> of the device.</param> + /// <param name="profileInfo">The <see cref="DeviceIdentification"/> of the profile.</param> + /// <returns><b>True</b> if they match.</returns> + public bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo) { - if (!string.IsNullOrEmpty(profileInfo.FriendlyName)) - { - if (deviceInfo.FriendlyName == null || !IsRegexOrSubstringMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(profileInfo.Manufacturer)) - { - if (deviceInfo.Manufacturer == null || !IsRegexOrSubstringMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(profileInfo.ManufacturerUrl)) - { - if (deviceInfo.ManufacturerUrl == null || !IsRegexOrSubstringMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(profileInfo.ModelDescription)) - { - if (deviceInfo.ModelDescription == null || !IsRegexOrSubstringMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(profileInfo.ModelName)) - { - if (deviceInfo.ModelName == null || !IsRegexOrSubstringMatch(deviceInfo.ModelName, profileInfo.ModelName)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(profileInfo.ModelNumber)) - { - if (deviceInfo.ModelNumber == null || !IsRegexOrSubstringMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) - { - return false; - } - } + return IsRegexOrSubstringMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName) + && IsRegexOrSubstringMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer) + && IsRegexOrSubstringMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl) + && IsRegexOrSubstringMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription) + && IsRegexOrSubstringMatch(deviceInfo.ModelName, profileInfo.ModelName) + && IsRegexOrSubstringMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber) + && IsRegexOrSubstringMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl) + && IsRegexOrSubstringMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber); + } - if (!string.IsNullOrEmpty(profileInfo.ModelUrl)) + private bool IsRegexOrSubstringMatch(string input, string pattern) + { + if (string.IsNullOrEmpty(pattern)) { - if (deviceInfo.ModelUrl == null || !IsRegexOrSubstringMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) - { - return false; - } + // In profile identification: An empty pattern matches anything. + return true; } - if (!string.IsNullOrEmpty(profileInfo.SerialNumber)) + if (string.IsNullOrEmpty(input)) { - if (deviceInfo.SerialNumber == null || !IsRegexOrSubstringMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) - { - return false; - } + // The profile contains a value, and the device doesn't. + return false; } - return true; - } - - private bool IsRegexOrSubstringMatch(string input, string pattern) - { try { - return input.Contains(pattern, StringComparison.OrdinalIgnoreCase) || Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + return input.Equals(pattern, StringComparison.OrdinalIgnoreCase) + || Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); } catch (ArgumentException ex) { diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index 8272e505a..f2f526221 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -188,7 +188,7 @@ namespace Emby.Dlna.PlayTo _sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName); - string serverAddress = _appHost.GetSmartApiUrl(info.LocalIpAddress); + string serverAddress = _appHost.GetSmartApiUrl(info.RemoteIpAddress); controller = new PlayToController( sessionInfo, diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs index d13871add..d9c6a93c7 100644 --- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs +++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs @@ -104,7 +104,7 @@ namespace Emby.Dlna.Ssdp { Location = e.DiscoveredDevice.DescriptionLocation, Headers = headers, - LocalIpAddress = e.LocalIpAddress + RemoteIpAddress = e.RemoteIpAddress }); DeviceDiscoveredInternal?.Invoke(this, args); diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 9248053f5..adbfe52c4 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -29,8 +29,8 @@ <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.3" /> <PackageReference Include="Mono.Nat" Version="3.0.1" /> - <PackageReference Include="prometheus-net.DotNetRuntime" Version="3.4.1" /> - <PackageReference Include="sharpcompress" Version="0.28.1" /> + <PackageReference Include="prometheus-net.DotNetRuntime" Version="4.0.0" /> + <PackageReference Include="sharpcompress" Version="0.28.2" /> <PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" /> <PackageReference Include="DotNet.Glob" Version="3.1.2" /> </ItemGroup> diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 6a9f4174d..7d030418a 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -2881,12 +2881,20 @@ namespace Emby.Server.Implementations.Library public void UpdatePeople(BaseItem item, List<PersonInfo> people) { + UpdatePeopleAsync(item, people, CancellationToken.None).GetAwaiter().GetResult(); + } + + /// <inheritdoc /> + public async Task UpdatePeopleAsync(BaseItem item, List<PersonInfo> people, CancellationToken cancellationToken) + { if (!item.SupportsPeople) { return; } _itemRepository.UpdatePeople(item.Id, people); + + await SavePeopleMetadataAsync(people, cancellationToken).ConfigureAwait(false); } public async Task<ItemImageInfo> ConvertImageToLocal(BaseItem item, ItemImageInfo image, int imageIndex) @@ -2990,6 +2998,58 @@ namespace Emby.Server.Implementations.Library } } + private async Task SavePeopleMetadataAsync(IEnumerable<PersonInfo> people, CancellationToken cancellationToken) + { + var personsToSave = new List<BaseItem>(); + + foreach (var person in people) + { + cancellationToken.ThrowIfCancellationRequested(); + + var itemUpdateType = ItemUpdateType.MetadataDownload; + var saveEntity = false; + var personEntity = GetPerson(person.Name); + + // if PresentationUniqueKey is empty it's likely a new item. + if (string.IsNullOrEmpty(personEntity.PresentationUniqueKey)) + { + personEntity.PresentationUniqueKey = personEntity.CreatePresentationUniqueKey(); + saveEntity = true; + } + + foreach (var id in person.ProviderIds) + { + if (!string.Equals(personEntity.GetProviderId(id.Key), id.Value, StringComparison.OrdinalIgnoreCase)) + { + personEntity.SetProviderId(id.Key, id.Value); + saveEntity = true; + } + } + + if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary)) + { + personEntity.SetImage( + new ItemImageInfo + { + Path = person.ImageUrl, + Type = ImageType.Primary + }, + 0); + + saveEntity = true; + itemUpdateType = ItemUpdateType.ImageUpdate; + } + + if (saveEntity) + { + personsToSave.Add(personEntity); + await RunMetadataSavers(personEntity, itemUpdateType).ConfigureAwait(false); + } + } + + CreateItems(personsToSave, null, CancellationToken.None); + } + private void StartScanInBackground() { Task.Run(() => diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index d6dc5a2dc..3868882e5 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -17,8 +17,8 @@ <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.5" /> <PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" /> - <PackageReference Include="Swashbuckle.AspNetCore" Version="6.0.7" /> - <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.0.7" /> + <PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.3" /> + <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.1.3" /> </ItemGroup> <ItemGroup> diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 80fcf71f3..6d9b568da 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -467,6 +467,15 @@ namespace MediaBrowser.Controller.Library void UpdatePeople(BaseItem item, List<PersonInfo> people); /// <summary> + /// Asynchronously updates the people. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="people">The people.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>The async task.</returns> + Task UpdatePeopleAsync(BaseItem item, List<PersonInfo> people, CancellationToken cancellationToken); + + /// <summary> /// Gets the item ids. /// </summary> /// <param name="query">The query.</param> diff --git a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs index d71013f01..987a3a908 100644 --- a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs +++ b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs @@ -16,5 +16,7 @@ namespace MediaBrowser.Model.Dlna public IPAddress LocalIpAddress { get; set; } public int LocalPort { get; set; } + + public IPAddress RemoteIpAddress { get; set; } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index f12586665..6b778a090 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -201,7 +201,7 @@ namespace MediaBrowser.Providers.Manager } // Save to database - await SaveItemAsync(metadataResult, libraryOptions, updateType, cancellationToken).ConfigureAwait(false); + await SaveItemAsync(metadataResult, updateType, cancellationToken).ConfigureAwait(false); } await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false); @@ -216,71 +216,18 @@ namespace MediaBrowser.Providers.Manager lookupInfo.Year = result.ProductionYear; } - protected async Task SaveItemAsync(MetadataResult<TItemType> result, LibraryOptions libraryOptions, ItemUpdateType reason, CancellationToken cancellationToken) + protected async Task SaveItemAsync(MetadataResult<TItemType> result, ItemUpdateType reason, CancellationToken cancellationToken) { if (result.Item.SupportsPeople && result.People != null) { var baseItem = result.Item; - LibraryManager.UpdatePeople(baseItem, result.People); - await SavePeopleMetadataAsync(result.People, cancellationToken).ConfigureAwait(false); + await LibraryManager.UpdatePeopleAsync(baseItem, result.People, cancellationToken).ConfigureAwait(false); } await result.Item.UpdateToRepositoryAsync(reason, cancellationToken).ConfigureAwait(false); } - private async Task SavePeopleMetadataAsync(IEnumerable<PersonInfo> people, CancellationToken cancellationToken) - { - var personsToSave = new List<BaseItem>(); - - foreach (var person in people) - { - cancellationToken.ThrowIfCancellationRequested(); - - var itemUpdateType = ItemUpdateType.MetadataDownload; - var saveEntity = false; - var personEntity = LibraryManager.GetPerson(person.Name); - - // if PresentationUniqueKey is empty it's likely a new item. - if (string.IsNullOrEmpty(personEntity.PresentationUniqueKey)) - { - personEntity.PresentationUniqueKey = personEntity.CreatePresentationUniqueKey(); - saveEntity = true; - } - - foreach (var id in person.ProviderIds) - { - if (!string.Equals(personEntity.GetProviderId(id.Key), id.Value, StringComparison.OrdinalIgnoreCase)) - { - personEntity.SetProviderId(id.Key, id.Value); - saveEntity = true; - } - } - - if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary)) - { - personEntity.SetImage( - new ItemImageInfo - { - Path = person.ImageUrl, - Type = ImageType.Primary - }, - 0); - - saveEntity = true; - itemUpdateType = ItemUpdateType.ImageUpdate; - } - - if (saveEntity) - { - personsToSave.Add(personEntity); - await LibraryManager.RunMetadataSavers(personEntity, itemUpdateType).ConfigureAwait(false); - } - } - - LibraryManager.CreateItems(personsToSave, null, CancellationToken.None); - } - protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) { item.AfterMetadataRefresh(); diff --git a/RSSDP/DeviceAvailableEventArgs.cs b/RSSDP/DeviceAvailableEventArgs.cs index b7d22a7df..04b14c4dc 100644 --- a/RSSDP/DeviceAvailableEventArgs.cs +++ b/RSSDP/DeviceAvailableEventArgs.cs @@ -8,7 +8,7 @@ namespace Rssdp /// </summary> public sealed class DeviceAvailableEventArgs : EventArgs { - public IPAddress LocalIpAddress { get; set; } + public IPAddress RemoteIpAddress { get; set; } private readonly DiscoveredSsdpDevice _DiscoveredDevice; diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index 0cdc5ce3d..188e298e2 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -211,7 +211,7 @@ namespace Rssdp.Infrastructure /// Raises the <see cref="DeviceAvailable"/> event. /// </summary> /// <seealso cref="DeviceAvailable"/> - protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress) + protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress IpAddress) { if (this.IsDisposed) { @@ -223,7 +223,7 @@ namespace Rssdp.Infrastructure { handlers(this, new DeviceAvailableEventArgs(device, isNewDevice) { - LocalIpAddress = localIpAddress + RemoteIpAddress = IpAddress }); } } @@ -289,7 +289,7 @@ namespace Rssdp.Infrastructure } } - private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device, IPAddress localIpAddress) + private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device, IPAddress IpAddress) { bool isNewDevice = false; lock (_Devices) @@ -307,17 +307,17 @@ namespace Rssdp.Infrastructure } } - DeviceFound(device, isNewDevice, localIpAddress); + DeviceFound(device, isNewDevice, IpAddress); } - private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress) + private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress IpAddress) { if (!NotificationTypeMatchesFilter(device)) { return; } - OnDeviceAvailable(device, isNewDevice, localIpAddress); + OnDeviceAvailable(device, isNewDevice, IpAddress); } private bool NotificationTypeMatchesFilter(DiscoveredSsdpDevice device) @@ -350,7 +350,7 @@ namespace Rssdp.Infrastructure return _CommunicationsServer.SendMulticastMessage(message, null, cancellationToken); } - private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) + private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress IpAddress) { if (!message.IsSuccessStatusCode) { @@ -370,11 +370,11 @@ namespace Rssdp.Infrastructure ResponseHeaders = message.Headers }; - AddOrUpdateDiscoveredDevice(device, localIpAddress); + AddOrUpdateDiscoveredDevice(device, IpAddress); } } - private void ProcessNotificationMessage(HttpRequestMessage message, IPAddress localIpAddress) + private void ProcessNotificationMessage(HttpRequestMessage message, IPAddress IpAddress) { if (String.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0) { @@ -384,7 +384,7 @@ namespace Rssdp.Infrastructure var notificationType = GetFirstHeaderStringValue("NTS", message); if (String.Compare(notificationType, SsdpConstants.SsdpKeepAliveNotification, StringComparison.OrdinalIgnoreCase) == 0) { - ProcessAliveNotification(message, localIpAddress); + ProcessAliveNotification(message, IpAddress); } else if (String.Compare(notificationType, SsdpConstants.SsdpByeByeNotification, StringComparison.OrdinalIgnoreCase) == 0) { @@ -392,7 +392,7 @@ namespace Rssdp.Infrastructure } } - private void ProcessAliveNotification(HttpRequestMessage message, IPAddress localIpAddress) + private void ProcessAliveNotification(HttpRequestMessage message, IPAddress IpAddress) { var location = GetFirstHeaderUriValue("Location", message); if (location != null) @@ -407,7 +407,7 @@ namespace Rssdp.Infrastructure ResponseHeaders = message.Headers }; - AddOrUpdateDiscoveredDevice(device, localIpAddress); + AddOrUpdateDiscoveredDevice(device, IpAddress); } } @@ -628,7 +628,7 @@ namespace Rssdp.Infrastructure private void CommsServer_RequestReceived(object sender, RequestReceivedEventArgs e) { - ProcessNotificationMessage(e.Message, e.LocalIpAddress); + ProcessNotificationMessage(e.Message, e.ReceivedFrom.Address); } } } diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 050d4c040..0071cda6e 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -15,7 +15,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="AutoFixture" Version="4.16.0" /> + <PackageReference Include="AutoFixture" Version="4.17.0" /> <PackageReference Include="AutoFixture.AutoMoq" Version="4.16.0" /> <PackageReference Include="AutoFixture.Xunit2" Version="4.16.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.5" /> diff --git a/tests/Jellyfin.Dlna.Tests/DlnaManagerTests.cs b/tests/Jellyfin.Dlna.Tests/DlnaManagerTests.cs new file mode 100644 index 000000000..668bd8f87 --- /dev/null +++ b/tests/Jellyfin.Dlna.Tests/DlnaManagerTests.cs @@ -0,0 +1,131 @@ +using Emby.Dlna; +using Emby.Dlna.PlayTo; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Serialization; +using Microsoft.Extensions.Logging; +using Moq; +using Xunit; + +namespace Jellyfin.Dlna.Tests +{ + public class DlnaManagerTests + { + private DlnaManager GetManager() + { + var xmlSerializer = new Mock<IXmlSerializer>(); + var fileSystem = new Mock<IFileSystem>(); + var appPaths = new Mock<IApplicationPaths>(); + var loggerFactory = new Mock<ILoggerFactory>(); + var appHost = new Mock<IServerApplicationHost>(); + + return new DlnaManager(xmlSerializer.Object, fileSystem.Object, appPaths.Object, loggerFactory.Object, appHost.Object); + } + + [Fact] + public void IsMatch_GivenMatchingName_ReturnsTrue() + { + var device = new DeviceInfo() + { + Name = "My Device", + Manufacturer = "LG Electronics", + ManufacturerUrl = "http://www.lge.com", + ModelDescription = "LG WebOSTV DMRplus", + ModelName = "LG TV", + ModelNumber = "1.0", + }; + + var profile = new DeviceProfile() + { + Name = "Test Profile", + FriendlyName = "My Device", + Manufacturer = "LG Electronics", + ManufacturerUrl = "http://www.lge.com", + ModelDescription = "LG WebOSTV DMRplus", + ModelName = "LG TV", + ModelNumber = "1.0", + Identification = new () + { + FriendlyName = "My Device", + Manufacturer = "LG Electronics", + ManufacturerUrl = "http://www.lge.com", + ModelDescription = "LG WebOSTV DMRplus", + ModelName = "LG TV", + ModelNumber = "1.0", + } + }; + + var profile2 = new DeviceProfile() + { + Name = "Test Profile", + FriendlyName = "My Device", + Identification = new DeviceIdentification() + { + FriendlyName = "My Device", + } + }; + + var deviceMatch = GetManager().IsMatch(device.ToDeviceIdentification(), profile2.Identification); + var deviceMatch2 = GetManager().IsMatch(device.ToDeviceIdentification(), profile.Identification); + + Assert.True(deviceMatch); + Assert.True(deviceMatch2); + } + + [Fact] + public void IsMatch_GivenNamesAndManufacturersDoNotMatch_ReturnsFalse() + { + var device = new DeviceInfo() + { + Name = "My Device", + Manufacturer = "JVC" + }; + + var profile = new DeviceProfile() + { + Name = "Test Profile", + FriendlyName = "My Device", + Manufacturer = "LG Electronics", + ManufacturerUrl = "http://www.lge.com", + ModelDescription = "LG WebOSTV DMRplus", + ModelName = "LG TV", + ModelNumber = "1.0", + Identification = new () + { + FriendlyName = "My Device", + Manufacturer = "LG Electronics", + ManufacturerUrl = "http://www.lge.com", + ModelDescription = "LG WebOSTV DMRplus", + ModelName = "LG TV", + ModelNumber = "1.0", + } + }; + + var deviceMatch = GetManager().IsMatch(device.ToDeviceIdentification(), profile.Identification); + + Assert.False(deviceMatch); + } + + [Fact] + public void IsMatch_GivenNamesAndRegExMatch_ReturnsTrue() + { + var device = new DeviceInfo() + { + Name = "My Device" + }; + + var profile = new DeviceProfile() + { + Name = "Test Profile", + FriendlyName = "My .*", + Identification = new () + }; + + var deviceMatch = GetManager().IsMatch(device.ToDeviceIdentification(), profile.Identification); + + Assert.True(deviceMatch); + } + } +} diff --git a/tests/Jellyfin.Dlna.Tests/Jellyfin.Dlna.Tests.csproj b/tests/Jellyfin.Dlna.Tests/Jellyfin.Dlna.Tests.csproj index c2c0dca1b..f7c21f072 100644 --- a/tests/Jellyfin.Dlna.Tests/Jellyfin.Dlna.Tests.csproj +++ b/tests/Jellyfin.Dlna.Tests/Jellyfin.Dlna.Tests.csproj @@ -10,7 +10,8 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" /> + <PackageReference Include="Moq" Version="4.16.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="3.0.3" /> diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index 486899f4f..7a4ab9b26 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -22,7 +22,7 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="AutoFixture" Version="4.16.0" /> + <PackageReference Include="AutoFixture" Version="4.17.0" /> <PackageReference Include="AutoFixture.AutoMoq" Version="4.16.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Moq" Version="4.16.1" /> diff --git a/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj b/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj index 0de92249a..8646b60b1 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj +++ b/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj @@ -9,7 +9,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="AutoFixture" Version="4.16.0" /> + <PackageReference Include="AutoFixture" Version="4.17.0" /> <PackageReference Include="AutoFixture.AutoMoq" Version="4.16.0" /> <PackageReference Include="AutoFixture.Xunit2" Version="4.16.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.5" /> diff --git a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj index 9e60dbcd9..64383a2d9 100644 --- a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj +++ b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj @@ -10,7 +10,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="AutoFixture" Version="4.16.0" /> + <PackageReference Include="AutoFixture" Version="4.17.0" /> <PackageReference Include="AutoFixture.AutoMoq" Version="4.16.0" /> <PackageReference Include="AutoFixture.Xunit2" Version="4.16.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.5" /> |
