Skip to content

Commit

Permalink
Merge pull request #2282 from U-lis/feature/gql-claim-items
Browse files Browse the repository at this point in the history
Introduce ClaimItems GQL endpoint
  • Loading branch information
U-lis authored Nov 3, 2023
2 parents f8a14dd + 1b3f712 commit b00020f
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 1 deletion.
86 changes: 86 additions & 0 deletions NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Libplanet.Common;
using Libplanet.Crypto;
using Libplanet.Types.Assets;
using Libplanet.Types.Tx;
using Nekoyume;
using Nekoyume.Action;
using Nekoyume.Action.Garages;
Expand Down Expand Up @@ -1340,5 +1341,90 @@ public async Task AuraSummon()
Assert.Equal(groupId, action.GroupId);
Assert.Equal(summonCount, action.SummonCount);
}

[Theory]
[InlineData(1)]
[InlineData(2)]
[InlineData(10)]
[InlineData(100)]
public async Task ClaimItems(int claimDataCount)
{
var random = new Random();
var tickerList = new List<string> { "Item_T_500000", "Item_T_400000", "Item_T_800201", "Item_NT_49900011" };
var claimDataList = new List<(Address, List<FungibleAssetValue>)>();
var queryBuilder = new StringBuilder().Append("{claimItems(claimData: [");
for (var i = 0; i < claimDataCount; i++)
{
var avatarAddress = new PrivateKey().ToAddress();
var currencyCount = random.Next(1, tickerList.Count + 1);
var tickerCandidates = tickerList.OrderBy(i => random.Next()).Take(currencyCount);
queryBuilder.Append($@"{{
avatarAddress: ""{avatarAddress}"",
fungibleAssetValues:[
");
var favList = tickerCandidates.Select(
ticker => new FungibleAssetValue(
Currency.Uncapped(
ticker: ticker,
decimalPlaces: 0,
minters: AddressSet.Empty
),
random.Next(1, 100), 0
)
).ToList();
foreach (var fav in favList)
{
queryBuilder.Append($@"{{
ticker: ""{fav.Currency.Ticker}"",
decimalPlaces: 0,
minters: [],
quantity: {fav.MajorUnit}
}}");
if (fav != favList[^1])
{
queryBuilder.Append(",");
}
}

claimDataList.Add((avatarAddress, favList));

queryBuilder.Append("]}");
if (i < claimDataCount - 1)
{
queryBuilder.Append(",");
}
}

queryBuilder.Append("])}");

var queryResult =
await ExecuteQueryAsync<ActionQuery>(queryBuilder.ToString(), standaloneContext: _standaloneContext);
var data = (Dictionary<string, object>)((ExecutionNode)queryResult.Data!).ToValue()!;
var plainValue = _codec.Decode(ByteUtil.ParseHex((string)data["claimItems"]));
Assert.IsType<Dictionary>(plainValue);
var actionBase = DeserializeNCAction(plainValue);
var action = Assert.IsType<ClaimItems>(actionBase);

for (var i = 0; i < claimDataList.Count; i++)
{
var (expectedAddr, expectedFavList) = claimDataList[i];
var (actualAddr, actualFavList) = action.ClaimData[i];
Assert.Equal(expectedAddr, actualAddr);
Assert.Equal(expectedFavList.Count, actualFavList.Count);
for (var j = 0; j < expectedFavList.Count; j++)
{
/* FIXME: Make Assert.Equal(FAV1, FAV2) works.
This test will fail because:
- GQL currency type does not allow `null` as minters to you should give empty list.
- But inside `Currency`, empty list is changed to null.
- As a result, currency hash are mismatch.
- See https://github.com/planetarium/NineChronicles.Headless/pull/2282#discussion_r1380857437
*/
// Assert.Equal(expectedFavList[i], actualFavList[i]);
Assert.Equal(expectedFavList[j].Currency.Ticker, actualFavList[j].Currency.Ticker);
Assert.Equal(expectedFavList[j].RawValue, actualFavList[j].RawValue);
}
}
}
}
}
2 changes: 1 addition & 1 deletion NineChronicles.Headless/GraphTypes/ActionQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Libplanet.Types.Assets;
using Libplanet.Explorer.GraphTypes;
using Nekoyume.Action;
using Nekoyume.Action.Factory;
using Nekoyume.Model;
using Nekoyume.Model.State;
using Nekoyume.TableData;
Expand Down Expand Up @@ -543,6 +542,7 @@ public ActionQuery(StandaloneContext standaloneContext)
RegisterMead();
RegisterGarages();
RegisterSummon();
RegisterClaimItems();

Field<NonNullGraphType<CraftQuery>>(
name: "craftQuery",
Expand Down
37 changes: 37 additions & 0 deletions NineChronicles.Headless/GraphTypes/ActionQueryFields/ClaimItems.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using GraphQL;
using GraphQL.Types;
using Libplanet.Crypto;
using Libplanet.Explorer.GraphTypes;
using Libplanet.Types.Assets;
using Nekoyume.Action;
using NineChronicles.Headless.GraphTypes.Input;

namespace NineChronicles.Headless.GraphTypes
{
public partial class ActionQuery
{
private void RegisterClaimItems()
{
Field<NonNullGraphType<ByteStringType>>(
"claimItems",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<ListGraphType<NonNullGraphType<ClaimDataInputType>>>>
{
Name = "claimData",
Description = "List of pair of avatar address, List<FAV> to claim."
}
),
resolve: context =>
{
var claimData =
context.GetArgument<
List<(Address avataAddress, IReadOnlyList<FungibleAssetValue> fungibleAssetValues)>
>("claimData").AsReadOnly();
ActionBase action = new ClaimItems(claimData);
return Encode(context, action);
}
);
}
}
}
25 changes: 25 additions & 0 deletions NineChronicles.Headless/GraphTypes/Input/ClaimDataInputType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using GraphQL.Types;
using Libplanet.Crypto;
using Libplanet.Explorer.GraphTypes;
using Libplanet.Types.Assets;

namespace NineChronicles.Headless.GraphTypes.Input;

public class ClaimDataInputType : InputObjectGraphType<(Address avatarAddress, IReadOnlyList<FungibleAssetValue> favList)>
{
public ClaimDataInputType()
{
Field<NonNullGraphType<AddressType>>("avatarAddress");
Field<NonNullGraphType<ListGraphType<NonNullGraphType<FungibleAssetValueInputType>>>>("fungibleAssetValues");
}

public override object ParseDictionary(IDictionary<string, object?> value)
{
return (
(Address)value["avatarAddress"]!,
(IReadOnlyList<FungibleAssetValue>)((object[])value["fungibleAssetValues"]!).Cast<FungibleAssetValue>().ToList()
);
}
}

0 comments on commit b00020f

Please sign in to comment.