using System.Collections.Generic; using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Profiles.Qualities; using NzbDrone.Core.Qualities; using NzbDrone.Core.Queue; using NzbDrone.Core.Music; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Profiles.Languages; using NzbDrone.Core.Languages; namespace NzbDrone.Core.Test.DecisionEngineTests { [TestFixture] public class QueueSpecificationFixture : CoreTest { private Artist _artist; private Album _album; private RemoteAlbum _remoteAlbum; private Artist _otherArtist; private Album _otherAlbum; private ReleaseInfo _releaseInfo; [SetUp] public void Setup() { Mocker.Resolve(); _artist = Builder.CreateNew() .With(e => e.QualityProfile = new QualityProfile { UpgradeAllowed = true, Items = Qualities.QualityFixture.GetDefaultQualities(), }) .With(l => l.LanguageProfile = new LanguageProfile { Languages = Languages.LanguageFixture.GetDefaultLanguages(), UpgradeAllowed = true, Cutoff = Language.Spanish }) .Build(); _album = Builder.CreateNew() .With(e => e.ArtistId = _artist.Id) .Build(); _otherArtist = Builder.CreateNew() .With(s => s.Id = 2) .Build(); _otherAlbum = Builder.CreateNew() .With(e => e.ArtistId = _otherArtist.Id) .With(e => e.Id = 2) .Build(); _releaseInfo = Builder.CreateNew() .Build(); _remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_256), Language = Language.Spanish }) .With(r => r.PreferredWordScore = 0) .Build(); } private void GivenEmptyQueue() { Mocker.GetMock() .Setup(s => s.GetQueue()) .Returns(new List()); } private void GivenQueue(IEnumerable remoteAlbums) { var queue = remoteAlbums.Select(remoteAlbum => new Queue.Queue { RemoteAlbum = remoteAlbum }); Mocker.GetMock() .Setup(s => s.GetQueue()) .Returns(queue.ToList()); } [Test] public void should_return_true_when_queue_is_empty() { GivenEmptyQueue(); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_true_when_artist_doesnt_match() { var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _otherArtist) .With(r => r.Albums = new List { _album }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_false_if_everything_is_the_same() { _artist.QualityProfile.Value.Cutoff = Quality.FLAC.Id; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_256), Language = Language.Spanish }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_true_when_quality_in_queue_is_lower() { _artist.QualityProfile.Value.Cutoff = Quality.MP3_320.Id; _artist.LanguageProfile.Value.Cutoff = Language.Spanish; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_192), Language = Language.Spanish }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_true_when_quality_in_queue_is_lower_but_language_is_higher() { _artist.QualityProfile.Value.Cutoff = Quality.FLAC.Id; _artist.LanguageProfile.Value.Cutoff = Language.Spanish; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_192), Language = Language.English }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_true_when_album_doesnt_match() { var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _otherAlbum }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_192) }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_true_when_qualities_are_the_same_and_languages_are_the_same_with_higher_preferred_word_score() { _remoteAlbum.PreferredWordScore = 1; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_256), Language = Language.Spanish, }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_false_when_qualities_are_the_same_and_languages_are_the_same() { var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_192), Language = Language.Spanish }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_true_when_qualities_are_the_same_but_language_is_better() { var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_192), Language = Language.English, }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_true_when_quality_is_better_language_is_better_and_upgrade_allowed_is_false_for_quality_profile() { _artist.QualityProfile.Value.Cutoff = Quality.FLAC.Id; _artist.QualityProfile.Value.UpgradeAllowed = false; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_224), Language = Language.English }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue(); } [Test] public void should_return_false_when_quality_in_queue_is_better() { _artist.QualityProfile.Value.Cutoff = Quality.FLAC.Id; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_320), Language = Language.English }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_false_if_matching_multi_album_is_in_queue() { var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album, _otherAlbum }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_320), Language = Language.English }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_false_if_multi_album_has_one_album_in_queue() { var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_320), Language = Language.English }) .With(r => r.Release = _releaseInfo) .Build(); _remoteAlbum.Albums.Add(_otherAlbum); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_false_if_multi_part_album_is_already_in_queue() { var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album, _otherAlbum }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_320), Language = Language.English }) .With(r => r.Release = _releaseInfo) .Build(); _remoteAlbum.Albums.Add(_otherAlbum); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_false_if_multi_part_album_has_two_albums_in_queue() { var remoteAlbums = Builder.CreateListOfSize(2) .All() .With(r => r.Artist = _artist) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_320), Language = Language.English }) .With(r => r.Release = _releaseInfo) .TheFirst(1) .With(r => r.Albums = new List { _album }) .TheNext(1) .With(r => r.Albums = new List { _otherAlbum }) .Build(); _remoteAlbum.Albums.Add(_otherAlbum); GivenQueue(remoteAlbums); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_false_if_quality_and_language_in_queue_meets_cutoff() { _artist.QualityProfile.Value.Cutoff = _remoteAlbum.ParsedAlbumInfo.Quality.Quality.Id; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_256), Language = Language.Spanish }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_false_when_quality_are_the_same_language_is_better_and_upgrade_allowed_is_false_for_language_profile() { _artist.LanguageProfile.Value.UpgradeAllowed = false; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_256), Language = Language.English }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } [Test] public void should_return_false_when_quality_is_better_languages_are_the_same_and_upgrade_allowed_is_false_for_quality_profile() { _artist.QualityProfile.Value.Cutoff = Quality.FLAC.Id; _artist.QualityProfile.Value.UpgradeAllowed = false; var remoteAlbum = Builder.CreateNew() .With(r => r.Artist = _artist) .With(r => r.Albums = new List { _album }) .With(r => r.ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.FLAC), Language = Language.Spanish }) .With(r => r.Release = _releaseInfo) .Build(); GivenQueue(new List { remoteAlbum }); Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse(); } } }