Skip to content

Commit

Permalink
improvement: attempted to make static_asset test more robust, doesn't…
Browse files Browse the repository at this point in the history
… work yet
  • Loading branch information
sentinel1909 committed Feb 21, 2025
1 parent 7f66083 commit c37b484
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 6 deletions.
23 changes: 19 additions & 4 deletions app/src/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ use pavex::request::path::PathParams;
use rust_embed_for_web::{EmbedableFile, RustEmbed};
use std::borrow::Cow;

// trait for asset retrieval
pub trait AssetProvider {
fn get_asset(&self, filename: &str) -> Option<Vec<u8>>;
}

// default provider for real assets
pub struct EmbeddedAssetProvider;

// implement the AssetProvider trait for EmbeddedAssetProvider
impl AssetProvider for crate::asset::EmbeddedAssetProvider {
fn get_asset(&self, filename: &str) -> Option<Vec<u8>> {
Asset::get(filename).map(|f| f.data())
}
}

// struct type to represent a static asset from the file system
#[derive(RustEmbed)]
#[folder = "../static"]
Expand All @@ -29,7 +44,7 @@ pub struct StaticAsset {

Check warning on line 44 in app/src/asset.rs

View workflow job for this annotation

GitHub Actions / Format

Diff in /home/runner/work/pavex-html/pavex-html/app/src/asset.rs
// methods for the StaticAsset type
impl StaticAsset {
pub fn build_static_asset(params: PathParams<GetFilenameParams>) -> Self {
pub fn build_static_asset(params: PathParams<GetFilenameParams>, provider: &dyn crate::asset::AssetProvider) -> Option<Self> {
let file = params.0.filename;

let name = Cow::Owned(file.to_string());
Expand All @@ -39,18 +54,18 @@ impl StaticAsset {
.map(Cow::Borrowed)
.unwrap_or_else(|| Cow::Borrowed("application/octet-stream"));

let data = Asset::get(file.as_ref()).unwrap().data();
let data = provider.get_asset(file.as_ref())?;

let mime_header = match HeaderValue::from_str(&mime_type) {
Ok(hv) => hv,
Err(_) => HeaderValue::from_static("application/octet-stream"),
};

Self {
Some(Self {
name,
data,
mime_type,
mime_header,
}
})
}
}
2 changes: 1 addition & 1 deletion app/src/blueprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ pub fn blueprint() -> Blueprint {
bp.singleton(f!(crate::template::compile_templates));

Check warning on line 14 in app/src/blueprint.rs

View workflow job for this annotation

GitHub Actions / Format

Diff in /home/runner/work/pavex-html/pavex-html/app/src/blueprint.rs
bp.transient(f!(crate::asset::StaticAsset::build_static_asset))
.clone_if_necessary();

bp.request_scoped(f!(<crate::asset::EmbeddedAssetProvider as crate::asset::AssetProvider>::get_asset));
bp
}
8 changes: 7 additions & 1 deletion app/src/routes/static_assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ impl TypedBody for StaticAsset {

Check warning on line 24 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Format

Diff in /home/runner/work/pavex-html/pavex-html/app/src/routes/static_assets.rs
// handler function which responds with a 200 OK and the CSS styles
pub fn get(asset: StaticAsset) -> Response {
Response::ok().set_typed_body(asset)

match asset {
Some(a) => Response::ok().set_typed_body(a),

Check failure on line 29 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Freshness

mismatched types

Check failure on line 29 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Code coverage

mismatched types

Check failure on line 29 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Lint

mismatched types

Check failure on line 29 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Test

mismatched types
None => Response::no_content().set_typed_body("No content")

Check failure on line 30 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Freshness

mismatched types

Check failure on line 30 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Code coverage

mismatched types

Check failure on line 30 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Lint

mismatched types

Check failure on line 30 in app/src/routes/static_assets.rs

View workflow job for this annotation

GitHub Actions / Test

mismatched types
}


}
16 changes: 16 additions & 0 deletions server/tests/integration/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ impl TestApi {

/// Convenient methods for calling the API under test.
impl TestApi {
pub async fn get_index(&self) -> reqwest::Response {
self.api_client
.get(format!("{}/", &self.api_address))
.send()
.await
.expect("Failed to execute request.")
}

pub async fn get_ping(&self) -> reqwest::Response {
self.api_client
.get(format!("{}/api/ping", &self.api_address))
Expand All @@ -80,6 +88,14 @@ impl TestApi {
.expect("Failed to execute request.")
}

pub async fn get_static_asset(&self, filename: &str) -> reqwest::Response {
self.api_client
.get(format!("{}/static/{}", &self.api_address, filename))
.send()
.await
.expect("Failed to execute request.")
}

pub async fn post_storage_create(&self, query: &str) -> reqwest::Response {
self.api_client
.post(format!(
Expand Down
31 changes: 31 additions & 0 deletions server/tests/integration/index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// tests/integration/index.rs

use crate::helpers::TestApi;
use pavex::http::StatusCode;

#[tokio::test]
async fn index_works() {
let api = TestApi::spawn().await;

let response = api.get_index().await;

assert_eq!(response.status(), StatusCode::OK);

let response_header = response
.headers()
.get("Content-Type")

Check warning on line 16 in server/tests/integration/index.rs

View workflow job for this annotation

GitHub Actions / Format

Diff in /home/runner/work/pavex-html/pavex-html/server/tests/integration/index.rs
.expect("Expected Content-Type header in response.");

let response_header_str = response_header.to_str().expect("Unable to get the response header text");

let expected_header_str = "text/html; charset=utf-8";

assert_eq!(response_header_str, expected_header_str);

let response_body = response.text().await.unwrap();

assert!(
response_body.contains("<!DOCTYPE html>"),
"Response body does not contain expected HTML."
)
}
2 changes: 2 additions & 0 deletions server/tests/integration/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod helpers;
mod index;
mod ping;
mod static_asset;
mod storage_create;
27 changes: 27 additions & 0 deletions server/tests/integration/static_asset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// tests/integration/static_asset.rs

use crate::helpers::TestApi;
use pavex::http::StatusCode;

#[tokio::test]
async fn static_asset_works() {
let api = TestApi::spawn().await;

let filename = "test.css";

let response = api.get_static_asset(filename).await;

assert_eq!(response.status(), StatusCode::OK);

let response_header = response
.headers()
.get("Content-Type")

Check warning on line 18 in server/tests/integration/static_asset.rs

View workflow job for this annotation

GitHub Actions / Format

Diff in /home/runner/work/pavex-html/pavex-html/server/tests/integration/static_asset.rs
.expect("Expected Content-Type header in response.");

let response_header_str = response_header.to_str().expect("Unable to get the response header text");

let expected_header_str = "text/css; charset=utf-8";

assert_eq!(response_header_str, expected_header_str);

Check warning on line 25 in server/tests/integration/static_asset.rs

View workflow job for this annotation

GitHub Actions / Format

Diff in /home/runner/work/pavex-html/pavex-html/server/tests/integration/static_asset.rs

}

0 comments on commit c37b484

Please sign in to comment.