diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/IndexerTagSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/IndexerTagSpecificationFixture.cs index 7ce13fde0..53c19b1ea 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/IndexerTagSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/IndexerTagSpecificationFixture.cs @@ -1,8 +1,9 @@ -using System.Collections.Generic; +using System.Collections.Generic; using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; +using NzbDrone.Core.Datastore; using NzbDrone.Core.DecisionEngine.Specifications.RssSync; using NzbDrone.Core.Indexers; using NzbDrone.Core.IndexerSearch.Definitions; @@ -31,8 +32,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync }; Mocker - .GetMock() + .GetMock() .Setup(m => m.Get(It.IsAny())) + .Throws(new ModelNotFoundException(typeof(IndexerDefinition), -1)); + + Mocker + .GetMock() + .Setup(m => m.Get(1)) .Returns(_fakeIndexerDefinition); _specification = Mocker.Resolve(); @@ -98,5 +104,25 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _specification.IsSatisfiedBy(_parseResultMulti, new MovieSearchCriteria()).Accepted.Should().BeFalse(); } + + [Test] + public void release_without_indexerid_should_return_true() + { + _fakeIndexerDefinition.Tags = new HashSet { 456 }; + _fakeMovie.Tags = new HashSet { 123, 789 }; + _fakeRelease.IndexerId = 0; + + _specification.IsSatisfiedBy(_parseResultMulti, new MovieSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeTrue(); + } + + [Test] + public void release_with_invalid_indexerid_should_return_true() + { + _fakeIndexerDefinition.Tags = new HashSet { 456 }; + _fakeMovie.Tags = new HashSet { 123, 789 }; + _fakeRelease.IndexerId = 2; + + _specification.IsSatisfiedBy(_parseResultMulti, new MovieSearchCriteria { MonitoredEpisodesOnly = true }).Accepted.Should().BeTrue(); + } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs index cb5d6b508..4f02eb065 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs @@ -1,6 +1,7 @@ using System.Linq; using NLog; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Datastore; using NzbDrone.Core.Indexers; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser.Model; @@ -10,12 +11,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync public class IndexerTagSpecification : IDecisionEngineSpecification { private readonly Logger _logger; - private readonly IIndexerRepository _indexerRepository; + private readonly IIndexerFactory _indexerFactory; - public IndexerTagSpecification(Logger logger, IIndexerRepository indexerRepository) + public IndexerTagSpecification(Logger logger, IIndexerFactory indexerFactory) { _logger = logger; - _indexerRepository = indexerRepository; + _indexerFactory = indexerFactory; } public SpecificationPriority Priority => SpecificationPriority.Default; @@ -23,8 +24,24 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { + if (subject.Release == null || subject.Movie?.Tags == null || subject.Release.IndexerId == 0) + { + return Decision.Accept(); + } + + IndexerDefinition indexer; + try + { + indexer = _indexerFactory.Get(subject.Release.IndexerId); + } + catch (ModelNotFoundException) + { + _logger.Debug("Indexer with id {0} does not exist, skipping indexer tags check", subject.Release.IndexerId); + return Decision.Accept(); + } + // If indexer has tags, check that at least one of them is present on the series - var indexerTags = _indexerRepository.Get(subject.Release.IndexerId).Tags; + var indexerTags = indexer.Tags; if (indexerTags.Any() && indexerTags.Intersect(subject.Movie.Tags).Empty()) {