diff --git a/Cargo.lock b/Cargo.lock index 88786c928..7ed150cb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3510,6 +3510,7 @@ dependencies = [ "rusqlite", "serde", "serde_json", + "similar-asserts", "tempfile", "thiserror", "tokio", diff --git a/Cargo.toml b/Cargo.toml index e481a4ea1..fd50365c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ members = [ "uniffi-bindgen", "xtask", ] +exclude = [ + "testing/data", +] # xtask, testing and the bindings should only be built when invoked explicitly. default-members = ["benchmarks", "crates/*", "labs/*"] resolver = "2" diff --git a/crates/matrix-sdk-sqlite/Cargo.toml b/crates/matrix-sdk-sqlite/Cargo.toml index b38e92e6d..8e4f9045a 100644 --- a/crates/matrix-sdk-sqlite/Cargo.toml +++ b/crates/matrix-sdk-sqlite/Cargo.toml @@ -39,6 +39,7 @@ matrix-sdk-base = { workspace = true, features = ["testing"] } matrix-sdk-crypto = { workspace = true, features = ["testing"] } matrix-sdk-test = { workspace = true } once_cell = { workspace = true } +similar-asserts = { workspace = true } tempfile = "3.3.0" tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } diff --git a/crates/matrix-sdk-sqlite/src/crypto_store.rs b/crates/matrix-sdk-sqlite/src/crypto_store.rs index 83696f5c9..6c1cdf012 100644 --- a/crates/matrix-sdk-sqlite/src/crypto_store.rs +++ b/crates/matrix-sdk-sqlite/src/crypto_store.rs @@ -1323,8 +1323,14 @@ impl CryptoStore for SqliteCryptoStore { #[cfg(test)] mod tests { - use matrix_sdk_crypto::{cryptostore_integration_tests, cryptostore_integration_tests_time}; + use std::path::PathBuf; + + use matrix_sdk_crypto::{ + cryptostore_integration_tests, cryptostore_integration_tests_time, store::CryptoStore, + }; + use matrix_sdk_test::async_test; use once_cell::sync::Lazy; + use similar_asserts::assert_eq; use tempfile::{tempdir, TempDir}; use tokio::fs; @@ -1332,6 +1338,98 @@ mod tests { static TMP_DIR: Lazy = Lazy::new(|| tempdir().unwrap()); + struct TestDb { + // Needs to be kept alive because the Drop implementation for TempDir deletes the + // directory. + #[allow(dead_code)] + dir: TempDir, + database: SqliteCryptoStore, + } + + async fn get_test_db() -> TestDb { + let db_name = "matrix-sdk-crypto.sqlite3"; + + let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../.."); + let database_path = manifest_path.join("testing/data/storage").join(db_name); + + let tmpdir = tempdir().unwrap(); + let destination = tmpdir.path().join(db_name); + + // Copy the test database to the tempdir so our test runs are idempotent. + std::fs::copy(&database_path, destination).unwrap(); + + let database = + SqliteCryptoStore::open(tmpdir.path(), None).await.expect("Can't open the test store"); + + TestDb { dir: tmpdir, database } + } + + /// Test that we didn't regress in our storage layer by loading data from a + /// pre-filled database, or in other words use a test vector for this. + #[async_test] + async fn open_test_vector_store() { + let TestDb { dir: _, database } = get_test_db().await; + + let account = database + .load_account() + .await + .unwrap() + .expect("The test database is prefilled with data, we should find an account"); + + let user_id = account.user_id(); + let device_id = account.device_id(); + + assert_eq!( + user_id.as_str(), + "@pjtest:synapse-oidc.element.dev", + "The user ID should match to the one we expect." + ); + + assert_eq!( + device_id.as_str(), + "v4TqgcuIH6", + "The device ID should match to the one we expect." + ); + + let device = database + .get_device(user_id, device_id) + .await + .unwrap() + .expect("Our own device should be found in the store."); + + assert_eq!(device.device_id(), device_id); + assert_eq!(device.user_id(), user_id); + + assert_eq!( + device.ed25519_key().expect("The device should have a Ed25519 key.").to_base64(), + "+cxl1Gl3du5i7UJwfWnoRDdnafFF+xYdAiTYYhYLr8s" + ); + + assert_eq!( + device.curve25519_key().expect("The device should have a Curve25519 key.").to_base64(), + "4SL9eEUlpyWSUvjljC5oMjknHQQJY7WZKo5S1KL/5VU" + ); + + let identity = database + .get_user_identity(user_id) + .await + .unwrap() + .expect("The store should contain an identity."); + + assert_eq!(identity.user_id(), user_id); + + let identity = identity + .own() + .expect("The identity should be of the correct type, it should be our own identity."); + + let master_key = identity + .master_key() + .get_first_key() + .expect("Our own identity should have a master key"); + + assert_eq!(master_key.to_base64(), "iCUEtB1RwANeqRa5epDrblLk4mer/36sylwQ5hYY3oE"); + } + async fn get_store( name: &str, passphrase: Option<&str>, diff --git a/testing/data/storage/matrix-sdk-crypto.sqlite3 b/testing/data/storage/matrix-sdk-crypto.sqlite3 new file mode 100644 index 000000000..8795136ed Binary files /dev/null and b/testing/data/storage/matrix-sdk-crypto.sqlite3 differ