fix(gift): wire reward_type is UserGoodsType integer, not legacy 1/4/9 encoding
Replace WireRewardTypeToUserGoodsType switch with a validating identity cast backed by GiftRewardTypes.IsSupported. Wire type 1 is RedEther (UserGoodsType.RedEther), not Crystal (UserGoodsType.Crystal=2); the old switch silently granted the wrong wallet for every tutorial-completion claim. Update all 5 GiftControllerTests assertions and 1 TutorialFlowEndToEndTests assertion to expect RedEther instead of Crystals. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -84,18 +84,19 @@ public class GiftControllerTests
|
||||
Assert.That(root.GetProperty("present_list").GetArrayLength(), Is.EqualTo(0));
|
||||
Assert.That(root.GetProperty("present_history_list").GetArrayLength(), Is.EqualTo(5));
|
||||
|
||||
// Currency credited: +400 crystals, +100 rupees.
|
||||
// Currency credited: +400 red ether, +100 rupees.
|
||||
// Tutorial gift 71478626 has reward_type=1 — that's RedEther per UserGoods.Type, not Crystal.
|
||||
var post = await factory.GetViewerCurrencyAsync(viewerId);
|
||||
Assert.That(post.Crystals - pre.Crystals, Is.EqualTo(400UL));
|
||||
Assert.That(post.RedEther - pre.RedEther, Is.EqualTo(400UL));
|
||||
Assert.That(post.Rupees - pre.Rupees, Is.EqualTo(100UL));
|
||||
|
||||
// reward_list carries post-state TOTALS, not deltas, per project_wire_reward_list_post_state.
|
||||
// After claiming gifts, the crystal/rupy entries in reward_list should equal viewer's post-grant totals.
|
||||
var rewardList = root.GetProperty("reward_list").EnumerateArray().ToList();
|
||||
var crystalEntry = rewardList.First(e => e.GetProperty("reward_type").GetString() == "1");
|
||||
var rupyEntry = rewardList.First(e => e.GetProperty("reward_type").GetString() == "9");
|
||||
Assert.That(crystalEntry.GetProperty("reward_num").GetString(),
|
||||
Is.EqualTo(post.Crystals.ToString()),
|
||||
var redEtherEntry = rewardList.First(e => e.GetProperty("reward_type").GetString() == "1");
|
||||
var rupyEntry = rewardList.First(e => e.GetProperty("reward_type").GetString() == "9");
|
||||
Assert.That(redEtherEntry.GetProperty("reward_num").GetString(),
|
||||
Is.EqualTo(post.RedEther.ToString()),
|
||||
"reward_list currency entries must carry POST-STATE TOTALS, not gift deltas (client does direct assignment).");
|
||||
Assert.That(rupyEntry.GetProperty("reward_num").GetString(),
|
||||
Is.EqualTo(post.Rupees.ToString()));
|
||||
@@ -243,13 +244,13 @@ public class GiftControllerTests
|
||||
|
||||
await client.PostAsync("/tutorial/gift_receive", new StringContent(json, Encoding.UTF8, "application/json"));
|
||||
var midPost = await factory.GetViewerCurrencyAsync(viewerId);
|
||||
Assert.That(midPost.Crystals - preFirst.Crystals, Is.EqualTo(400UL));
|
||||
Assert.That(midPost.RedEther - preFirst.RedEther, Is.EqualTo(400UL));
|
||||
Assert.That(midPost.Rupees - preFirst.Rupees, Is.EqualTo(100UL));
|
||||
|
||||
var second = await client.PostAsync("/tutorial/gift_receive", new StringContent(json, Encoding.UTF8, "application/json"));
|
||||
Assert.That(second.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var finalPost = await factory.GetViewerCurrencyAsync(viewerId);
|
||||
Assert.That(finalPost.Crystals, Is.EqualTo(midPost.Crystals), "Second claim of same present_ids must not re-grant.");
|
||||
Assert.That(finalPost.RedEther, Is.EqualTo(midPost.RedEther), "Second claim of same present_ids must not re-grant.");
|
||||
Assert.That(finalPost.Rupees, Is.EqualTo(midPost.Rupees));
|
||||
}
|
||||
|
||||
@@ -314,7 +315,7 @@ public class GiftControllerTests
|
||||
|
||||
var preCurrency = await factory.GetViewerCurrencyAsync(viewerId);
|
||||
|
||||
// Delete the crystal gift (71478626 grants +400 crystals on state=1).
|
||||
// Delete the red-ether gift (71478626 grants +400 RedEther on state=1).
|
||||
var json = $$"""{"present_id_array":["71478626"],"state":3,{{BaseAuthBlock}}}""";
|
||||
var response = await client.PostAsync("/gift/receive_gift",
|
||||
new StringContent(json, Encoding.UTF8, "application/json"));
|
||||
@@ -325,7 +326,7 @@ public class GiftControllerTests
|
||||
|
||||
// No currency granted.
|
||||
var postCurrency = await factory.GetViewerCurrencyAsync(viewerId);
|
||||
Assert.That(postCurrency.Crystals, Is.EqualTo(preCurrency.Crystals),
|
||||
Assert.That(postCurrency.RedEther, Is.EqualTo(preCurrency.RedEther),
|
||||
"state=3 (MAIL_DELETE) must not grant.");
|
||||
|
||||
// No reward_list / total_receive_count_list entries.
|
||||
|
||||
@@ -85,7 +85,8 @@ public class TutorialFlowEndToEndTests
|
||||
Assert.That(receiveResp.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
|
||||
var midCurrency = await factory.GetViewerCurrencyAsync(viewerId);
|
||||
Assert.That(midCurrency.Crystals - preCurrency.Crystals, Is.EqualTo(400UL));
|
||||
// Tutorial gift 71478626 has reward_type=1 — that's RedEther per UserGoods.Type, not Crystal.
|
||||
Assert.That(midCurrency.RedEther - preCurrency.RedEther, Is.EqualTo(400UL));
|
||||
Assert.That(midCurrency.Rupees - preCurrency.Rupees, Is.EqualTo(100UL));
|
||||
|
||||
// gift_receive should also have advanced the tutorial step to 41 server-side.
|
||||
|
||||
Reference in New Issue
Block a user