From 0a7edadca401221f4391e4356e62f042b915a63f Mon Sep 17 00:00:00 2001 From: Dan Chiarlone Date: Fri, 5 Jan 2024 11:20:46 -0800 Subject: [PATCH] Add tests (#79) * added tests to error_logs and pidgtm_compile_times Signed-off-by: danbugs * fix && fmt Signed-off-by: danbugs * added tests to game, player, player_page_views, set, and tournament Signed-off-by: danbugs * fix && fmt Signed-off-by: danbugs * modified CI to run tests Signed-off-by: danbugs * fix CI Signed-off-by: danbugs * fix CI Signed-off-by: danbugs * added codecov, fixed CI Signed-off-by: danbugs * fixing typo Signed-off-by: danbugs * trying cargo test Signed-off-by: danbugs * fixing typo Signed-off-by: danbugs * fixing typo Signed-off-by: danbugs * fixed CI Signed-off-by: danbugs * fix && fmt Signed-off-by: danbugs --------- Signed-off-by: danbugs --- .codecov.yml | 15 ++ .github/workflows/ci-cd.yml | 45 ++++- .gitignore | 3 +- README.md | 2 +- backend/src/main.rs | 16 -- database/src/db_models/set.rs | 2 +- database/src/lib.rs | 1 + lib/Cargo.toml | 5 +- lib/src/common.rs | 114 ++++++++++++- lib/src/error_logs.rs | 34 ++++ lib/src/game.rs | 56 +++++- lib/src/pidgtm_compile_times.rs | 28 +++ lib/src/player.rs | 197 +++++++++++++++++++++- lib/src/player_page_views.rs | 28 +++ lib/src/set.rs | 129 +++++++++++++- lib/src/tournament.rs | 117 ++++++++++++- src/pidgtm/compile.rs | 17 -- startgg_api/src/lib.rs | 2 +- startgg_api/src/queries/event_getter.rs | 1 + startgg_api/src/queries/player_getter.rs | 1 + startgg_api/src/queries/seeding_getter.rs | 1 + startgg_api/src/queries/set_getter.rs | 1 + 22 files changed, 748 insertions(+), 67 deletions(-) create mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..067aebe --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,15 @@ +--- +codecov: + notify: + after_n_builds: 1 + require_ci_to_pass: false + +coverage: + precision: 2 + round: down + range: 5..20 + +comment: + layout: "header, diff" + behavior: default + require_changes: false \ No newline at end of file diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 2051a65..f950e5d 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -60,6 +60,7 @@ jobs: name: Install PostgreSQL uses: ikalnytskyi/action-setup-postgres@v4 + # This test is necessary to run cross build - if: matrix.os == 'ubuntu-latest' name: Install QEMU user emulation run: docker run --rm --privileged tonistiigi/binfmt --install all @@ -74,7 +75,15 @@ jobs: profile: minimal toolchain: stable override: true - target: ${{ matrix.target }} + target: ${{ matrix.target }} + + # We use cargo-llvm-cov for tests rather than cargo test to also evaluate test coverage + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@v1 + with: + tool: cargo-llvm-cov + - name: Install llvm-tools-preview for cargo-llvm-cov + run: rustup component add llvm-tools-preview - name: Cache Rust targets uses: actions/cache@v3 @@ -85,7 +94,32 @@ jobs: target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - ${{ runner.os }}-cargo- + ${{ runner.os }}-cargo- + + - name: Build + run: cargo build --release --all + env: + SERVER_ADDRESS: 'http://127.0.0.1:8080' + SERVER_ADDRESS_2: ${{ secrets.SERVER_ADDRESS_2 }} + RECAPTCHA_SITE_KEY: ${{ secrets.RECAPTCHA_SITE_KEY }} + # ^^^ the front-end looks for keys at compile time, so we need these in + + # We need `--test-threads=1` due to a Diesel/postgres bug + - name: Run tests and get coverage + run: | + cargo llvm-cov clean --workspace + cargo llvm-cov --no-report --package smithe_lib --no-default-features -- --exact --nocapture --test-threads=1 + cargo llvm-cov report --lcov --output-path ./coverage.lcov + env: + PIDGTM_DATABASE_URL: ${{ secrets.PIDGTM_DATABASE_URL }} + STARTGG_TOKEN: ${{ secrets.STARTGG_TOKEN }} + + - name: Upload Code Coverage Results + uses: codecov/codecov-action@v3 + with: + file: ./coverage.lcov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # Conditional step for standard Rust build for non-arm64 targets - if: matrix.os == 'ubuntu-latest' @@ -95,12 +129,7 @@ jobs: ls -la target/aarch64-unknown-linux-gnu/ env: SERVER_ADDRESS: 'http://127.0.0.1:8080' - CROSS_CONTAINER_OPTS: '--platform linux/arm64' - - - name: Build - run: cargo build --release --target ${{ matrix.target }} - env: - SERVER_ADDRESS: 'http://127.0.0.1:8080' + CROSS_CONTAINER_OPTS: '--platform linux/arm64' - if: matrix.os == 'ubuntu-latest' name: Upload arm64 pidgtm artifact diff --git a/.gitignore b/.gitignore index d9de290..23fd849 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ test.out frontend/dist tokens.txt -id_ranges.txt \ No newline at end of file +id_ranges.txt +coverage.lcov \ No newline at end of file diff --git a/README.md b/README.md index 913ccff..59a2c6b 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ In the future, I hope to make it possible for you to claim your profile (i.e., v ## What Can It Do Right Now? Smithereens is not yet available as a website, only as a command-line tool. With it, you can: -- ✅ view the hidden seeding for an event, +- ✅ view the hidden seeding for an event (only in the CLI), - ✅ view a player's overall results, - ✅ view a 'digested' tournament result, and - ❎ claim your profile, and make it your own. diff --git a/backend/src/main.rs b/backend/src/main.rs index bbb70bd..cd5d535 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -157,19 +157,3 @@ async fn main() -> Result<(), Box> { let _ = rocket().launch().await?; Ok(()) } - -#[cfg(test)] -mod tests { - use rocket::{http::Status, local::blocking::Client}; - - use super::rocket; - - #[test] - fn get_player_tournaments_test() -> Result<(), Box> { - let client = Client::tracked(rocket())?; - let response = client.get("/tournaments/1178271").dispatch(); - assert_eq!(response.status(), Status::Ok); - - Ok(()) - } -} diff --git a/database/src/db_models/set.rs b/database/src/db_models/set.rs index c95595d..c54a51e 100644 --- a/database/src/db_models/set.rs +++ b/database/src/db_models/set.rs @@ -4,7 +4,7 @@ use serde::Serialize; #[derive(Debug, Serialize, Insertable, Queryable, QueryableByName)] #[diesel(table_name = player_sets)] pub struct Set { - id: i32, + pub id: i32, pub completed_at: i64, requester_id: i32, requester_tag_with_prefix: String, diff --git a/database/src/lib.rs b/database/src/lib.rs index f897e13..0a0443a 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -59,6 +59,7 @@ fn try_connect() -> ConnectionResult { #[cfg(test)] mod tests { + #![allow(unused)] use super::*; use anyhow::Result; diff --git a/lib/Cargo.toml b/lib/Cargo.toml index bb955ee..eacb64e 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -6,7 +6,6 @@ authors = [ "Dan Chiarlone" ] [lib] doctest = false -test = false [dependencies] anyhow = "1" @@ -20,3 +19,7 @@ ctrlc = "3.4" as-any = "0.3" tokio = { version = "1.1", features = [ "rt", "macros" ] } chrono = "0.4" + +[features] +default = ["skip_db_tests"] +skip_db_tests = [] \ No newline at end of file diff --git a/lib/src/common.rs b/lib/src/common.rs index 5853561..966066a 100644 --- a/lib/src/common.rs +++ b/lib/src/common.rs @@ -2,6 +2,10 @@ use anyhow::Result; use as_any::Downcast; +use startgg::{ + Entrant, Event, PhaseGroup, Player, Score, Seed, Set as SGGSet, SetSlot, Standing, + StandingConnection, StandingStats, Tournament, User, Videogame, +}; use tracing::Level; use tracing_subscriber::FmtSubscriber; @@ -16,6 +20,13 @@ use std::{ time::{Duration, Instant}, }; +use startgg::{queries::set_getter::SetGetterVars, GQLData, GQLVars}; + +use crate::{ + error_logs::insert_error_log, game::delete_games_from_requester_id, + set::delete_sets_by_requester_id, tournament::delete_tournaments_from_requester_id, +}; + pub fn init_logger() -> Result<()> { let subscriber = FmtSubscriber::builder() .with_max_level(Level::INFO) @@ -26,13 +37,6 @@ pub fn init_logger() -> Result<()> { Ok(()) } -use startgg::{queries::set_getter::SetGetterVars, GQLData, GQLVars}; - -use crate::{ - error_logs::insert_error_log, game::delete_games_from_requester_id, - set::delete_sets_by_requester_id, tournament::delete_tournaments_from_requester_id, -}; - #[allow(clippy::too_many_arguments)] pub async fn start_read_all_by_increment_execute_finish_maybe_cancel( is_cli: bool, @@ -166,3 +170,99 @@ where finish(gql_vars)?; Ok(()) } + +pub fn get_sggset_test_data() -> SGGSet { + SGGSet { + id: 44887323, + games: None, + slots: vec![ + SetSlot { + entrant: Some(Entrant { + id: Some(9412484), + name: Some("Ancient 3 scrub".to_string()), + }), + seed: Some(Seed { + seedNum: Some(2), + entrant: None, + }), + standing: Some(Standing { + entrant: None, + player: None, + stats: Some(StandingStats { + score: Score { value: Some(2.0) }, + }), + placement: None, + }), + }, + SetSlot { + entrant: Some(Entrant { + id: Some(9410060), + name: Some("tyrese".to_string()), + }), + seed: Some(Seed { + seedNum: Some(10), + entrant: None, + }), + standing: Some(Standing { + entrant: None, + player: None, + stats: Some(StandingStats { + score: Score { value: Some(0.0) }, + }), + placement: None, + }), + }, + ], + completedAt: Some(1645848034), + phaseGroup: Some(PhaseGroup { + bracketType: "DOUBLE_ELIMINATION".to_string(), + }), + event: Some(Event { + id: Some(685122), + slug: Some( + "tournament/vsb-novice-friday-17/event/novice-ultimate-singles-bc-cooler-set" + .to_string(), + ), + phases: None, + name: Some("Novice Ultimate Singles (BC Cooler Set 😎)".to_string()), + numEntrants: Some(12), + isOnline: Some(false), + videogame: Some(Videogame { + name: "Super Smash Bros. Ultimate".to_string(), + }), + tournament: Some(Tournament { + id: 423456, + name: "VSB - Novice Friday #17".to_string(), + endAt: Some(1645862340), + }), + standings: Some(StandingConnection { + nodes: vec![Standing { + entrant: Some(Entrant { + id: Some(9410060), + name: None, + }), + player: Some(Player { + id: 2021528, + prefix: None, + gamerTag: None, + user: Some(User { + name: None, + location: None, + bio: None, + birthday: None, + images: None, + slug: Some("user/1f1bee01".to_string()), + genderPronoun: None, + authorizations: None, + }), + rankings: None, + sets: None, + }), + stats: None, + placement: Some(5), + }], + }), + teamRosterSize: None, + }), + } +} diff --git a/lib/src/error_logs.rs b/lib/src/error_logs.rs index b3a3a71..54857dd 100644 --- a/lib/src/error_logs.rs +++ b/lib/src/error_logs.rs @@ -10,3 +10,37 @@ pub fn insert_error_log(err: String) -> Result<()> { .execute(&mut db_connection)?; Ok(()) } + +#[cfg(test)] +mod tests { + #![allow(unused)] + use super::*; + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_insert_error_log() -> Result<()> { + // get count of all error_logs w/ "test error" message + let mut db_connection = smithe_database::connect().unwrap(); + let err_logs = error_logs.filter(error_message.eq("test error")); + let count = err_logs + .count() + .get_result::(&mut db_connection) + .unwrap(); + + // insert error + let err = "test error".to_string(); + insert_error_log(err.clone())?; + + // get count again and check that it increased by 1 + let new_count = err_logs + .count() + .get_result::(&mut db_connection) + .unwrap(); + assert_eq!(new_count, count + 1); + + // delete all error_logs w/ "test error" message + diesel::delete(err_logs).execute(&mut db_connection)?; + + Ok(()) + } +} diff --git a/lib/src/game.rs b/lib/src/game.rs index d765751..cf74b49 100644 --- a/lib/src/game.rs +++ b/lib/src/game.rs @@ -59,7 +59,61 @@ pub fn maybe_get_games_from_set( // delete a player's games given a requester id pub fn delete_games_from_requester_id(player_id: i32) -> Result<()> { let mut db_connection = smithe_database::connect()?; - diesel::delete(player_games.filter(requester_id.eq(player_id))).execute(&mut db_connection)?; + delete_games_from_requester_id_provided_connection(player_id, &mut db_connection)?; Ok(()) } + +// delete a player's games given a requester id +fn delete_games_from_requester_id_provided_connection( + player_id: i32, + db_connection: &mut PgConnection, +) -> Result<()> { + diesel::delete(player_games.filter(requester_id.eq(player_id))).execute(db_connection)?; + Ok(()) +} + +#[cfg(test)] +mod tests { + #![allow(unused)] + use super::*; + use anyhow::Result; + + const DANTOTTO_PLAYER_ID: i32 = 1178271; + + // test delete_games_from_requester_id w/ transactions + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_delete_games_from_requester_id() -> Result<()> { + let mut db_connection = smithe_database::connect().unwrap(); + + let err = db_connection.transaction::<(), _, _>(|db_connection| { + delete_games_from_requester_id_provided_connection(DANTOTTO_PLAYER_ID, db_connection) + .expect("failed to delete games"); + assert_eq!( + player_games + .filter(requester_id.eq(DANTOTTO_PLAYER_ID)) + .count() + .get_result::(db_connection) + .unwrap(), + 0 + ); + + Err(diesel::result::Error::RollbackTransaction) + }); + + assert!(err.is_err()); + + // check that there are still games under the player's id + assert_ne!( + player_games + .filter(requester_id.eq(DANTOTTO_PLAYER_ID)) + .count() + .get_result::(&mut db_connection) + .unwrap(), + 0 + ); + + Ok(()) + } +} diff --git a/lib/src/pidgtm_compile_times.rs b/lib/src/pidgtm_compile_times.rs index b55646b..3e98c57 100644 --- a/lib/src/pidgtm_compile_times.rs +++ b/lib/src/pidgtm_compile_times.rs @@ -12,3 +12,31 @@ pub fn insert_pidgtm_compile_time(tis: i32) -> Result<()> { .execute(&mut db_connection)?; Ok(()) } + +#[cfg(test)] +mod tests { + #![allow(unused)] + use super::*; + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_insert_pidgtm_compile_time() -> Result<()> { + // get count of all pidgtm_compile_times w/ -999 ti + let mut db_connection = smithe_database::connect().unwrap(); + let pct = pidgtm_compile_times.filter(time_in_seconds.eq(-999)); + let count = pct.count().get_result::(&mut db_connection).unwrap(); + + // insert pidgtm_compile_time + let tis = -999; + insert_pidgtm_compile_time(tis)?; + + // get count again and check that it increased by 1 + let new_count = pct.count().get_result::(&mut db_connection).unwrap(); + assert_eq!(new_count, count + 1); + + // delete all pidgtm_compile_times w/ -999 ti + diesel::delete(pct).execute(&mut db_connection)?; + + Ok(()) + } +} diff --git a/lib/src/player.rs b/lib/src/player.rs index 572edce..5bfae46 100644 --- a/lib/src/player.rs +++ b/lib/src/player.rs @@ -76,9 +76,16 @@ pub fn get_player(pid: i32) -> Result { pub fn add_new_player_to_pidgtm_db(pti: &SGGPlayer) -> Result<()> { let mut db_connection = smithe_database::connect()?; + add_new_player_to_pidgtm_db_provided_connection(pti, &mut db_connection) +} + +fn add_new_player_to_pidgtm_db_provided_connection( + pti: &SGGPlayer, + db_connection: &mut PgConnection, +) -> Result<()> { match insert_into(players) .values(Player::from(pti.clone())) - .execute(&mut db_connection) + .execute(db_connection) { Ok(_) => Ok(()), Err(e) => match e { @@ -93,6 +100,13 @@ pub fn add_new_player_to_pidgtm_db(pti: &SGGPlayer) -> Result<()> { fn update_player_in_pidgtm_db(pti: &SGGPlayer) -> Result<()> { let mut db_connection = smithe_database::connect()?; + update_player_in_pidgtm_db_provided_connection(pti, &mut db_connection) +} + +fn update_player_in_pidgtm_db_provided_connection( + pti: &SGGPlayer, + db_connection: &mut PgConnection, +) -> Result<()> { let player = Player::from(pti.clone()); update(players) .filter(smithe_database::schema::players::player_id.eq(player.player_id)) @@ -110,11 +124,11 @@ fn update_player_in_pidgtm_db(pti: &SGGPlayer) -> Result<()> { bio.eq(player.bio), rankings.eq(player.rankings), )) - .execute(&mut db_connection)?; + .execute(db_connection)?; Ok(()) } -pub fn update_and_handle_deleted(pti: &SGGPlayer) -> Result<()> { +fn update_and_handle_deleted(pti: &SGGPlayer) -> Result<()> { if pti.user.is_none() { tracing::info!("❎ caught a deleted account #1 (id: '{}')...", pti.id); pti.clone().user = get_empty_user_with_slug(pti.id)?; @@ -134,10 +148,18 @@ pub fn update_and_handle_deleted(pti: &SGGPlayer) -> Result<()> { pub fn add_new_empty_player_record(pid: i32) -> Result<()> { let mut db_connection = smithe_database::connect()?; + add_new_empty_player_record_provided_connection(pid, &mut db_connection)?; + Ok(()) +} + +fn add_new_empty_player_record_provided_connection( + pid: i32, + db_connection: &mut PgConnection, +) -> Result<()> { insert_into(empty_player_ids) .values(EmptyPlayerId::from(pid)) .on_conflict_do_nothing() - .execute(&mut db_connection)?; + .execute(db_connection)?; Ok(()) } @@ -207,10 +229,17 @@ pub fn get_max_player_id() -> Result { pub fn get_empty_user_with_slug(pid: i32) -> Result> { let mut db_connection = smithe_database::connect()?; + get_empty_user_with_slug_provided_connection(pid, &mut db_connection) +} + +fn get_empty_user_with_slug_provided_connection( + pid: i32, + db_connection: &mut PgConnection, +) -> Result> { let some_slug = players .select(user_slug) .filter(smithe_database::schema::players::player_id.eq(pid)) - .get_result(&mut db_connection) + .get_result(db_connection) .optional()?; Ok(Some(User { @@ -447,10 +476,166 @@ pub fn get_top_two_characters(pid: i32) -> Result>> { #[cfg(test)] mod tests { + #![allow(unused)] use super::*; + const DANTOTTO_PLAYER_ID: i32 = 1178271; + #[test] + #[cfg(feature = "skip_db_tests")] fn test_check_if_large_consecutive_playerid_grouping_exists() { - check_if_large_consecutive_playerid_grouping_exists().unwrap(); + let res = check_if_large_consecutive_playerid_grouping_exists(); + assert!(res.is_ok()); + assert!(!res.unwrap()); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_max_player_id() { + let res = get_max_player_id(); + assert!(res.is_ok()); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_top_two_characters() { + let res = get_top_two_characters(DANTOTTO_PLAYER_ID); + assert!(res.is_ok()); + assert_eq!( + res.unwrap(), + vec![Some("King Dedede".to_string()), Some("Steve".to_string())] + ); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_subsequent_player_id_with_circle_back() { + let res = get_subsequent_player_id_with_circle_back(DANTOTTO_PLAYER_ID); + assert!(res.is_ok()); + assert_eq!(res.unwrap(), 1178566); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_empty_user_with_slug() { + let res = get_empty_user_with_slug(DANTOTTO_PLAYER_ID); + assert!(res.is_ok()); + assert_eq!( + res.unwrap().unwrap().slug, + Some("user/566b1fb5".to_string()) + ); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_add_new_empty_player_record() { + let mut db_connection = smithe_database::connect().unwrap(); + let err = db_connection.transaction::<(), _, _>(|db_connection| { + add_new_empty_player_record_provided_connection(DANTOTTO_PLAYER_ID, db_connection) + .expect("failed to add new empty player record"); + + // check that the player id was added + assert_eq!( + empty_player_ids + .filter( + smithe_database::schema::empty_player_ids::player_id.eq(DANTOTTO_PLAYER_ID) + ) + .count() + .get_result::(db_connection) + .unwrap(), + 1 + ); + + Err(diesel::result::Error::RollbackTransaction) + }); + + assert!(err.is_err()); + + // check no id in empty_player_ids + assert_eq!( + empty_player_ids + .filter(smithe_database::schema::empty_player_ids::player_id.eq(DANTOTTO_PLAYER_ID)) + .count() + .get_result::(&mut db_connection) + .unwrap(), + 0 + ); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_add_new_player_to_pidgtm_db() { + let mut db_connection = smithe_database::connect().unwrap(); + let err = db_connection.transaction::<(), _, _>(|db_connection| { + add_new_player_to_pidgtm_db_provided_connection( + &SGGPlayer { + id: 999, + prefix: None, + gamerTag: Some("Orinorae Thaamtekelud".to_string()), + rankings: None, + user: Some(User { + name: None, + location: None, + bio: None, + birthday: None, + images: None, + slug: Some("user/123a4bc5".to_string()), + genderPronoun: None, + authorizations: None, + }), + sets: None, + }, + db_connection, + ) + .expect("failed to add new player to pidgtm db"); + + // check that the player id was added + assert_eq!( + players + .filter(smithe_database::schema::players::player_id.eq(999)) + .count() + .get_result::(db_connection) + .unwrap(), + 1 + ); + + Err(diesel::result::Error::RollbackTransaction) + }); + + assert!(err.is_err()); + + // check no id in empty_player_ids + assert_eq!( + players + .filter(smithe_database::schema::players::player_id.eq(999)) + .count() + .get_result::(&mut db_connection) + .unwrap(), + 0 + ); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_all_like() { + let res = get_all_like("dantotto"); + assert!(res.is_ok()); + assert_eq!(res.unwrap().len(), 1); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_player() { + let res = get_player(DANTOTTO_PLAYER_ID); + assert!(res.is_ok()); + assert_eq!(res.unwrap().player_id, DANTOTTO_PLAYER_ID); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_highest_id_with_sets_between() { + let res = get_highest_id_with_sets_between(1000, 1001); + assert!(res.is_ok()); + assert_eq!(res.unwrap(), Some(1000)); } } diff --git a/lib/src/player_page_views.rs b/lib/src/player_page_views.rs index ded0a57..f993f18 100644 --- a/lib/src/player_page_views.rs +++ b/lib/src/player_page_views.rs @@ -14,3 +14,31 @@ pub fn insert_player_page_view(pid: i32) -> Result<()> { Ok(()) } + +#[cfg(test)] +mod tests { + #![allow(unused)] + use super::*; + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_insert_player_page_view() -> Result<()> { + // get count of all player_page_views w/ -999 pid + let mut db_connection = smithe_database::connect().unwrap(); + let ppv = player_page_views.filter(player_id.eq(-999)); + let count = ppv.count().get_result::(&mut db_connection).unwrap(); + + // insert player_page_view + let pid = -999; + insert_player_page_view(pid)?; + + // get count again and check that it increased by 1 + let new_count = ppv.count().get_result::(&mut db_connection).unwrap(); + assert_eq!(new_count, count + 1); + + // delete all player_page_views w/ -999 pid + diesel::delete(ppv).execute(&mut db_connection)?; + + Ok(()) + } +} diff --git a/lib/src/set.rs b/lib/src/set.rs index f52a2b0..0ba1397 100644 --- a/lib/src/set.rs +++ b/lib/src/set.rs @@ -42,9 +42,16 @@ pub fn get_head_to_head_record(requester_id_param: i32) -> Result Result> { let mut db_connection = smithe_database::connect()?; + get_all_from_player_id_provided_connection(player_id, &mut db_connection) +} + +fn get_all_from_player_id_provided_connection( + player_id: i32, + db_connection: &mut PgConnection, +) -> Result> { let cache = player_sets .filter(requester_id.eq(player_id)) - .load::(&mut db_connection)?; + .load::(db_connection)?; Ok(cache) } @@ -116,7 +123,15 @@ pub fn get_set_wins_without_dqs(player_id: i32) -> Result { // delete a player's sets given a requester_id pub fn delete_sets_by_requester_id(player_id: i32) -> Result<()> { let mut db_connection = smithe_database::connect()?; - diesel::delete(player_sets.filter(requester_id.eq(player_id))).execute(&mut db_connection)?; + delete_sets_by_requester_id_provided_connection(player_id, &mut db_connection)?; + Ok(()) +} + +fn delete_sets_by_requester_id_provided_connection( + player_id: i32, + db_connection: &mut PgConnection, +) -> Result<()> { + diesel::delete(player_sets.filter(requester_id.eq(player_id))).execute(db_connection)?; Ok(()) } @@ -202,13 +217,121 @@ pub fn get_competitor_type(player_id: i32) -> Result<(u32, u32)> { #[cfg(test)] mod tests { + #![allow(unused)] + use crate::common::get_sggset_test_data; + use super::*; const DANTOTTO_PLAYER_ID: i32 = 1178271; #[test] + #[cfg(feature = "skip_db_tests")] fn test_get_head_to_head_record() -> Result<()> { - dbg!(get_head_to_head_record(DANTOTTO_PLAYER_ID)?); + get_head_to_head_record(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_all_from_player_id() -> Result<()> { + get_all_from_player_id(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_last_completed_at() -> Result<()> { + let cache = get_all_from_player_id(DANTOTTO_PLAYER_ID)?; + get_last_completed_at(cache).expect("failed to get last completed_at"); + Ok(()) + } + + #[test] + fn test_get_requester_set_slot() -> Result<()> { + let set = get_sggset_test_data(); + get_requester_set_slot(9410060, &set).expect("failed to get requester set slot"); + Ok(()) + } + + #[test] + fn test_get_opponent_set_slot() -> Result<()> { + let set = get_sggset_test_data(); + get_opponent_set_slot(9412484, &set).expect("failed to get opponent set slot"); + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_set_wins_without_dqs() -> Result<()> { + get_set_wins_without_dqs(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_delete_sets_by_requester_id() -> Result<()> { + let mut db_connection = smithe_database::connect()?; + let err = db_connection.transaction::<(), _, _>(|db_connection| { + delete_sets_by_requester_id_provided_connection(DANTOTTO_PLAYER_ID, db_connection) + .expect("failed to delete sets by requester id"); + + // check that there are no sets for the player + let sets = + get_all_from_player_id_provided_connection(DANTOTTO_PLAYER_ID, db_connection) + .expect("failed to get sets"); + assert!(sets.is_empty()); + + Err(diesel::result::Error::RollbackTransaction) + }); + + assert!(err.is_err()); + + // check that there are sets for the player + let sets = get_all_from_player_id(DANTOTTO_PLAYER_ID)?; + assert!(!sets.is_empty()); + + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_set_losses_without_dqs() -> Result<()> { + get_set_losses_without_dqs(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_set_wins_by_dq() -> Result<()> { + get_set_wins_by_dq(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_set_losses_by_dq() -> Result<()> { + get_set_losses_by_dq(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_winrate() -> Result<()> { + get_winrate(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_sets_per_player_id() -> Result<()> { + get_sets_per_player_id(DANTOTTO_PLAYER_ID)?; + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn test_get_competitor_type() -> Result<()> { + get_competitor_type(DANTOTTO_PLAYER_ID)?; Ok(()) } } diff --git a/lib/src/tournament.rs b/lib/src/tournament.rs index 0703f44..cb400d8 100644 --- a/lib/src/tournament.rs +++ b/lib/src/tournament.rs @@ -100,10 +100,17 @@ pub fn is_ssbu_singles_and_supported_tournament(s: &SGGSet) -> bool { pub fn get_num_tournaments_attended(pid: i32) -> Result { let mut db_connection = smithe_database::connect()?; + get_num_tournaments_attended_provided_connection(pid, &mut db_connection) +} + +fn get_num_tournaments_attended_provided_connection( + pid: i32, + db_connection: &mut PgConnection, +) -> Result { let count: i64 = player_tournaments .select(count_star()) .filter(requester_id.eq(pid)) - .first(&mut db_connection)?; + .first(db_connection)?; Ok(count) } @@ -142,21 +149,31 @@ pub fn is_tournament_cached(player_id: i32, s: &SGGSet) -> Result { // delete a player's tournaments given a requester id pub fn delete_tournaments_from_requester_id(player_id: i32) -> Result<()> { let mut db_connection = smithe_database::connect()?; - diesel::delete(player_tournaments.filter(requester_id.eq(player_id))) - .execute(&mut db_connection)?; + delete_tournaments_from_requester_id_provided_connection(player_id, &mut db_connection) +} + +fn delete_tournaments_from_requester_id_provided_connection( + player_id: i32, + db_connection: &mut PgConnection, +) -> Result<()> { + diesel::delete(player_tournaments.filter(requester_id.eq(player_id))).execute(db_connection)?; Ok(()) } #[cfg(test)] mod tests { + #![allow(unused)] use anyhow::Result; + use diesel::Connection; - use crate::common::init_logger; + use crate::common::{get_sggset_test_data, init_logger}; const DANTOTTO_PLAYER_ID: i32 = 1178271; + const TYRESE_PLAYER_ID: i32 = 2021528; #[tokio::test] + #[cfg(feature = "skip_db_tests")] async fn get_tournaments_from_requester_id_test() -> Result<()> { init_logger()?; let now = std::time::Instant::now(); @@ -166,4 +183,96 @@ mod tests { tracing::info!("Test took: {:?} seconds", elapsed.as_secs()); Ok(()) } + + #[test] + fn is_tournament_finished_test() { + let s = get_sggset_test_data(); + + assert!(super::is_tournament_finished(&s)); + } + + #[test] + fn get_placement_test() { + let s = get_sggset_test_data(); + + assert_eq!(super::get_placement(&s, TYRESE_PLAYER_ID), 5); + } + + #[test] + fn get_requester_id_from_standings_test() { + let s = get_sggset_test_data(); + + assert_eq!( + super::get_requester_id_from_standings(&s, TYRESE_PLAYER_ID), + 9410060 + ); + } + + #[test] + fn is_ssbu_singles_and_supported_tournament_test() { + let s = get_sggset_test_data(); + + assert!(super::is_ssbu_singles_and_supported_tournament(&s)); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn get_num_tournaments_attended_test() -> Result<()> { + let count = super::get_num_tournaments_attended(DANTOTTO_PLAYER_ID)?; + + // check that it is greater than or equalt to 237 + assert!(count >= 237); + + Ok(()) + } + + #[test] + fn get_seed_test() { + let s = get_sggset_test_data(); + + assert_eq!(super::get_seed(9410060, &s), Some(10)); + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn is_tournament_cached_test() -> Result<()> { + let s = get_sggset_test_data(); + + assert!(super::is_tournament_cached(TYRESE_PLAYER_ID, &s)?); + + Ok(()) + } + + #[test] + #[cfg(feature = "skip_db_tests")] + fn delete_tournaments_from_requester_id_test() -> Result<()> { + let mut db_connection = smithe_database::connect()?; + + let err = db_connection.transaction::<(), _, _>(|db_connection| { + super::delete_tournaments_from_requester_id_provided_connection( + DANTOTTO_PLAYER_ID, + db_connection, + ) + .expect("failed to delete tournaments"); + + // check player doesn't have any tournaments + assert_eq!( + super::get_num_tournaments_attended_provided_connection( + DANTOTTO_PLAYER_ID, + db_connection + ) + .expect("failed to get num tournaments"), + 0 + ); + + Err(diesel::result::Error::RollbackTransaction) + }); + + assert!(err.is_err()); + + // check player has tournaments again + assert!(super::get_num_tournaments_attended(DANTOTTO_PLAYER_ID)? > 0); + + Ok(()) + } } diff --git a/src/pidgtm/compile.rs b/src/pidgtm/compile.rs index 3443707..f1d1997 100644 --- a/src/pidgtm/compile.rs +++ b/src/pidgtm/compile.rs @@ -82,20 +82,3 @@ pub async fn handle_compile( Ok(()) } - -#[cfg(test)] -mod tests { - use anyhow::Result; - use smithe_lib::common::init_logger; - - use super::*; - - const RANDOM_ID: i32 = 26324; - - #[tokio::test] - async fn test_handle_compile() -> Result<()> { - init_logger()?; - handle_compile(Some(RANDOM_ID), Some(RANDOM_ID + 1)).await?; - Ok(()) - } -} diff --git a/startgg_api/src/lib.rs b/startgg_api/src/lib.rs index d6f777a..bf3c3c3 100644 --- a/startgg_api/src/lib.rs +++ b/startgg_api/src/lib.rs @@ -30,7 +30,7 @@ pub struct SeedConnection { #[derive(Debug, Clone, Deserialize)] pub struct Seed { pub seedNum: Option, - entrant: Option, + pub entrant: Option, } #[derive(Debug, Clone, Deserialize)] diff --git a/startgg_api/src/queries/event_getter.rs b/startgg_api/src/queries/event_getter.rs index 721cff7..c917550 100644 --- a/startgg_api/src/queries/event_getter.rs +++ b/startgg_api/src/queries/event_getter.rs @@ -65,6 +65,7 @@ pub async fn get_phase_id_from_event_slug(event_slug: &str) -> Result { #[cfg(test)] mod tests { + #![allow(unused)] use anyhow::Result; use crate::queries::event_getter::make_event_getter_query; diff --git a/startgg_api/src/queries/player_getter.rs b/startgg_api/src/queries/player_getter.rs index b8e9369..a367381 100644 --- a/startgg_api/src/queries/player_getter.rs +++ b/startgg_api/src/queries/player_getter.rs @@ -96,6 +96,7 @@ pub async fn make_pidgtm_player_getter_query( #[cfg(test)] mod tests { + #![allow(unused)] use std::sync::{Arc, Mutex}; use anyhow::Result; diff --git a/startgg_api/src/queries/seeding_getter.rs b/startgg_api/src/queries/seeding_getter.rs index 654f0a4..6883622 100644 --- a/startgg_api/src/queries/seeding_getter.rs +++ b/startgg_api/src/queries/seeding_getter.rs @@ -85,6 +85,7 @@ pub async fn make_seeding_getter_query(phase_id: i32) -> Result> { #[cfg(test)] mod tests { + #![allow(unused)] use crate::{ queries::seeding_getter::{SeedingGetterData, SeedingGetterVars, SEEDING_GETTER_QUERY}, StartGG, diff --git a/startgg_api/src/queries/set_getter.rs b/startgg_api/src/queries/set_getter.rs index fd4cc23..4d78560 100644 --- a/startgg_api/src/queries/set_getter.rs +++ b/startgg_api/src/queries/set_getter.rs @@ -150,6 +150,7 @@ pub async fn make_set_getter_query( #[cfg(test)] mod tests { + #![allow(unused)] use std::sync::Arc; use std::sync::Mutex;