added RestSharpExtensions to help validate REST response
This commit is contained in:
parent
e7805a5afb
commit
9c8c485c98
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.MetadataSource;
|
using NzbDrone.Core.MetadataSource;
|
||||||
|
using NzbDrone.Core.Rest;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common.Categories;
|
using NzbDrone.Test.Common.Categories;
|
||||||
|
@ -45,6 +46,13 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||||
ValidateEpisodes(details.Item2);
|
ValidateEpisodes(details.Item2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void getting_details_of_invalid_series()
|
||||||
|
{
|
||||||
|
Assert.Throws<RestException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
|
||||||
|
}
|
||||||
|
|
||||||
private void ValidateSeries(Series series)
|
private void ValidateSeries(Series series)
|
||||||
{
|
{
|
||||||
series.Should().NotBeNull();
|
series.Should().NotBeNull();
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Core.MetadataSource.Trakt;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
using Episode = NzbDrone.Core.Tv.Episode;
|
using Episode = NzbDrone.Core.Tv.Episode;
|
||||||
|
using NzbDrone.Core.Rest;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource
|
namespace NzbDrone.Core.MetadataSource
|
||||||
{
|
{
|
||||||
|
@ -19,23 +20,20 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
{
|
{
|
||||||
var client = BuildClient("search", "shows");
|
var client = BuildClient("search", "shows");
|
||||||
var restRequest = new RestRequest(title.ToSearchTerm());
|
var restRequest = new RestRequest(title.ToSearchTerm());
|
||||||
var response = client.Execute<List<Show>>(restRequest);
|
var response = client.ExecuteAndValidate<List<Show>>(restRequest);
|
||||||
|
|
||||||
CheckForError(response);
|
return response.Select(MapSeries).ToList();
|
||||||
|
|
||||||
return response.Data.Select(MapSeries).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tuple<Series, List<Episode>> GetSeriesInfo(int tvDbSeriesId)
|
public Tuple<Series, List<Episode>> GetSeriesInfo(int tvDbSeriesId)
|
||||||
{
|
{
|
||||||
var client = BuildClient("show", "summary");
|
var client = BuildClient("show", "summary");
|
||||||
var restRequest = new RestRequest(tvDbSeriesId.ToString() + "/extended");
|
var restRequest = new RestRequest(tvDbSeriesId.ToString() + "/extended");
|
||||||
var response = client.Execute<Show>(restRequest);
|
var response = client.ExecuteAndValidate<Show>(restRequest);
|
||||||
|
|
||||||
CheckForError(response);
|
|
||||||
|
|
||||||
var episodes = response.Data.seasons.SelectMany(c => c.episodes).Select(MapEpisode).ToList();
|
var episodes = response.seasons.SelectMany(c => c.episodes).Select(MapEpisode).ToList();
|
||||||
var series = MapSeries(response.Data);
|
var series = MapSeries(response);
|
||||||
|
|
||||||
return new Tuple<Series, List<Episode>>(series, episodes);
|
return new Tuple<Series, List<Episode>>(series, episodes);
|
||||||
}
|
}
|
||||||
|
@ -126,12 +124,6 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
return match.Captures[0].Value;
|
return match.Captures[0].Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckForError(IRestResponse response)
|
|
||||||
{
|
|
||||||
if (response.StatusCode != HttpStatusCode.OK)
|
|
||||||
{
|
|
||||||
throw new TraktCommunicationException(response.ErrorMessage, response.ErrorException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,11 +4,11 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
public class Pushover : NotificationBase<PushoverSettings>
|
public class Pushover : NotificationBase<PushoverSettings>
|
||||||
{
|
{
|
||||||
private readonly IPushoverService _pushoverService;
|
private readonly IPushoverProxy _pushoverProxy;
|
||||||
|
|
||||||
public Pushover(IPushoverService pushoverService)
|
public Pushover(IPushoverProxy pushoverProxy)
|
||||||
{
|
{
|
||||||
_pushoverService = pushoverService;
|
_pushoverProxy = pushoverProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
public override string Name
|
||||||
|
@ -30,14 +30,14 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
const string title = "Episode Grabbed";
|
const string title = "Episode Grabbed";
|
||||||
|
|
||||||
_pushoverService.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
_pushoverProxy.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDownload(string message, Series series)
|
public override void OnDownload(string message, Series series)
|
||||||
{
|
{
|
||||||
const string title = "Episode Downloaded";
|
const string title = "Episode Downloaded";
|
||||||
|
|
||||||
_pushoverService.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
_pushoverProxy.SendNotification(title, message, Settings.UserKey, (PushoverPriority)Settings.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AfterRename(Series series)
|
public override void AfterRename(Series series)
|
||||||
|
|
|
@ -1,27 +1,19 @@
|
||||||
using System.Net;
|
using NzbDrone.Common.Messaging;
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Messaging;
|
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
using NzbDrone.Core.Rest;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Pushover
|
namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
public interface IPushoverService
|
public interface IPushoverProxy
|
||||||
{
|
{
|
||||||
void SendNotification(string title, string message, string userKey, PushoverPriority priority);
|
void SendNotification(string title, string message, string userKey, PushoverPriority priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PushoverService : IPushoverService, IExecute<TestPushoverCommand>
|
public class PushoverProxy : IPushoverProxy, IExecute<TestPushoverCommand>
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
private const string TOKEN = "yz9b4U215iR4vrKFRfjNXP24NMNPKJ";
|
private const string TOKEN = "yz9b4U215iR4vrKFRfjNXP24NMNPKJ";
|
||||||
private const string URL = "https://api.pushover.net/1/messages.json";
|
private const string URL = "https://api.pushover.net/1/messages.json";
|
||||||
|
|
||||||
public PushoverService(Logger logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendNotification(string title, string message, string userKey, PushoverPriority priority)
|
public void SendNotification(string title, string message, string userKey, PushoverPriority priority)
|
||||||
{
|
{
|
||||||
var client = new RestClient(URL);
|
var client = new RestClient(URL);
|
||||||
|
@ -32,12 +24,7 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
request.AddParameter("message", message);
|
request.AddParameter("message", message);
|
||||||
request.AddParameter("priority", (int)priority);
|
request.AddParameter("priority", (int)priority);
|
||||||
|
|
||||||
var response = client.Execute(request);
|
client.ExecuteAndValidate(request);
|
||||||
|
|
||||||
if (response.StatusCode != HttpStatusCode.OK)
|
|
||||||
{
|
|
||||||
throw new InvalidResponseException(response.Content);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(TestPushoverCommand message)
|
public void Execute(TestPushoverCommand message)
|
||||||
|
|
|
@ -342,6 +342,8 @@
|
||||||
<Compile Include="Qualities\QualityProfileInUseException.cs" />
|
<Compile Include="Qualities\QualityProfileInUseException.cs" />
|
||||||
<Compile Include="Qualities\QualitySizeRepository.cs" />
|
<Compile Include="Qualities\QualitySizeRepository.cs" />
|
||||||
<Compile Include="Qualities\QualityProfileRepository.cs" />
|
<Compile Include="Qualities\QualityProfileRepository.cs" />
|
||||||
|
<Compile Include="Rest\RestSharpExtensions.cs" />
|
||||||
|
<Compile Include="Rest\RestException.cs" />
|
||||||
<Compile Include="SeriesStats\SeriesStatisticsService.cs" />
|
<Compile Include="SeriesStats\SeriesStatisticsService.cs" />
|
||||||
<Compile Include="Tv\EpisodeService.cs" />
|
<Compile Include="Tv\EpisodeService.cs" />
|
||||||
<Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" />
|
<Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" />
|
||||||
|
@ -541,6 +543,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Download\Clients\Sabnzbd\Api\" />
|
<Folder Include="Download\Clients\Sabnzbd\Api\" />
|
||||||
|
<Folder Include="Download\Clients\uTorrent\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using RestSharp;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Rest
|
||||||
|
{
|
||||||
|
public class RestException : Exception
|
||||||
|
{
|
||||||
|
public IRestResponse Response { get; private set; }
|
||||||
|
|
||||||
|
public RestException(IRestResponse response, IRestClient restClient)
|
||||||
|
: base(string.Format("REST request failed: [{0}] [{1}] at [{2}]", (int)response.StatusCode, response.Request.Method, restClient.BuildUri(response.Request)))
|
||||||
|
{
|
||||||
|
Response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (Response != null)
|
||||||
|
{
|
||||||
|
return base.ToString() + Environment.NewLine + Response.Content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
using System.Net;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.EnsureThat;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using RestSharp;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Rest
|
||||||
|
{
|
||||||
|
public static class RestSharpExtensions
|
||||||
|
{
|
||||||
|
private static readonly Logger Logger = LogManager.GetLogger("RestExtensions");
|
||||||
|
|
||||||
|
public static IRestResponse ValidateResponse(this IRestResponse response, IRestClient restClient)
|
||||||
|
{
|
||||||
|
Ensure.That(() => response).IsNotNull();
|
||||||
|
|
||||||
|
if (response.Request == null && response.ErrorException != null)
|
||||||
|
{
|
||||||
|
throw response.ErrorException;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ensure.That(() => response.Request).IsNotNull();
|
||||||
|
Ensure.That(() => restClient).IsNotNull();
|
||||||
|
|
||||||
|
Logger.Debug("Validating Responses from [{0}] [{1}] status: [{2}] body:[{3}]", response.Request.Method, restClient.BuildUri(response.Request), response.StatusCode, response.Content);
|
||||||
|
|
||||||
|
if (response.ResponseUri == null)
|
||||||
|
{
|
||||||
|
Logger.ErrorException("Error communicating with server", response.ErrorException);
|
||||||
|
throw response.ErrorException;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (response.StatusCode)
|
||||||
|
{
|
||||||
|
case HttpStatusCode.OK:
|
||||||
|
{
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Logger.Warn("[{0}] [{1}] Failed. [{2}]", response.Request.Method, response.ResponseUri.ToString(), response.StatusCode);
|
||||||
|
throw new RestException(response, restClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Read<T>(this IRestResponse restResponse, IRestClient restClient) where T : class, new()
|
||||||
|
{
|
||||||
|
restResponse.ValidateResponse(restClient);
|
||||||
|
|
||||||
|
return Json.Deserialize<T>(restResponse.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T ExecuteAndValidate<T>(this IRestClient client, IRestRequest request) where T : class, new()
|
||||||
|
{
|
||||||
|
return client.Execute(request).Read<T>(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IRestResponse ExecuteAndValidate(this IRestClient client, IRestRequest request)
|
||||||
|
{
|
||||||
|
return client.Execute(request).ValidateResponse(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void AddQueryString(this IRestRequest request, string name, object value)
|
||||||
|
{
|
||||||
|
request.AddParameter(name, value.ToString(), ParameterType.GetOrPost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,7 +48,7 @@ namespace NzbDrone.Test.Common
|
||||||
|
|
||||||
//can't use because of a bug in mono with 2.6.2,
|
//can't use because of a bug in mono with 2.6.2,
|
||||||
//https://bugs.launchpad.net/nunitv2/+bug/1076932
|
//https://bugs.launchpad.net/nunitv2/+bug/1076932
|
||||||
//if (TestContext.CurrentContext.Result.State == TestState.Success)
|
if (OsInfo.IsWindows && TestContext.CurrentContext.Result.State == TestState.Success)
|
||||||
{
|
{
|
||||||
ExceptionVerification.AssertNoUnexcpectedLogs();
|
ExceptionVerification.AssertNoUnexcpectedLogs();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvokeAsExtensionMethod/@EntryIndexedValue">ERROR</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvokeAsExtensionMethod/@EntryIndexedValue">ERROR</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=NUnit_002ENonPublicMethodWithTestAttribute/@EntryIndexedValue">ERROR</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=NUnit_002ENonPublicMethodWithTestAttribute/@EntryIndexedValue">ERROR</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002EGlobal/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002EGlobal/@EntryIndexedValue">HINT</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue">WARNING</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=NzbDrone/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="NzbDrone"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_EXCEPT_SIMPLE_TYPES</LocalVariableStyle><ForeachVariableStyle>ALWAYS_IMPLICIT</ForeachVariableStyle></CSUseVar><CSUpdateFileHeader>True</CSUpdateFileHeader><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReorderTypeMembers>True</CSReorderTypeMembers><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags></Profile></s:String>
|
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=NzbDrone/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="NzbDrone"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_EXCEPT_SIMPLE_TYPES</LocalVariableStyle><ForeachVariableStyle>ALWAYS_IMPLICIT</ForeachVariableStyle></CSUseVar><CSUpdateFileHeader>True</CSUpdateFileHeader><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReorderTypeMembers>True</CSReorderTypeMembers><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags></Profile></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">NzbDrone</s:String>
|
<s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">NzbDrone</s:String>
|
||||||
|
|
Loading…
Reference in New Issue