forked from torrust/torrust-index
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: [torrust#56] tests for upgrader
Extract different testers for every type of data transferred.
- Loading branch information
1 parent
f993107
commit 5d0def2
Showing
4 changed files
with
113 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod sqlite_v1_0_0; | ||
pub mod sqlite_v2_0_0; | ||
pub mod tests; | ||
pub mod testers; | ||
pub mod upgrader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod user_data_tester; |
91 changes: 91 additions & 0 deletions
91
tests/upgrades/from_v1_0_0_to_v2_0_0/testers/user_data_tester.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
use crate::upgrades::from_v1_0_0_to_v2_0_0::sqlite_v1_0_0::SqliteDatabaseV1_0_0; | ||
use crate::upgrades::from_v1_0_0_to_v2_0_0::sqlite_v2_0_0::SqliteDatabaseV2_0_0; | ||
use argon2::password_hash::SaltString; | ||
use argon2::{Argon2, PasswordHasher}; | ||
use rand_core::OsRng; | ||
use std::sync::Arc; | ||
use torrust_index_backend::upgrades::from_v1_0_0_to_v2_0_0::databases::sqlite_v1_0_0::UserRecordV1; | ||
|
||
pub struct UserDataTester { | ||
source_database: Arc<SqliteDatabaseV1_0_0>, | ||
destiny_database: Arc<SqliteDatabaseV2_0_0>, | ||
execution_time: String, | ||
test_data: TestData, | ||
} | ||
|
||
pub struct TestData { | ||
pub user: UserRecordV1, | ||
} | ||
|
||
impl UserDataTester { | ||
pub fn new( | ||
source_database: Arc<SqliteDatabaseV1_0_0>, | ||
destiny_database: Arc<SqliteDatabaseV2_0_0>, | ||
execution_time: &str, | ||
) -> Self { | ||
let user = UserRecordV1 { | ||
user_id: 1, | ||
username: "user01".to_string(), | ||
email: "[email protected]".to_string(), | ||
email_verified: true, | ||
password: hashed_valid_password(), | ||
administrator: true, | ||
}; | ||
|
||
Self { | ||
source_database, | ||
destiny_database, | ||
execution_time: execution_time.to_owned(), | ||
test_data: TestData { user }, | ||
} | ||
} | ||
|
||
pub async fn load_data_into_source_db(&self) { | ||
self.source_database | ||
.insert_user(&self.test_data.user) | ||
.await | ||
.unwrap(); | ||
} | ||
|
||
pub async fn assert(&self) { | ||
self.assert_user().await; | ||
} | ||
|
||
/// Table `torrust_users` | ||
async fn assert_user(&self) { | ||
let imported_user = self | ||
.destiny_database | ||
.get_user(self.test_data.user.user_id) | ||
.await | ||
.unwrap(); | ||
|
||
assert_eq!(imported_user.user_id, self.test_data.user.user_id); | ||
assert!(imported_user.date_registered.is_none()); | ||
assert_eq!(imported_user.date_imported.unwrap(), self.execution_time); | ||
assert_eq!( | ||
imported_user.administrator, | ||
self.test_data.user.administrator | ||
); | ||
} | ||
} | ||
|
||
fn hashed_valid_password() -> String { | ||
hash_password(&valid_password()) | ||
} | ||
|
||
fn valid_password() -> String { | ||
"123456".to_string() | ||
} | ||
|
||
fn hash_password(plain_password: &str) -> String { | ||
let salt = SaltString::generate(&mut OsRng); | ||
|
||
// Argon2 with default params (Argon2id v19) | ||
let argon2 = Argon2::default(); | ||
|
||
// Hash password to PHC string ($argon2id$v=19$...) | ||
argon2 | ||
.hash_password(plain_password.as_bytes(), &salt) | ||
.unwrap() | ||
.to_string() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,19 @@ | ||
//! You can run this test with: | ||
//! | ||
//! ```text | ||
//! cargo test upgrade_data_from_version_v1_0_0_to_v2_0_0 -- --nocapture | ||
//! cargo test upgrades_data_from_version_v1_0_0_to_v2_0_0 -- --nocapture | ||
//! ``` | ||
use crate::upgrades::from_v1_0_0_to_v2_0_0::sqlite_v1_0_0::SqliteDatabaseV1_0_0; | ||
use crate::upgrades::from_v1_0_0_to_v2_0_0::sqlite_v2_0_0::SqliteDatabaseV2_0_0; | ||
use argon2::password_hash::SaltString; | ||
use argon2::{Argon2, PasswordHasher}; | ||
use rand_core::OsRng; | ||
use crate::upgrades::from_v1_0_0_to_v2_0_0::testers::user_data_tester::UserDataTester; | ||
use std::fs; | ||
use std::sync::Arc; | ||
use torrust_index_backend::upgrades::from_v1_0_0_to_v2_0_0::databases::sqlite_v1_0_0::UserRecordV1; | ||
use torrust_index_backend::upgrades::from_v1_0_0_to_v2_0_0::upgrader::{ | ||
datetime_iso_8601, upgrade, Arguments, | ||
}; | ||
|
||
#[tokio::test] | ||
async fn upgrade_data_from_version_v1_0_0_to_v2_0_0() { | ||
async fn upgrades_data_from_version_v1_0_0_to_v2_0_0() { | ||
// Directories | ||
let fixtures_dir = "./tests/upgrades/from_v1_0_0_to_v2_0_0/fixtures/".to_string(); | ||
let output_dir = "./tests/upgrades/from_v1_0_0_to_v2_0_0/output/".to_string(); | ||
|
@@ -25,24 +22,28 @@ async fn upgrade_data_from_version_v1_0_0_to_v2_0_0() { | |
let source_database_file = format!("{}source.db", output_dir); | ||
let destiny_database_file = format!("{}destiny.db", output_dir); | ||
|
||
// Set up clean database | ||
// Set up clean source database | ||
reset_databases(&source_database_file, &destiny_database_file); | ||
let source_database = source_db_connection(&source_database_file).await; | ||
source_database.migrate(&fixtures_dir).await; | ||
|
||
// Set up connection for the destiny database | ||
let destiny_database = destiny_db_connection(&destiny_database_file).await; | ||
|
||
// The datetime when the upgrader is executed | ||
let execution_time = datetime_iso_8601(); | ||
|
||
// Load data into database v1 | ||
|
||
// `torrust_users` table | ||
|
||
let user = UserRecordV1 { | ||
user_id: 1, | ||
username: "user01".to_string(), | ||
email: "[email protected]".to_string(), | ||
email_verified: true, | ||
password: hashed_valid_password(), | ||
administrator: true, | ||
}; | ||
let user_id = source_database.insert_user(&user).await.unwrap(); | ||
let user_data_tester = UserDataTester::new( | ||
source_database.clone(), | ||
destiny_database.clone(), | ||
&execution_time, | ||
); | ||
|
||
user_data_tester.load_data_into_source_db().await; | ||
|
||
// `torrust_tracker_keys` table | ||
|
||
|
@@ -58,21 +59,13 @@ async fn upgrade_data_from_version_v1_0_0_to_v2_0_0() { | |
destiny_database_file: destiny_database_file.clone(), | ||
upload_path: format!("{}uploads/", fixtures_dir), | ||
}; | ||
let now = datetime_iso_8601(); | ||
upgrade(&args, &now).await; | ||
upgrade(&args, &execution_time).await; | ||
|
||
// Assertions in database v2 | ||
|
||
let destiny_database = destiny_db_connection(&destiny_database_file).await; | ||
|
||
// `torrust_users` table | ||
|
||
let imported_user = destiny_database.get_user(user_id).await.unwrap(); | ||
|
||
assert_eq!(imported_user.user_id, user.user_id); | ||
assert!(imported_user.date_registered.is_none()); | ||
assert_eq!(imported_user.date_imported.unwrap(), now); | ||
assert_eq!(imported_user.administrator, user.administrator); | ||
user_data_tester.assert().await; | ||
|
||
// `torrust_user_authentication` table | ||
|
||
|
@@ -117,24 +110,3 @@ fn reset_databases(source_database_file: &str, destiny_database_file: &str) { | |
fs::remove_file(&source_database_file).expect("Can't remove source DB file."); | ||
fs::remove_file(&destiny_database_file).expect("Can't remove destiny DB file."); | ||
} | ||
|
||
fn hashed_valid_password() -> String { | ||
hash_password(&valid_password()) | ||
} | ||
|
||
fn valid_password() -> String { | ||
"123456".to_string() | ||
} | ||
|
||
fn hash_password(plain_password: &str) -> String { | ||
let salt = SaltString::generate(&mut OsRng); | ||
|
||
// Argon2 with default params (Argon2id v19) | ||
let argon2 = Argon2::default(); | ||
|
||
// Hash password to PHC string ($argon2id$v=19$...) | ||
argon2 | ||
.hash_password(plain_password.as_bytes(), &salt) | ||
.unwrap() | ||
.to_string() | ||
} |