docs(fifa17): numeric squad ids are real; our collapsing is safe, not authentic
The numeric id in squad/<n> was being justified as "matching the oracle". That justification does not survive inspection, and the code now says why. FIFA 17 has genuine multi-squad semantics. The client's own shipped action table has SelectSquadById, RetrieveSquad as an action DISTINCT from LoadActiveSquad, CreateSquadWithName, RenameSquad, DeleteSquad, CopySquad, indexed SQUAD_ID-%d list entries and FUT_MAX_NUM_SQUAD_REACHED. The base template is `ut/%s/squad` with the id appended. The number identifies a squad. The inherited behaviour came from a bare prefix regex in the Python oracle - `re.compile(G + r"/squad")` calling squad_route(), which never reads the URL id (GET returns current_squad(), PUT echoes the id from the BODY). The comments around it show /squad/list and the draft routes had to be registered first because that rule was swallowing them. It was expedient, not evidence-driven. Collapsing the id is nonetheless SAFE today, and only for a specific reason: we advertise exactly one squad. ACTIVE_SQUAD_WIRE_ID is a constant 0, /squad/list returns a single-element array carrying it, and no create/rename/delete/copy route exists, so the client can only echo back the id we gave it. Every numeric path in retained captures is squad/0, all PUTs whose body id also reads 0; no numeric GET has ever been recorded. Behaviour is therefore UNCHANGED - no evidence justifies changing it, and unknown-id semantics are deliberately not invented. What changes is that the assumption is now explicit and enforced: numeric_squad_routing_is_safe_only_while_one_squad_is_advertised pins the wire id at 0 and /squad/list at one entry, and fails the moment a second squad becomes addressable. Verified by simulating a second advertised squad. Workspace 1252 passed (1251 + this test), 0 failed.
This commit is contained in:
@@ -1111,8 +1111,9 @@ fn classify_squad_and_usermassinfo_routes() {
|
||||
Route::Passthrough
|
||||
);
|
||||
|
||||
// GET /squad/active and every numeric GET are the one Core-backed current
|
||||
// squad, matching the oracle's single-squad response regardless of URL id.
|
||||
// GET /squad/active and every numeric GET resolve to the one Core-backed
|
||||
// squad. SAFE, not authentic — see is_numeric_squad_tail and the invariant
|
||||
// test below.
|
||||
assert_eq!(
|
||||
classify("GET", "/ut/game/fifa17/squad/active"),
|
||||
Route::SquadActive
|
||||
@@ -2825,3 +2826,45 @@ fn no_shipped_training_card_exceeds_the_declared_ceiling() {
|
||||
}
|
||||
assert_eq!(rare, 6, "all 6 rare all-six cards must resolve");
|
||||
}
|
||||
|
||||
/// Collapsing every numeric `squad/<id>` onto one squad is safe ONLY while
|
||||
/// exactly one squad is advertised. This is the tripwire for that assumption.
|
||||
///
|
||||
/// FIFA 17 has real multi-squad semantics — the client ships `SelectSquadById`,
|
||||
/// `RetrieveSquad` (distinct from `LoadActiveSquad`), `CreateSquadWithName`,
|
||||
/// `RenameSquad`, `DeleteSquad` and indexed `SQUAD_ID-%d` entries. We get away
|
||||
/// with ignoring the id purely because the client can never learn another one:
|
||||
/// the wire id is a constant 0 and `/squad/list` advertises a single squad.
|
||||
///
|
||||
/// If either fact stops holding, the numeric route needs a real lookup and this
|
||||
/// test must be the thing that says so.
|
||||
#[test]
|
||||
fn numeric_squad_routing_is_safe_only_while_one_squad_is_advertised() {
|
||||
assert_eq!(
|
||||
openfut_utas_host::ACTIVE_SQUAD_WIRE_ID,
|
||||
0,
|
||||
"the single advertised squad id is what makes id-collapsing safe"
|
||||
);
|
||||
|
||||
let projected = serde_json::json!({
|
||||
"id": openfut_utas_host::ACTIVE_SQUAD_WIRE_ID,
|
||||
"squadName": "OpenFUT",
|
||||
"formation": "f442",
|
||||
"squadType": "REGULAR_SQUAD",
|
||||
"rating": 90,
|
||||
"chemistry": 52,
|
||||
});
|
||||
let list = openfut_adapter_fifa17::fut::squad_projection::squad_list(&projected);
|
||||
let squads = list["squad"].as_array().expect("squad list is an array");
|
||||
assert_eq!(
|
||||
squads.len(),
|
||||
1,
|
||||
"more than one advertised squad means the client can address a second \
|
||||
id, and every numeric GET/PUT collapsing onto one squad becomes wrong"
|
||||
);
|
||||
assert_eq!(
|
||||
squads[0]["id"],
|
||||
openfut_utas_host::ACTIVE_SQUAD_WIRE_ID,
|
||||
"the advertised id must be the one the client echoes back"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user