diff --git a/radicle-cli/tests/commands.rs b/radicle-cli/tests/commands.rs index ff562771..f09f1cad 100644 --- a/radicle-cli/tests/commands.rs +++ b/radicle-cli/tests/commands.rs @@ -1,22 +1,67 @@ use std::env; use std::path::Path; +use radicle::crypto::ssh::Keystore; +use radicle::crypto::KeyPair; use radicle::profile::{Home, Profile}; +use radicle::storage::git::transport; +use radicle::storage::git::Storage; use radicle::test::fixtures; mod framework; use framework::TestFormula; +use radicle_crypto::Seed; + +/// Test environment. +pub struct Environment { + tempdir: tempfile::TempDir, + users: usize, +} + +impl Environment { + /// Create a new test environment. + fn new() -> Self { + Self { + tempdir: tempfile::tempdir().unwrap(), + users: 0, + } + } + + /// Create a new profile in this environment. + fn profile(&mut self, name: &str) -> Profile { + let home = Home::new(self.tempdir.path().join(name)).init().unwrap(); + let storage = Storage::open(home.storage()).unwrap(); + let keystore = Keystore::new(&home.keys()); + let keypair = KeyPair::from_seed(Seed::from([!(self.users as u8); 32])); + + transport::local::register(storage.clone()); + keystore + .store(keypair.clone(), "radicle", "radicle".to_owned()) + .unwrap(); + + // Ensures that each user has a unique but deterministic public key. + self.users += 1; + + Profile { + home, + storage, + keystore, + public_key: keypair.pk.into(), + } + } +} /// Run a CLI test file. -fn test( +fn test<'a>( test: impl AsRef, cwd: impl AsRef, - profile: Option<&Profile>, + home: Option<&Home>, + envs: impl IntoIterator, ) -> Result<(), Box> { let base = Path::new(env!("CARGO_MANIFEST_DIR")); let tmp = tempfile::tempdir().unwrap(); - let home = if let Some(profile) = profile { - profile.home().to_path_buf() + let home = if let Some(home) = home { + home.path().to_path_buf() } else { tmp.path().to_path_buf() }; @@ -28,11 +73,11 @@ fn test( .env("GIT_COMMITTER_DATE", "1671125284") .env("GIT_COMMITTER_EMAIL", "radicle@localhost") .env("GIT_COMMITTER_NAME", "radicle") - .env("RAD_DEBUG", "1") .env("RAD_HOME", home.to_string_lossy()) .env("RAD_PASSPHRASE", "radicle") .env("TZ", "Etc/GMT") .env(radicle_cob::git::RAD_COMMIT_TIME, "1671125284") + .envs(envs) .cwd(cwd) .file(base.join(test))? .run()?; @@ -40,70 +85,77 @@ fn test( Ok(()) } -/// Create a new user profile. -fn profile(home: &Path) -> Profile { - // Set debug mode, to make test output more predictable. - env::set_var("RAD_DEBUG", "1"); - // Setup a new user. - Profile::init(Home::new(home.to_path_buf()), "radicle".to_owned()).unwrap() -} - #[test] fn rad_auth() { - test("examples/rad-auth.md", Path::new("."), None).unwrap(); + test( + "examples/rad-auth.md", + Path::new("."), + None, + [("RAD_DEBUG", "1")], + ) + .unwrap(); } #[test] fn rad_issue() { - let home = tempfile::tempdir().unwrap(); + let mut environment = Environment::new(); + let profile = environment.profile("alice"); + let home = &profile.home; let working = tempfile::tempdir().unwrap(); - let profile = profile(home.path()); // Setup a test repository. fixtures::repository(working.path()); // Set a fixed commit time. env::set_var(radicle_cob::git::RAD_COMMIT_TIME, "1671125284"); - test("examples/rad-init.md", working.path(), Some(&profile)).unwrap(); - test("examples/rad-issue.md", working.path(), Some(&profile)).unwrap(); + test("examples/rad-init.md", working.path(), Some(home), []).unwrap(); + test("examples/rad-issue.md", working.path(), Some(home), []).unwrap(); } #[test] fn rad_init() { - let home = tempfile::tempdir().unwrap(); + let mut environment = Environment::new(); + let profile = environment.profile("alice"); let working = tempfile::tempdir().unwrap(); - let profile = profile(home.path()); // Setup a test repository. fixtures::repository(working.path()); - test("examples/rad-init.md", working.path(), Some(&profile)).unwrap(); + test( + "examples/rad-init.md", + working.path(), + Some(&profile.home), + [], + ) + .unwrap(); } #[test] fn rad_delegate() { - let home = tempfile::tempdir().unwrap(); + let mut environment = Environment::new(); + let profile = environment.profile("alice"); let working = tempfile::tempdir().unwrap(); - let profile = profile(home.path()); + let home = &profile.home; // Setup a test repository. fixtures::repository(working.path()); - test("examples/rad-init.md", working.path(), Some(&profile)).unwrap(); - test("examples/rad-delegate.md", working.path(), Some(&profile)).unwrap(); + test("examples/rad-init.md", working.path(), Some(home), []).unwrap(); + test("examples/rad-delegate.md", working.path(), Some(home), []).unwrap(); } #[test] #[ignore] fn rad_patch() { - let home = tempfile::tempdir().unwrap(); + let mut environment = Environment::new(); + let profile = environment.profile("alice"); let working = tempfile::tempdir().unwrap(); - let profile = profile(home.path()); + let home = &profile.home; // Setup a test repository. fixtures::repository(working.path()); - test("examples/rad-init.md", working.path(), Some(&profile)).unwrap(); - test("examples/rad-issue.md", working.path(), Some(&profile)).unwrap(); - test("examples/rad-patch.md", working.path(), Some(&profile)).unwrap(); + test("examples/rad-init.md", working.path(), Some(home), []).unwrap(); + test("examples/rad-issue.md", working.path(), Some(home), []).unwrap(); + test("examples/rad-patch.md", working.path(), Some(home), []).unwrap(); } diff --git a/radicle-cli/tests/framework/mod.rs b/radicle-cli/tests/framework/mod.rs index 68a75ec3..a4af6a17 100644 --- a/radicle-cli/tests/framework/mod.rs +++ b/radicle-cli/tests/framework/mod.rs @@ -70,6 +70,16 @@ impl TestFormula { self } + pub fn envs( + &mut self, + envs: impl IntoIterator, + ) -> &mut Self { + for (k, v) in envs { + self.env.insert(k.to_string(), v.to_string()); + } + self + } + pub fn file(&mut self, path: impl AsRef) -> Result<&mut Self, Error> { let contents = fs::read(path)?; self.read(io::Cursor::new(contents)) diff --git a/radicle-crypto/src/ssh/keystore.rs b/radicle-crypto/src/ssh/keystore.rs index e69165ee..b7348f9d 100644 --- a/radicle-crypto/src/ssh/keystore.rs +++ b/radicle-crypto/src/ssh/keystore.rs @@ -201,8 +201,7 @@ impl MemorySigner { /// Generate a new memory signer. pub fn gen() -> Self { - let seed = crate::Seed::generate(); - let keypair = KeyPair::from_seed(seed); + let keypair = KeyPair::generate(); let sk = keypair.sk; Self {