aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--atuin/tests/common/mod.rs99
-rw-r--r--atuin/tests/sync.rs158
-rw-r--r--atuin/tests/users.rs131
3 files changed, 233 insertions, 155 deletions
diff --git a/atuin/tests/common/mod.rs b/atuin/tests/common/mod.rs
new file mode 100644
index 00000000..bda6abd3
--- /dev/null
+++ b/atuin/tests/common/mod.rs
@@ -0,0 +1,99 @@
+use std::{env, time::Duration};
+
+use atuin_client::api_client;
+use atuin_common::{api::AddHistoryRequest, utils::uuid_v7};
+use atuin_server::{launch_with_tcp_listener, Settings as ServerSettings};
+use atuin_server_postgres::{Postgres, PostgresSettings};
+use futures_util::TryFutureExt;
+use time::OffsetDateTime;
+use tokio::{net::TcpListener, sync::oneshot, task::JoinHandle};
+use tracing::{dispatcher, Dispatch};
+use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
+
+pub async fn start_server(path: &str) -> (String, oneshot::Sender<()>, JoinHandle<()>) {
+ let formatting_layer = tracing_tree::HierarchicalLayer::default()
+ .with_writer(tracing_subscriber::fmt::TestWriter::new())
+ .with_indent_lines(true)
+ .with_ansi(true)
+ .with_targets(true)
+ .with_indent_amount(2);
+
+ let dispatch: Dispatch = tracing_subscriber::registry()
+ .with(formatting_layer)
+ .with(EnvFilter::new("atuin_server=debug,atuin_client=debug,info"))
+ .into();
+
+ let db_uri = env::var("ATUIN_DB_URI")
+ .unwrap_or_else(|_| "postgres://atuin:pass@localhost:5432/atuin".to_owned());
+
+ let server_settings = ServerSettings {
+ host: "127.0.0.1".to_owned(),
+ port: 0,
+ path: path.to_owned(),
+ open_registration: true,
+ max_history_length: 8192,
+ max_record_size: 1024 * 1024 * 1024,
+ page_size: 1100,
+ register_webhook_url: None,
+ register_webhook_username: String::new(),
+ db_settings: PostgresSettings { db_uri },
+ metrics: atuin_server::settings::Metrics::default(),
+ tls: atuin_server::settings::Tls::default(),
+ };
+
+ let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel();
+ let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
+ let addr = listener.local_addr().unwrap();
+ let server = tokio::spawn(async move {
+ let _tracing_guard = dispatcher::set_default(&dispatch);
+
+ if let Err(e) = launch_with_tcp_listener::<Postgres>(
+ server_settings,
+ listener,
+ shutdown_rx.unwrap_or_else(|_| ()),
+ )
+ .await
+ {
+ tracing::error!(error=?e, "server error");
+ panic!("error running server: {e:?}");
+ }
+ });
+
+ // let the server come online
+ tokio::time::sleep(Duration::from_millis(200)).await;
+
+ (format!("http://{addr}{path}"), shutdown_tx, server)
+}
+
+pub async fn register_inner<'a>(
+ address: &'a str,
+ username: &str,
+ password: &str,
+) -> api_client::Client<'a> {
+ let email = format!("{}@example.com", uuid_v7().as_simple());
+
+ // registration works
+ let registration_response = api_client::register(address, username, &email, password)
+ .await
+ .unwrap();
+
+ api_client::Client::new(address, &registration_response.session, 5, 30).unwrap()
+}
+
+pub async fn login(address: &str, username: String, password: String) -> api_client::Client<'_> {
+ // registration works
+ let login_respose = api_client::login(
+ address,
+ atuin_common::api::LoginRequest { username, password },
+ )
+ .await
+ .unwrap();
+
+ api_client::Client::new(address, &login_respose.session, 5, 30).unwrap()
+}
+
+pub async fn register(address: &str) -> api_client::Client<'_> {
+ let username = uuid_v7().as_simple().to_string();
+ let password = uuid_v7().as_simple().to_string();
+ register_inner(address, &username, &password).await
+}
diff --git a/atuin/tests/sync.rs b/atuin/tests/sync.rs
index 6dacbd54..1835b20b 100644
--- a/atuin/tests/sync.rs
+++ b/atuin/tests/sync.rs
@@ -10,166 +10,14 @@ use tokio::{net::TcpListener, sync::oneshot, task::JoinHandle};
use tracing::{dispatcher, Dispatch};
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
-async fn start_server(path: &str) -> (String, oneshot::Sender<()>, JoinHandle<()>) {
- let formatting_layer = tracing_tree::HierarchicalLayer::default()
- .with_writer(tracing_subscriber::fmt::TestWriter::new())
- .with_indent_lines(true)
- .with_ansi(true)
- .with_targets(true)
- .with_indent_amount(2);
-
- let dispatch: Dispatch = tracing_subscriber::registry()
- .with(formatting_layer)
- .with(EnvFilter::new("atuin_server=debug,atuin_client=debug,info"))
- .into();
-
- let db_uri = env::var("ATUIN_DB_URI")
- .unwrap_or_else(|_| "postgres://atuin:pass@localhost:5432/atuin".to_owned());
-
- let server_settings = ServerSettings {
- host: "127.0.0.1".to_owned(),
- port: 0,
- path: path.to_owned(),
- open_registration: true,
- max_history_length: 8192,
- max_record_size: 1024 * 1024 * 1024,
- page_size: 1100,
- register_webhook_url: None,
- register_webhook_username: String::new(),
- db_settings: PostgresSettings { db_uri },
- metrics: atuin_server::settings::Metrics::default(),
- tls: atuin_server::settings::Tls::default(),
- };
-
- let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel();
- let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
- let addr = listener.local_addr().unwrap();
- let server = tokio::spawn(async move {
- let _tracing_guard = dispatcher::set_default(&dispatch);
-
- if let Err(e) = launch_with_tcp_listener::<Postgres>(
- server_settings,
- listener,
- shutdown_rx.unwrap_or_else(|_| ()),
- )
- .await
- {
- tracing::error!(error=?e, "server error");
- panic!("error running server: {e:?}");
- }
- });
-
- // let the server come online
- tokio::time::sleep(Duration::from_millis(200)).await;
-
- (format!("http://{addr}{path}"), shutdown_tx, server)
-}
-
-async fn register_inner<'a>(
- address: &'a str,
- username: &str,
- password: &str,
-) -> api_client::Client<'a> {
- let email = format!("{}@example.com", uuid_v7().as_simple());
-
- // registration works
- let registration_response = api_client::register(address, username, &email, password)
- .await
- .unwrap();
-
- api_client::Client::new(address, &registration_response.session, 5, 30).unwrap()
-}
-
-async fn login(address: &str, username: String, password: String) -> api_client::Client<'_> {
- // registration works
- let login_respose = api_client::login(
- address,
- atuin_common::api::LoginRequest { username, password },
- )
- .await
- .unwrap();
-
- api_client::Client::new(address, &login_respose.session, 5, 30).unwrap()
-}
-
-async fn register(address: &str) -> api_client::Client<'_> {
- let username = uuid_v7().as_simple().to_string();
- let password = uuid_v7().as_simple().to_string();
- register_inner(address, &username, &password).await
-}
-
-#[tokio::test]
-async fn registration() {
- let path = format!("/{}", uuid_v7().as_simple());
- let (address, shutdown, server) = start_server(&path).await;
- dbg!(&address);
-
- // -- REGISTRATION --
-
- let username = uuid_v7().as_simple().to_string();
- let password = uuid_v7().as_simple().to_string();
- let client = register_inner(&address, &username, &password).await;
-
- // the session token works
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- // -- LOGIN --
-
- let client = login(&address, username.clone(), password).await;
-
- // the session token works
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- shutdown.send(()).unwrap();
- server.await.unwrap();
-}
-
-#[tokio::test]
-async fn change_password() {
- let path = format!("/{}", uuid_v7().as_simple());
- let (address, shutdown, server) = start_server(&path).await;
-
- // -- REGISTRATION --
-
- let username = uuid_v7().as_simple().to_string();
- let password = uuid_v7().as_simple().to_string();
- let client = register_inner(&address, &username, &password).await;
-
- // the session token works
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- // -- PASSWORD CHANGE --
-
- let current_password = password;
- let new_password = uuid_v7().as_simple().to_string();
- let result = client
- .change_password(current_password, new_password.clone())
- .await;
-
- // the password change request succeeded
- assert!(result.is_ok());
-
- // -- LOGIN --
-
- let client = login(&address, username.clone(), new_password).await;
-
- // login with new password yields a working token
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- shutdown.send(()).unwrap();
- server.await.unwrap();
-}
+mod common;
#[tokio::test]
async fn sync() {
let path = format!("/{}", uuid_v7().as_simple());
- let (address, shutdown, server) = start_server(&path).await;
+ let (address, shutdown, server) = common::start_server(&path).await;
- let client = register(&address).await;
+ let client = common::register(&address).await;
let hostname = uuid_v7().as_simple().to_string();
let now = OffsetDateTime::now_utc();
diff --git a/atuin/tests/users.rs b/atuin/tests/users.rs
new file mode 100644
index 00000000..8580d64c
--- /dev/null
+++ b/atuin/tests/users.rs
@@ -0,0 +1,131 @@
+use std::{env, time::Duration};
+
+use atuin_client::api_client;
+use atuin_common::{api::AddHistoryRequest, utils::uuid_v7};
+use atuin_server::{launch_with_tcp_listener, Settings as ServerSettings};
+use atuin_server_postgres::{Postgres, PostgresSettings};
+use futures_util::TryFutureExt;
+use time::OffsetDateTime;
+use tokio::{net::TcpListener, sync::oneshot, task::JoinHandle};
+use tracing::{dispatcher, Dispatch};
+use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
+
+mod common;
+
+#[tokio::test]
+async fn registration() {
+ let path = format!("/{}", uuid_v7().as_simple());
+ let (address, shutdown, server) = common::start_server(&path).await;
+ dbg!(&address);
+
+ // -- REGISTRATION --
+
+ let username = uuid_v7().as_simple().to_string();
+ let password = uuid_v7().as_simple().to_string();
+ let client = common::register_inner(&address, &username, &password).await;
+
+ // the session token works
+ let status = client.status().await.unwrap();
+ assert_eq!(status.username, username);
+
+ // -- LOGIN --
+
+ let client = common::login(&address, username.clone(), password).await;
+
+ // the session token works
+ let status = client.status().await.unwrap();
+ assert_eq!(status.username, username);
+
+ shutdown.send(()).unwrap();
+ server.await.unwrap();
+}
+
+#[tokio::test]
+async fn change_password() {
+ let path = format!("/{}", uuid_v7().as_simple());
+ let (address, shutdown, server) = common::start_server(&path).await;
+
+ // -- REGISTRATION --
+
+ let username = uuid_v7().as_simple().to_string();
+ let password = uuid_v7().as_simple().to_string();
+ let client = common::register_inner(&address, &username, &password).await;
+
+ // the session token works
+ let status = client.status().await.unwrap();
+ assert_eq!(status.username, username);
+
+ // -- PASSWORD CHANGE --
+
+ let current_password = password;
+ let new_password = uuid_v7().as_simple().to_string();
+ let result = client
+ .change_password(current_password, new_password.clone())
+ .await;
+
+ // the password change request succeeded
+ assert!(result.is_ok());
+
+ // -- LOGIN --
+
+ let client = common::login(&address, username.clone(), new_password).await;
+
+ // login with new password yields a working token
+ let status = client.status().await.unwrap();
+ assert_eq!(status.username, username);
+
+ shutdown.send(()).unwrap();
+ server.await.unwrap();
+}
+
+#[tokio::test]
+async fn multi_user_test() {
+ let path = format!("/{}", uuid_v7().as_simple());
+ let (address, shutdown, server) = common::start_server(&path).await;
+ dbg!(&address);
+
+ // -- REGISTRATION --
+
+ let user_one = uuid_v7().as_simple().to_string();
+ let password_one = uuid_v7().as_simple().to_string();
+ let client_one = common::register_inner(&address, &user_one, &password_one).await;
+
+ // the session token works
+ let status = client_one.status().await.unwrap();
+ assert_eq!(status.username, user_one);
+
+ let user_two = uuid_v7().as_simple().to_string();
+ let password_two = uuid_v7().as_simple().to_string();
+ let client_two = common::register_inner(&address, &user_two, &password_two).await;
+
+ // the session token works
+ let status = client_two.status().await.unwrap();
+ assert_eq!(status.username, user_two);
+
+ // check that we can change user one's password, and _this does not affect user two_
+
+ let current_password = password_one;
+ let new_password = uuid_v7().as_simple().to_string();
+ let result = client_one
+ .change_password(current_password, new_password.clone())
+ .await;
+
+ // the password change request succeeded
+ assert!(result.is_ok());
+
+ // -- LOGIN --
+
+ let client_one = common::login(&address, user_one.clone(), new_password).await;
+ let client_two = common::login(&address, user_two.clone(), password_two).await;
+
+ // login with new password yields a working token
+ let status = client_one.status().await.unwrap();
+ assert_eq!(status.username, user_one);
+ assert_ne!(status.username, user_two);
+
+ let status = client_two.status().await.unwrap();
+ assert_eq!(status.username, user_two);
+
+ shutdown.send(()).unwrap();
+ server.await.unwrap();
+}