Phase 25: division leaderboard, market trade history
CI / Build, lint & test (push) Failing after 2m10s
CI / Build, lint & test (push) Failing after 2m10s
- Market: record buy/sell history in market_history table; expose via GET /market/trade-history (last 30 events, newest first) - Division: GET /division/leaderboard returns 10-club table with 9 seeded NPC entries + player row, sorted by pts; stable within a season - rand feature small_rng enabled in Cargo.toml for SmallRng use - 3 new integration tests (leaderboard count, sort order, empty trade history) - Core: 96 tests passing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1850,3 +1850,50 @@ async fn test_milestones_endpoint_structure() {
|
||||
assert!(json["sbcs_completed"].is_number());
|
||||
assert!(json["total_checkins"].is_number());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_leaderboard_has_ten_clubs() {
|
||||
let app = build_test_app().await;
|
||||
auth(&app, "LeaderboardPlayer").await;
|
||||
|
||||
let (status, json) = json_get(&app, "/division/leaderboard").await;
|
||||
assert_eq!(status, StatusCode::OK, "{json}");
|
||||
let table = json["leaderboard"].as_array().unwrap();
|
||||
assert_eq!(table.len(), 10, "leaderboard should have 10 clubs (9 NPC + player)");
|
||||
|
||||
// Exactly one entry should be the player's club
|
||||
let player_entries: Vec<_> = table.iter().filter(|e| e["is_player"].as_bool() == Some(true)).collect();
|
||||
assert_eq!(player_entries.len(), 1, "exactly one player club entry");
|
||||
assert!(json["division"].is_number());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_leaderboard_sorted_by_pts() {
|
||||
let app = build_test_app().await;
|
||||
auth(&app, "SortedLeader").await;
|
||||
|
||||
let (_, json) = json_get(&app, "/division/leaderboard").await;
|
||||
let table = json["leaderboard"].as_array().unwrap();
|
||||
let pts: Vec<i64> = table.iter().map(|e| e["pts"].as_i64().unwrap_or(0)).collect();
|
||||
let sorted = {
|
||||
let mut s = pts.clone();
|
||||
s.sort_by(|a, b| b.cmp(a));
|
||||
s
|
||||
};
|
||||
assert_eq!(pts, sorted, "leaderboard should be sorted by pts desc");
|
||||
// Positions should be sequential
|
||||
for (i, entry) in table.iter().enumerate() {
|
||||
assert_eq!(entry["position"].as_i64().unwrap_or(-1), (i + 1) as i64);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_trade_history_empty_initially() {
|
||||
let app = build_test_app().await;
|
||||
auth(&app, "TradeHistPlayer").await;
|
||||
|
||||
let (status, json) = json_get(&app, "/market/trade-history").await;
|
||||
assert_eq!(status, StatusCode::OK, "{json}");
|
||||
assert!(json["trades"].is_array());
|
||||
assert_eq!(json["trades"].as_array().unwrap().len(), 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user