You've already forked Sonarr
							
							
				mirror of
				https://github.com/Sonarr/Sonarr.git
				synced 2025-10-31 00:07:55 +02:00 
			
		
		
		
	added RestSharpExtensions to help validate REST response
This commit is contained in:
		| @@ -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> | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								NzbDrone.Core/Rest/RestException.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								NzbDrone.Core/Rest/RestException.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								NzbDrone.Core/Rest/RestSharpExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								NzbDrone.Core/Rest/RestSharpExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user