test(fifa17): update squad_projection integration test to ownership-backed manager

The manager moved from an opaque extension field to an ownership-backed
canonical assignment: SquadProjectionInput.manager (owned item) replaces
Fifa17SquadExtensionV1.manager.

- project_put stand-in passes manager: None; baseline asserts the manager
  projects empty when none is owned.
- persisted_read registers the manager's owned instance + identity and
  passes it as the assignment, asserting the resolved [{id,dream}] ref
  round-trips to the read oracle's manager.
This commit is contained in:
funman300
2026-08-20 17:38:32 +00:00
parent 9ddd80993c
commit 56bd9ddc85
@@ -11,8 +11,9 @@
//! ``` //! ```
//! //!
//! Fidelity is asserted by ownership class: //! Fidelity is asserted by ownership class:
//! CANONICAL player instance per index, formation, captain, bench split //! CANONICAL player instance per index, formation, captain, bench split, and
//! EXTENSION custom, kicktakers, manager, kit numbers (by player), squadType //! the ownership-backed manager assignment (migration 0023)
//! EXTENSION custom, kicktakers, kit numbers (by player), squadType
//! SHADOW chemistry/rating/starRating (client-reported, round-tripped as-is) //! SHADOW chemistry/rating/starRating (client-reported, round-tripped as-is)
//! DERIVED correct FIFA 17 item identity (wire id + resourceId) //! DERIVED correct FIFA 17 item identity (wire id + resourceId)
//! //!
@@ -146,6 +147,9 @@ fn project_put(
slots, slots,
ext: SquadExtInput::Fresh(extension), ext: SquadExtInput::Fresh(extension),
owned, owned,
// This stand-in supplies no owned manager; the manager is projected from
// the ownership-backed assignment, exercised in persisted_read below.
manager: None,
}; };
match project_squad(&input, ident, &NoEntities).unwrap() { match project_squad(&input, ident, &NoEntities).unwrap() {
SquadProjection::Projected(v) => v, SquadProjection::Projected(v) => v,
@@ -194,9 +198,11 @@ fn baseline_projects_the_known_squad_round_trip() {
projected["captain"], 100000001, projected["captain"], 100000001,
"captain is the player's WIRE id" "captain is the player's WIRE id"
); );
// EXTENSION: custom byte-identical, manager + squadType preserved. // EXTENSION: custom byte-identical, squadType preserved. The manager is now
// an ownership-backed assignment (not projected from the PUT/ext); with none
// supplied to this stand-in it projects empty.
assert_eq!(projected["custom"], put_v["custom"]); assert_eq!(projected["custom"], put_v["custom"]);
assert_eq!(projected["manager"], put_v["manager"]); assert!(projected["manager"].as_array().unwrap().is_empty());
assert_eq!(projected["squadType"], "REGULAR_SQUAD"); assert_eq!(projected["squadType"], "REGULAR_SQUAD");
// SHADOW: client-reported values carried as-is (baseline chemistry 52). // SHADOW: client-reported values carried as-is (baseline chemistry 52).
assert_eq!(projected["chemistry"], 52); assert_eq!(projected["chemistry"], 52);
@@ -268,13 +274,11 @@ fn persisted_read_round_trips_via_reconstructed_canonical_and_extension() {
// evidence, then project and require the read back — the strongest fidelity // evidence, then project and require the read back — the strongest fidelity
// check across all four ownership classes. // check across all four ownership classes.
use openfut_adapter_fifa17::fut::squad::ClientReportedSquadEval; use openfut_adapter_fifa17::fut::squad::ClientReportedSquadEval;
use openfut_adapter_fifa17::fut::squad_ext::{ use openfut_adapter_fifa17::fut::squad_ext::{Fifa17SquadExtensionV1, KicktakerRef};
Fifa17SquadExtensionV1, KicktakerRef, WireItemRef,
};
use std::collections::BTreeMap; use std::collections::BTreeMap;
let oracle: Value = serde_json::from_str(READ_ORACLE).unwrap(); let oracle: Value = serde_json::from_str(READ_ORACLE).unwrap();
let (owned, ident) = oracle_tables(); let (owned, mut ident) = oracle_tables();
let captain = oracle["captain"].as_i64().unwrap(); let captain = oracle["captain"].as_i64().unwrap();
let mut slots = Vec::new(); let mut slots = Vec::new();
@@ -294,14 +298,35 @@ fn persisted_read_round_trips_via_reconstructed_canonical_and_extension() {
is_on_bench: index >= 11, is_on_bench: index >= 11,
}); });
} }
let manager: Vec<WireItemRef> = serde_json::from_value(oracle["manager"].clone()).unwrap(); // The manager is now ownership-backed: register its owned instance + identity
// and pass it as the assignment, not as an opaque extension field.
let mgr_wire = oracle["manager"][0]["id"].as_i64().unwrap();
let mgr_oc = format!("oc-{mgr_wire}");
ident.0.insert(
mgr_oc.clone(),
Fifa17Identity {
item_id: mgr_wire as u32,
asset_id: 5001,
resource_id: 5001,
rareflag: 1,
},
);
let manager_item = CoreOwnedItem {
owned_card_id: mgr_oc,
card_id: "def-manager".to_string(),
rating: 0,
position: String::new(),
nation: String::new(),
league: String::new(),
club: String::new(),
attributes: [0; 6],
};
let kicktakers: Vec<KicktakerRef> = let kicktakers: Vec<KicktakerRef> =
serde_json::from_value(oracle["kicktakers"].clone()).unwrap(); serde_json::from_value(oracle["kicktakers"].clone()).unwrap();
let ext = Fifa17SquadExtensionV1 { let ext = Fifa17SquadExtensionV1 {
custom: oracle["custom"].as_str().map(str::to_string), custom: oracle["custom"].as_str().map(str::to_string),
squad_type: oracle["squadType"].as_str().map(str::to_string), squad_type: oracle["squadType"].as_str().map(str::to_string),
kit_numbers, kit_numbers,
manager,
kicktakers, kicktakers,
client_reported: ClientReportedSquadEval { client_reported: ClientReportedSquadEval {
chemistry: oracle["chemistry"].as_i64(), chemistry: oracle["chemistry"].as_i64(),
@@ -316,6 +341,7 @@ fn persisted_read_round_trips_via_reconstructed_canonical_and_extension() {
slots, slots,
ext: SquadExtInput::Fresh(ext), ext: SquadExtInput::Fresh(ext),
owned: &owned, owned: &owned,
manager: Some(manager_item),
}; };
let SquadProjection::Projected(projected) = project_squad(&input, &ident, &NoEntities).unwrap() let SquadProjection::Projected(projected) = project_squad(&input, &ident, &NoEntities).unwrap()
else { else {