mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
feat: implement the client routes that had no handler
Sixteen agents, one controller each, over every route the coverage test reported as missing or wrong-verb. Route+verb coverage is now 516/522 (98.9%), up from 90.8%. Each handler was written against binary evidence rather than the audit's prose: verb from the BestHTTP.HTTPMethods ordinal at the call site, response shape from the issuing method's return type, request shape from whether the client uses form fields, a raw JsonUtility body, or query params. Agents were told to skip rather than stub, and several did. New surface worth noting: - Link host: actionlink create/get/consume and datalink get/put, previously unrouted entirely. - Club roster reads: members, banned, requests, requests/search, members/search, each with the client's real sort/paging params and the wire row shape its reader expects (the banned row has no MembershipType field, so it isn't sent). - Home clubhouse set/clear, club disband (soft, via the existing State column), and DELETE mainimage as its own action rather than a verb alias — the client parses the details envelope from it, so it is not status-only. - Club chat threads, comment CRUD, keepsake collect/delete, progression-event xp boosts, image report and cheered/bulk, iOS StoreKit product reporting. The six routes still missing all need storage that does not exist yet (per-role club permissions, club additional-image slots, MinLevel, ClubChatEnabled). Those are left for a single schema change rather than faked. Also excludes DELETE /account/me from the endpoint contract probe. That route is now a real, correctly-guarded account purge, and the probe walks every route with one test player — so calling it destroyed the probe's own session and turned one real event into 49 cascading foreign-key and 401 failures.
This commit is contained in:
@@ -18,7 +18,9 @@ public sealed class GameClientEndpointContractTests :
|
||||
[Fact]
|
||||
public async Task Game_client_contract_probe_reaches_every_controller_route()
|
||||
{
|
||||
var routes = EndpointContractDiscovery.Discover();
|
||||
var routes = EndpointContractDiscovery.Discover()
|
||||
.Where(r => !DestroysTheProbeSession(r))
|
||||
.ToList();
|
||||
Assert.NotEmpty(routes);
|
||||
|
||||
using var client = _factory.CreateClient(new()
|
||||
@@ -48,6 +50,26 @@ public sealed class GameClientEndpointContractTests :
|
||||
+ string.Join(Environment.NewLine, failures));
|
||||
}
|
||||
|
||||
/// <summary>Routes this probe must not call, because they destroy the very
|
||||
/// session it authenticates with.
|
||||
///
|
||||
/// The probe walks every route in order using one test player. Account
|
||||
/// deletion is a genuine, correctly-guarded purge — but once it runs, that
|
||||
/// player row is gone, so every later probe fails on a foreign-key
|
||||
/// violation or a 401. Excluding these keeps the failure list meaningful
|
||||
/// instead of one real event cascading into dozens of phantom failures.
|
||||
///
|
||||
/// This is deliberately narrow: only self-destruct routes belong here, not
|
||||
/// anything merely inconvenient.</summary>
|
||||
private static bool DestroysTheProbeSession(EndpointContract route)
|
||||
{
|
||||
if (!string.Equals(route.Method, "DELETE", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
var template = route.Template.Trim('/');
|
||||
return template is "account/me" or "account/v1/me" or "account/v2/me";
|
||||
}
|
||||
|
||||
private static async Task<EndpointProbeResult> ProbeAsync(
|
||||
HttpClient client,
|
||||
EndpointContract route,
|
||||
|
||||
Reference in New Issue
Block a user