diff options
Diffstat (limited to '')
| -rw-r--r-- | tests/server_core.rs | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/tests/server_core.rs b/tests/server_core.rs index cf05102..3ad277a 100644 --- a/tests/server_core.rs +++ b/tests/server_core.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use std::path::PathBuf; | 1 | use std::path::PathBuf; |
| 2 | 2 | ||
| 3 | use rusqlite::Connection; | 3 | use rusqlite::Connection; |
| 4 | use zagan_bet::blackjack::BlackjackState; | ||
| 4 | use zagan_bet::server::core::{ConnectionState, ServerCore}; | 5 | use zagan_bet::server::core::{ConnectionState, ServerCore}; |
| 5 | use zagan_bet::server::database; | 6 | use zagan_bet::server::database; |
| 6 | use zagan_bet::server::games::registry::GameRegistry; | 7 | use zagan_bet::server::games::registry::GameRegistry; |
| @@ -47,6 +48,31 @@ fn setup_roulette(name: &str, number: u8) -> (ServerCore, String) { | |||
| 47 | (ServerCore::with_registry(conn, registry, 4), path) | 48 | (ServerCore::with_registry(conn, registry, 4), path) |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 51 | fn setup_blackjack(name: &str, deck: &[&str]) -> (ServerCore, String) { | ||
| 52 | let path = PathBuf::from(env!("CARGO_TARGET_TMPDIR")) | ||
| 53 | .join(format!("server-core-{name}.db")) | ||
| 54 | .to_string_lossy() | ||
| 55 | .into_owned(); | ||
| 56 | let _ = std::fs::remove_file(&path); | ||
| 57 | |||
| 58 | let conn = Connection::open(&path).unwrap(); | ||
| 59 | database::init_db(&conn); | ||
| 60 | |||
| 61 | let deck = deck.iter().map(|card| card.to_string()).collect(); | ||
| 62 | ( | ||
| 63 | ServerCore::with_registry(conn, GameRegistry::with_defaults(), 4) | ||
| 64 | .with_blackjack_deck(deck), | ||
| 65 | path, | ||
| 66 | ) | ||
| 67 | } | ||
| 68 | |||
| 69 | fn blackjack_state(response: &str) -> BlackjackState { | ||
| 70 | let raw = response | ||
| 71 | .strip_prefix("BLACKJACK_STATE ") | ||
| 72 | .expect("blackjack state response"); | ||
| 73 | serde_json::from_str(raw).expect("valid blackjack state") | ||
| 74 | } | ||
| 75 | |||
| 50 | fn register(core: &mut ServerCore, state: &mut ConnectionState, user: &str) { | 76 | fn register(core: &mut ServerCore, state: &mut ConnectionState, user: &str) { |
| 51 | assert_eq!( | 77 | assert_eq!( |
| 52 | core.handle_message(state, &format!("REGISTER {user} credential")), | 78 | core.handle_message(state, &format!("REGISTER {user} credential")), |
| @@ -337,3 +363,136 @@ fn unknown_games_are_rejected_before_a_session_is_created() { | |||
| 337 | ); | 363 | ); |
| 338 | assert_eq!(core.session_count(), 0); | 364 | assert_eq!(core.session_count(), 0); |
| 339 | } | 365 | } |
| 366 | |||
| 367 | #[test] | ||
| 368 | fn blackjack_reserves_the_bet_and_settles_a_hit_hand() { | ||
| 369 | let (mut core, path) = setup_blackjack( | ||
| 370 | "blackjack-hit", | ||
| 371 | &["10S", "9D", "6H", "8C", "5D"], | ||
| 372 | ); | ||
| 373 | let mut state = ConnectionState::default(); | ||
| 374 | register(&mut core, &mut state, "alice"); | ||
| 375 | login(&mut core, &mut state, "alice"); | ||
| 376 | |||
| 377 | let response = core.handle_message(&mut state, "PLAY_START blackjack 10"); | ||
| 378 | let current = blackjack_state(&response); | ||
| 379 | |||
| 380 | assert_eq!(current.phase, "player"); | ||
| 381 | assert_eq!(current.player_total, 16); | ||
| 382 | assert_eq!(current.dealer, vec!["9D".to_string(), "?".to_string()]); | ||
| 383 | assert_eq!(current.balance, 990); | ||
| 384 | assert_eq!(current.actions, vec!["hit", "stand", "double"]); | ||
| 385 | assert_eq!(core.session_count(), 1); | ||
| 386 | |||
| 387 | let response = core.handle_message( | ||
| 388 | &mut state, | ||
| 389 | &format!("BLACKJACK_ACTION {} hit", current.session_id), | ||
| 390 | ); | ||
| 391 | let done = blackjack_state(&response); | ||
| 392 | |||
| 393 | assert_eq!(done.phase, "done"); | ||
| 394 | assert_eq!(done.result, "win"); | ||
| 395 | assert_eq!(done.winnings, 20); | ||
| 396 | assert_eq!(done.balance, 1010); | ||
| 397 | assert_eq!(core.balance("alice"), Some(1010)); | ||
| 398 | assert_eq!(core.play_count("alice"), 1); | ||
| 399 | assert_eq!(core.session_count(), 0); | ||
| 400 | |||
| 401 | let conn = Connection::open(&path).unwrap(); | ||
| 402 | let (game_type, details): (String, String) = conn | ||
| 403 | .query_row( | ||
| 404 | "SELECT game_type, details FROM plays WHERE username = 'alice'", | ||
| 405 | [], | ||
| 406 | |row| Ok((row.get(0)?, row.get(1)?)), | ||
| 407 | ) | ||
| 408 | .unwrap(); | ||
| 409 | assert_eq!(game_type, "blackjack"); | ||
| 410 | let details: BlackjackState = serde_json::from_str(&details).unwrap(); | ||
| 411 | assert_eq!(details.result, "win"); | ||
| 412 | assert_eq!(details.winnings, 20); | ||
| 413 | } | ||
| 414 | |||
| 415 | #[test] | ||
| 416 | fn blackjack_double_reserves_an_extra_bet() { | ||
| 417 | let (mut core, _path) = setup_blackjack( | ||
| 418 | "blackjack-double", | ||
| 419 | &["5S", "9D", "5H", "8C", "10D"], | ||
| 420 | ); | ||
| 421 | let mut state = ConnectionState::default(); | ||
| 422 | register(&mut core, &mut state, "alice"); | ||
| 423 | login(&mut core, &mut state, "alice"); | ||
| 424 | |||
| 425 | let current = blackjack_state(&core.handle_message(&mut state, "PLAY_START blackjack 10")); | ||
| 426 | assert_eq!(current.balance, 990); | ||
| 427 | |||
| 428 | let done = blackjack_state(&core.handle_message( | ||
| 429 | &mut state, | ||
| 430 | &format!("BLACKJACK_ACTION {} double", current.session_id), | ||
| 431 | )); | ||
| 432 | |||
| 433 | assert_eq!(done.phase, "done"); | ||
| 434 | assert_eq!(done.bet, 20); | ||
| 435 | assert_eq!(done.winnings, 40); | ||
| 436 | assert_eq!(done.balance, 1020); | ||
| 437 | assert_eq!(core.balance("alice"), Some(1020)); | ||
| 438 | assert_eq!(core.play_count("alice"), 1); | ||
| 439 | } | ||
| 440 | |||
| 441 | #[test] | ||
| 442 | fn blackjack_natural_settles_immediately() { | ||
| 443 | let (mut core, _path) = | ||
| 444 | setup_blackjack("blackjack-natural", &["AS", "9D", "KH", "8C"]); | ||
| 445 | let mut state = ConnectionState::default(); | ||
| 446 | register(&mut core, &mut state, "alice"); | ||
| 447 | login(&mut core, &mut state, "alice"); | ||
| 448 | |||
| 449 | let done = blackjack_state(&core.handle_message(&mut state, "PLAY_START blackjack 10")); | ||
| 450 | |||
| 451 | assert_eq!(done.phase, "done"); | ||
| 452 | assert_eq!(done.result, "blackjack"); | ||
| 453 | assert_eq!(done.winnings, 25); | ||
| 454 | assert_eq!(done.balance, 1015); | ||
| 455 | assert_eq!(core.session_count(), 0); | ||
| 456 | assert_eq!(core.play_count("alice"), 1); | ||
| 457 | } | ||
| 458 | |||
| 459 | #[test] | ||
| 460 | fn blackjack_cancel_refunds_the_reserved_bet() { | ||
| 461 | let (mut core, _path) = | ||
| 462 | setup_blackjack("blackjack-cancel", &["10S", "9D", "6H", "8C"]); | ||
| 463 | let mut state = ConnectionState::default(); | ||
| 464 | register(&mut core, &mut state, "alice"); | ||
| 465 | login(&mut core, &mut state, "alice"); | ||
| 466 | |||
| 467 | let current = blackjack_state(&core.handle_message(&mut state, "PLAY_START blackjack 10")); | ||
| 468 | assert_eq!(current.balance, 990); | ||
| 469 | |||
| 470 | let cancelled = blackjack_state(&core.handle_message( | ||
| 471 | &mut state, | ||
| 472 | &format!("BLACKJACK_ACTION {} cancel", current.session_id), | ||
| 473 | )); | ||
| 474 | |||
| 475 | assert_eq!(cancelled.result, "cancelled"); | ||
| 476 | assert_eq!(cancelled.balance, 1000); | ||
| 477 | assert_eq!(core.balance("alice"), Some(1000)); | ||
| 478 | assert_eq!(core.play_count("alice"), 0); | ||
| 479 | assert_eq!(core.session_count(), 0); | ||
| 480 | } | ||
| 481 | |||
| 482 | #[test] | ||
| 483 | fn blackjack_disconnect_refunds_the_reserved_bet() { | ||
| 484 | let (mut core, _path) = | ||
| 485 | setup_blackjack("blackjack-disconnect", &["10S", "9D", "6H", "8C"]); | ||
| 486 | let mut state = ConnectionState::default(); | ||
| 487 | register(&mut core, &mut state, "alice"); | ||
| 488 | login(&mut core, &mut state, "alice"); | ||
| 489 | |||
| 490 | let current = blackjack_state(&core.handle_message(&mut state, "PLAY_START blackjack 10")); | ||
| 491 | assert_eq!(current.balance, 990); | ||
| 492 | |||
| 493 | core.disconnect(&state); | ||
| 494 | |||
| 495 | assert_eq!(core.balance("alice"), Some(1000)); | ||
| 496 | assert_eq!(core.play_count("alice"), 0); | ||
| 497 | assert_eq!(core.session_count(), 0); | ||
| 498 | } | ||
