diff options
Diffstat (limited to 'tests/server_core.rs')
| -rw-r--r-- | tests/server_core.rs | 92 |
1 files changed, 44 insertions, 48 deletions
diff --git a/tests/server_core.rs b/tests/server_core.rs index 0350fb6..6b7b415 100644 --- a/tests/server_core.rs +++ b/tests/server_core.rs | |||
| @@ -4,13 +4,13 @@ use std::sync::Arc; | |||
| 4 | use rusqlite::Connection; | 4 | use rusqlite::Connection; |
| 5 | use zagan_bet::blackjack::BlackjackState; | 5 | use zagan_bet::blackjack::BlackjackState; |
| 6 | use zagan_bet::crash::CrashState; | 6 | use zagan_bet::crash::CrashState; |
| 7 | use zagan_bet::roulette::Bets; | ||
| 7 | use zagan_bet::server::core::{ConnectionState, ServerCore}; | 8 | use zagan_bet::server::core::{ConnectionState, ServerCore}; |
| 8 | use zagan_bet::server::database; | 9 | use zagan_bet::server::database; |
| 9 | use zagan_bet::server::games::crash::ManualClock; | 10 | use zagan_bet::server::games::crash::ManualClock; |
| 10 | use zagan_bet::server::games::registry::GameRegistry; | 11 | use zagan_bet::server::games::registry::GameRegistry; |
| 11 | use zagan_bet::server::games::roulette::RouletteGame; | 12 | use zagan_bet::server::games::roulette::RouletteGame; |
| 12 | use zagan_bet::server::games::slots::SlotsGame; | 13 | use zagan_bet::server::games::slots::SlotsGame; |
| 13 | use zagan_bet::roulette::Bets; | ||
| 14 | 14 | ||
| 15 | fn setup(name: &str, grid: &str) -> (ServerCore, String) { | 15 | fn setup(name: &str, grid: &str) -> (ServerCore, String) { |
| 16 | let path = PathBuf::from(env!("CARGO_TARGET_TMPDIR")) | 16 | let path = PathBuf::from(env!("CARGO_TARGET_TMPDIR")) |
| @@ -63,8 +63,7 @@ fn setup_blackjack(name: &str, deck: &[&str]) -> (ServerCore, String) { | |||
| 63 | 63 | ||
| 64 | let deck = deck.iter().map(|card| card.to_string()).collect(); | 64 | let deck = deck.iter().map(|card| card.to_string()).collect(); |
| 65 | ( | 65 | ( |
| 66 | ServerCore::with_registry(conn, GameRegistry::with_defaults(), 4) | 66 | ServerCore::with_registry(conn, GameRegistry::with_defaults(), 4).with_blackjack_deck(deck), |
| 67 | .with_blackjack_deck(deck), | ||
| 68 | path, | 67 | path, |
| 69 | ) | 68 | ) |
| 70 | } | 69 | } |
| @@ -216,7 +215,10 @@ fn plays_record_the_game_type_and_game_specific_details() { | |||
| 216 | login(&mut core, &mut state, "alice"); | 215 | login(&mut core, &mut state, "alice"); |
| 217 | 216 | ||
| 218 | let response = core.handle_message(&mut state, "PLAY_START slots 10"); | 217 | let response = core.handle_message(&mut state, "PLAY_START slots 10"); |
| 219 | assert!(response.starts_with("GAME_RESULT"), "spin failed: {response}"); | 218 | assert!( |
| 219 | response.starts_with("GAME_RESULT"), | ||
| 220 | "spin failed: {response}" | ||
| 221 | ); | ||
| 220 | 222 | ||
| 221 | let conn = Connection::open(&path).unwrap(); | 223 | let conn = Connection::open(&path).unwrap(); |
| 222 | let (game_type, details): (String, String) = conn | 224 | let (game_type, details): (String, String) = conn |
| @@ -242,8 +244,7 @@ fn roulette_settles_split_bets_and_records_details() { | |||
| 242 | register(&mut core, &mut state, "alice"); | 244 | register(&mut core, &mut state, "alice"); |
| 243 | login(&mut core, &mut state, "alice"); | 245 | login(&mut core, &mut state, "alice"); |
| 244 | 246 | ||
| 245 | let bets = | 247 | let bets = r#"{"red":10,"black":10,"even":10,"odd":10,"numbers":[{"number":17,"amount":5}]}"#; |
| 246 | r#"{"red":10,"black":10,"even":10,"odd":10,"numbers":[{"number":17,"amount":5}]}"#; | ||
| 247 | let response = core.handle_message(&mut state, &format!("PLAY_START roulette 45 {bets}")); | 248 | let response = core.handle_message(&mut state, &format!("PLAY_START roulette 45 {bets}")); |
| 248 | 249 | ||
| 249 | assert!( | 250 | assert!( |
| @@ -254,7 +255,10 @@ fn roulette_settles_split_bets_and_records_details() { | |||
| 254 | response.contains(" 220 45 1175 17 black "), | 255 | response.contains(" 220 45 1175 17 black "), |
| 255 | "response: {response}" | 256 | "response: {response}" |
| 256 | ); | 257 | ); |
| 257 | assert!(response.ends_with(&format!(" {bets}")), "response: {response}"); | 258 | assert!( |
| 259 | response.ends_with(&format!(" {bets}")), | ||
| 260 | "response: {response}" | ||
| 261 | ); | ||
| 258 | assert_eq!(core.balance("alice"), Some(1175)); | 262 | assert_eq!(core.balance("alice"), Some(1175)); |
| 259 | assert_eq!(core.play_count("alice"), 1); | 263 | assert_eq!(core.play_count("alice"), 1); |
| 260 | assert_eq!(core.session_count(), 0); | 264 | assert_eq!(core.session_count(), 0); |
| @@ -327,7 +331,10 @@ fn a_winning_spin_updates_the_balance_and_the_audit_row() { | |||
| 327 | login(&mut core, &mut state, "alice"); | 331 | login(&mut core, &mut state, "alice"); |
| 328 | 332 | ||
| 329 | let response = core.handle_message(&mut state, "PLAY_START slots 10"); | 333 | let response = core.handle_message(&mut state, "PLAY_START slots 10"); |
| 330 | assert!(response.starts_with("GAME_RESULT"), "spin failed: {response}"); | 334 | assert!( |
| 335 | response.starts_with("GAME_RESULT"), | ||
| 336 | "spin failed: {response}" | ||
| 337 | ); | ||
| 331 | assert!(response.contains(" 10 10 1000 "), "response: {response}"); | 338 | assert!(response.contains(" 10 10 1000 "), "response: {response}"); |
| 332 | assert!(response.ends_with(" win 1 0,3,6"), "response: {response}"); | 339 | assert!(response.ends_with(" win 1 0,3,6"), "response: {response}"); |
| 333 | 340 | ||
| @@ -364,11 +371,8 @@ fn a_negative_balance_is_rejected_without_wrapping() { | |||
| 364 | login(&mut core, &mut state, "alice"); | 371 | login(&mut core, &mut state, "alice"); |
| 365 | 372 | ||
| 366 | let conn = Connection::open(&path).unwrap(); | 373 | let conn = Connection::open(&path).unwrap(); |
| 367 | conn.execute( | 374 | conn.execute("UPDATE users SET balance = -5 WHERE username = 'alice'", []) |
| 368 | "UPDATE users SET balance = -5 WHERE username = 'alice'", | 375 | .unwrap(); |
| 369 | [], | ||
| 370 | ) | ||
| 371 | .unwrap(); | ||
| 372 | 376 | ||
| 373 | assert_eq!( | 377 | assert_eq!( |
| 374 | core.handle_message(&mut state, "PLAY_START slots 10"), | 378 | core.handle_message(&mut state, "PLAY_START slots 10"), |
| @@ -394,10 +398,7 @@ fn unknown_games_are_rejected_before_a_session_is_created() { | |||
| 394 | 398 | ||
| 395 | #[test] | 399 | #[test] |
| 396 | fn blackjack_reserves_the_bet_and_settles_a_hit_hand() { | 400 | fn blackjack_reserves_the_bet_and_settles_a_hit_hand() { |
| 397 | let (mut core, path) = setup_blackjack( | 401 | let (mut core, path) = setup_blackjack("blackjack-hit", &["10S", "9D", "6H", "8C", "5D"]); |
| 398 | "blackjack-hit", | ||
| 399 | &["10S", "9D", "6H", "8C", "5D"], | ||
| 400 | ); | ||
| 401 | let mut state = ConnectionState::default(); | 402 | let mut state = ConnectionState::default(); |
| 402 | register(&mut core, &mut state, "alice"); | 403 | register(&mut core, &mut state, "alice"); |
| 403 | login(&mut core, &mut state, "alice"); | 404 | login(&mut core, &mut state, "alice"); |
| @@ -442,10 +443,7 @@ fn blackjack_reserves_the_bet_and_settles_a_hit_hand() { | |||
| 442 | 443 | ||
| 443 | #[test] | 444 | #[test] |
| 444 | fn blackjack_double_reserves_an_extra_bet() { | 445 | fn blackjack_double_reserves_an_extra_bet() { |
| 445 | let (mut core, path) = setup_blackjack( | 446 | let (mut core, path) = setup_blackjack("blackjack-double", &["5S", "9D", "5H", "8C", "10D"]); |
| 446 | "blackjack-double", | ||
| 447 | &["5S", "9D", "5H", "8C", "10D"], | ||
| 448 | ); | ||
| 449 | let mut state = ConnectionState::default(); | 447 | let mut state = ConnectionState::default(); |
| 450 | register(&mut core, &mut state, "alice"); | 448 | register(&mut core, &mut state, "alice"); |
| 451 | login(&mut core, &mut state, "alice"); | 449 | login(&mut core, &mut state, "alice"); |
| @@ -483,8 +481,7 @@ fn blackjack_double_reserves_an_extra_bet() { | |||
| 483 | 481 | ||
| 484 | #[test] | 482 | #[test] |
| 485 | fn blackjack_natural_settles_immediately() { | 483 | fn blackjack_natural_settles_immediately() { |
| 486 | let (mut core, _path) = | 484 | let (mut core, _path) = setup_blackjack("blackjack-natural", &["AS", "9D", "KH", "8C"]); |
| 487 | setup_blackjack("blackjack-natural", &["AS", "9D", "KH", "8C"]); | ||
| 488 | let mut state = ConnectionState::default(); | 485 | let mut state = ConnectionState::default(); |
| 489 | register(&mut core, &mut state, "alice"); | 486 | register(&mut core, &mut state, "alice"); |
| 490 | login(&mut core, &mut state, "alice"); | 487 | login(&mut core, &mut state, "alice"); |
| @@ -501,8 +498,7 @@ fn blackjack_natural_settles_immediately() { | |||
| 501 | 498 | ||
| 502 | #[test] | 499 | #[test] |
| 503 | fn blackjack_forfeit_keeps_the_reserved_bet() { | 500 | fn blackjack_forfeit_keeps_the_reserved_bet() { |
| 504 | let (mut core, _path) = | 501 | let (mut core, _path) = setup_blackjack("blackjack-cancel", &["10S", "9D", "6H", "8C"]); |
| 505 | setup_blackjack("blackjack-cancel", &["10S", "9D", "6H", "8C"]); | ||
| 506 | let mut state = ConnectionState::default(); | 502 | let mut state = ConnectionState::default(); |
| 507 | register(&mut core, &mut state, "alice"); | 503 | register(&mut core, &mut state, "alice"); |
| 508 | login(&mut core, &mut state, "alice"); | 504 | login(&mut core, &mut state, "alice"); |
| @@ -524,8 +520,7 @@ fn blackjack_forfeit_keeps_the_reserved_bet() { | |||
| 524 | 520 | ||
| 525 | #[test] | 521 | #[test] |
| 526 | fn blackjack_disconnect_forfeits_the_reserved_bet() { | 522 | fn blackjack_disconnect_forfeits_the_reserved_bet() { |
| 527 | let (mut core, _path) = | 523 | let (mut core, _path) = setup_blackjack("blackjack-disconnect", &["10S", "9D", "6H", "8C"]); |
| 528 | setup_blackjack("blackjack-disconnect", &["10S", "9D", "6H", "8C"]); | ||
| 529 | let mut state = ConnectionState::default(); | 524 | let mut state = ConnectionState::default(); |
| 530 | register(&mut core, &mut state, "alice"); | 525 | register(&mut core, &mut state, "alice"); |
| 531 | login(&mut core, &mut state, "alice"); | 526 | login(&mut core, &mut state, "alice"); |
| @@ -578,10 +573,9 @@ fn crash_cashout_pays_the_multiplier_from_the_server_clock() { | |||
| 578 | 573 | ||
| 579 | // Five seconds of round time: 2.00x, still below the 3.00x crash point. | 574 | // Five seconds of round time: 2.00x, still below the 3.00x crash point. |
| 580 | clock.advance(5.0); | 575 | clock.advance(5.0); |
| 581 | let cashed = crash_state(&core.handle_message( | 576 | let cashed = crash_state( |
| 582 | &mut state, | 577 | &core.handle_message(&mut state, &format!("CRASH_CASHOUT {}", started.session_id)), |
| 583 | &format!("CRASH_CASHOUT {}", started.session_id), | 578 | ); |
| 584 | )); | ||
| 585 | 579 | ||
| 586 | assert_eq!(cashed.phase, "cashed"); | 580 | assert_eq!(cashed.phase, "cashed"); |
| 587 | assert_eq!(cashed.multiplier, 2.0); | 581 | assert_eq!(cashed.multiplier, 2.0); |
| @@ -600,7 +594,15 @@ fn crash_cashout_pays_the_multiplier_from_the_server_clock() { | |||
| 600 | "SELECT game_type, bet_amount, winnings, balance_after, details | 594 | "SELECT game_type, bet_amount, winnings, balance_after, details |
| 601 | FROM plays WHERE username = 'alice'", | 595 | FROM plays WHERE username = 'alice'", |
| 602 | [], | 596 | [], |
| 603 | |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?, row.get(4)?)), | 597 | |row| { |
| 598 | Ok(( | ||
| 599 | row.get(0)?, | ||
| 600 | row.get(1)?, | ||
| 601 | row.get(2)?, | ||
| 602 | row.get(3)?, | ||
| 603 | row.get(4)?, | ||
| 604 | )) | ||
| 605 | }, | ||
| 604 | ) | 606 | ) |
| 605 | .unwrap(); | 607 | .unwrap(); |
| 606 | assert_eq!(game_type, "crash"); | 608 | assert_eq!(game_type, "crash"); |
| @@ -627,10 +629,9 @@ fn a_cashout_after_the_crash_time_loses_the_reserved_bet() { | |||
| 627 | let started = crash_state(&core.handle_message(&mut state, "PLAY_START crash 10")); | 629 | let started = crash_state(&core.handle_message(&mut state, "PLAY_START crash 10")); |
| 628 | 630 | ||
| 629 | clock.advance(20.0); | 631 | clock.advance(20.0); |
| 630 | let late = crash_state(&core.handle_message( | 632 | let late = crash_state( |
| 631 | &mut state, | 633 | &core.handle_message(&mut state, &format!("CRASH_CASHOUT {}", started.session_id)), |
| 632 | &format!("CRASH_CASHOUT {}", started.session_id), | 634 | ); |
| 633 | )); | ||
| 634 | 635 | ||
| 635 | assert_eq!(late.phase, "crashed"); | 636 | assert_eq!(late.phase, "crashed"); |
| 636 | assert_eq!(late.payout, 0); | 637 | assert_eq!(late.payout, 0); |
| @@ -679,10 +680,9 @@ fn crash_forfeit_keeps_the_reserved_bet() { | |||
| 679 | login(&mut core, &mut state, "alice"); | 680 | login(&mut core, &mut state, "alice"); |
| 680 | 681 | ||
| 681 | let started = crash_state(&core.handle_message(&mut state, "PLAY_START crash 10")); | 682 | let started = crash_state(&core.handle_message(&mut state, "PLAY_START crash 10")); |
| 682 | let forfeited = crash_state(&core.handle_message( | 683 | let forfeited = crash_state( |
| 683 | &mut state, | 684 | &core.handle_message(&mut state, &format!("CRASH_FORFEIT {}", started.session_id)), |
| 684 | &format!("CRASH_FORFEIT {}", started.session_id), | 685 | ); |
| 685 | )); | ||
| 686 | 686 | ||
| 687 | assert_eq!(forfeited.phase, "forfeit"); | 687 | assert_eq!(forfeited.phase, "forfeit"); |
| 688 | assert_eq!(forfeited.payout, 0); | 688 | assert_eq!(forfeited.payout, 0); |
| @@ -747,10 +747,7 @@ fn crash_rounds_are_owned_by_the_player_who_started_them() { | |||
| 747 | 747 | ||
| 748 | clock.advance(5.0); | 748 | clock.advance(5.0); |
| 749 | assert_eq!( | 749 | assert_eq!( |
| 750 | core.handle_message( | 750 | core.handle_message(&mut bob, &format!("CRASH_CASHOUT {}", started.session_id)), |
| 751 | &mut bob, | ||
| 752 | &format!("CRASH_CASHOUT {}", started.session_id) | ||
| 753 | ), | ||
| 754 | "ERROR Invalid session" | 751 | "ERROR Invalid session" |
| 755 | ); | 752 | ); |
| 756 | assert_eq!(core.balance("bob"), Some(1000)); | 753 | assert_eq!(core.balance("bob"), Some(1000)); |
| @@ -775,10 +772,9 @@ fn a_crash_reservation_is_durable_until_the_round_settles() { | |||
| 775 | drop(conn); | 772 | drop(conn); |
| 776 | 773 | ||
| 777 | clock.advance(5.0); | 774 | clock.advance(5.0); |
| 778 | let cashed = crash_state(&core.handle_message( | 775 | let cashed = crash_state( |
| 779 | &mut state, | 776 | &core.handle_message(&mut state, &format!("CRASH_CASHOUT {}", started.session_id)), |
| 780 | &format!("CRASH_CASHOUT {}", started.session_id), | 777 | ); |
| 781 | )); | ||
| 782 | assert_eq!(cashed.phase, "cashed"); | 778 | assert_eq!(cashed.phase, "cashed"); |
| 783 | 779 | ||
| 784 | let conn = Connection::open(&path).unwrap(); | 780 | let conn = Connection::open(&path).unwrap(); |
