From daa457cc6b0ada08b6b09a1f20ec19036bd58e52 Mon Sep 17 00:00:00 2001 From: Michel Bagnol Date: Fri, 4 Oct 2019 14:57:25 +0200 Subject: [PATCH 1/6] Properly decode the HTML data from the received json response, and decode HTML entities in the org name. --- Imbick.StarCitizen.Api/GetOrgsRestRequest.cs | 1 - Imbick.StarCitizen.Api/Imbick.StarCitizen.Api.csproj | 4 ++-- Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs | 2 +- Imbick.StarCitizen.Api/OrganisationsClient.cs | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs b/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs index 8fc888b..d6f5168 100644 --- a/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs +++ b/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs @@ -2,7 +2,6 @@ using System.Linq; using Models; using RestSharp; - using SimpleJson; public class GetOrgsRestRequest : RestRequest { diff --git a/Imbick.StarCitizen.Api/Imbick.StarCitizen.Api.csproj b/Imbick.StarCitizen.Api/Imbick.StarCitizen.Api.csproj index d3af44f..29f7f8e 100644 --- a/Imbick.StarCitizen.Api/Imbick.StarCitizen.Api.csproj +++ b/Imbick.StarCitizen.Api/Imbick.StarCitizen.Api.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs b/Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs index bc82f3c..ae77198 100644 --- a/Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs +++ b/Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs @@ -22,7 +22,7 @@ public Organisation Deserialise(string org) { private Organisation Deserialise(HtmlNode orgNode) { try { return new Organisation { - Name = orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[2]/span[2]/h3[@class=\"trans-03s name\"]").InnerText, + Name = HtmlEntity.DeEntitize(orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[2]/span[2]/h3[@class=\"trans-03s name\"]").InnerText), Symbol = orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[2]/span[2]/span[@class=\"symbol\"]").InnerText, ThumbnailUrl = orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[2]/span[1]/img").GetAttributeValue("src", string.Empty), Archetype = ToArchetype(orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[3]/span[1]/span[1]//span[2]").InnerText), diff --git a/Imbick.StarCitizen.Api/OrganisationsClient.cs b/Imbick.StarCitizen.Api/OrganisationsClient.cs index 133d8fd..5c2a364 100644 --- a/Imbick.StarCitizen.Api/OrganisationsClient.cs +++ b/Imbick.StarCitizen.Api/OrganisationsClient.cs @@ -31,7 +31,7 @@ public async Task> GetAsync(SearchRequest searchReques var response = await _client.ExecutePostTaskAsync(request); if (!response.IsSuccessful) throw new Exception($"Request to endpoint was unsuccessful. {response.ErrorMessage}"); - var decodedHtml = response.Data.Data.Html.Replace("\\\"", "\""); //todo properly decode this + var decodedHtml = SimpleJson.DeserializeObject("\"" + response.Data.Data.Html + "\"", SimpleJson.CurrentJsonSerializerStrategy); return _deserialiser.DeserialiseList(decodedHtml); } catch (Exception e) { throw new Exception("Problem retrieving orgs. See inner exception for details.", e); From 875d5a212f5932b9967acd08d2ab634463f678ef Mon Sep 17 00:00:00 2001 From: Michel Bagnol Date: Fri, 4 Oct 2019 23:02:31 +0200 Subject: [PATCH 2/6] Support RSI's getOrgMembers API. BREAKING-CHANGE: OrganisationClient renamed to to RsiApiClient. --- .../GetOrgMembersTests.cs | 69 ++++++++++++ ...isationsClientTests.cs => GetOrgsTests.cs} | 22 ++-- .../Models/OrgMembersSearchRequestTests.cs | 45 ++++++++ .../Models/OrgsSearchRequestTests.cs | 105 ++++++++++++++++++ .../Models/SearchRequestTests.cs | 105 ------------------ .../GetOrgMembersRestRequest.cs | 17 +++ Imbick.StarCitizen.Api/GetOrgsRestRequest.cs | 12 +- .../CamelCaseSerializerStrategy.cs | 13 +++ .../OrgHtmlSerializer.cs} | 30 ++--- .../OrgMemberHtmlSerializer.cs | 40 +++++++ .../Models/{Organisation.cs => Org.cs} | 20 ++-- Imbick.StarCitizen.Api/Models/OrgMember.cs | 43 +++++++ .../Models/OrgMembersSearchRequest.cs | 63 +++++++++++ ...{SearchRequest.cs => OrgsSearchRequest.cs} | 66 +++++------ Imbick.StarCitizen.Api/OrganisationsClient.cs | 44 -------- Imbick.StarCitizen.Api/RsiApiClient.cs | 73 ++++++++++++ 16 files changed, 540 insertions(+), 227 deletions(-) create mode 100644 Imbick.StarCitizen.Api.Tests/GetOrgMembersTests.cs rename Imbick.StarCitizen.Api.Tests/{OrganisationsClientTests.cs => GetOrgsTests.cs} (98%) create mode 100644 Imbick.StarCitizen.Api.Tests/Models/OrgMembersSearchRequestTests.cs create mode 100644 Imbick.StarCitizen.Api.Tests/Models/OrgsSearchRequestTests.cs delete mode 100644 Imbick.StarCitizen.Api.Tests/Models/SearchRequestTests.cs create mode 100644 Imbick.StarCitizen.Api/GetOrgMembersRestRequest.cs create mode 100644 Imbick.StarCitizen.Api/HtmlSerializers/CamelCaseSerializerStrategy.cs rename Imbick.StarCitizen.Api/{OrganisationHtmlSerialiser.cs => HtmlSerializers/OrgHtmlSerializer.cs} (70%) create mode 100644 Imbick.StarCitizen.Api/HtmlSerializers/OrgMemberHtmlSerializer.cs rename Imbick.StarCitizen.Api/Models/{Organisation.cs => Org.cs} (87%) create mode 100644 Imbick.StarCitizen.Api/Models/OrgMember.cs create mode 100644 Imbick.StarCitizen.Api/Models/OrgMembersSearchRequest.cs rename Imbick.StarCitizen.Api/Models/{SearchRequest.cs => OrgsSearchRequest.cs} (66%) delete mode 100644 Imbick.StarCitizen.Api/OrganisationsClient.cs create mode 100644 Imbick.StarCitizen.Api/RsiApiClient.cs diff --git a/Imbick.StarCitizen.Api.Tests/GetOrgMembersTests.cs b/Imbick.StarCitizen.Api.Tests/GetOrgMembersTests.cs new file mode 100644 index 0000000..e31a451 --- /dev/null +++ b/Imbick.StarCitizen.Api.Tests/GetOrgMembersTests.cs @@ -0,0 +1,69 @@ + +namespace Imbick.StarCitizen.Api.Tests { + using System.Linq; + using System.Net; + using System.Threading.Tasks; + using Api.Models; + using Xunit; + using Moq; + using RestSharp; + + public class GetOrgMembersTests { + + [Fact] + public async Task ListOrgMembersAsync_Always_ReturnsCorrectResultsAsync() { + var response = new RestResponse { + Data = _dummyResponse_9Members, + StatusCode = HttpStatusCode.OK, + ResponseStatus = ResponseStatus.Completed + }; + _mockRest.Setup(r => r.ExecutePostTaskAsync(It.IsAny())) + .Returns(Task.FromResult>(response)); + var client = new RsiApiClient(_mockRest.Object); + + var orgMembers = await client.ListOrgMembersAsync("SWISS"); + + Assert.Equal(9, orgMembers.Count()); + } + + [Fact] + public async Task GetOrgMembersAsync_WithSearchTerm_ReturnsCorrectResultAsync() { + var response = new RestResponse { + Data = _dummyResponse_1Member, + StatusCode = HttpStatusCode.OK, + ResponseStatus = ResponseStatus.Completed + }; + _mockRest.Setup(c => c.ExecutePostTaskAsync(It.IsAny())) + .Returns(Task.FromResult>(response)); + var client = new RsiApiClient(_mockRest.Object); + var searchRequest = new OrgMembersSearchRequest { Symbol = "SWISS", Search = "meetsch" }; + var orgMembers = await client.GetOrgMembersAsync(searchRequest); + + Assert.Equal(1, orgMembers.Count()); + Assert.Equal(_dummyOrgMember, orgMembers.First()); + } + + private readonly OrgMember _dummyOrgMember = new OrgMember + { + Name = "Meetsch", + Handle = "meetsch", + AvatarUrl = "/media/80d4lybcin5dhr/avatar/Swiss-Starships-Ecusson.png" + }; + + private readonly Response _dummyResponse_1Member = new Response + { + Data = new ResponseData + { + Html = @"\t
  • \n\t\t\n \n \t\t\t\t\n
    <\/div>\n
    <\/div>\n
    <\/div>\n
    <\/div>\n\t\t\t<\/span>\n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles<\/span>\n\t\t\t\t\t