Skip to content

Commit

Permalink
feat: add request context management and tests
Browse files Browse the repository at this point in the history
- Introduced `create_request_context` and updated `get_request_context` in `mysession.rs` for managing request context data.
- Added tests for setting and getting request context data in `mysession.rs`.
- Updated `test.yaml` and `teste2e.yaml` to include request context configuration.
- Minor refactoring and cleanup in `cookie.rs` and other test files.
  • Loading branch information
yinho999 committed Aug 11, 2024
1 parent 9b05a67 commit c326037
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 20 deletions.
7 changes: 4 additions & 3 deletions examples/demo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions examples/demo/config/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ server:
enable: true
cors:
enable: true
request_context:
enable: true
session:
type: Cookie
value:
private_key: [ 219, 25, 129, 200, 66, 52, 72, 66, 249, 60, 206, 40, 77, 150, 2, 8, 30, 192, 221, 5, 243, 74, 17, 172, 109, 96, 218, 46, 235, 118, 131, 150, 224, 205, 55, 147, 45, 151, 245, 23, 250, 48, 133, 115, 105, 252, 193, 15, 162, 167, 77, 189, 169, 91, 205, 172, 120, 254, 136, 111, 167, 161, 255, 107 ]
# Set the value of the [`Access-Control-Allow-Origin`][mdn] header
# allow_origins:
# - https://loco.rs
Expand Down
9 changes: 7 additions & 2 deletions examples/demo/config/teste2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ server:
enable: true
# Duration time in milliseconds.
timeout: 5000

request_context:
enable: true
session:
type: Cookie
value:
private_key: [ 219, 25, 129, 200, 66, 52, 72, 66, 249, 60, 206, 40, 77, 150, 2, 8, 30, 192, 221, 5, 243, 74, 17, 172, 109, 96, 218, 46, 235, 118, 131, 150, 224, 205, 55, 147, 45, 151, 245, 23, 250, 48, 133, 115, 105, 252, 193, 15, 162, 167, 77, 189, 169, 91, 205, 172, 120, 254, 136, 111, 167, 161, 255, 107 ]
# Worker Configuration
workers:
# specifies the worker mode. Options:
Expand Down Expand Up @@ -77,7 +82,7 @@ mailer:
# Database Configuration
database:
# Database connection URI
uri: {{get_env(name="DATABASE_URL", default="postgres://localhost:5432/loco_app")}}
uri: {{get_env(name="DATABASE_URL", default="postgres://loco:loco@localhost:5432/loco_app_test")}}
# When enabled, the sql query will be logged.
enable_logging: false
# Set the timeout duration when acquiring a connection.
Expand Down
52 changes: 45 additions & 7 deletions examples/demo/src/controllers/mysession.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#![allow(clippy::unused_async)]

use axum::debug_handler;
use axum::{debug_handler, Extension};
use axum_session::{Session, SessionNullPool};
use loco_rs::errors;
use loco_rs::prelude::*;
use loco_rs::request_context::RequestContext;

const REQUEST_CONTEXT_DATA_KEY: &str = "alan";

/// Get a session
///
/// # Errors
Expand All @@ -14,19 +17,54 @@ pub async fn get_session(_session: Session<SessionNullPool>) -> Result<Response>
format::empty()
}

/// Get a request context
/// Set a request context
///
/// # Errors
///
/// This function will return an error if result fails
///
#[debug_handler]
pub async fn get_request_context(mut req: RequestContext) -> Result<Response> {
pub async fn create_request_context(mut req: RequestContext) -> Result<Response> {
let mut driver = req.driver();
tracing::info!("Request Context: {:?}", driver.get::<String>("alan").await);
driver.insert("alan", "turing").await.unwrap();
tracing::info!("Request Context: {:?}", driver.get::<String>("alan").await);
format::empty()
let data = "turing".to_string();
driver
.insert(REQUEST_CONTEXT_DATA_KEY, data.clone())
.await
.map_err(|_| errors::Error::InternalServerError)?;
tracing::info!(
"Request Context data set - Key: {:?}, Value: {:?}",
REQUEST_CONTEXT_DATA_KEY,
data
);
Ok(data.into_response())
}

/// Get a request context
///
/// # Errors
///
/// This function will return an error if result fails
///
#[debug_handler]
pub async fn get_request_context(mut req: Extension<RequestContext>) -> Result<Response> {
let driver = req.driver();
let data = driver
.get::<String>(REQUEST_CONTEXT_DATA_KEY)
.await
.map_err(|e| errors::Error::InternalServerError)?
.unwrap_or_default();
tracing::info!(
"Request Context data retrieved - Key: {:?}, Value: {:?}",
REQUEST_CONTEXT_DATA_KEY,
data
);
Ok(data.into_response())
}

pub fn routes() -> Routes {
Routes::new()
.prefix("mysession")
.add("/", get(get_session))
.add("/request_context", post(create_request_context))
.add("/request_context", get(get_request_context))
}
2 changes: 2 additions & 0 deletions examples/demo/tests/cmd/cli.trycmd
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ $ blo-cli routes --environment test
[GET] /mylayer/echo
[GET] /mylayer/user
[GET] /mysession
[POST] /mysession/request_context
[GET] /mysession/request_context
[GET] /notes
[POST] /notes
[GET] /notes/:id
Expand Down
3 changes: 1 addition & 2 deletions examples/demo/tests/models/roles.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use blo::{
app::App,
models::{roles, sea_orm_active_enums, users, users::RegisterParams, users_roles},
models::{roles, sea_orm_active_enums, users, users::RegisterParams},
};
use loco_rs::{prelude::*, testing};
use sea_orm::DatabaseConnection;
use serial_test::serial;

macro_rules! configure_insta {
Expand Down
1 change: 1 addition & 0 deletions examples/demo/tests/requests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod auth;
mod cache;
mod mylayer;
mod mysession;
mod notes;
mod ping;
mod prepare_data;
Expand Down
66 changes: 66 additions & 0 deletions examples/demo/tests/requests/mysession.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use blo::app::App;
use loco_rs::testing;
use serial_test::serial;

macro_rules! configure_insta {
($($expr:expr),*) => {
let mut settings = insta::Settings::clone_current();
settings.set_prepend_module_to_snapshot(false);
settings.set_snapshot_suffix("cache");
let _guard = settings.bind_to_scope();
};
}

#[tokio::test]
#[serial]
async fn set_request_context_data() {
configure_insta!();
testing::request::<App, _, _>(|request, _ctx| async move {
let response = request.post("/mysession/request_context").await;

// Get Cookie from response header
let headers = response.headers();
let cookie = headers.get("set-cookie");
assert_eq!(response.status_code(), 200);
assert_eq!(response.text(), "turing");
assert!(cookie.is_some());
})
.await;
}
#[tokio::test]
#[serial]
async fn get_request_context_without_setting_data() {
configure_insta!();
testing::request::<App, _, _>(|request, _ctx| async move {
let response = request.get("/mysession/request_context").await;
// Get response body
assert_eq!(response.status_code(), 200);
assert_eq!(response.text(), "")
})
.await;
}

#[tokio::test]
#[serial]
async fn get_request_context_with_setting_data() {
configure_insta!();
testing::request::<App, _, _>(|request, _ctx| async move {
let response = request.post("/mysession/request_context").await;
// Get Cookie from response header
let headers = response.headers();
let cookie_value = headers.get("set-cookie");
assert_eq!(response.status_code(), 200);
assert_eq!(response.text(), "turing");
assert!(cookie_value.is_some());
let data = response.text();

let response = request
.get("/mysession/request_context")
.add_header("cookie".parse().unwrap(), cookie_value.unwrap().clone())
.await;
// Get response body
assert_eq!(response.status_code(), 200);
assert_eq!(response.text(), data);
})
.await;
}
2 changes: 1 addition & 1 deletion src/controller/app_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ impl AppRoutes {
) -> Result<AXRouter<AppContext>> {
if config.must_exist
&& (!PathBuf::from(&config.folder.path).exists()
|| !PathBuf::from(&config.fallback).exists())
|| !PathBuf::from(&config.fallback).exists())
{
return Err(errors::Error::Message(format!(
"one of the static path are not found, Folder `{}` fallback: `{}`",
Expand Down
9 changes: 4 additions & 5 deletions src/request_context/driver/cookie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,7 @@ mod test {

// Check if empty cookie map doesn't create any private cookie jar
#[test]
fn test_signed_private_cookie_jar_when_empty_cookie_map(
) -> Result<(), SignedPrivateCookieJarError> {
fn test_signed_private_cookie_jar_when_empty_cookie_map() -> Result<(), SignedPrivateCookieJarError> {
let private_key = Key::generate();
// Simulate empty request context
let map = CookieMap::new(HashMap::new());
Expand All @@ -369,7 +368,7 @@ mod test {
);
let cookie_map = CookieMap::new(map.clone());
let jar = SignedPrivateCookieJar::from_cookie_map(&private_key, cookie_map)?;
assert_eq!(jar.is_some(), true);
assert!(jar.is_some());
let jar = jar.unwrap();
let cookies = get_cookies_from_response(jar);
assert_eq!(cookies.len(), 1);
Expand Down Expand Up @@ -401,7 +400,7 @@ mod test {
// Turn into headers
let headers = signed_private_jar_to_headers(new_jar);
// create new jar from headers
let new_jar = SignedPrivateCookieJar::new(&headers, private_key.clone());
let new_jar = SignedPrivateCookieJar::new(&headers, private_key);
// Turn into cookie map
let new_cookie_map = new_jar.into_cookie_map()?;
assert_ne!(new_cookie_map.0, HashMap::new());
Expand Down Expand Up @@ -445,7 +444,7 @@ mod test {
// Turn into headers
let headers = signed_private_jar_to_headers(new_jar.unwrap());
// create new jar from headers
let new_jar = SignedPrivateCookieJar::new(&headers, private_key.clone());
let new_jar = SignedPrivateCookieJar::new(&headers, private_key);
// Turn into cookie map
let new_cookie_map = new_jar.into_cookie_map()?;
assert_ne!(new_cookie_map.0, map);
Expand Down

0 comments on commit c326037

Please sign in to comment.