diff --git a/Source/HaloSharp.Test/Config/Halo5Config.cs b/Source/HaloSharp.Test/Config/Halo5Config.cs
index 71729d9..03338dc 100644
--- a/Source/HaloSharp.Test/Config/Halo5Config.cs
+++ b/Source/HaloSharp.Test/Config/Halo5Config.cs
@@ -44,6 +44,12 @@ public static class Halo5Config
public const string WeaponsJsonPath = "JSON/Halo5/Metadata/weapons.json";
public const string WeaponsJsonSchemaPath = "JSON/Halo5/Metadata/weapons.schema.json";
+ public const string SpartanCompanyPath = "JSON/Halo5/Stats/spartan-company.json";
+ public const string SpartanCompanySchemaPath = "JSON/Halo5/Stats/spartan-company.schema.json";
+
+ public const string PlayerAppearancePath = "JSON/Halo5/Profile/player-appearance.json";
+ public const string PlayerAppearanceSchemaPath = "JSON/Halo5/Profile/player-appearance.schema.json";
+
public const string ArenaMatchJsonPath = "JSON/Halo5/Stats/CarnageReport/arena-match.json";
public const string ArenaMatchJsonSchemaPath = "JSON/Halo5/Stats/CarnageReport/arena-match.schema.json";
public const string CampaignMatchJsonPath = "JSON/Halo5/Stats/CarnageReport/campaign-match.json";
diff --git a/Source/HaloSharp.Test/HaloSharp.Test.csproj b/Source/HaloSharp.Test/HaloSharp.Test.csproj
index f6a9592..ac5e306 100644
--- a/Source/HaloSharp.Test/HaloSharp.Test.csproj
+++ b/Source/HaloSharp.Test/HaloSharp.Test.csproj
@@ -86,6 +86,7 @@
+
@@ -93,6 +94,7 @@
+
@@ -270,6 +272,12 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -384,6 +392,8 @@
PreserveNewest
+
+
PreserveNewest
@@ -623,6 +633,9 @@
HaloSharp
+
+
+
diff --git a/Source/HaloSharp.Test/JSON/Halo5/Profile/player-appearance.json b/Source/HaloSharp.Test/JSON/Halo5/Profile/player-appearance.json
new file mode 100644
index 0000000..1bf5dcb
--- /dev/null
+++ b/Source/HaloSharp.Test/JSON/Halo5/Profile/player-appearance.json
@@ -0,0 +1,14 @@
+{
+ "Gamertag": "Furiousn00b",
+ "LastModifiedUtc": {
+ "ISO8601Date": "2016-07-03T00:00:00Z"
+ },
+ "FirstModifiedUtc": {
+ "ISO8601Date": "2015-10-19T00:00:00Z"
+ },
+ "ServiceTag": "FURI",
+ "Company": {
+ "Id": "a2f47e59-5cc0-44f8-a542-77c162fe69e8",
+ "Name": "Section 3"
+ }
+}
\ No newline at end of file
diff --git a/Source/HaloSharp.Test/JSON/Halo5/Profile/player-appearance.schema.json b/Source/HaloSharp.Test/JSON/Halo5/Profile/player-appearance.schema.json
new file mode 100644
index 0000000..11c38a2
--- /dev/null
+++ b/Source/HaloSharp.Test/JSON/Halo5/Profile/player-appearance.schema.json
@@ -0,0 +1,47 @@
+{
+ "definitions": {
+ "Player-Appearance": {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "Gamertag": {
+ "type": "string"
+ },
+ "LastModifiedUTC": {
+ "$ref": "../../common/iso-8061.schema.json"
+ },
+ "FirstModifiedUTC": {
+ "$ref": "../../common/iso-8061.schema.json"
+ },
+ "ServiceTag": {
+ "type": "string"
+ },
+ "Company": {
+ "type": [ "array", "null" ],
+ "items": {
+ "Id": {
+ "type": "guid"
+ },
+ "Name": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "required": [
+ "Gamertag",
+ "LastModifiedUTC",
+ "FirstModifiedUTC",
+ "ServiceTag",
+ "Company"
+ ]
+ }
+ },
+
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Player-Appearance"
+ }
+}
\ No newline at end of file
diff --git a/Source/HaloSharp.Test/JSON/Halo5/Stats/spartan-company.json b/Source/HaloSharp.Test/JSON/Halo5/Stats/spartan-company.json
new file mode 100644
index 0000000..fa8e529
--- /dev/null
+++ b/Source/HaloSharp.Test/JSON/Halo5/Stats/spartan-company.json
@@ -0,0 +1,1230 @@
+{
+ "Id": "a23876ac-321e-497d-933b-65e226d01b2f",
+ "Name": "Adamant",
+ "Creator": {
+ "Gamertag": "XbL Divinity",
+ "Xuid": null
+ },
+ "PeakMembershipCount": 100,
+ "SuspendedUntilDate": {
+ "ISO8601Date": "1601-01-01T00:00:00Z"
+ },
+ "Members": [
+ {
+ "Player": {
+ "Gamertag": "CLD",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-23T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Omega S021",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-09-04T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "SL Grimp",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-08T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-08T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Monstrosity HCS",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-10-14T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "rampage217",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-10-19T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "SpartanB302",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-11-08T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Sylxeria",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-11-22T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Murdur",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Adanite",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-29T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "ZeroBlvk",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-08T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "ieota",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-09T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Quasar MB",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-01T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "xAssazzinx23x",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-02-09T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "oDelly",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-02-26T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "shadowinthehood",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-20T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "LicensedSinger0",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-05T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Guardian2301",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-03T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-03T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Orpins",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-27T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "xXSotelogamzXx",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "BackSideBlowOut",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-25T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Striker Century",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Skyco23",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-01T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "iV HoRiZoN Vi",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-25T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-25T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "SeventhMaestro",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-02T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "madmanxPr3stige",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-06T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Ex Zen Mute",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-06T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "ViIlainous",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-02-19T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Crooked TV",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-08T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Renegade JW",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-02-17T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Hyperent",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-01-13T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Chancxllor",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-10T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Esilious",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-16T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Definitive",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-14T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Achilles Qc",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-18T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Brainstrm",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-02-16T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Certain Finesse",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-19T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Killion",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-30T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "I WakeUp I",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-10T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Immortal Boss",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-06T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Grubkiller955",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-09T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Fox Is My Main",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-06T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Shxpard",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-20T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Middle ninjaz",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-08-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-08-18T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "BRxFLUXxBR",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-03-23T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "And Now We Cry",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-17T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "BENGALA89",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-05T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "HaXoR73",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-05T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "XxtAnkExX 9F77",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-22T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-22T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Moshimo97",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-12T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "AlphaMale FLAME",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-08-29T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-08-29T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "GCO Siddhartha",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-17T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Handicap",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "KHANartists",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-19T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "H6BR",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-04-22T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Isolate AW",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-05-23T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-23T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Leaxze",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-05-25T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-25T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Alpha Recon1911",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-15T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-15T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "ThirstierMax",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-17T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-17T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "SpatialComic11",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-02T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-02T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "XxJack DanielzX",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-21T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-21T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Exenius",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-23T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-23T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "xDeUsx zILuZion",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-24T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-24T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Themistocles l",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-25T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-25T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Fyshy Fishy",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-06-29T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-29T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "SelCrashed",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-08-08T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-08-08T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "KEA",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-07T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-07T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "IxPurexSutonxI",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-08-13T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-08-13T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "HeIpness",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-14T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-14T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "x ViNcE v",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-15T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-15T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Live4K",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-08T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-08T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "VoyoN",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-18T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Viper Skills",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-22T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-22T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "StiIio",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-23T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-23T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "humoungusdingus",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-24T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-24T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Bexti",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-07-28T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-07-28T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "RahFeaki",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-08-30T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-08-30T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Knipe",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-08-11T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-08-11T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Menxtal",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-08-31T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-08-31T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Sparkz315",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-03T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-03T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Zhxdow",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "L3GENDARYvNOBLE",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Nerdz XXA",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Scorpigeon1",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-04T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Elevated HCS",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-06T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "DashPrime",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-10T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-10T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Ms Tator Totz",
+ "Xuid": null
+ },
+ "Role": 0,
+ "JoinedDate": {
+ "ISO8601Date": "2017-09-13T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-13T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "EagleSierra115",
+ "Xuid": null
+ },
+ "Role": 1,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-23T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "RaVenClaw1996",
+ "Xuid": null
+ },
+ "Role": 1,
+ "JoinedDate": {
+ "ISO8601Date": "2016-08-25T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Gh0stx0fx0nyx",
+ "Xuid": null
+ },
+ "Role": 1,
+ "JoinedDate": {
+ "ISO8601Date": "2016-08-25T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Botsu",
+ "Xuid": null
+ },
+ "Role": 1,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-19T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "UNSCDF Guy",
+ "Xuid": null
+ },
+ "Role": 1,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-29T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "Freeform Virus",
+ "Xuid": null
+ },
+ "Role": 1,
+ "JoinedDate": {
+ "ISO8601Date": "2016-12-08T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-06-30T00:00:00Z"
+ }
+ },
+ {
+ "Player": {
+ "Gamertag": "XbL Divinity",
+ "Xuid": null
+ },
+ "Role": 2,
+ "JoinedDate": {
+ "ISO8601Date": "2016-07-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-05-06T00:00:00Z"
+ }
+ }
+ ],
+ "CreatedDate": {
+ "ISO8601Date": "2016-07-18T00:00:00Z"
+ },
+ "LastModifiedDate": {
+ "ISO8601Date": "2017-09-17T00:00:00Z"
+ }
+}
+
diff --git a/Source/HaloSharp.Test/JSON/Halo5/Stats/spartan-company.schema.json b/Source/HaloSharp.Test/JSON/Halo5/Stats/spartan-company.schema.json
new file mode 100644
index 0000000..e974427
--- /dev/null
+++ b/Source/HaloSharp.Test/JSON/Halo5/Stats/spartan-company.schema.json
@@ -0,0 +1,78 @@
+{
+ "definitions": {
+ "Spartan-Company": {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "Id": {
+ "type": "string"
+ },
+ "Name": {
+ "type": "string"
+ },
+ "Creator": {
+ "type" : "object",
+ "properties": {
+ "gamertag" : {
+ "type": "string"
+ }
+ }
+ },
+ "PeakMembershipCount": {
+ "type": "integer"
+ },
+
+ "SuspendedUntilDate": {
+ "$ref": "../../common/iso-8061.schema.json"
+ },
+
+ "Members": {
+ "type": [ "array", "null" ],
+ "items": {
+
+ "Identity": {
+ "$ref": "../../common/identity.schema.json"
+ },
+
+ "Role" : {
+ "type": "integer"
+ },
+
+ "JoinedDate": {
+ "$ref": "../../common/iso-8061.schema.json"
+ },
+
+ "LastModifiedDate": {
+ "$ref": "../../common/iso-8061.schema.json"
+ }
+ }
+ },
+
+ "CreatedDate": {
+ "$ref": "../../common/iso-8061.schema.json"
+ },
+
+ "LastModifiedDate": {
+ "$ref": "../../common/iso-8061.schema.json"
+ }
+ },
+ "required":[
+ "Id",
+ "Name",
+ "Creator",
+ "PeakMembershipCount",
+ "SuspendedUntilDate",
+ "Members",
+ "CreatedDate",
+ "LastModifiedDate"
+ ]
+ }
+ },
+
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Player-Appearance"
+ }
+}
diff --git a/Source/HaloSharp.Test/Query/Halo5/Profile/GetPlayerAppearanceTests.cs b/Source/HaloSharp.Test/Query/Halo5/Profile/GetPlayerAppearanceTests.cs
new file mode 100644
index 0000000..0d898b3
--- /dev/null
+++ b/Source/HaloSharp.Test/Query/Halo5/Profile/GetPlayerAppearanceTests.cs
@@ -0,0 +1,144 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using HaloSharp.Exception;
+using HaloSharp.Extension;
+using HaloSharp.Model;
+using HaloSharp.Model.Common;
+using HaloSharp.Model.Halo5.Profile;
+using HaloSharp.Query.Halo5.Profile;
+using HaloSharp.Test.Config;
+using HaloSharp.Test.Utility;
+using Moq;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Schema;
+using NUnit.Framework;
+
+namespace HaloSharp.Test.Query.Halo5.Profile
+{
+ [TestFixture]
+ public class GetPlayerAppearanceTests
+ {
+
+ private IHaloSession _mockSession;
+ private PlayerAppearance _playerAppearance;
+
+ [SetUp]
+ public void Setup()
+ {
+ _playerAppearance = JsonConvert.DeserializeObject(File.ReadAllText(Halo5Config.PlayerAppearancePath));
+
+ var mock = new Mock();
+ mock.Setup(m => m.Get(It.IsAny()))
+ .ReturnsAsync(_playerAppearance);
+
+ _mockSession = mock.Object;
+ }
+
+ [Test]
+ [TestCase("Sn1p3r C")]
+ [TestCase("Furiousn00b")]
+ public void Uri_MatchesExpected(string gamertag)
+ {
+ var query = new GetPlayerAppearance(gamertag);
+
+ Assert.AreEqual($"https://www.haloapi.com/profile/h5/profiles/{gamertag}/appearance", query.Uri);
+ }
+
+ [Test]
+ [TestCase("Furiousn00b")]
+ public async Task Query_DoesNotThrow(string gamertag)
+ {
+ var query = new GetPlayerAppearance(gamertag)
+ .SkipCache();
+
+ var result = await _mockSession.Query(query);
+
+ Assert.IsInstanceOf(typeof(PlayerAppearance), result);
+ Assert.AreEqual(_playerAppearance, result);
+ }
+
+ [Test]
+ [TestCase("Greenskull")]
+ [TestCase("Furiousn00b")]
+ public async Task GetPlayerAppearance_DoesNotThrow(string gamertag)
+ {
+ var query = new GetPlayerAppearance(gamertag)
+ .SkipCache();
+
+ var result = await Global.Session.Query(query);
+
+ Assert.IsInstanceOf(typeof(PlayerAppearance), result);
+ }
+
+ [Test]
+ [TestCase("Greenskull")]
+ [TestCase("Furiousn00b")]
+ public async Task GetPlayerAppearance_SchemaIsValid(string gamertag)
+ {
+ var playerAppearanceSchema = JSchema.Parse(File.ReadAllText(Halo5Config.PlayerAppearancePath), new JSchemaReaderSettings
+ {
+ Resolver = new JSchemaUrlResolver(),
+ BaseUri = new Uri(Path.GetFullPath(Halo5Config.PlayerAppearanceSchemaPath))
+ });
+
+ var query = new GetPlayerAppearance(gamertag)
+ .SkipCache();
+
+ var jArray = await Global.Session.Get(query.Uri);
+
+ SchemaUtility.AssertSchemaIsValid(playerAppearanceSchema, jArray);
+ }
+
+ [Test]
+ [TestCase("Greenskull")]
+ [TestCase("Furiousn00b")]
+ public async Task GetPlayerAppearance_ModelMatchesSchema(string gamertag)
+ {
+
+ var schema = JSchema.Parse(File.ReadAllText(Halo5Config.PlayerAppearancePath), new JSchemaReaderSettings
+ {
+ Resolver = new JSchemaUrlResolver(),
+ BaseUri = new Uri(Path.GetFullPath(Halo5Config.PlayerAppearanceSchemaPath))
+ });
+
+ var query = new GetPlayerAppearance(gamertag)
+ .SkipCache();
+
+ var result = await Global.Session.Query(query);
+
+ var json = JsonConvert.SerializeObject(result);
+ var jContainer = JsonConvert.DeserializeObject(json);
+
+ SchemaUtility.AssertSchemaIsValid(schema, jContainer);
+ }
+
+ [Test]
+ [TestCase("Greenskull")]
+ [TestCase("Furiousn00b")]
+ public async Task GetPlayerAppearance_IsSerializable(string gamertag)
+ {
+ var query = new GetPlayerAppearance(gamertag)
+ .SkipCache();
+
+ var result = await Global.Session.Query(query);
+
+ SerializationUtility.AssertRoundTripSerializationIsPossible(result);
+ }
+
+ [Test]
+ [TestCase("00000000000000017")]
+ [TestCase("!$%")]
+ [ExpectedException(typeof(ValidationException))]
+ public async Task GetPlayerAppearance_InvalidGamertag(string gamertag)
+ {
+ var query = new GetPlayerAppearance(gamertag);
+
+ await Global.Session.Query(query);
+ Assert.Fail("An exception should have been thrown");
+ }
+
+
+ }
+}
diff --git a/Source/HaloSharp.Test/Query/Halo5/Stats/GetSpartanCompanyTests.cs b/Source/HaloSharp.Test/Query/Halo5/Stats/GetSpartanCompanyTests.cs
new file mode 100644
index 0000000..e26f4ec
--- /dev/null
+++ b/Source/HaloSharp.Test/Query/Halo5/Stats/GetSpartanCompanyTests.cs
@@ -0,0 +1,156 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using HaloSharp.Exception;
+using HaloSharp.Extension;
+using HaloSharp.Model;
+using HaloSharp.Model.Common;
+using HaloSharp.Model.Halo5.Stats;
+using HaloSharp.Query.Halo5.Stats;
+using HaloSharp.Test.Config;
+using HaloSharp.Test.Utility;
+using Moq;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Schema;
+using NUnit.Framework;
+
+namespace HaloSharp.Test.Query.Halo5.Stats
+{
+ [TestFixture]
+ public class GetSpartanCompanyTests
+ {
+ private IHaloSession _mockSession;
+ private SpartanCompany _spartanCompany;
+
+ [SetUp]
+ public void Setup()
+ {
+ _spartanCompany = JsonConvert.DeserializeObject(File.ReadAllText(Halo5Config.SpartanCompanyPath));
+
+ var mock = new Mock();
+ mock.Setup(m => m.Get(It.IsAny()))
+ .ReturnsAsync(_spartanCompany);
+
+ _mockSession = mock.Object;
+ }
+
+ [Test]
+ [TestCase("a23876ac-321e-497d-933b-65e226d01b2f")]
+ [TestCase("c376dcc0-600c-498e-b656-0c18950fa8bb")]
+ public void Uri_MatchesExpected(string companyID)
+ {
+ Guid companyId = new Guid(companyID);
+
+ var query = new GetSpartanCompany(companyId);
+ Assert.AreEqual($"https://www.haloapi.com/stats/h5/companies/{companyId}", query.Uri);
+ }
+
+ [Test]
+ [TestCase("a23876ac-321e-497d-933b-65e226d01b2f")]
+ public async Task Query_DoesNotThrow(string companyID)
+ {
+ Guid companyId = new Guid(companyID);
+
+ var query = new GetSpartanCompany(companyId)
+ .SkipCache();
+
+ var result = await _mockSession.Query(query);
+
+ Assert.IsInstanceOf(typeof(SpartanCompany), result);
+ Assert.AreEqual(_spartanCompany, result);
+ }
+
+
+ //Need to create GUID objects after function starts.
+ [Test]
+ [TestCase("a23876ac-321e-497d-933b-65e226d01b2f")]
+ [TestCase("c376dcc0-600c-498e-b656-0c18950fa8bb")]
+ public async Task GetSpartanCompany_DoesNotThrow(string companyID)
+ {
+ Guid companyId = new Guid(companyID);
+ var query = new GetSpartanCompany(companyId)
+ .SkipCache();
+
+ var result = await Global.Session.Query(query);
+
+ Assert.IsInstanceOf(typeof(SpartanCompany), result);
+ }
+
+ [Test]
+ [TestCase("a23876ac-321e-497d-933b-65e226d01b2f")]
+ [TestCase("c376dcc0-600c-498e-b656-0c18950fa8bb")]
+ public async Task GetSpartanCompany_SchemaIsValid(string companyID)
+ {
+ Guid companyId = new Guid(companyID);
+
+ var spartanCompanySchema = JSchema.Parse(File.ReadAllText(Halo5Config.SpartanCompanyPath), new JSchemaReaderSettings
+ {
+ Resolver = new JSchemaUrlResolver(),
+ BaseUri = new Uri(Path.GetFullPath(Halo5Config.SpartanCompanySchemaPath))
+ });
+
+ var query = new GetSpartanCompany(companyId)
+ .SkipCache();
+
+ var jArray = await Global.Session.Get(query.Uri);
+
+ SchemaUtility.AssertSchemaIsValid(spartanCompanySchema, jArray);
+ }
+
+ [Test]
+ [TestCase("a23876ac-321e-497d-933b-65e226d01b2f")]
+ [TestCase("c376dcc0-600c-498e-b656-0c18950fa8bb")]
+ public async Task GetSpartanCompany_ModelMatchesSchema(string companyID)
+ {
+ Guid companyId = new Guid(companyID);
+
+ var schema = JSchema.Parse(File.ReadAllText(Halo5Config.SpartanCompanyPath), new JSchemaReaderSettings
+ {
+ Resolver = new JSchemaUrlResolver(),
+ BaseUri = new Uri(Path.GetFullPath(Halo5Config.SpartanCompanySchemaPath))
+ });
+
+ var query = new GetSpartanCompany(companyId)
+ .SkipCache();
+
+ var result = await Global.Session.Query(query);
+
+ var json = JsonConvert.SerializeObject(result);
+ var jContainer = JsonConvert.DeserializeObject(json);
+
+ SchemaUtility.AssertSchemaIsValid(schema, jContainer);
+ }
+
+ [Test]
+ [TestCase("a23876ac-321e-497d-933b-65e226d01b2f")]
+ [TestCase("c376dcc0-600c-498e-b656-0c18950fa8bb")]
+ public async Task GetSpartanCompany_IsSerializable(string companyID)
+ {
+
+ Guid companyId = new Guid(companyID);
+
+ var query = new GetSpartanCompany(companyId)
+ .SkipCache();
+
+ var result = await Global.Session.Query(query);
+
+ SerializationUtility.AssertRoundTripSerializationIsPossible(result);
+ }
+
+ [Test]
+ [TestCase("0")]
+ [TestCase("!$%@")]
+ [ExpectedException(typeof(FormatException))]
+ public async Task GetSpartanCompany_InvalidGuid(string companyID)
+ {
+ Guid companyId = new Guid(companyID);
+
+ var query = new GetSpartanCompany(companyId);
+
+ await Global.Session.Query(query);
+ Assert.Fail("An exception should have been thrown");
+ }
+
+ }
+}
diff --git a/Source/HaloSharp/HaloSharp.csproj b/Source/HaloSharp/HaloSharp.csproj
index d9387ac..c4eb24f 100644
--- a/Source/HaloSharp/HaloSharp.csproj
+++ b/Source/HaloSharp/HaloSharp.csproj
@@ -91,6 +91,7 @@
+
@@ -101,6 +102,7 @@
+
@@ -262,6 +264,7 @@
+
@@ -271,6 +274,7 @@
+
diff --git a/Source/HaloSharp/Model/Halo5/Profile/PlayerAppearance.cs b/Source/HaloSharp/Model/Halo5/Profile/PlayerAppearance.cs
new file mode 100644
index 0000000..41c56a5
--- /dev/null
+++ b/Source/HaloSharp/Model/Halo5/Profile/PlayerAppearance.cs
@@ -0,0 +1,77 @@
+using System;
+using Newtonsoft.Json;
+using HaloSharp.Model.Common;
+
+namespace HaloSharp.Model.Halo5.Profile
+{
+ [Serializable]
+ public class PlayerAppearance : IEquatable
+ {
+ [JsonProperty(PropertyName = "gamertag")]
+ public string Gamertag { get; set; }
+
+ [JsonProperty(PropertyName = "LastModifiedUtc")]
+ public ISO8601 LastModifiedUtc { get; set; }
+
+ [JsonProperty(PropertyName = "FirstModifiedUtc")]
+ public ISO8601 FirstModifiedUtc { get; set; }
+
+ [JsonProperty(PropertyName = "serviceTag")]
+ public string ServiceTag { get; set; }
+
+ [JsonProperty(PropertyName = "Company")]
+ public Company Company { get; set; }
+
+ public bool Equals(PlayerAppearance other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return Company.Equals(other.Company)
+ && Gamertag == other.Gamertag
+ && LastModifiedUtc == other.LastModifiedUtc
+ && FirstModifiedUtc == other.FirstModifiedUtc
+ && ServiceTag == other.ServiceTag;
+ }
+ }
+
+ [Serializable]
+ public class Company : IEquatable
+ {
+ [JsonProperty(PropertyName = "id")]
+ public Guid Id { get; set; }
+
+ [JsonProperty(PropertyName = "name")]
+ public string Name { get; set; }
+
+
+ public bool Equals(Company other)
+ {
+
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return Id == other.Id
+ && Name == other.Name;
+ }
+
+ }
+
+
+
+
+}
diff --git a/Source/HaloSharp/Model/Halo5/Stats/SpartanCompany.cs b/Source/HaloSharp/Model/Halo5/Stats/SpartanCompany.cs
new file mode 100644
index 0000000..45f543b
--- /dev/null
+++ b/Source/HaloSharp/Model/Halo5/Stats/SpartanCompany.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using HaloSharp.Model.Common;
+using HaloSharp.Model.Halo5.Profile;
+
+namespace HaloSharp.Model.Halo5.Stats
+{
+ [Serializable]
+ public class SpartanCompany :IEquatable, IEquatable
+ {
+ [JsonProperty(PropertyName = "id")]
+ public Guid Id { get; set; }
+
+ [JsonProperty(PropertyName = "name")]
+ public string Name { get; set; }
+
+ [JsonProperty(PropertyName = "Creator")]
+ public Creator Creator { get; set; }
+
+ [JsonProperty(PropertyName = "peakMembershipCount")]
+ public int PeakMembershipCount { get; set; }
+
+ [JsonProperty(PropertyName = "suspendedUntilDate")]
+ public ISO8601 SuspendedUntilDate { get; set; }
+
+ [JsonProperty(PropertyName = "members")]
+ public List Members { get; set; }
+
+ [JsonProperty(PropertyName = "CreatedDate")]
+ public ISO8601 CreatedDate { get; set; }
+
+ [JsonProperty(PropertyName = "LastModifiedDate")]
+ public ISO8601 LastModifiedDate{ get; set; }
+
+ public bool Equals(SpartanCompany other)
+ {
+ if(ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if(ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return Id == other.Id
+ && Name == other.Name
+ && Creator.Equals(other.Creator)
+ && PeakMembershipCount == other.PeakMembershipCount
+ && SuspendedUntilDate == other.SuspendedUntilDate
+ && Members.OrderBy(m => m.Identity.Gamertag).SequenceEqual(other.Members.OrderBy(m => m.Identity.Gamertag))
+ && CreatedDate == other.CreatedDate
+ && LastModifiedDate == other.LastModifiedDate;
+ }
+
+ public bool Equals(Company other)
+ {
+
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return Id == other.Id
+ && Name == other.Name;
+ }
+
+ }
+
+ [Serializable]
+ public class Creator : IEquatable
+ {
+ [JsonProperty(PropertyName = "gamertag")]
+ public string gamertag { get; set; }
+
+ public bool Equals(Creator other)
+ {
+
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return gamertag == other.gamertag;
+ }
+ }
+
+ [Serializable]
+ public class Member : IEquatable
+ {
+ [JsonProperty(PropertyName = "Player")]
+ public Identity Identity { get; set; }
+
+ [JsonProperty(PropertyName = "role")]
+ public int Role { get; set; }
+
+ [JsonProperty(PropertyName = "joinedDate")]
+ public ISO8601 JoinedDate { get; set; }
+
+ [JsonProperty(PropertyName = "lastModifiedDate")]
+ public ISO8601 LastModifiedDate { get; set; }
+
+ public bool Equals(Member other)
+ {
+
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return Identity.Equals(other.Identity)
+ && Role == other.Role
+ && JoinedDate == other.JoinedDate
+ && LastModifiedDate == other.LastModifiedDate;
+ }
+ }
+
+
+
+
+}
diff --git a/Source/HaloSharp/Query/Halo5/Profile/GetPlayerAppearance.cs b/Source/HaloSharp/Query/Halo5/Profile/GetPlayerAppearance.cs
new file mode 100644
index 0000000..54757ae
--- /dev/null
+++ b/Source/HaloSharp/Query/Halo5/Profile/GetPlayerAppearance.cs
@@ -0,0 +1,37 @@
+using HaloSharp.Exception;
+using HaloSharp.Model;
+using HaloSharp.Model.Halo5.Profile;
+using HaloSharp.Validation.Common;
+
+namespace HaloSharp.Query.Halo5.Profile
+{
+ public class GetPlayerAppearance : Query
+ {
+ protected virtual string Path => $"profile/h5/profiles/{_player}/appearance";
+
+ public override string Uri => HaloUriBuilder.Build(Path);
+
+ private readonly string _player;
+
+ public GetPlayerAppearance(string gamertag)
+ {
+ _player = gamertag;
+ }
+
+ protected override void Validate()
+ {
+ var validationResult = new ValidationResult();
+
+ if(!_player.IsValidGamertag())
+ {
+ validationResult.Messages.Add("GetPlayerAppearance query requires a valid Gamertag (Player) to be set.");
+ }
+
+ if (!validationResult.Success)
+ {
+ throw new ValidationException(validationResult.Messages);
+ }
+ }
+
+ }
+}
diff --git a/Source/HaloSharp/Query/Halo5/Stats/GetSpartanCompany.cs b/Source/HaloSharp/Query/Halo5/Stats/GetSpartanCompany.cs
new file mode 100644
index 0000000..0b71a30
--- /dev/null
+++ b/Source/HaloSharp/Query/Halo5/Stats/GetSpartanCompany.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HaloSharp.Exception;
+using HaloSharp.Model;
+using HaloSharp.Model.Halo5.Stats;
+using HaloSharp.Validation.Common;
+
+namespace HaloSharp.Query.Halo5.Stats
+{
+
+ public class GetSpartanCompany : Query
+ {
+ protected virtual string Path => $"stats/h5/companies/{_companyId}";
+
+ public override string Uri => HaloUriBuilder.Build(Path);
+
+ private readonly Guid _companyId;
+
+ public GetSpartanCompany(Guid companyId)
+ {
+ _companyId = companyId;
+ }
+
+ protected override void Validate()
+ {
+ var validationResult = new ValidationResult();
+
+ if (!_companyId.IsValid())
+ {
+ validationResult.Messages.Add("GetSpartanyCompany query requires a valid company Id to be set.");
+ }
+
+ if (!validationResult.Success)
+ {
+ throw new ValidationException(validationResult.Messages);
+ }
+ }
+ }
+}