diff --git a/Imbick.StarCitizen.Api.Tests/GetOrgMembersTests.cs b/Imbick.StarCitizen.Api.Tests/GetOrgMembersTests.cs new file mode 100644 index 0000000..1aa421a --- /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
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMeetsch\n\t\t\t\t\t\tmeetsch\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Recrue\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n" + } + }; + + private readonly Response _dummyResponse_9Members = new Response { + Data = new ResponseData { + Html = @"\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t\t
    • Etat-major
    • \n\t\t\t\t\t\t\t\t\t\t\t\t
    • Membre du Conseil
    • \n\t\t\t\t\t\t\t\t\t\t\t\t
    • Pilote en service
    • \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMaarkreidi\n\t\t\t\t\t\tMaark\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Commandant de corps\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMr_Pandalf\n\t\t\t\t\t\tMr_Pandalf\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Recrue\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMeetsch\n\t\t\t\t\t\tmeetsch\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Recrue\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMickael\n\t\t\t\t\t\tMi_K_L\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Réserviste\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMike_LaMenace\n\t\t\t\t\t\tRogor_Roxor\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Réserviste\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMajor Duke\n\t\t\t\t\t\tMajor_Duke\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Recrue\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMerlin\n\t\t\t\t\t\tOlderan\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Réserviste\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMike Swissmade\n\t\t\t\t\t\tMike_Roxor\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Réserviste\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n\t
  • \n\t\t\n \n \t\t\t\t\n
    \n
    \n
    \n
    \n\t\t\t
    \n\t\t\t\n \t\t\t\t\n \t\t\t\t\tRoles\n\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\t\t\t
    \n \t\t\t\t
    \n \n \n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tMute\n\t\t\t\t\t\tGenju\n
    \n
    \n\t\t\t\t\t
    \n\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\n\t\t\t\t\t Réserviste\n \t\t\t\t\t\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n \t\t
    \n
    \n
    \n
    \n\t
  • \n" + } + }; + + private Mock _mockRest = new Mock(); + } +} \ No newline at end of file diff --git a/Imbick.StarCitizen.Api.Tests/OrganisationsClientTests.cs b/Imbick.StarCitizen.Api.Tests/GetOrgsTests.cs similarity index 98% rename from Imbick.StarCitizen.Api.Tests/OrganisationsClientTests.cs rename to Imbick.StarCitizen.Api.Tests/GetOrgsTests.cs index 93249c7..95c72b7 100644 --- a/Imbick.StarCitizen.Api.Tests/OrganisationsClientTests.cs +++ b/Imbick.StarCitizen.Api.Tests/GetOrgsTests.cs @@ -8,10 +8,10 @@ namespace Imbick.StarCitizen.Api.Tests { using Moq; using RestSharp; - public class OrganisationsClientTests { + public class GetOrgsTests { [Fact] - public async Task ListAsync_Always_ReturnsCorrectResultsAsync() { + public async Task ListOrgsAsync_Always_ReturnsCorrectResultsAsync() { var response = new RestResponse { Data = _dummyResponse, StatusCode = HttpStatusCode.OK, @@ -19,16 +19,16 @@ public async Task ListAsync_Always_ReturnsCorrectResultsAsync() { }; _mockRest.Setup(r => r.ExecutePostTaskAsync(It.IsAny())) .Returns(Task.FromResult>(response)); - var client = new OrganisationsClient(_mockRest.Object); + var client = new RsiApiClient(_mockRest.Object); - var orgs = await client.ListAsync(); + var orgs = await client.ListOrgsAsync(); Assert.Equal(32, orgs.Count()); Assert.Equal(_dummyOrg, orgs.First()); } [Fact] - public async Task GetAsync_WithSearchTerm_ReturnsCorrectResultAsync() { + public async Task GetOrgsAsync_WithSearchTerm_ReturnsCorrectResultAsync() { var response = new RestResponse { Data = _dummyResponse, StatusCode = HttpStatusCode.OK, @@ -36,20 +36,20 @@ public async Task GetAsync_WithSearchTerm_ReturnsCorrectResultAsync() { }; _mockRest.Setup(c => c.ExecutePostTaskAsync(It.IsAny())) .Returns(Task.FromResult>(response)); - var client = new OrganisationsClient(_mockRest.Object); - var searchRequest = new SearchRequest {Search = "Empire De La Soumission" }; - var orgs = await client.GetAsync(searchRequest); + var client = new RsiApiClient(_mockRest.Object); + var searchRequest = new OrgsSearchRequest {Search = "Empire De La Soumission" }; + var orgs = await client.GetOrgsAsync(searchRequest); Assert.Equal(32, orgs.Count()); Assert.Equal(_dummyOrg, orgs.First()); } - private readonly Organisation _dummyOrg = new Organisation { + private readonly Org _dummyOrg = new Org { Name = "Rogue Pirates", Symbol = "ROGPIRATES", ThumbnailUrl = "/rsi/static/images/organization/defaults/logo/syndicate.jpg", - Archetype = Archetype.Syndicate, - Commitment = Commitment.Hardcore, + Archetype = OrgArchetype.Syndicate, + Commitment = OrgCommitment.Hardcore, Language = "Italian", IsRecruiting = true, IsRolePlay = false, diff --git a/Imbick.StarCitizen.Api.Tests/Models/OrgMembersSearchRequestTests.cs b/Imbick.StarCitizen.Api.Tests/Models/OrgMembersSearchRequestTests.cs new file mode 100644 index 0000000..36f00b9 --- /dev/null +++ b/Imbick.StarCitizen.Api.Tests/Models/OrgMembersSearchRequestTests.cs @@ -0,0 +1,45 @@ + +namespace Imbick.StarCitizen.Api.Tests.Models { + using System; + using System.Collections.Generic; + using System.Linq; + using Imbick.StarCitizen.Api.Models; + using Xunit; + + public class OrgMembersSearchRequestTests + { + [Fact] + public void Ctor_WithMembershipMainOrg_MapsCorrectly() + { + var request = new OrgMembersSearchRequest + { + Membership = OrgMembersSearchRequest.MembershipType.MainOrg + }; + var result = new OrgMembersSearchRequestInternal(request); + Assert.True(result.Main_Org == 1); + } + + [Fact] + public void Ctor_WithMembershipAffiliate_MapsCorrectly() + { + var request = new OrgMembersSearchRequest + { + Membership = OrgMembersSearchRequest.MembershipType.Affiliate + }; + var result = new OrgMembersSearchRequestInternal(request); + Assert.True(result.Main_Org == 0); + } + + [Fact] + public void Ctor_WithMembershipAny_MapsCorrectly() + { + var request = new OrgMembersSearchRequest + { + Membership = OrgMembersSearchRequest.MembershipType.Any + }; + var result = new OrgMembersSearchRequestInternal(request); + Assert.True(result.Main_Org == null); + } + + } +} diff --git a/Imbick.StarCitizen.Api.Tests/Models/OrgsSearchRequestTests.cs b/Imbick.StarCitizen.Api.Tests/Models/OrgsSearchRequestTests.cs new file mode 100644 index 0000000..3bcfcdc --- /dev/null +++ b/Imbick.StarCitizen.Api.Tests/Models/OrgsSearchRequestTests.cs @@ -0,0 +1,105 @@ + +namespace Imbick.StarCitizen.Api.Tests.Models { + using System; + using System.Collections.Generic; + using System.Linq; + using Imbick.StarCitizen.Api.Models; + using Xunit; + + public class OrgsSearchRequestTests + { + [Fact] + public void Ctor_WithBooleanYes_MapsCorrectly() { + var request = new OrgsSearchRequest { + Recruiting = OrgsSearchRequest.Boolean.Yes, + RolePlay = OrgsSearchRequest.Boolean.Yes + }; + var result = new OrgsSearchRequestInternal(request); + Assert.True(result.Recruiting.Count() == 1); + Assert.True(result.Recruiting.First() == 1); + Assert.True(result.RolePlay.Count() == 1); + Assert.True(result.RolePlay.First() == 1); + } + + [Fact] + public void Ctor_WithBooleanNo_MapsCorrectly() { + var request = new OrgsSearchRequest { + Recruiting = OrgsSearchRequest.Boolean.No, + RolePlay = OrgsSearchRequest.Boolean.No + }; + var result = new OrgsSearchRequestInternal(request); + Assert.True(result.Recruiting.Count() == 1); + Assert.True(result.Recruiting.First() == 0); + Assert.True(result.RolePlay.Count() == 1); + Assert.True(result.RolePlay.First() == 0); + } + + [Fact] + public void Ctor_WithBooleanBoth_MapsCorrectly() { + var request = new OrgsSearchRequest { + Recruiting = OrgsSearchRequest.Boolean.YesAndNo, + RolePlay = OrgsSearchRequest.Boolean.YesAndNo + }; + var result = new OrgsSearchRequestInternal(request); + AssertContains(result.Recruiting, new List()); + AssertContains(result.RolePlay, new List()); + } + + [Fact] + public void Ctor_WithSort_MapsCorrectly() { + var result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.ActiveAscending}); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.ActiveAsc); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.ActiveDescending }); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.ActiveDesc); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.CreatedAscending}); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.CreatedAsc); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.CreatedDescending}); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.CreatedDesc); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.NameAscending}); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.NameAsc); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.NameDescending}); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.NameDesc); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.SizeAscending}); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.SizeAsc); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Sort = OrgsSearchRequest.OrganisationSorting.SizeDescending }); + Assert.Equal(result.Sort, OrgsSearchRequestInternal.SizeDesc); + Assert.Throws(() => + result = new OrgsSearchRequestInternal(new OrgsSearchRequest {Sort = (OrgsSearchRequest.OrganisationSorting)123})); + } + + [Fact] + public void Ctor_WithSize_MapsCorrectly() { + var result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Size = new[] { OrgSize.Large } }); + AssertContains(result.Size, new[] { OrgSize.Large.ToString().ToLower() }); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Size = new[] { OrgSize.Medium } }); + AssertContains(result.Size, new[] { OrgSize.Medium.ToString().ToLower() }); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Size = new[] { OrgSize.Small } }); + AssertContains(result.Size, new[] { OrgSize.Small.ToString().ToLower() }); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Size = new[] { OrgSize.Small, OrgSize.Medium, OrgSize.Large } }); + AssertContains(result.Size, new[] { OrgSize.Small.ToString().ToLower(), OrgSize.Medium.ToString().ToLower(), OrgSize.Large.ToString().ToLower() }); + Assert.Throws(() => + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Size = new [] { (OrgSize)123} })); + } + + [Fact] + public void Ctor_WithCommitment_MapsCorrectly() { + var result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Commitment = new[] { OrgCommitment.Regular } }); + AssertContains(result.Commitment, new[] { "RE" }); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Commitment = new[] { OrgCommitment.Casual } }); + AssertContains(result.Commitment, new[] { "CA" }); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Commitment = new[] { OrgCommitment.Hardcore } }); + AssertContains(result.Commitment, new[] { "HA" }); + result = new OrgsSearchRequestInternal(new OrgsSearchRequest { Commitment = new[] { OrgCommitment.Casual, OrgCommitment.Hardcore } }); + AssertContains(result.Commitment, new[] { "CA", "HA" }); + /*Assert.Throws(() => + result = new SearchRequestInternal(new SearchRequest { Commitment = new[] { (Commitment)123 } }));*/ + } + + private static void AssertContains(IEnumerable collection, IReadOnlyCollection expectedContent) { + Assert.True(collection.Count() == expectedContent.Count); + foreach (var i in expectedContent) { + Assert.Contains(i, collection); + } + } + } +} diff --git a/Imbick.StarCitizen.Api.Tests/Models/SearchRequestTests.cs b/Imbick.StarCitizen.Api.Tests/Models/SearchRequestTests.cs deleted file mode 100644 index 1ac06a7..0000000 --- a/Imbick.StarCitizen.Api.Tests/Models/SearchRequestTests.cs +++ /dev/null @@ -1,105 +0,0 @@ - -namespace Imbick.StarCitizen.Api.Tests.Models { - using System; - using System.Collections.Generic; - using System.Linq; - using Imbick.StarCitizen.Api.Models; - using Xunit; - - public class SearchRequestTests - { - [Fact] - public void Ctor_WithBooleanYes_MapsCorrectly() { - var request = new SearchRequest { - Recruiting = SearchRequest.Boolean.Yes, - RolePlay = SearchRequest.Boolean.Yes - }; - var result = new SearchRequestInternal(request); - Assert.True(result.Recruiting.Count() == 1); - Assert.True(result.Recruiting.First() == 1); - Assert.True(result.RolePlay.Count() == 1); - Assert.True(result.RolePlay.First() == 1); - } - - [Fact] - public void Ctor_WithBooleanNo_MapsCorrectly() { - var request = new SearchRequest { - Recruiting = SearchRequest.Boolean.No, - RolePlay = SearchRequest.Boolean.No - }; - var result = new SearchRequestInternal(request); - Assert.True(result.Recruiting.Count() == 1); - Assert.True(result.Recruiting.First() == 0); - Assert.True(result.RolePlay.Count() == 1); - Assert.True(result.RolePlay.First() == 0); - } - - [Fact] - public void Ctor_WithBooleanBoth_MapsCorrectly() { - var request = new SearchRequest { - Recruiting = SearchRequest.Boolean.YesAndNo, - RolePlay = SearchRequest.Boolean.YesAndNo - }; - var result = new SearchRequestInternal(request); - AssertContains(result.Recruiting, new List()); - AssertContains(result.RolePlay, new List()); - } - - [Fact] - public void Ctor_WithSort_MapsCorrectly() { - var result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.ActiveAscending}); - Assert.Equal(result.Sort, SearchRequestInternal.ActiveAsc); - result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.ActiveDescending }); - Assert.Equal(result.Sort, SearchRequestInternal.ActiveDesc); - result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.CreatedAscending}); - Assert.Equal(result.Sort, SearchRequestInternal.CreatedAsc); - result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.CreatedDescending}); - Assert.Equal(result.Sort, SearchRequestInternal.CreatedDesc); - result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.NameAscending}); - Assert.Equal(result.Sort, SearchRequestInternal.NameAsc); - result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.NameDescending}); - Assert.Equal(result.Sort, SearchRequestInternal.NameDesc); - result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.SizeAscending}); - Assert.Equal(result.Sort, SearchRequestInternal.SizeAsc); - result = new SearchRequestInternal(new SearchRequest { Sort = SearchRequest.Sorting.SizeDescending }); - Assert.Equal(result.Sort, SearchRequestInternal.SizeDesc); - Assert.Throws(() => - result = new SearchRequestInternal(new SearchRequest {Sort = (SearchRequest.Sorting)123})); - } - - [Fact] - public void Ctor_WithSize_MapsCorrectly() { - var result = new SearchRequestInternal(new SearchRequest { Size = new[] { Size.Large } }); - AssertContains(result.Size, new[] { Size.Large.ToString().ToLower() }); - result = new SearchRequestInternal(new SearchRequest { Size = new[] { Size.Medium } }); - AssertContains(result.Size, new[] { Size.Medium.ToString().ToLower() }); - result = new SearchRequestInternal(new SearchRequest { Size = new[] { Size.Small } }); - AssertContains(result.Size, new[] { Size.Small.ToString().ToLower() }); - result = new SearchRequestInternal(new SearchRequest { Size = new[] { Size.Small, Size.Medium, Size.Large } }); - AssertContains(result.Size, new[] { Size.Small.ToString().ToLower(), Size.Medium.ToString().ToLower(), Size.Large.ToString().ToLower() }); - Assert.Throws(() => - result = new SearchRequestInternal(new SearchRequest { Size = new [] { (Size)123} })); - } - - [Fact] - public void Ctor_WithCommitment_MapsCorrectly() { - var result = new SearchRequestInternal(new SearchRequest { Commitment = new[] { Commitment.Regular } }); - AssertContains(result.Commitment, new[] { "RE" }); - result = new SearchRequestInternal(new SearchRequest { Commitment = new[] { Commitment.Casual } }); - AssertContains(result.Commitment, new[] { "CA" }); - result = new SearchRequestInternal(new SearchRequest { Commitment = new[] { Commitment.Hardcore } }); - AssertContains(result.Commitment, new[] { "HA" }); - result = new SearchRequestInternal(new SearchRequest { Commitment = new[] { Commitment.Casual, Commitment.Hardcore } }); - AssertContains(result.Commitment, new[] { "CA", "HA" }); - /*Assert.Throws(() => - result = new SearchRequestInternal(new SearchRequest { Commitment = new[] { (Commitment)123 } }));*/ - } - - private static void AssertContains(IEnumerable collection, IReadOnlyCollection expectedContent) { - Assert.True(collection.Count() == expectedContent.Count); - foreach (var i in expectedContent) { - Assert.Contains(i, collection); - } - } - } -} diff --git a/Imbick.StarCitizen.Api/GetOrgMembersRestRequest.cs b/Imbick.StarCitizen.Api/GetOrgMembersRestRequest.cs new file mode 100644 index 0000000..4fcef71 --- /dev/null +++ b/Imbick.StarCitizen.Api/GetOrgMembersRestRequest.cs @@ -0,0 +1,17 @@ +namespace Imbick.StarCitizen.Api { + using System.Linq; + using Imbick.StarCitizen.Api.HtmlSerializers; + using Models; + using RestSharp; + + public class GetOrgMembersRestRequest + : RestRequest { + public static string GetOrgMembersResource = "api/orgs/getOrgMembers"; + + public GetOrgMembersRestRequest(OrgMembersSearchRequest searchRequest) + : base(GetOrgMembersResource) { + SimpleJson.CurrentJsonSerializerStrategy = new LowerCaseSerializerStrategy(); + AddJsonBody(searchRequest == null ? null : new OrgMembersSearchRequestInternal(searchRequest)); + } + } +} \ No newline at end of file diff --git a/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs b/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs index 8fc888b..3126d8b 100644 --- a/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs +++ b/Imbick.StarCitizen.Api/GetOrgsRestRequest.cs @@ -1,24 +1,17 @@ namespace Imbick.StarCitizen.Api { using System.Linq; + using Imbick.StarCitizen.Api.HtmlSerializers; using Models; using RestSharp; - using SimpleJson; public class GetOrgsRestRequest : RestRequest { public static string GetOrgsResource = "api/orgs/getOrgs"; - public GetOrgsRestRequest(SearchRequest searchRequest) + public GetOrgsRestRequest(OrgsSearchRequest searchRequest) : base(GetOrgsResource) { - SimpleJson.CurrentJsonSerializerStrategy = new CamelCaseSerializerStrategy(); - AddJsonBody(searchRequest == null ? null : new SearchRequestInternal(searchRequest)); - } - } - - internal class CamelCaseSerializerStrategy - : PocoJsonSerializerStrategy { - protected override string MapClrMemberNameToJsonFieldName(string clrPropertyName) { - return char.ToLower(clrPropertyName[0]) + clrPropertyName.Substring(1); + SimpleJson.CurrentJsonSerializerStrategy = new LowerCaseSerializerStrategy(); + AddJsonBody(searchRequest == null ? null : new OrgsSearchRequestInternal(searchRequest)); } } } \ No newline at end of file diff --git a/Imbick.StarCitizen.Api/HtmlSerializers/LowerCaseSerializerStrategy.cs b/Imbick.StarCitizen.Api/HtmlSerializers/LowerCaseSerializerStrategy.cs new file mode 100644 index 0000000..4b08a0a --- /dev/null +++ b/Imbick.StarCitizen.Api/HtmlSerializers/LowerCaseSerializerStrategy.cs @@ -0,0 +1,12 @@ +namespace Imbick.StarCitizen.Api.HtmlSerializers { + using System.Linq; + using System.Text.RegularExpressions; + using RestSharp; + + internal class LowerCaseSerializerStrategy + : PocoJsonSerializerStrategy { + protected override string MapClrMemberNameToJsonFieldName(string clrPropertyName) { + return clrPropertyName.ToLower(); + } + } +} \ No newline at end of file diff --git a/Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs b/Imbick.StarCitizen.Api/HtmlSerializers/OrgHtmlSerializer.cs similarity index 64% rename from Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs rename to Imbick.StarCitizen.Api/HtmlSerializers/OrgHtmlSerializer.cs index bc82f3c..ad3d502 100644 --- a/Imbick.StarCitizen.Api/OrganisationHtmlSerialiser.cs +++ b/Imbick.StarCitizen.Api/HtmlSerializers/OrgHtmlSerializer.cs @@ -1,32 +1,32 @@ -namespace Imbick.StarCitizen.Api { +namespace Imbick.StarCitizen.Api.HtmlSerializers { using System; using System.Collections.Generic; using System.Linq; using HtmlAgilityPack; using Models; - public class OrganisationHtmlSerialiser { + public class OrgHtmlSerializer { - public IEnumerable DeserialiseList(string orgs) { + public IEnumerable DeserializeList(string orgs) { _doc.LoadHtml(orgs); return _doc.DocumentNode.ChildNodes .Where(n => n.Name == "div") - .Select(Deserialise); + .Select(Deserialize); } - public Organisation Deserialise(string org) { + public Org Deserialize(string org) { _doc.LoadHtml(org); - return Deserialise(_doc.DocumentNode); + return Deserialize(_doc.DocumentNode); } - private Organisation Deserialise(HtmlNode orgNode) { + private Org Deserialize(HtmlNode orgNode) { try { - return new Organisation { - Name = orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[2]/span[2]/h3[@class=\"trans-03s name\"]").InnerText, + return new Org { + 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), - Commitment = (Commitment)Enum.Parse(typeof(Commitment), orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[3]/span[1]/span[3]//span[2]").InnerText), + Commitment = (OrgCommitment)Enum.Parse(typeof(OrgCommitment), orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[3]/span[1]/span[3]//span[2]").InnerText), Language = orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[3]/span[1]/span[2]//span[2]").InnerText, IsRecruiting = orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[3]/span[2]/span[1]//span[2]").InnerText == "Yes", IsRolePlay = orgNode.SelectSingleNode("./a[@class=\"trans-03s clearfix\"]/span[3]/span[2]/span[2]//span[2]").InnerText == "Yes", @@ -38,18 +38,18 @@ private Organisation Deserialise(HtmlNode orgNode) { } } - private Archetype ToArchetype(string value) { + private OrgArchetype ToArchetype(string value) { switch (value.ToLower()) { case "organization": - return Archetype.Organization; + return OrgArchetype.Organization; case "corporation": - return Archetype.Corporation; + return OrgArchetype.Corporation; case "pmc": - return Archetype.Pmc; + return OrgArchetype.Pmc; case "faith": - return Archetype.Faith; + return OrgArchetype.Faith; case "syndicate": - return Archetype.Syndicate; + return OrgArchetype.Syndicate; } throw new ArgumentException(value); diff --git a/Imbick.StarCitizen.Api/HtmlSerializers/OrgMemberHtmlSerializer.cs b/Imbick.StarCitizen.Api/HtmlSerializers/OrgMemberHtmlSerializer.cs new file mode 100644 index 0000000..8571c04 --- /dev/null +++ b/Imbick.StarCitizen.Api/HtmlSerializers/OrgMemberHtmlSerializer.cs @@ -0,0 +1,40 @@ +namespace Imbick.StarCitizen.Api.HtmlSerializers { + using System; + using System.Collections.Generic; + using System.Linq; + using HtmlAgilityPack; + using Models; + + public class OrgMemberHtmlSerializer { + + public IEnumerable DeserializeList(string orgs) { + _doc.LoadHtml(orgs); + return _doc.DocumentNode.ChildNodes + .Where(n => n.Name == "li") + .Select(Deserialize) + .Where(m => !String.IsNullOrWhiteSpace(m.Handle)); + } + + public OrgMember Deserialize(string org) { + _doc.LoadHtml(org); + return Deserialize(_doc.DocumentNode); + } + + private OrgMember Deserialize(HtmlNode orgMemberNode) { + try { + var imgNode = orgMemberNode.SelectSingleNode("./a//span[contains(concat(' ', normalize-space(@class), ' '), ' thumb ')]/img"); + return new OrgMember + { + Name = HtmlEntity.DeEntitize(orgMemberNode.SelectSingleNode("./a//span[contains(concat(' ', normalize-space(@class), ' '), ' name ')]").InnerText).Trim(), + Handle = HtmlEntity.DeEntitize(orgMemberNode.SelectSingleNode("./a//span[contains(concat(' ', normalize-space(@class), ' '), ' nick ')]").InnerText).Trim(), + AvatarUrl = imgNode != null ? imgNode.GetAttributeValue("src", string.Empty) : null + }; + } + catch (Exception e) { + throw new Exception("Unable to parse org member. Probably the HTML has changed.", e); + } + } + + private readonly HtmlDocument _doc = new HtmlDocument(); + } +} \ No newline at end of file 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/Models/Organisation.cs b/Imbick.StarCitizen.Api/Models/Org.cs similarity index 87% rename from Imbick.StarCitizen.Api/Models/Organisation.cs rename to Imbick.StarCitizen.Api/Models/Org.cs index 1694055..86f775b 100644 --- a/Imbick.StarCitizen.Api/Models/Organisation.cs +++ b/Imbick.StarCitizen.Api/Models/Org.cs @@ -3,19 +3,19 @@ namespace Imbick.StarCitizen.Api.Models { using System; using System.Diagnostics; - public enum Size { + public enum OrgSize { Small, Medium, Large } - public enum Commitment { + public enum OrgCommitment { Casual, Regular, Hardcore } - public enum Archetype { + public enum OrgArchetype { Organization, Corporation, Pmc, @@ -23,7 +23,7 @@ public enum Archetype { Syndicate } - public enum Activity { + public enum OrgActivity { BountyHunting = 9, Engineering = 7, Exploration = 12, @@ -40,16 +40,16 @@ public enum Activity { } [DebuggerDisplay("{" + nameof(Name) + "}")] - public class Organisation - : IEquatable { + public class Org + : IEquatable { public string Name { get; set; } public string Symbol { get; set; } public string ThumbnailUrl { get; set; } - public Archetype Archetype { get; set; } + public OrgArchetype Archetype { get; set; } - public Commitment Commitment { get; set; } + public OrgCommitment Commitment { get; set; } public string Language { get; set; } @@ -59,7 +59,7 @@ public class Organisation public long MemberCount { get; set; } - public bool Equals(Organisation other) { + public bool Equals(Org other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return string.Equals(Name, other.Name) && string.Equals(Symbol, other.Symbol) && @@ -73,7 +73,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; - return Equals((Organisation) obj); + return Equals((Org) obj); } public override int GetHashCode() { diff --git a/Imbick.StarCitizen.Api/Models/OrgMember.cs b/Imbick.StarCitizen.Api/Models/OrgMember.cs new file mode 100644 index 0000000..21a1c55 --- /dev/null +++ b/Imbick.StarCitizen.Api/Models/OrgMember.cs @@ -0,0 +1,43 @@ + +namespace Imbick.StarCitizen.Api.Models +{ + using System; + using System.Diagnostics; + + [DebuggerDisplay("{" + nameof(Name) + "}")] + public class OrgMember + : IEquatable + { + public string Name { get; set; } + public string Handle { get; set; } + + public string AvatarUrl { get; set; } + + public bool Equals(OrgMember other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return string.Equals(Name, other.Name) && string.Equals(Handle, other.Handle) && + string.Equals(AvatarUrl, other.AvatarUrl); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((OrgMember)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (Name != null ? Name.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Handle != null ? Handle.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (AvatarUrl != null ? AvatarUrl.GetHashCode() : 0); + return hashCode; + } + } + } +} \ No newline at end of file diff --git a/Imbick.StarCitizen.Api/Models/OrgMembersSearchRequest.cs b/Imbick.StarCitizen.Api/Models/OrgMembersSearchRequest.cs new file mode 100644 index 0000000..3247e34 --- /dev/null +++ b/Imbick.StarCitizen.Api/Models/OrgMembersSearchRequest.cs @@ -0,0 +1,60 @@ + +namespace Imbick.StarCitizen.Api.Models { + using System; + using System.Collections.Generic; + using System.Linq; + + public class OrgMembersSearchRequest { + public enum MembershipType + { + Any, + MainOrg, + Affiliate + } + + public string Symbol { get; set; } + public string Search { get; set; } + public int? Rank { get; set; } = null; + public int? Role { get; set; } = null; + public MembershipType Membership { get; set; } = MembershipType.Any; + public int PageSize { get; set; } = 32; + public int Page { get; set; } = 1; + } + + internal class OrgMembersSearchRequestInternal { + public string Symbol { get; set; } + public string Search { get; set; } + public int? Rank { get; set; } + public int? Role { get; set; } + public int? Main_Org { get; set; } + + public int PageSize { get; set; } + public int Page { get; set; } + + public OrgMembersSearchRequestInternal(OrgMembersSearchRequest copy) { + Symbol = copy.Symbol; + Search = copy.Search; + Rank = copy.Rank; + Role = copy.Role; + Main_Org = MapMembershipType(copy.Membership); + PageSize = copy.PageSize; + Page = copy.Page; + } + + private int? MapMembershipType(OrgMembersSearchRequest.MembershipType membershipType) + { + return membershipType == OrgMembersSearchRequest.MembershipType.MainOrg ? 1 : + membershipType == OrgMembersSearchRequest.MembershipType.Affiliate ? 0 : + (int?)null; + } + } +} +/* +minimal {symbol:"SWISS",search:"",pagesize:32,page:1} +search name {symbol:"SWISS",search:"Meetsch"} +filter rank {symbol:"SWISS",search:"",rank:1} +filter role {symbol:"SWISS",search:"",role:1} +filter main_org {symbol:"SWISS",search:"",main_org:1} +filter affiliate {symbol:"SWISS",search:"",main_org:0} +full {symbol:"SWISS",search:"Looping",rank:1,role:1,main_org:1,pagesize:32,page:1} +*/ diff --git a/Imbick.StarCitizen.Api/Models/SearchRequest.cs b/Imbick.StarCitizen.Api/Models/OrgsSearchRequest.cs similarity index 56% rename from Imbick.StarCitizen.Api/Models/SearchRequest.cs rename to Imbick.StarCitizen.Api/Models/OrgsSearchRequest.cs index e466f1a..6a57a1e 100644 --- a/Imbick.StarCitizen.Api/Models/SearchRequest.cs +++ b/Imbick.StarCitizen.Api/Models/OrgsSearchRequest.cs @@ -4,8 +4,8 @@ namespace Imbick.StarCitizen.Api.Models { using System.Collections.Generic; using System.Linq; - public class SearchRequest { - public enum Sorting { + public class OrgsSearchRequest { + public enum OrganisationSorting { ActiveAscending, ActiveDescending, SizeAscending, @@ -22,20 +22,20 @@ public enum Boolean { No } - public Sorting Sort { get; set; } + public OrganisationSorting Sort { get; set; } public string Search { get; set; } public string Language { get; set; } //todo enumerate these - public ICollection Commitment { get; set; } = new List(); - public ICollection Size { get; set; } = new List(); - public ICollection Model => new List(); - public ICollection Activity => new List(); + public ICollection Commitment { get; set; } = new List(); + public ICollection Size { get; set; } = new List(); + public ICollection Model => new List(); + public ICollection Activity => new List(); public Boolean RolePlay { get; set; } public Boolean Recruiting { get; set; } public int PageSize { get; set; } = 12; public int Page { get; set; } = 1; } - public class SearchRequestInternal { + internal class OrgsSearchRequestInternal { public static string SizeAsc = "size_asc"; public static string SizeDesc = "size_desc"; public static string NameAsc = "name_asc"; @@ -60,7 +60,7 @@ public class SearchRequestInternal { public int PageSize { get; set; } public int Page { get; set; } - public SearchRequestInternal(SearchRequest copy) { + public OrgsSearchRequestInternal(OrgsSearchRequest copy) { Search = copy.Search; Language = copy.Language != null ? new List {copy.Language} : new List(); Sort = MapSort(copy.Sort); @@ -77,65 +77,65 @@ public SearchRequestInternal(SearchRequest copy) { Recruiting = MapBoolean(copy.Recruiting); } - private IEnumerable MapSize(ICollection sizes) { - if (sizes.Any(s => !Enum.IsDefined(typeof(Size), s))) + private IEnumerable MapSize(ICollection sizes) { + if (sizes.Any(s => !Enum.IsDefined(typeof(OrgSize), s))) throw new ArgumentOutOfRangeException(nameof(sizes)); return sizes.Select(s => s.ToString().ToLower()); } - private IEnumerable MapBoolean(SearchRequest.Boolean boolean) { - return boolean == SearchRequest.Boolean.Yes ? new List {1} : - boolean == SearchRequest.Boolean.No ? new List {0} : + private IEnumerable MapBoolean(OrgsSearchRequest.Boolean boolean) { + return boolean == OrgsSearchRequest.Boolean.Yes ? new List {1} : + boolean == OrgsSearchRequest.Boolean.No ? new List {0} : new List( ); } - private string MapCommitment(Commitment commitment) { + private string MapCommitment(OrgCommitment commitment) { switch (commitment) { - case Models.Commitment.Regular: + case Models.OrgCommitment.Regular: return "RE"; - case Models.Commitment.Casual: + case Models.OrgCommitment.Casual: return "CA"; - case Models.Commitment.Hardcore: + case Models.OrgCommitment.Hardcore: return "HA"; } throw new ArgumentOutOfRangeException(nameof(commitment), commitment, null); } - private string MapArchetype(Archetype archetype) { + private string MapArchetype(OrgArchetype archetype) { switch (archetype) { - case Archetype.Organization: + case OrgArchetype.Organization: return "generic"; - case Archetype.Corporation: + case OrgArchetype.Corporation: return "corp"; - case Archetype.Pmc: + case OrgArchetype.Pmc: return "pmc"; - case Archetype.Faith: + case OrgArchetype.Faith: return "faith"; - case Archetype.Syndicate: + case OrgArchetype.Syndicate: return "syndicate"; } throw new ArgumentOutOfRangeException(nameof(archetype), archetype, null); } - private string MapSort(SearchRequest.Sorting sort) { + private string MapSort(OrgsSearchRequest.OrganisationSorting sort) { switch (sort) { - case SearchRequest.Sorting.SizeAscending: + case OrgsSearchRequest.OrganisationSorting.SizeAscending: return SizeAsc; - case SearchRequest.Sorting.SizeDescending: + case OrgsSearchRequest.OrganisationSorting.SizeDescending: return SizeDesc; - case SearchRequest.Sorting.NameAscending: + case OrgsSearchRequest.OrganisationSorting.NameAscending: return NameAsc; - case SearchRequest.Sorting.NameDescending: + case OrgsSearchRequest.OrganisationSorting.NameDescending: return NameDesc; - case SearchRequest.Sorting.CreatedAscending: + case OrgsSearchRequest.OrganisationSorting.CreatedAscending: return CreatedAsc; - case SearchRequest.Sorting.CreatedDescending: + case OrgsSearchRequest.OrganisationSorting.CreatedDescending: return CreatedDesc; - case SearchRequest.Sorting.ActiveAscending: + case OrgsSearchRequest.OrganisationSorting.ActiveAscending: return ActiveAsc; - case SearchRequest.Sorting.ActiveDescending: + case OrgsSearchRequest.OrganisationSorting.ActiveDescending: return ActiveDesc; } @@ -144,7 +144,7 @@ private string MapSort(SearchRequest.Sorting sort) { } } /* -empty {"sort":"size_desc","search":"","commitment":[],"roleplay":[],"size":[],"model":[],"activity":[],"language":[],"recruiting":[],"pagesize":12,"page":1} -partial {"sort":"size_desc","search":"","commitment":["CA","RE"],"roleplay":["1","0"],"size":["small","medium"],"model":["generic","corp"],"activity":["9","7"],"language":[],"recruiting":["1","0"],"pagesize":12,"page":1} -full {"sort":"size_desc","search":"test","commitment":["CA","RE","HA"],"roleplay":["1","0"],"size":["small","medium","large"],"model":["generic","corp","pmc","faith","syndicate"],"activity":["9","7","12","6","5","10","4","3","8","2","13","11","1"],"language":["ce"],"recruiting":["1","0"],"pagesize":12,"page":1} +empty {sort:"size_desc",search:"",commitment:[],roleplay:[],size:[],model:[],activity:[],language:[],recruiting:[],pagesize:12,page:1} +partial {sort:"size_desc",search:"",commitment:["CA","RE"],roleplay:["1","0"],size:["small","medium"],model:["generic","corp"],activity:["9","7"],"language":[],recruiting:["1","0"],pagesize:12,page:1} +full {sort:"size_desc",search:"test",commitment:["CA","RE","HA"],roleplay:["1","0"],size:["small","medium","large"],model:["generic","corp","pmc","faith","syndicate"],activity:["9","7","12","6","5","10","4","3","8","2","13","11","1"],language:["ce"],recruiting:["1","0"],pagesize:12,page:1} */ \ No newline at end of file diff --git a/Imbick.StarCitizen.Api/OrganisationsClient.cs b/Imbick.StarCitizen.Api/OrganisationsClient.cs deleted file mode 100644 index 133d8fd..0000000 --- a/Imbick.StarCitizen.Api/OrganisationsClient.cs +++ /dev/null @@ -1,44 +0,0 @@ - -namespace Imbick.StarCitizen.Api { - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - using Models; - using RestSharp; - - public class OrganisationsClient { - - public OrganisationsClient() - : this("https://robertsspaceindustries.com/") { } - - public OrganisationsClient(string baseUrl) - : this(new Uri(baseUrl)) { } - - public OrganisationsClient(Uri baseUrl) - : this(new RestClient(baseUrl)) { } - - public OrganisationsClient(IRestClient client) { - _client = client; - } - - public async Task> ListAsync() { - return await GetAsync(); - } - - public async Task> GetAsync(SearchRequest searchRequest = null) { - var request = new GetOrgsRestRequest(searchRequest); - try { - 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 - return _deserialiser.DeserialiseList(decodedHtml); - } catch (Exception e) { - throw new Exception("Problem retrieving orgs. See inner exception for details.", e); - } - } - - private readonly IRestClient _client; - private readonly OrganisationHtmlSerialiser _deserialiser = new OrganisationHtmlSerialiser(); - } -} \ No newline at end of file diff --git a/Imbick.StarCitizen.Api/RsiApiClient.cs b/Imbick.StarCitizen.Api/RsiApiClient.cs new file mode 100644 index 0000000..5b073c2 --- /dev/null +++ b/Imbick.StarCitizen.Api/RsiApiClient.cs @@ -0,0 +1,73 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Imbick.StarCitizen.Api.Tests")] +namespace Imbick.StarCitizen.Api { + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + using Imbick.StarCitizen.Api.HtmlSerializers; + using Models; + using RestSharp; + + public class RsiApiClient { + private readonly IRestClient _client; + + public RsiApiClient() + : this("https://robertsspaceindustries.com/") { } + + public RsiApiClient(string baseUrl) + : this(new Uri(baseUrl)) { } + + public RsiApiClient(Uri baseUrl) + : this(new RestClient(baseUrl)) { } + + public RsiApiClient(IRestClient client) { + _client = client; + } + + #region getOrgs + public async Task> ListOrgsAsync() { + return await GetOrgsAsync(); + } + + public async Task> GetOrgsAsync(OrgsSearchRequest searchRequest = null) { + var request = new GetOrgsRestRequest(searchRequest); + try { + 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("\\\"", "\""); + return _orgDeserialiser.DeserializeList(decodedHtml); + } catch (Exception e) { + throw new Exception("Problem retrieving orgs. See inner exception for details.", e); + } + } + + private readonly OrgHtmlSerializer _orgDeserialiser = new OrgHtmlSerializer(); + #endregion + + #region getOrgMembers + public async Task> ListOrgMembersAsync(string orgSymbol, string memberSearch = null) + { + return await GetOrgMembersAsync(new OrgMembersSearchRequest() { Symbol = orgSymbol, Search = memberSearch }); + } + + public async Task> GetOrgMembersAsync(OrgMembersSearchRequest searchRequest = null) + { + var request = new GetOrgMembersRestRequest(searchRequest); + try + { + 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("\\\"", "\""); + return _orgMemberDeserializer.DeserializeList(decodedHtml); + } + catch (Exception e) + { + throw new Exception("Problem retrieving org members. See inner exception for details.", e); + } + } + + private readonly OrgMemberHtmlSerializer _orgMemberDeserializer = new OrgMemberHtmlSerializer(); + #endregion + } +} \ No newline at end of file diff --git a/README.md b/README.md index 2811fac..1c397f2 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,34 @@ This repository provides a C# wrapper around the Star Citizen REST API(s). -Currently only the organisation API is supported https://robertsspaceindustries.com/api/orgs/getOrgs +## Supported APIs from robertsspaceindustries.com + +Currently the only supported APIs are: + +* the organisation https://robertsspaceindustries.com/api/orgs/getOrgs +* the organisation's members https://robertsspaceindustries.com/api/orgs/getOrgMembers + +### Organisations It accepts `POST` requests with no body to list all organisations with the default sorting of `size_desc`. Alternatively a json payload can be provided in the body with the following example structure: -`{"sort":"size_desc","search":"","commitment":[],"roleplay":[],"size":[],"model":[],"activity":[],"language":[],"recruiting":[],"pagesize":12,"page":1}` +`{sort:"size_desc",search:"",commitment:[],roleplay:[],size:[],model:[],activity:[],language:[],recruiting:[],pagesize:12,page:1}` + +Supported values for each of the properties can be found in the `Imbick.StarCitizen.Api.Models.OrgsSearchRequest.cs` file. + +### Organisation's Members + +It accepts `POST` requests with at least the symbol of the organisation to get the members. Alternatively a json payload can be provided in the body with the following example structure: + +`{symbol:"SWISS",search:"",pagesize:32,page:1}` +`{symbol:"SWISS",search:"Meetsch",pagesize:32,page:1}` +`{symbol:"SWISS",search:"",rank:1,role:1,main_org:1,pagesize:32,page:1}` + +Supported values for each of the properties can be found in the `Imbick.StarCitizen.Api.Models.OrgMembersSearchRequest.cs` file. -Supported values for each of the properties can be found in the `Imbick.StarCitizen.Api.Models.SearchRequest.cs` file. +## Roadmap -Additional APIs I am aware of and may support in the future are: +Additional APIs may be supported in the future: `/api/leaderboards/getLeaderboard` `/api/stats/getCrowdfundStats` `/api/starmap`