Migrate club rename and numeric squad reads
This commit is contained in:
@@ -451,10 +451,8 @@ fn economy_sequence(base: &str, dir: &std::path::Path) -> SeqResult {
|
||||
"POST",
|
||||
"/ut/game/fifa17/auctionhouse",
|
||||
&[],
|
||||
format!(
|
||||
r#"{{"itemData":{{"id":{list_wire}}},"buyNowPrice":1000,"startingBid":500}}"#
|
||||
)
|
||||
.as_bytes(),
|
||||
format!(r#"{{"itemData":{{"id":{list_wire}}},"buyNowPrice":1000,"startingBid":500}}"#)
|
||||
.as_bytes(),
|
||||
None,
|
||||
)
|
||||
.expect("market list routed");
|
||||
@@ -767,6 +765,10 @@ fn from_config(base: &str, dir: &std::path::Path) -> openfut_utas_host::config::
|
||||
market_db_path: dir.join("market.db").to_string_lossy().into_owned(),
|
||||
pile_db_path: dir.join("pile.db").to_string_lossy().into_owned(),
|
||||
clientdata_path: dir.join("clientdata.json").to_string_lossy().into_owned(),
|
||||
account_path: dir
|
||||
.join("active_account.json")
|
||||
.to_string_lossy()
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ use openfut_adapter_fifa17::fut::catalog::Fifa17CardCatalog;
|
||||
use openfut_adapter_fifa17::fut::club_response::{CoreOwnedItem, ItemIdentityResolver};
|
||||
use openfut_adapter_fifa17::fut::entities::Fifa17Entities;
|
||||
use openfut_identity::JsonIdentityStore;
|
||||
use openfut_utas_host::account_store::AccountStore;
|
||||
use openfut_utas_host::{
|
||||
classify, handle_club, handle_put_squad, handle_squad_active, handle_squad_list,
|
||||
handle_user_mass_info, read_request, ClubDeps, CoreAccess, CoreError, CoreExtState, CorePage,
|
||||
@@ -302,9 +303,33 @@ fn resolver_for(cards: &[(&str, u32)]) -> Arc<Fifa17IdentityResolver> {
|
||||
fn club_excludes_listed_items_and_paginates_the_visible_set() {
|
||||
let core = Arc::new(FakeCore::new(
|
||||
vec![
|
||||
item("oc1", "card_a", 86, "CDM", "Argentina", "Premier League", "Chelsea"),
|
||||
item("oc2", "card_b", 85, "ST", "Argentina", "Premier League", "Chelsea"),
|
||||
item("oc3", "card_c", 84, "CB", "Argentina", "Premier League", "Chelsea"),
|
||||
item(
|
||||
"oc1",
|
||||
"card_a",
|
||||
86,
|
||||
"CDM",
|
||||
"Argentina",
|
||||
"Premier League",
|
||||
"Chelsea",
|
||||
),
|
||||
item(
|
||||
"oc2",
|
||||
"card_b",
|
||||
85,
|
||||
"ST",
|
||||
"Argentina",
|
||||
"Premier League",
|
||||
"Chelsea",
|
||||
),
|
||||
item(
|
||||
"oc3",
|
||||
"card_c",
|
||||
84,
|
||||
"CB",
|
||||
"Argentina",
|
||||
"Premier League",
|
||||
"Chelsea",
|
||||
),
|
||||
],
|
||||
3,
|
||||
));
|
||||
@@ -502,21 +527,43 @@ fn passthrough_forwards_verbatim_and_never_calls_core() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mutating_route_classifies_to_passthrough_not_rust() {
|
||||
// A PUT to the club PATH is NOT the read route; it must go to Python, never
|
||||
// execute Rust/Core (guards against double-applying a mutation).
|
||||
assert_eq!(classify("PUT", "/ut/game/fifa17/club"), Route::Passthrough);
|
||||
fn club_rename_is_rust_owned_persistent_and_never_calls_python_or_core() {
|
||||
assert_eq!(classify("PUT", "/ut/game/fifa17/club"), Route::ClubRename);
|
||||
assert_eq!(
|
||||
classify("PUT", "/ut/game/fifa17/user/club"),
|
||||
Route::ClubRename
|
||||
);
|
||||
assert_eq!(
|
||||
classify("POST", "/ut/game/fifa17/user/club"),
|
||||
Route::ClubRename
|
||||
);
|
||||
assert_eq!(
|
||||
classify("POST", "/ut/game/fifa17/squad/0"),
|
||||
Route::Passthrough
|
||||
);
|
||||
|
||||
let (upstream, _rec) = spawn_mock_python();
|
||||
let (upstream, rec) = spawn_mock_python();
|
||||
let core = Arc::new(FakeCore::forbidden());
|
||||
let server = build_server(core.clone(), &upstream, None);
|
||||
let resp = server.handle("PUT", "/ut/game/fifa17/club", &[], br#"{"x":1}"#);
|
||||
let account_path = unique_store_path();
|
||||
let account = Arc::new(AccountStore::open(&account_path));
|
||||
let server = build_server(core.clone(), &upstream, None).with_account(account.clone());
|
||||
let resp = server.handle(
|
||||
"PUT",
|
||||
"/ut/game/fifa17/user/club",
|
||||
&[],
|
||||
br#"{"clubName":"Real FUT","clubAbbr":"RF"}"#,
|
||||
);
|
||||
assert_eq!(resp.status, 200);
|
||||
assert_eq!(
|
||||
serde_json::from_slice::<Value>(&resp.body).unwrap(),
|
||||
json!({})
|
||||
);
|
||||
assert_eq!(account.club().name, "Real FUT");
|
||||
assert_eq!(account.club().abbr, "RF");
|
||||
assert_eq!(AccountStore::open(&account_path).club(), account.club());
|
||||
assert_eq!(core.calls(), 0);
|
||||
assert_eq!(rec.lock().len(), 0, "rename never reached Python");
|
||||
let _ = std::fs::remove_file(account_path);
|
||||
}
|
||||
|
||||
// ── End-to-end over a socket (read_request + write_response + keep-alive) ─────
|
||||
@@ -874,9 +921,8 @@ fn classify_squad_and_usermassinfo_routes() {
|
||||
classify("GET", "/ut/game/fifa17/userMassInfo"),
|
||||
Route::UserMassInfo
|
||||
);
|
||||
// GET /squad/active is now Core-backed (SquadActive). A squad PUT is never a
|
||||
// GET. GET /squad/0 IS the active squad (id 0) -> SquadActive; a numeric
|
||||
// GET /squad/<n> for a NON-active squad (n != 0) stays on Python.
|
||||
// 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.
|
||||
assert_eq!(
|
||||
classify("GET", "/ut/game/fifa17/squad/active"),
|
||||
Route::SquadActive
|
||||
@@ -891,7 +937,7 @@ fn classify_squad_and_usermassinfo_routes() {
|
||||
);
|
||||
assert_eq!(
|
||||
classify("GET", "/ut/game/fifa17/squad/5"),
|
||||
Route::Passthrough
|
||||
Route::SquadActive
|
||||
);
|
||||
assert_eq!(
|
||||
classify("PUT", "/ut/game/fifa17/squad/list"),
|
||||
@@ -900,6 +946,39 @@ fn classify_squad_and_usermassinfo_routes() {
|
||||
assert_eq!(classify("GET", "/ut/game/fifa17/club"), Route::Club);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numbered_squad_get_returns_current_core_squad_without_python() {
|
||||
let items = vec![gk(), st()];
|
||||
let (resolver, wires) = resolver_with_wires(&items, ASSETS);
|
||||
let core = Arc::new(FakeCore::new(items, 2));
|
||||
let (python, recorded) = spawn_mock_python();
|
||||
let server = Server::new(
|
||||
core,
|
||||
Arc::new(entities()),
|
||||
Arc::new(resolver),
|
||||
Arc::new(PassClient::new(&python)),
|
||||
33_068_179,
|
||||
);
|
||||
let put = server.handle(
|
||||
"PUT",
|
||||
"/ut/game/fifa17/squad/0",
|
||||
&[],
|
||||
&put_body(
|
||||
"f442",
|
||||
wires["oc-a"],
|
||||
&[(0, wires["oc-a"], 1), (1, wires["oc-b"], 9)],
|
||||
"[1,2,3]",
|
||||
),
|
||||
);
|
||||
assert_eq!(put.status, 200);
|
||||
|
||||
let active = server.handle("GET", "/ut/game/fifa17/squad/active", &[], b"");
|
||||
let numbered = server.handle("GET", "/ut/game/fifa17/squad/5", &[], b"");
|
||||
assert_eq!(numbered.status, 200);
|
||||
assert_eq!(numbered.body, active.body);
|
||||
assert_eq!(recorded.lock().len(), 0, "numeric GET never reached Python");
|
||||
}
|
||||
|
||||
// ── PUT pipeline ────────────────────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user