using System.Collections.Generic; using System.Linq; using System.Net; using FluentAssertions; using NLog; using NzbDrone.Common.Serializer; using Readarr.Http; using Readarr.Http.REST; using RestSharp; namespace NzbDrone.Integration.Test.Client { public class ClientBase { protected readonly IRestClient _restClient; protected readonly string _resource; protected readonly string _apiKey; protected readonly Logger _logger; public ClientBase(IRestClient restClient, string apiKey, string resource) { _restClient = restClient; _resource = resource; _apiKey = apiKey; _logger = LogManager.GetLogger("REST"); } public RestRequest BuildRequest(string command = "") { var request = new RestRequest(_resource + "/" + command.Trim('/')) { RequestFormat = DataFormat.Json, }; request.AddHeader("Authorization", _apiKey); request.AddHeader("X-Api-Key", _apiKey); return request; } public string Execute(IRestRequest request, HttpStatusCode statusCode) { _logger.Info("{0}: {1}", request.Method, _restClient.BuildUri(request)); var response = _restClient.Execute(request); _logger.Info("Response: {0}", response.Content); if (response.ErrorException != null) { throw response.ErrorException; } AssertDisableCache(response); response.ErrorMessage.Should().BeNullOrWhiteSpace(); response.StatusCode.Should().Be(statusCode, response.Content ?? string.Empty); return response.Content; } public T Execute(IRestRequest request, HttpStatusCode statusCode) where T : class, new() { var content = Execute(request, statusCode); return Json.Deserialize(content); } private static void AssertDisableCache(IRestResponse response) { // cache control header gets reordered on net core var headers = response.Headers; ((string)headers.SingleOrDefault(c => c.Name == "Cache-Control")?.Value ?? string.Empty).Split(',').Select(x => x.Trim()) .Should().BeEquivalentTo("no-store, no-cache".Split(',').Select(x => x.Trim())); headers.Single(c => c.Name == "Pragma").Value.Should().Be("no-cache"); headers.Single(c => c.Name == "Expires").Value.Should().Be("-1"); } } public class ClientBase : ClientBase where TResource : RestResource, new() { public ClientBase(IRestClient restClient, string apiKey, string resource = null) : base(restClient, apiKey, resource ?? new TResource().ResourceName) { } public List All() { var request = BuildRequest(); return Get>(request); } public PagingResource GetPaged(int pageNumber, int pageSize, string sortKey, string sortDir, string filterKey = null, object filterValue = null) { var request = BuildRequest(); request.AddParameter("page", pageNumber); request.AddParameter("pageSize", pageSize); request.AddParameter("sortKey", sortKey); request.AddParameter("sortDir", sortDir); if (filterKey != null && filterValue != null) { request.AddParameter(filterKey, filterValue); } return Get>(request); } public TResource Post(TResource body, HttpStatusCode statusCode = HttpStatusCode.Created) { var request = BuildRequest(); request.AddJsonBody(body); return Post(request, statusCode); } public TResource Put(TResource body, HttpStatusCode statusCode = HttpStatusCode.Accepted) { var request = BuildRequest(); request.AddJsonBody(body); return Put(request, statusCode); } public TResource Get(int id, HttpStatusCode statusCode = HttpStatusCode.OK) { var request = BuildRequest(id.ToString()); return Get(request, statusCode); } public TResource GetSingle(HttpStatusCode statusCode = HttpStatusCode.OK) { var request = BuildRequest(); return Get(request, statusCode); } public void Delete(int id) { var request = BuildRequest(id.ToString()); Delete(request); } public object InvalidGet(int id, HttpStatusCode statusCode = HttpStatusCode.NotFound) { var request = BuildRequest(id.ToString()); return Get(request, statusCode); } public object InvalidPost(TResource body, HttpStatusCode statusCode = HttpStatusCode.BadRequest) { var request = BuildRequest(); request.AddJsonBody(body); return Post(request, statusCode); } public object InvalidPut(TResource body, HttpStatusCode statusCode = HttpStatusCode.BadRequest) { var request = BuildRequest(); request.AddJsonBody(body); return Put(request, statusCode); } public T Get(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.OK) where T : class, new() { request.Method = Method.GET; return Execute(request, statusCode); } public T Post(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.Created) where T : class, new() { request.Method = Method.POST; return Execute(request, statusCode); } public T Put(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.Accepted) where T : class, new() { request.Method = Method.PUT; return Execute(request, statusCode); } public void Delete(IRestRequest request, HttpStatusCode statusCode = HttpStatusCode.OK) { request.Method = Method.DELETE; Execute(request, statusCode); } } }