fix(friend): add BaseRequest body param to 6 body-less actions
ShadowverseTranslationMiddleware throws InvalidOperationException when a Unity client posts an encrypted msgpack body to an action with zero [FromBody] parameters — it has no target type for the deserializer. Tests pass because they post JSON directly with no UnityPlayer UA and the middleware short-circuits. Same defect already fixed on /replay/info in 216dcab; this catches up the friend system shipped 2026-06-09. Fixed actions: info, receive_apply_info, send_apply_info, played_together_info, reject_apply_all, cancel_apply_all. Tests updated to post the BaseRequest auth fields so [ApiController] model validation passes (BaseRequest.ViewerId is non-nullable string). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,13 @@ public class FriendControllerTests
|
||||
{
|
||||
private static StringContent JsonBody(string json) => new(json, Encoding.UTF8, "application/json");
|
||||
|
||||
// Minimal BaseRequest-shaped payload. Body-less /friend/* actions now declare
|
||||
// [FromBody] BaseRequest _ so the prod translation middleware can deserialize
|
||||
// the encrypted msgpack body (it requires at least one parameter). Tests post
|
||||
// these auth fields so [ApiController] model validation passes — the actual
|
||||
// viewer_id comes from the session claim, not the body.
|
||||
private const string EmptyBody = """{"viewer_id":"0","steam_id":0,"steam_session_ticket":""}""";
|
||||
|
||||
private static async Task<long> SeedViewer(SVSimTestFactory factory, ulong steamId, string name = "Test Viewer")
|
||||
=> await factory.SeedViewerAsync(steamId: steamId, displayName: name);
|
||||
|
||||
@@ -23,7 +30,7 @@ public class FriendControllerTests
|
||||
long viewerId = await SeedViewer(factory, 76_561_198_000_010_001UL);
|
||||
using var client = factory.CreateAuthenticatedClient(viewerId);
|
||||
|
||||
var response = await client.PostAsync("/friend/info", JsonBody("{}"));
|
||||
var response = await client.PostAsync("/friend/info", JsonBody(EmptyBody));
|
||||
var raw = await response.Content.ReadAsStringAsync();
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), raw);
|
||||
|
||||
@@ -40,7 +47,7 @@ public class FriendControllerTests
|
||||
long viewerId = await SeedViewer(factory, 76_561_198_000_010_002UL);
|
||||
using var client = factory.CreateAuthenticatedClient(viewerId);
|
||||
|
||||
var response = await client.PostAsync("/friend/receive_apply_info", JsonBody("{}"));
|
||||
var response = await client.PostAsync("/friend/receive_apply_info", JsonBody(EmptyBody));
|
||||
var raw = await response.Content.ReadAsStringAsync();
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), raw);
|
||||
|
||||
@@ -56,7 +63,7 @@ public class FriendControllerTests
|
||||
long viewerId = await SeedViewer(factory, 76_561_198_000_010_003UL);
|
||||
using var client = factory.CreateAuthenticatedClient(viewerId);
|
||||
|
||||
var response = await client.PostAsync("/friend/send_apply_info", JsonBody("{}"));
|
||||
var response = await client.PostAsync("/friend/send_apply_info", JsonBody(EmptyBody));
|
||||
var raw = await response.Content.ReadAsStringAsync();
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), raw);
|
||||
|
||||
@@ -73,7 +80,7 @@ public class FriendControllerTests
|
||||
long viewerId = await SeedViewer(factory, 76_561_198_000_010_004UL);
|
||||
using var client = factory.CreateAuthenticatedClient(viewerId);
|
||||
|
||||
var response = await client.PostAsync("/friend/played_together_info", JsonBody("{}"));
|
||||
var response = await client.PostAsync("/friend/played_together_info", JsonBody(EmptyBody));
|
||||
var raw = await response.Content.ReadAsStringAsync();
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK), raw);
|
||||
|
||||
@@ -223,7 +230,7 @@ public class FriendControllerTests
|
||||
}
|
||||
|
||||
using var client = factory.CreateAuthenticatedClient(me);
|
||||
var response = await client.PostAsync("/friend/reject_apply_all", JsonBody("{}"));
|
||||
var response = await client.PostAsync("/friend/reject_apply_all", JsonBody(EmptyBody));
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
|
||||
using var verifyScope = factory.Services.CreateScope();
|
||||
@@ -245,7 +252,7 @@ public class FriendControllerTests
|
||||
}
|
||||
|
||||
using var client = factory.CreateAuthenticatedClient(me);
|
||||
var response = await client.PostAsync("/friend/cancel_apply_all", JsonBody("{}"));
|
||||
var response = await client.PostAsync("/friend/cancel_apply_all", JsonBody(EmptyBody));
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
|
||||
using var verifyScope = factory.Services.CreateScope();
|
||||
@@ -281,7 +288,7 @@ public class FriendControllerTests
|
||||
using var factory = new SVSimTestFactory();
|
||||
var client = factory.CreateClient();
|
||||
|
||||
var response = await client.PostAsync("/friend/info", JsonBody("{}"));
|
||||
var response = await client.PostAsync("/friend/info", JsonBody(EmptyBody));
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized));
|
||||
}
|
||||
|
||||
@@ -303,7 +310,7 @@ public class FriendControllerTests
|
||||
int applyId;
|
||||
using (var clientB = factory.CreateAuthenticatedClient(viewerB))
|
||||
{
|
||||
var resp = await clientB.PostAsync("/friend/receive_apply_info", JsonBody("{}"));
|
||||
var resp = await clientB.PostAsync("/friend/receive_apply_info", JsonBody(EmptyBody));
|
||||
var raw = await resp.Content.ReadAsStringAsync();
|
||||
using var doc = JsonDocument.Parse(raw);
|
||||
var applies = doc.RootElement.GetProperty("receive_applies");
|
||||
@@ -323,7 +330,7 @@ public class FriendControllerTests
|
||||
async Task<string> GetFriendName(long ownerId)
|
||||
{
|
||||
using var client = factory.CreateAuthenticatedClient(ownerId);
|
||||
var resp = await client.PostAsync("/friend/info", JsonBody("{}"));
|
||||
var resp = await client.PostAsync("/friend/info", JsonBody(EmptyBody));
|
||||
var raw = await resp.Content.ReadAsStringAsync();
|
||||
using var doc = JsonDocument.Parse(raw);
|
||||
var friends = doc.RootElement.GetProperty("friends");
|
||||
|
||||
Reference in New Issue
Block a user