From cd61e67dd61e7a195e21b18ef57f2d91b3b48568 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 14:43:49 -0400 Subject: [PATCH 01/13] Adding functions to db::message module --- src/repo/message.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/repo/message.rs b/src/repo/message.rs index 312e893..0e3b015 100644 --- a/src/repo/message.rs +++ b/src/repo/message.rs @@ -23,3 +23,69 @@ pub async fn insert( Err(_) => Err(sqlx::Error::RowNotFound), } } + +pub async fn get( + pool: &sqlx::PgPool, + id: &uuid::Uuid, +) -> Result { + match sqlx::query( + r#" + SELECT id, content, user_id FROM "messages" + WHERE + id = $1; + "#, + ) + .bind(id) + .fetch_one(pool) + .await + { + Ok(row) => { + let id: uuid::Uuid = row.try_get("id")?; + + let content: String = row.try_get("content")?; + let user_id: uuid::Uuid = row.try_get("user_id")?; + Ok(textsender_models::message::Message { + id: Some(id), + content, + user_id: Some(user_id), + }) + } + Err(_) => Err(sqlx::Error::RowNotFound), + } +} + +pub async fn get_with_user_id( + pool: &sqlx::PgPool, + user_id: &uuid::Uuid, +) -> Result, sqlx::Error> { + match sqlx::query( + r#" + SELECT id, content, user_id FROM "messages" + WHERE + user_id = $1; + "#, + ) + .bind(user_id) + .fetch_all(pool) + .await + { + Ok(rows) => { + let mut messages: Vec = Vec::new(); + for row in rows { + let id: uuid::Uuid = row.try_get("id")?; + let content: String = row.try_get("content")?; + let user_id: uuid::Uuid = row.try_get("user_id")?; + + let message = textsender_models::message::Message { + id: Some(id), + content, + user_id: Some(user_id), + }; + messages.push(message); + } + + Ok(messages) + } + Err(_) => Err(sqlx::Error::RowNotFound), + } +} -- 2.47.3 From 24dca570a53eddf28b8334725cbc2c67f72b1911 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 14:44:04 -0400 Subject: [PATCH 02/13] Adding code to get messages endpoint --- src/caller/contact.rs | 2 +- src/caller/message.rs | 67 +++++++++++++++++++++++++++++++++++++++++++ src/caller/mod.rs | 2 ++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/caller/contact.rs b/src/caller/contact.rs index 3b07568..6093df5 100644 --- a/src/caller/contact.rs +++ b/src/caller/contact.rs @@ -171,7 +171,7 @@ pub mod endpoint { } } - // Endpoint to get songs + /// Endpoint to get Contacts #[utoipa::path( get, path = super::super::endpoints::GET_CONTACT, diff --git a/src/caller/message.rs b/src/caller/message.rs index 05d8280..b262dea 100644 --- a/src/caller/message.rs +++ b/src/caller/message.rs @@ -13,6 +13,12 @@ pub mod request { !self.content.is_empty() || !self.user_id.is_nil() } } + + #[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)] + pub struct GetMessageParams { + pub id: Option, + pub user_id: Option, + } } pub mod response { @@ -24,6 +30,8 @@ pub mod response { pub message: String, pub data: Vec, } + + pub use AddMessageResponse as GetMessageResponse; } pub mod endpoint { @@ -81,4 +89,63 @@ pub mod endpoint { (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) } } + + /// Endpoint to get Messages + #[utoipa::path( + get, + path = super::super::endpoints::GET_MESSAGE, + params( + ("id" = uuid::Uuid, Path, description = "Id of Message"), + ("user_id" = uuid::Uuid, Path, description = "User Id associated with the Message") + ), + responses( + (status = 200, description = "Songs found", body = super::response::GetMessageResponse), + (status = 400, description = "Error getting songs", body = super::response::GetMessageResponse) + ) + )] + pub async fn get_messages( + axum::Extension(pool): axum::Extension, + axum::extract::Query(params): axum::extract::Query, + ) -> ( + axum::http::StatusCode, + axum::Json, + ) { + let mut response = super::response::GetMessageResponse::default(); + + let messages = match params.id { + Some(id) => match message_repo::get(&pool, &id).await { + Ok(message) => { + vec![message] + } + Err(err) => { + eprintln!("Error: {err:?}"); + return ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response), + ); + } + }, + None => match params.user_id { + Some(user_id) => match message_repo::get_with_user_id(&pool, &user_id).await { + Ok(messages) => messages, + Err(err) => { + eprintln!("Error: {err:?}"); + return ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response), + ); + } + }, + None => { + response.message = String::from("Invalid parameter"); + return (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)); + } + }, + }; + + response.data = messages; + response.message = String::from(super::super::response::SUCCESSFUL); + + (axum::http::StatusCode::OK, axum::Json(response)) + } } diff --git a/src/caller/mod.rs b/src/caller/mod.rs index 85b102e..3a9e62a 100644 --- a/src/caller/mod.rs +++ b/src/caller/mod.rs @@ -12,6 +12,8 @@ pub mod endpoints { pub const UPDATE_CONTACT_NAME: &str = "/api/v1/contact/update"; /// Constant for adding message endpoint pub const ADD_MESSAGE: &str = "/api/v1/message/new"; + /// Constant for getting messages endpoint + pub const GET_MESSAGE: &str = "/api/v1/message"; } pub mod response { -- 2.47.3 From c9968818a47dfc8ffb9c21c9a2c195002b08f617 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 14:44:30 -0400 Subject: [PATCH 03/13] Making endpoint available --- src/config/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/config/mod.rs b/src/config/mod.rs index f8a03e9..f795269 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -111,6 +111,12 @@ pub mod init { crate::auth::auth::, )), ) + .route( + crate::caller::endpoints::GET_MESSAGE, + post(message_endpoints::get_messages).route_layer(axum::middleware::from_fn( + crate::auth::auth::, + )), + ) .layer(cors::configure_cors().await) } -- 2.47.3 From 6cb57f5f41906ee44f7e61c36aa0b4df254a71de Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 14:51:16 -0400 Subject: [PATCH 04/13] Fixed endpoint routing issue --- src/config/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index f795269..111e1b0 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -113,7 +113,7 @@ pub mod init { ) .route( crate::caller::endpoints::GET_MESSAGE, - post(message_endpoints::get_messages).route_layer(axum::middleware::from_fn( + get(message_endpoints::get_messages).route_layer(axum::middleware::from_fn( crate::auth::auth::, )), ) -- 2.47.3 From 2287ac9d226de57d04e914c3583861dd9ea77a5d Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 14:57:15 -0400 Subject: [PATCH 05/13] Adding workflow for tests --- .gitea/workflows/tests.yml | 91 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 .gitea/workflows/tests.yml diff --git a/.gitea/workflows/tests.yml b/.gitea/workflows/tests.yml new file mode 100644 index 0000000..5d64798 --- /dev/null +++ b/.gitea/workflows/tests.yml @@ -0,0 +1,91 @@ +name: Rust Build + +on: + pull_request: + branches: + - alot_of_changes + + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Test Suite + runs-on: ubuntu-24.04 + # --- Add database service definition --- + services: + postgres: + image: postgres:18.3-alpine + env: + # Use secrets for DB init, with fallbacks for flexibility + POSTGRES_USER: ${{ secrets.DB_TEST_USER || 'testuser' }} + POSTGRES_PASSWORD: ${{ secrets.DB_TEST_PASSWORD || 'testpassword' }} + POSTGRES_DB: ${{ secrets.DB_TEST_NAME || 'testdb' }} + POSTGRES_PORT: ${{ secrets.DB_PORT || 5432 }} + # Options to wait until the database is ready + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v5 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: 1.96 + # --- Add this step for explicit verification --- + - name: Verify Docker Environment + run: | + echo "Runner User Info:" + id + echo "Checking Docker Version:" + docker --version + echo "Checking Docker Daemon Status (info):" + docker info + echo "Checking Docker Daemon Status (ps):" + docker ps -a + echo "Docker environment check complete." + # NOTE: Do NOT use continue-on-error here. + # If Docker isn't working as expected, the job SHOULD fail here. + - name: Run tests + env: + # Define DATABASE_URL for tests to use + DATABASE_URL: postgresql://${{ secrets.DB_TEST_USER || 'testuser' }}:${{ secrets.DB_TEST_PASSWORD || 'testpassword' }}@postgres:${{ secrets.DB_PORT || 5432 }}/${{ secrets.DB_TEST_NAME || 'testdb' }} + RUST_LOG: info # Optional: configure test log level + SECRET_MAIN_KEY: ${{ secrets.SECRET_KEY }} + # Make SSH agent available if tests fetch private dependencies + SSH_AUTH_SOCK: ${{ env.SSH_AUTH_SOCK }} + ENABLE_REGISTRATION: 'TRUE' + run: | + mkdir -p ~/.ssh + echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/textsender-models_deploy_key + chmod 600 ~/.ssh/textsender-models_deploy_key + ssh-keyscan ${{ secrets.MY_HOST }} >> ~/.ssh/known_hosts + + eval $(ssh-agent -s) + ssh-add -v ~/.ssh/textsender-models_deploy_key + + cargo test + + fmt: + name: Rustfmt + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v5 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: 1.96 + - run: rustup component add rustfmt + - uses: Swatinem/rust-cache@v2 + - run: | + mkdir -p ~/.ssh + echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/textsender-models_deploy_key + chmod 600 ~/.ssh/textsender-models_deploy_key + ssh-keyscan ${{ secrets.MY_HOST }} >> ~/.ssh/known_hosts + + eval $(ssh-agent -s) + ssh-add -v ~/.ssh/textsender-models_deploy_key + cargo fmt --all -- --check -- 2.47.3 From 224d278bdf84b538c1bc3abce9422b241c7beff3 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:02:09 -0400 Subject: [PATCH 06/13] Clean up --- src/caller/message.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/caller/message.rs b/src/caller/message.rs index b262dea..3e07c0a 100644 --- a/src/caller/message.rs +++ b/src/caller/message.rs @@ -31,7 +31,7 @@ pub mod response { pub data: Vec, } - pub use AddMessageResponse as GetMessageResponse; + pub use AddMessageResponse as GetMessageResponse; } pub mod endpoint { -- 2.47.3 From ebabd77369df129fde24926fe8dc1ffd5e549b33 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:11:17 -0400 Subject: [PATCH 07/13] Test changes --- tests/test.rs | 100 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/tests/test.rs b/tests/test.rs index 801fc62..437c80a 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -170,12 +170,13 @@ mod request { pub async fn create_contact( app: &axum::Router, - ) -> Result { + ) -> Result { let payload = serde_json::json!({ "phone_number": super::TEST_CONTACT_PHONE_NUMBER, "user_id": super::TEST_USER_ID, }); + /* let req = axum::http::Request::builder() .method(axum::http::Method::POST) .uri(textsender_api::caller::endpoints::ADD_CONTACT) @@ -186,7 +187,20 @@ mod request { ) .body(axum::body::Body::from(payload.to_string())) .unwrap(); - app.clone().oneshot(req).await + */ + match run_post( + &payload, + textsender_api::caller::endpoints::ADD_CONTACT, + axum::http::Method::POST, + ) + .await + { + Ok(req) => match app.clone().oneshot(req).await { + Ok(response) => Ok(response), + Err(err) => Err(axum::http::Error::from(err)), + }, + Err(err) => Err(err), + } } pub async fn get_contact( @@ -240,6 +254,77 @@ mod request { .unwrap(); app.clone().oneshot(req).await } + + /* + pub mod message { + pub async fn create_message( + app: &axum::Router, + ) -> Result { + let payload = serde_json::json!({ + "content": super::TEST_MESSAGE_CONTENT, + "user_id": super::TEST_USER_ID, + }); + + let req = axum::http::Request::builder() + .method(axum::http::Method::POST) + .uri(textsender_api::caller::endpoints::ADD_MESSAGE) + .header(axum::http::header::CONTENT_TYPE, "application/json") + .header( + axum::http::header::AUTHORIZATION, + super::bearer_auth().await, + ) + .body(axum::body::Body::from(payload.to_string())) + .unwrap(); + app.clone().oneshot(req).await + } + + pub async fn get_contact( + app: &axum::Router, + id: &uuid::Uuid, + ) -> Result { + let uri = format!( + "{}?id={}", + textsender_api::caller::endpoints::GET_CONTACT, + id + ); + + let req = axum::http::Request::builder() + .method(axum::http::Method::GET) + .uri(uri) + .header(axum::http::header::CONTENT_TYPE, "application/json") + .header( + axum::http::header::AUTHORIZATION, + super::bearer_auth().await, + ) + .body(axum::body::Body::empty()) + .unwrap(); + + app.clone().oneshot(req).await + } + } + */ + + pub async fn run_post( + payload: &serde_json::Value, + uri: &str, + method: axum::http::Method, + ) -> Result, axum::http::Error> { + // textsender_api::caller::endpoints::ADD_MESSAGE) + //axum::http::Method::POST) + match axum::http::Request::builder() + .method(method) + .uri(uri) + .header(axum::http::header::CONTENT_TYPE, "application/json") + .header( + axum::http::header::AUTHORIZATION, + super::bearer_auth().await, + ) + .body(axum::body::Body::from(payload.to_string())) + { + Ok(t) => Ok(t), + Err(err) => Err(err), + } + } } /// Test contact phone number @@ -252,6 +337,9 @@ pub const TEST_CONTACT_UPDATED_LASTNAME: &str = "CASH"; /// Test contact updated nickname pub const TEST_CONTACT_UPDATED_NICKNAME: &str = "The Man in Black"; +/// Test message content +pub const TEST_MESSAGE_CONTENT: &str = "The wind cries mary"; + #[tokio::test] async fn test_create_contact() { let tm_pool = db_mgr::get_pool().await.unwrap(); @@ -433,3 +521,11 @@ async fn test_update_contact_names() { let _ = db_mgr::drop_database(&tm_pool, &db_name).await; } + +/* +#[tokio::test] +async fn test_ + +#[tokio::test] +async fn test_ +*/ -- 2.47.3 From 22b6478c07cb3241e966a9e56b78fd4ec375f3b9 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:28:01 -0400 Subject: [PATCH 08/13] Test change --- tests/test.rs | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/tests/test.rs b/tests/test.rs index 437c80a..942598c 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -176,22 +176,11 @@ mod request { "user_id": super::TEST_USER_ID, }); - /* - let req = axum::http::Request::builder() - .method(axum::http::Method::POST) - .uri(textsender_api::caller::endpoints::ADD_CONTACT) - .header(axum::http::header::CONTENT_TYPE, "application/json") - .header( - axum::http::header::AUTHORIZATION, - super::bearer_auth().await, - ) - .body(axum::body::Body::from(payload.to_string())) - .unwrap(); - */ match run_post( - &payload, + Some(&payload), textsender_api::caller::endpoints::ADD_CONTACT, axum::http::Method::POST, + true, ) .await { @@ -206,13 +195,22 @@ mod request { pub async fn get_contact( app: &axum::Router, id: &uuid::Uuid, - ) -> Result { + ) -> Result { let uri = format!( "{}?id={}", textsender_api::caller::endpoints::GET_CONTACT, id ); + match run_post(None, &uri, axum::http::Method::GET, false).await { + Ok(req) => match app.clone().oneshot(req).await { + Ok(response) => Ok(response), + Err(err) => Err(axum::http::Error::from(err)), + }, + Err(err) => Err(err), + } + + /* let req = axum::http::Request::builder() .method(axum::http::Method::GET) .uri(uri) @@ -225,6 +223,7 @@ mod request { .unwrap(); app.clone().oneshot(req).await + */ } pub async fn update_contact_names( @@ -305,12 +304,21 @@ mod request { */ pub async fn run_post( - payload: &serde_json::Value, + payload: Option<&serde_json::Value>, uri: &str, method: axum::http::Method, + has_body: bool, ) -> Result, axum::http::Error> { - // textsender_api::caller::endpoints::ADD_MESSAGE) - //axum::http::Method::POST) + let body = if has_body { + assert_eq!( + true, + payload.is_some(), + "Has request body and payload has data" + ); + axum::body::Body::from(payload.unwrap().to_string()) + } else { + axum::body::Body::empty() + }; match axum::http::Request::builder() .method(method) .uri(uri) @@ -319,7 +327,7 @@ mod request { axum::http::header::AUTHORIZATION, super::bearer_auth().await, ) - .body(axum::body::Body::from(payload.to_string())) + .body(body) { Ok(t) => Ok(t), Err(err) => Err(err), -- 2.47.3 From 0f7f9fb8031a5e54647e58cff896fb4ad2336b74 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:40:00 -0400 Subject: [PATCH 09/13] Code changes --- tests/test.rs | 153 ++++++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 72 deletions(-) diff --git a/tests/test.rs b/tests/test.rs index 942598c..9056a62 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -129,8 +129,22 @@ pub fn token_fields() -> (String, String, String) { ) } +/// Test User Id pub const TEST_USER_ID: uuid::Uuid = uuid::uuid!("cc938368-615a-4694-b2ca-6e122fa31c52"); +/// Test contact phone number +pub const TEST_CONTACT_PHONE_NUMBER: &str = "+10123456789"; + +/// Test contact updated firstname +pub const TEST_CONTACT_UPDATED_FIRSTNAME: &str = "Johnny"; +/// Test contact updated lastname +pub const TEST_CONTACT_UPDATED_LASTNAME: &str = "CASH"; +/// Test contact updated nickname +pub const TEST_CONTACT_UPDATED_NICKNAME: &str = "The Man in Black"; + +/// Test message content +pub const TEST_MESSAGE_CONTENT: &str = "The wind cries mary"; + pub async fn test_token() -> Result { let key: String = textsender_models::envy::environment::get_secret_main_key() .await @@ -209,21 +223,6 @@ mod request { }, Err(err) => Err(err), } - - /* - let req = axum::http::Request::builder() - .method(axum::http::Method::GET) - .uri(uri) - .header(axum::http::header::CONTENT_TYPE, "application/json") - .header( - axum::http::header::AUTHORIZATION, - super::bearer_auth().await, - ) - .body(axum::body::Body::empty()) - .unwrap(); - - app.clone().oneshot(req).await - */ } pub async fn update_contact_names( @@ -232,7 +231,7 @@ mod request { firstname: Option<&str>, lastname: Option<&str>, nickname: Option<&str>, - ) -> Result { + ) -> Result { let payload = serde_json::json!({ "firstname": firstname, "lastname": lastname, @@ -241,67 +240,54 @@ mod request { "id": id }); - let req = axum::http::Request::builder() - .method(axum::http::Method::PATCH) - .uri(textsender_api::caller::endpoints::UPDATE_CONTACT_NAME) - .header(axum::http::header::CONTENT_TYPE, "application/json") - .header( - axum::http::header::AUTHORIZATION, - super::bearer_auth().await, - ) - .body(axum::body::Body::from(payload.to_string())) - .unwrap(); - app.clone().oneshot(req).await + match run_post(Some(&payload), textsender_api::caller::endpoints::UPDATE_CONTACT_NAME, axum::http::Method::PATCH, true).await { + Ok(req) => match app.clone().oneshot(req).await { + Ok(response) => Ok(response), + Err(err) => Err(axum::http::Error::from(err)), + }, + Err(err) => Err(err), + } } - /* pub mod message { + use tower::ServiceExt; + pub async fn create_message( app: &axum::Router, - ) -> Result { + ) -> Result { let payload = serde_json::json!({ - "content": super::TEST_MESSAGE_CONTENT, - "user_id": super::TEST_USER_ID, + "content": super::super::TEST_MESSAGE_CONTENT, + "user_id": super::super::TEST_USER_ID, }); - let req = axum::http::Request::builder() - .method(axum::http::Method::POST) - .uri(textsender_api::caller::endpoints::ADD_MESSAGE) - .header(axum::http::header::CONTENT_TYPE, "application/json") - .header( - axum::http::header::AUTHORIZATION, - super::bearer_auth().await, - ) - .body(axum::body::Body::from(payload.to_string())) - .unwrap(); - app.clone().oneshot(req).await + match super::run_post(Some(&payload), textsender_api::caller::endpoints::ADD_MESSAGE, axum::http::Method::POST, true).await { + Ok(req) => match app.clone().oneshot(req).await { + Ok(response) => Ok(response), + Err(err) => Err(axum::http::Error::from(err)), + }, + Err(err) => Err(err), + } } pub async fn get_contact( app: &axum::Router, id: &uuid::Uuid, - ) -> Result { + ) -> Result { let uri = format!( "{}?id={}", textsender_api::caller::endpoints::GET_CONTACT, id ); - let req = axum::http::Request::builder() - .method(axum::http::Method::GET) - .uri(uri) - .header(axum::http::header::CONTENT_TYPE, "application/json") - .header( - axum::http::header::AUTHORIZATION, - super::bearer_auth().await, - ) - .body(axum::body::Body::empty()) - .unwrap(); - - app.clone().oneshot(req).await + match super::run_post(None, &uri, axum::http::Method::GET, false).await { + Ok(req) => match app.clone().oneshot(req).await { + Ok(response) => Ok(response), + Err(err) => Err(axum::http::Error::from(err)), + }, + Err(err) => Err(err), + } } } - */ pub async fn run_post( payload: Option<&serde_json::Value>, @@ -335,18 +321,6 @@ mod request { } } -/// Test contact phone number -pub const TEST_CONTACT_PHONE_NUMBER: &str = "+10123456789"; - -/// Test contact updated firstname -pub const TEST_CONTACT_UPDATED_FIRSTNAME: &str = "Johnny"; -/// Test contact updated lastname -pub const TEST_CONTACT_UPDATED_LASTNAME: &str = "CASH"; -/// Test contact updated nickname -pub const TEST_CONTACT_UPDATED_NICKNAME: &str = "The Man in Black"; - -/// Test message content -pub const TEST_MESSAGE_CONTENT: &str = "The wind cries mary"; #[tokio::test] async fn test_create_contact() { @@ -530,10 +504,45 @@ async fn test_update_contact_names() { let _ = db_mgr::drop_database(&tm_pool, &db_name).await; } +#[tokio::test] +async fn test_create_message() { + let tm_pool = db_mgr::get_pool().await.unwrap(); + let db_name = db_mgr::generate_db_name().await; + + match db_mgr::create_database(&tm_pool, &db_name).await { + Ok(_) => { + println!("Success"); + } + Err(err) => { + assert!(false, "Error: {:?}", err); + } + } + + let pool = db_mgr::connect_to_db(&db_name).await.unwrap(); + db::migrations(&pool).await; + + let app = init::app(pool).await; + + // Send request + match request::message::create_message(&app).await { + Ok(response) => { + let resp = util::get_resp_data::< + textsender_api::caller::message::response::AddMessageResponse, + >(response) + .await; + assert_eq!(false, resp.data.is_empty(), "Should not be empty"); + let message = &resp.data[0]; + assert_eq!(TEST_MESSAGE_CONTENT, message.content, "The content of the created message should match"); + } + Err(err) => { + assert!(false, "Error: {:?}", err); + } + }; + + let _ = db_mgr::drop_database(&tm_pool, &db_name).await; +} + /* #[tokio::test] -async fn test_ - -#[tokio::test] -async fn test_ +async fn test_get_message() */ -- 2.47.3 From c9d3bef42a26976b83c8f1446853f48f0cca5b24 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:45:36 -0400 Subject: [PATCH 10/13] Removing base64 dependency --- Cargo.lock | 1 - Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 29d1fdd..b8944f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2297,7 +2297,6 @@ version = "0.1.8" dependencies = [ "axum", "axum-extra", - "base64", "common-multipart-rfc7578", "futures", "josekit", diff --git a/Cargo.toml b/Cargo.toml index 5797080..1a544c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ uuid = { version = "1.23.3", features = ["v4", "serde"] } sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-native-tls", "time", "uuid"] } time = { version = "0.3.49", features = ["formatting", "macros", "parsing", "serde"] } thiserror = "2.0.18" -base64 = "0.22.1" +# base64 = "0.22.1" jsonwebtoken = { version = "10.4.0", features = ["rust_crypto"] } josekit = { version = "0.10.3" } utoipa = { version = "5.5.0", features = ["axum_extras"] } -- 2.47.3 From f2c264296917eef6e4ad76419599b5ce96302574 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:45:52 -0400 Subject: [PATCH 11/13] Adding tests --- tests/test.rs | 117 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 23 deletions(-) diff --git a/tests/test.rs b/tests/test.rs index 9056a62..6bb0b09 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -240,7 +240,14 @@ mod request { "id": id }); - match run_post(Some(&payload), textsender_api::caller::endpoints::UPDATE_CONTACT_NAME, axum::http::Method::PATCH, true).await { + match run_post( + Some(&payload), + textsender_api::caller::endpoints::UPDATE_CONTACT_NAME, + axum::http::Method::PATCH, + true, + ) + .await + { Ok(req) => match app.clone().oneshot(req).await { Ok(response) => Ok(response), Err(err) => Err(axum::http::Error::from(err)), @@ -250,7 +257,7 @@ mod request { } pub mod message { - use tower::ServiceExt; + use tower::ServiceExt; pub async fn create_message( app: &axum::Router, @@ -260,32 +267,39 @@ mod request { "user_id": super::super::TEST_USER_ID, }); - match super::run_post(Some(&payload), textsender_api::caller::endpoints::ADD_MESSAGE, axum::http::Method::POST, true).await { - Ok(req) => match app.clone().oneshot(req).await { - Ok(response) => Ok(response), - Err(err) => Err(axum::http::Error::from(err)), - }, - Err(err) => Err(err), - } + match super::run_post( + Some(&payload), + textsender_api::caller::endpoints::ADD_MESSAGE, + axum::http::Method::POST, + true, + ) + .await + { + Ok(req) => match app.clone().oneshot(req).await { + Ok(response) => Ok(response), + Err(err) => Err(axum::http::Error::from(err)), + }, + Err(err) => Err(err), + } } - pub async fn get_contact( + pub async fn get_message( app: &axum::Router, id: &uuid::Uuid, ) -> Result { let uri = format!( "{}?id={}", - textsender_api::caller::endpoints::GET_CONTACT, + textsender_api::caller::endpoints::GET_MESSAGE, id ); - match super::run_post(None, &uri, axum::http::Method::GET, false).await { - Ok(req) => match app.clone().oneshot(req).await { - Ok(response) => Ok(response), - Err(err) => Err(axum::http::Error::from(err)), - }, - Err(err) => Err(err), - } + match super::run_post(None, &uri, axum::http::Method::GET, false).await { + Ok(req) => match app.clone().oneshot(req).await { + Ok(response) => Ok(response), + Err(err) => Err(axum::http::Error::from(err)), + }, + Err(err) => Err(err), + } } } @@ -321,7 +335,6 @@ mod request { } } - #[tokio::test] async fn test_create_contact() { let tm_pool = db_mgr::get_pool().await.unwrap(); @@ -532,7 +545,10 @@ async fn test_create_message() { .await; assert_eq!(false, resp.data.is_empty(), "Should not be empty"); let message = &resp.data[0]; - assert_eq!(TEST_MESSAGE_CONTENT, message.content, "The content of the created message should match"); + assert_eq!( + TEST_MESSAGE_CONTENT, message.content, + "The content of the created message should match" + ); } Err(err) => { assert!(false, "Error: {:?}", err); @@ -542,7 +558,62 @@ async fn test_create_message() { let _ = db_mgr::drop_database(&tm_pool, &db_name).await; } -/* #[tokio::test] -async fn test_get_message() -*/ +async fn test_get_message() { + let tm_pool = db_mgr::get_pool().await.unwrap(); + let db_name = db_mgr::generate_db_name().await; + + match db_mgr::create_database(&tm_pool, &db_name).await { + Ok(_) => { + println!("Success"); + } + Err(err) => { + assert!(false, "Error: {:?}", err); + } + } + + let pool = db_mgr::connect_to_db(&db_name).await.unwrap(); + db::migrations(&pool).await; + + let app = init::app(pool).await; + let mut message_result: Option = None; + + // Send request + match request::message::create_message(&app).await { + Ok(response) => { + let resp = util::get_resp_data::< + textsender_api::caller::message::response::AddMessageResponse, + >(response) + .await; + assert_eq!(false, resp.data.is_empty(), "Should not be empty"); + let message = &resp.data[0]; + assert_eq!( + TEST_MESSAGE_CONTENT, message.content, + "The content of the created message should match" + ); + message_result = Some(message.clone()); + } + Err(err) => { + assert!(false, "Error: {:?}", err); + } + }; + + assert_eq!(true, message_result.is_some()); + + let message = message_result.unwrap(); + let message_id = message.id.unwrap(); + match request::message::get_message(&app, &message_id).await { + Ok(response) => { + let resp = util::get_resp_data::< + textsender_api::caller::message::response::GetMessageResponse, + >(response) + .await; + assert_eq!(false, resp.data.is_empty(), "Should not be empty"); + } + Err(err) => { + assert!(false, "Error: {err:?}"); + } + } + + let _ = db_mgr::drop_database(&tm_pool, &db_name).await; +} -- 2.47.3 From 8550a3caf56d211d5490b90e9e797a00e8ad34ed Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:49:23 -0400 Subject: [PATCH 12/13] Removing mime_guess and thiserror crates --- Cargo.lock | 2 -- Cargo.toml | 3 --- 2 files changed, 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8944f1..b23fd2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2301,13 +2301,11 @@ dependencies = [ "futures", "josekit", "jsonwebtoken", - "mime_guess", "serde", "serde_json", "sqlx", "tempfile", "textsender_models", - "thiserror 2.0.18", "time", "tokio", "tokio-util", diff --git a/Cargo.toml b/Cargo.toml index 1a544c5..5097a00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,12 +15,9 @@ tower = { version = "0.5.3", features = ["full"] } tower-http = { version = "0.6.11", features = ["cors", "timeout"] } tracing-subscriber = "0.3.23" futures = { version = "0.3.32" } -mime_guess = { version = "2.0.5" } uuid = { version = "1.23.3", features = ["v4", "serde"] } sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-native-tls", "time", "uuid"] } time = { version = "0.3.49", features = ["formatting", "macros", "parsing", "serde"] } -thiserror = "2.0.18" -# base64 = "0.22.1" jsonwebtoken = { version = "10.4.0", features = ["rust_crypto"] } josekit = { version = "0.10.3" } utoipa = { version = "5.5.0", features = ["axum_extras"] } -- 2.47.3 From 1453c513e68e30e98dd5051896dfc46983afbc03 Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 17 Jun 2026 15:50:35 -0400 Subject: [PATCH 13/13] bump: textsender_api --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b23fd2b..993ac87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2293,7 +2293,7 @@ dependencies = [ [[package]] name = "textsender_api" -version = "0.1.8" +version = "0.1.9" dependencies = [ "axum", "axum-extra", diff --git a/Cargo.toml b/Cargo.toml index 5097a00..44b5dc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "textsender_api" -version = "0.1.8" +version = "0.1.9" edition = "2024" rust-version = "1.96" -- 2.47.3