From fdd8ec4c7f321cb0a8f2fff23cca5ba02882b1aa Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 12 Apr 2024 14:43:12 +0200 Subject: [PATCH] Add item endpoints --- lib/api/community/item.ml | 19 ++ lib/index.mld | 4 +- lib/models/response/community/inventory.ml | 29 +++ lib/models/stub/inventory.ml | 48 ++++ lib/models/stub/inventory_metadata.ml | 0 tests/unit/res/getInventoryByProfileIDs.json | 236 +++++++++++++++++++ tests/unit/test.ml | 6 +- tests/unit/test_cases/api.ml | 10 + 8 files changed, 349 insertions(+), 3 deletions(-) create mode 100644 lib/models/response/community/inventory.ml create mode 100644 lib/models/stub/inventory.ml create mode 100644 lib/models/stub/inventory_metadata.ml create mode 100644 tests/unit/res/getInventoryByProfileIDs.json diff --git a/lib/api/community/item.ml b/lib/api/community/item.ml index e69de29..e37865b 100644 --- a/lib/api/community/item.ml +++ b/lib/api/community/item.ml @@ -0,0 +1,19 @@ +open Lwt.Syntax + +let get_inventory ?(profile_ids = []) game domain send = + match profile_ids with + | [] -> Lwt.fail_with "Profile IDs list cannot be empty" + | _ids -> + let base_url = + Uri.make ~scheme:"https" ~host:domain ~path:"/community/achievement/getInventoryByProfileIDs" () + in + let url = + Uri.with_query' base_url [ "title", Data.Game.to_str game; "profileids", Data.Query.encode_lst_i profile_ids ] + in + let* json = send url in + (match json with + | Some j -> + let model = Models.Response.Community.Inventory.from_json j in + Lwt.return @@ Some model + | None -> Lwt.return None) +;; diff --git a/lib/index.mld b/lib/index.mld index d36045f..7b5cb1c 100644 --- a/lib/index.mld +++ b/lib/index.mld @@ -18,12 +18,14 @@ let () = let client = Client.create domain game in ]} -At this point your client can be used to make requests through the use of the {!module:Relic_sdk.Api} modules. The API is segmented into two modules: +At this point your client can be used to make requests through the use of the {!module:Relic_sdk.Api} modules. {[ let* achievements = Client.get Api.Community.Achievement.get_available client in ]} +The API is segmented into two modules: + {2 Community} Community endpoints are open to the general public and do not require any authentication credentials. The following modules are exposed: diff --git a/lib/models/response/community/inventory.ml b/lib/models/response/community/inventory.ml new file mode 100644 index 0000000..d7baf6d --- /dev/null +++ b/lib/models/response/community/inventory.ml @@ -0,0 +1,29 @@ +type t = + { result : Stub.Response.t + ; item_instances_by_profile_id : (string * Stub.Inventory.t list) list + } + +let to_json r = + `Assoc + [ "result", Stub.Response.to_json r.result + ; ( "itemInstancesByProfileID" + , `List + (List.map + (fun (profile_id, items) -> `Assoc [ profile_id, `List (List.map Stub.Inventory.to_json items) ]) + r.item_instances_by_profile_id) ) + ] +;; + +let from_json json = + let open Yojson.Basic.Util in + { result = json |> member "result" |> Stub.Response.from_json + ; item_instances_by_profile_id = + json + |> member "itemInstancesByProfileID" + |> to_list + |> List.map (fun json -> + match json with + | `Assoc [ (profile_id, `List items) ] -> profile_id, List.map Stub.Inventory.from_json items + | _ -> failwith "JSON structure mismatch") + } +;; diff --git a/lib/models/stub/inventory.ml b/lib/models/stub/inventory.ml new file mode 100644 index 0000000..fcf9231 --- /dev/null +++ b/lib/models/stub/inventory.ml @@ -0,0 +1,48 @@ +type t = + { id : int + ; entityversion : int + ; itemdefinition_id : int + ; profile_id : int + ; durability : int + ; durabilitytype : int + ; metadata : string + ; creationdate : int + ; itemlocation_locationid : int + ; itemtrade_id : int + ; permissionflags : int + ; maxchargesperitem : int + } + +let to_json i = + `Assoc + [ "id", `Int i.id + ; "entityversion", `Int i.entityversion + ; "itemdefinition_id", `Int i.itemdefinition_id + ; "profile_id", `Int i.profile_id + ; "durability", `Int i.durability + ; "durabilitytype", `Int i.durabilitytype + ; "metadata", `String i.metadata + ; "creationdate", `Int i.creationdate + ; "itemlocation_locationid", `Int i.itemlocation_locationid + ; "itemtrade_id", `Int i.itemtrade_id + ; "permissionflags", `Int i.permissionflags + ; "maxchargesperitem", `Int i.maxchargesperitem + ] +;; + +let from_json json = + let open Yojson.Basic.Util in + { id = json |> member "id" |> to_int + ; entityversion = json |> member "entityversion" |> to_int + ; itemdefinition_id = json |> member "itemdefinition_id" |> to_int + ; profile_id = json |> member "profile_id" |> to_int + ; durability = json |> member "durability" |> to_int + ; durabilitytype = json |> member "durabilitytype" |> to_int + ; metadata = json |> member "metadata" |> to_string + ; creationdate = json |> member "creationdate" |> to_int + ; itemlocation_locationid = json |> member "itemlocation_locationid" |> to_int + ; itemtrade_id = json |> member "itemtrade_id" |> to_int + ; permissionflags = json |> member "permissionflags" |> to_int + ; maxchargesperitem = json |> member "maxchargesperitem" |> to_int + } +;; diff --git a/lib/models/stub/inventory_metadata.ml b/lib/models/stub/inventory_metadata.ml new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/res/getInventoryByProfileIDs.json b/tests/unit/res/getInventoryByProfileIDs.json new file mode 100644 index 0000000..4de8893 --- /dev/null +++ b/tests/unit/res/getInventoryByProfileIDs.json @@ -0,0 +1,236 @@ +{ + "result": { + "code": 0, + "message": "SUCCESS" + }, + "itemInstancesByProfileID": [ + { + "\"196240\"": [ + { + "id": 60757, + "entityversion": 4, + "itemdefinition_id": 451923, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"att\":{\"sigil_pos\":{\"val\":\"001_centre_large_single\"}}}", + "creationdate": 1634470265, + "itemlocation_locationid": 4, + "itemtrade_id": -1, + "permissionflags": 3, + "maxchargesperitem": 2147483647 + }, + { + "id": 1261739493, + "entityversion": 7, + "itemdefinition_id": 454688, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "", + "creationdate": 1699988311, + "itemlocation_locationid": 2, + "itemtrade_id": -1, + "permissionflags": 51, + "maxchargesperitem": -1 + }, + { + "id": 60758, + "entityversion": 2, + "itemdefinition_id": 451960, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{}", + "creationdate": 1634470265, + "itemlocation_locationid": 5, + "itemtrade_id": -1, + "permissionflags": 3, + "maxchargesperitem": 2147483647 + }, + { + "id": 333168196, + "entityversion": 5, + "itemdefinition_id": 453145, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"att\":{\"is_new\":{\"val\":\"0\"}}}", + "creationdate": 1651697316, + "itemlocation_locationid": 5, + "itemtrade_id": -1, + "permissionflags": 51, + "maxchargesperitem": -1 + }, + { + "id": 789328289, + "entityversion": 1, + "itemdefinition_id": 453186, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{}", + "creationdate": 1681644640, + "itemlocation_locationid": 5, + "itemtrade_id": -1, + "permissionflags": 3, + "maxchargesperitem": 2147483647 + }, + { + "id": 60759, + "entityversion": 247, + "itemdefinition_id": 452595, + "profile_id": 196240, + "durability": 10182420, + "durabilitytype": 0, + "metadata": "{}", + "creationdate": 1634470265, + "itemlocation_locationid": 3, + "itemtrade_id": -1, + "permissionflags": 3, + "maxchargesperitem": 2147483647 + }, + { + "id": 333152484, + "entityversion": 5, + "itemdefinition_id": 452432, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"att\":{\"is_new\":{\"val\":\"0\"}}}", + "creationdate": 1651695281, + "itemlocation_locationid": 3, + "itemtrade_id": -1, + "permissionflags": 51, + "maxchargesperitem": -1 + }, + { + "id": 60770, + "entityversion": 2, + "itemdefinition_id": 451952, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"eslot\":\"2\"}", + "creationdate": 1634470265, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 19, + "maxchargesperitem": 2147483647 + }, + { + "id": 60784, + "entityversion": 2, + "itemdefinition_id": 452534, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"eslot\":\"10\"}", + "creationdate": 1634470265, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 19, + "maxchargesperitem": 2147483647 + }, + { + "id": 60793, + "entityversion": 2, + "itemdefinition_id": 452547, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"eslot\":\"4\"}", + "creationdate": 1634470265, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 19, + "maxchargesperitem": 2147483647 + }, + { + "id": 60807, + "entityversion": 4, + "itemdefinition_id": 452486, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"eslot\":\"8\"}", + "creationdate": 1634470265, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 19, + "maxchargesperitem": 2147483647 + }, + { + "id": 60810, + "entityversion": 2, + "itemdefinition_id": 452553, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"eslot\":\"6\"}", + "creationdate": 1634470265, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 19, + "maxchargesperitem": 2147483647 + }, + { + "id": 234628989, + "entityversion": 5, + "itemdefinition_id": 451939, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"att\":{\"is_new\":{\"val\":\"0\"}},\"eslot\":\"3\"}", + "creationdate": 1639776723, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 51, + "maxchargesperitem": -1 + }, + { + "id": 334039191, + "entityversion": 5, + "itemdefinition_id": 453329, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"att\":{\"is_new\":{\"val\":\"0\"}},\"eslot\":\"5\"}", + "creationdate": 1651859675, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 51, + "maxchargesperitem": -1 + }, + { + "id": 341369934, + "entityversion": 6, + "itemdefinition_id": 453439, + "profile_id": 196240, + "durability": 2, + "durabilitytype": 0, + "metadata": "{\"att\":{\"is_new\":{\"val\":\"0\"}},\"eslot\":\"7\"}", + "creationdate": 1653498648, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 51, + "maxchargesperitem": -1 + }, + { + "id": 342281892, + "entityversion": 5, + "itemdefinition_id": 453442, + "profile_id": 196240, + "durability": 1, + "durabilitytype": 0, + "metadata": "{\"att\":{\"is_new\":{\"val\":\"0\"}},\"eslot\":\"1\"}", + "creationdate": 1653680895, + "itemlocation_locationid": 60757, + "itemtrade_id": -1, + "permissionflags": 51, + "maxchargesperitem": -1 + } + ] + } + ] +} diff --git a/tests/unit/test.ml b/tests/unit/test.ml index 3f86386..2972852 100644 --- a/tests/unit/test.ml +++ b/tests/unit/test.ml @@ -2,7 +2,7 @@ let () = Lwt_main.run @@ Alcotest_lwt.run "Relic SDK" - [ ( "api" + [ ( "Community API" , [ Alcotest_lwt.test_case "/community/advertisement/findAdvertisements" `Quick (fun _ () -> Test_cases.Api.test_get_advertisements ()) ; Alcotest_lwt.test_case "/community/news/getNews" `Quick (fun _ () -> Test_cases.Api.test_get_news ()) @@ -19,8 +19,10 @@ let () = Test_cases.Api.test_get_leaderboards ()) ; Alcotest_lwt.test_case "/community/leaderboard/GetAvatarStatForProfile" `Quick (fun _ () -> Test_cases.Api.test_get_avatar_stat ()) - ; Alcotest_lwt.test_case "/community/leaderboard/getLeaderBoard2.json" `Quick (fun _ () -> + ; Alcotest_lwt.test_case "/community/leaderboard/getLeaderBoard2" `Quick (fun _ () -> Test_cases.Api.test_get_leaderboard2 ()) + ; Alcotest_lwt.test_case "/community/leaderboard/getInventoryByProfileIDs" `Quick (fun _ () -> + Test_cases.Api.test_get_inventory ()) ; Alcotest_lwt.test_case "invalid json" `Quick (fun _ () -> Test_cases.Api.test_invalid ()) ] ) ] diff --git a/tests/unit/test_cases/api.ml b/tests/unit/test_cases/api.ml index 6b6f1d2..3117733 100644 --- a/tests/unit/test_cases/api.ml +++ b/tests/unit/test_cases/api.ml @@ -103,6 +103,16 @@ let test_get_leaderboard2 () = | None -> Lwt.fail_with "Expected Some but got None" ;; +let test_get_inventory () = + let requester = Mock.Json_file.create_requester "getInventoryByProfileIDs.json" in + let client = Client.create "aoe-api.worldsedgelink.com" Data.Game.Age4 in + let endpoint = Api.Community.Item.get_inventory ~profile_ids:[ 1 ] in + Client.get endpoint client ~requester + >>= function + | Some r -> Lwt.return @@ Alcotest.(check string) "Response was success" "SUCCESS" r.result.message + | None -> Lwt.fail_with "Expected Some but got None" +;; + let test_invalid () = let endpoints = [ Api.Community.News.get ] in Lwt_list.iter_s (fun endpoint -> Util.request_with_file_throw endpoint) endpoints