diff --git a/PlexRequests.Store/RequestedModel.cs b/PlexRequests.Store/RequestedModel.cs index 65b1b31cf..7f9f44996 100644 --- a/PlexRequests.Store/RequestedModel.cs +++ b/PlexRequests.Store/RequestedModel.cs @@ -12,6 +12,7 @@ namespace PlexRequests.Store public RequestedModel() { RequestedUsers = new List(); + Episodes = new List(); } // ReSharper disable once IdentifierTypo @@ -42,7 +43,7 @@ namespace PlexRequests.Store public string ArtistName { get; set; } public string ArtistId { get; set; } public int IssueId { get; set; } - public EpisodesModel[] Episodes { get; set; } + public List Episodes { get; set; } [JsonIgnore] public List AllUsers diff --git a/PlexRequests.UI.Tests/PlexRequests.UI.Tests.csproj b/PlexRequests.UI.Tests/PlexRequests.UI.Tests.csproj index 12ac1f175..93705fea4 100644 --- a/PlexRequests.UI.Tests/PlexRequests.UI.Tests.csproj +++ b/PlexRequests.UI.Tests/PlexRequests.UI.Tests.csproj @@ -110,6 +110,7 @@ + diff --git a/PlexRequests.UI.Tests/TvSenderTests.cs b/PlexRequests.UI.Tests/TvSenderTests.cs new file mode 100644 index 000000000..879f8aa39 --- /dev/null +++ b/PlexRequests.UI.Tests/TvSenderTests.cs @@ -0,0 +1,198 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: TvSenderTests.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using Moq; + +using NUnit.Framework; + +using PlexRequests.Api.Interfaces; +using PlexRequests.Api.Models.Sonarr; +using PlexRequests.Core.SettingModels; +using PlexRequests.Store; +using PlexRequests.UI.Helpers; + +using Ploeh.AutoFixture; + +namespace PlexRequests.UI.Tests +{ + [TestFixture] + public class TvSenderTests + { + + private Mock SonarrMock { get; set; } + private Mock SickrageMock { get; set; } + + private TvSender Sender { get; set; } + private Fixture F { get; set; } + + [SetUp] + public void Setup() + { + F = new Fixture(); + SonarrMock = new Mock(); + SickrageMock = new Mock(); + Sender = new TvSender(SonarrMock.Object, SickrageMock.Object); + } + + [Test] + public async Task HappyPathSendSeriesToSonarr() + { + var seriesResult = new SonarrAddSeries() { monitored = true }; + SonarrMock.Setup(x => x.GetSeries(It.IsAny(), It.IsAny())).Returns(new List()); + SonarrMock.Setup( + x => + x.AddSeries( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).Returns(seriesResult); + Sender = new TvSender(SonarrMock.Object, SickrageMock.Object); + + var request = new RequestedModel(); + + var result = await Sender.SendToSonarr(GetSonarrSettings(), request); + + Assert.That(result, Is.EqualTo(seriesResult)); + SonarrMock.Verify(x => x.AddSeries(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + true), Times.Once); + } + + [Test] + public async Task HappyPathSendEpisodeWithExistingSeriesToSonarr() + { + var seriesResult = new SonarrAddSeries { monitored = true, title = "TitleReturned" }; + var selectedSeries = F.Build().With(x => x.tvdbId, 1).CreateMany(); + SonarrMock.Setup(x => x.GetSeries(It.IsAny(), It.IsAny())).Returns(selectedSeries.ToList()); + SonarrMock.Setup(x => x.AddSeries( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).Returns(seriesResult); + var sonarrEpisodes = new SonarrEpisodes() + { + title = "abc", + seasonNumber = 2, + episodeNumber = 1, + monitored = false + }; + var episodesList = F.CreateMany().ToList(); + episodesList.Add(sonarrEpisodes); + + SonarrMock.Setup(x => x.GetEpisodes(It.IsAny(), It.IsAny(), + It.IsAny())).Returns(F.CreateMany()); + + Sender = new TvSender(SonarrMock.Object, SickrageMock.Object); + var episodes = new List + { + new EpisodesModel + { + EpisodeNumber = 1, + SeasonNumber = 2 + } + }; + var model = F.Build().With(x => x.ProviderId, 1) + .With(x => x.Episodes, episodes).Create(); + + var result = await Sender.SendToSonarr(GetSonarrSettings(), model, "2"); + + Assert.That(result, Is.EqualTo(seriesResult)); + SonarrMock.Verify(x => x.AddSeries(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + true), Times.Once); + } + + [Test] + public async Task RequestEpisodesWithExistingSeriesTest() + { + var episodesReturned = new List + { + new SonarrEpisodes {episodeNumber = 1, seasonNumber = 2, monitored = false, id=22} + }; + SonarrMock.Setup(x => x.GetEpisodes(It.IsAny(), It.IsAny(), + It.IsAny())).Returns(episodesReturned); + SonarrMock.Setup(x => x.GetEpisode("22", It.IsAny(), It.IsAny())).Returns(new SonarrEpisode {id=22}); + + + Sender = new TvSender(SonarrMock.Object, SickrageMock.Object); + + var model = new RequestedModel + { + Episodes = new List { new EpisodesModel { EpisodeNumber = 1, SeasonNumber = 2 } } + }; + + var series = new Series(); + await Sender.RequestEpisodesWithExistingSeries(model, series, GetSonarrSettings()); + + SonarrMock.Verify(x => x.UpdateEpisode(It.Is(e => e.monitored), It.IsAny(), It.IsAny())); + SonarrMock.Verify(x => x.GetEpisode("22", It.IsAny(), It.IsAny()),Times.Once); + SonarrMock.Verify(x => x.SearchForEpisodes(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + } + + private SonarrSettings GetSonarrSettings() + { + var sonarrSettings = new SonarrSettings + { + ApiKey = "abc", + Enabled = true, + Ip = "192.168.1.1", + Port = 8989, + }; + return sonarrSettings; + } + } +} \ No newline at end of file diff --git a/PlexRequests.UI/Helpers/TvSender.cs b/PlexRequests.UI/Helpers/TvSender.cs index 3007a598a..7376355fd 100644 --- a/PlexRequests.UI/Helpers/TvSender.cs +++ b/PlexRequests.UI/Helpers/TvSender.cs @@ -60,7 +60,7 @@ namespace PlexRequests.UI.Helpers public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model, string qualityId) { var qualityProfile = 0; - var episodeRequest = model.Episodes.Length > 0; + var episodeRequest = model.Episodes.Any(); if (!string.IsNullOrEmpty(qualityId)) // try to parse the passed in quality, otherwise use the settings default quality { int.TryParse(qualityId, out qualityProfile); @@ -150,7 +150,7 @@ namespace PlexRequests.UI.Helpers return result; } - private async Task RequestEpisodesWithExistingSeries(RequestedModel model, Series selectedSeries, SonarrSettings sonarrSettings) + internal async Task RequestEpisodesWithExistingSeries(RequestedModel model, Series selectedSeries, SonarrSettings sonarrSettings) { // Show Exists // Look up all episodes diff --git a/PlexRequests.UI/Modules/RequestsModule.cs b/PlexRequests.UI/Modules/RequestsModule.cs index b69c7d67d..cb8ed6882 100644 --- a/PlexRequests.UI/Modules/RequestsModule.cs +++ b/PlexRequests.UI/Modules/RequestsModule.cs @@ -248,7 +248,7 @@ namespace PlexRequests.UI.Modules IssueId = tv.IssueId, TvSeriesRequestType = tv.SeasonsRequested, Qualities = qualities.ToArray(), - Episodes = tv.Episodes, + Episodes = tv.Episodes.ToArray(), }).ToList(); return Response.AsJson(viewModel); diff --git a/PlexRequests.UI/Modules/SearchModule.cs b/PlexRequests.UI/Modules/SearchModule.cs index 5015130b6..0f1120d4f 100644 --- a/PlexRequests.UI/Modules/SearchModule.cs +++ b/PlexRequests.UI/Modules/SearchModule.cs @@ -60,6 +60,7 @@ using PlexRequests.Store.Repository; using TMDbLib.Objects.General; using Action = PlexRequests.Helpers.Analytics.Action; +using EpisodesModel = PlexRequests.Store.EpisodesModel; namespace PlexRequests.UI.Modules { @@ -659,10 +660,10 @@ namespace PlexRequests.UI.Modules model.SeasonsRequested = "All"; break; case "episode": - model.Episodes = new Store.EpisodesModel[episodeModel.Episodes.Length]; + model.Episodes = new List(); for (var i = 0; i < episodeModel.Episodes.Length; i++) { - model.Episodes[i] = new Store.EpisodesModel { EpisodeNumber = episodeModel.Episodes[i].EpisodeNumber, SeasonNumber = episodeModel.Episodes[i].SeasonNumber }; + model.Episodes[i] = new EpisodesModel { EpisodeNumber = episodeModel.Episodes[i].EpisodeNumber, SeasonNumber = episodeModel.Episodes[i].SeasonNumber }; } break; default: diff --git a/PlexRequests.UI/Properties/AssemblyInfo.cs b/PlexRequests.UI/Properties/AssemblyInfo.cs index 8e32c54ad..04abf3e05 100644 --- a/PlexRequests.UI/Properties/AssemblyInfo.cs +++ b/PlexRequests.UI/Properties/AssemblyInfo.cs @@ -1,36 +1,37 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("PlexRequests.UI")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("PlexRequests.UI")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 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 -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("354f3a80-8093-46a6-8ef5-139aef621c10")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: AssemblyInformationalVersionAttribute("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PlexRequests.UI")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PlexRequests.UI")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 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 +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("354f3a80-8093-46a6-8ef5-139aef621c10")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyInformationalVersionAttribute("1.0.0.0")] +[assembly: InternalsVisibleTo("PlexRequests.UI.Tests")] \ No newline at end of file