Skip to content

Commit

Permalink
Added doc/unit tests and CI (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
ranger-ross authored Jul 7, 2024
1 parent 280f296 commit 13fc8cf
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 6 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Check

on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
branches: [ main ]

env:
CARGO_TERM_COLOR: always

# TODO: Maybe use a matrix and test multiple rust versions
jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@1.79.0
with:
components: clippy, rustfmt

- uses: Swatinem/rust-cache@v2

- run: cargo fmt --check
- run: cargo clippy -- -D warnings


test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@1.79.0
with:
components: llvm-tools-preview

- uses: Swatinem/rust-cache@v2

- run: cargo install cargo-llvm-cov

- name: cargo llvm-cov
run: cargo llvm-cov --lcov --output-path lcov.info --all-features

- name: Record Rust version
run: echo "RUST=$(rustc --version)" >> "$GITHUB_ENV"

- name: Upload to codecov.io
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS,RUST
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ thiserror = "1"
validator = { version = "0.18", optional = true }
garde = { version = "0.20", optional = true }

[dev-dependencies]
serde = { version = "1", features = ["derive"]}
validator = { version = "0.18", features = ["derive"] }
garde = { version = "0.20", features = ["derive"] }

[features]

# Use validator crate (https://github.com/Keats/validator) as the validation implmentation
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ actix-web-validation = { version = "0.0.0", features = ["validator"]}
actix-web-validation = { version = "0.0.0", features = ["garde"]}
```

```rust
```rust,ignore
use actix_web_validation::validator::Validated;
use validator::Validate;
Expand All @@ -53,7 +53,7 @@ async fn hello(Validated(Json(payload)): Validated<Json<Example>>) -> impl Respo
Custom error responses can achieved by providing an error handler.

Below is an example custom error response that responds with JSON
```rust
```rust,ignore
#[derive(Debug, Serialize, Error)]
struct CustomErrorResponse {
custom_message: String,
Expand All @@ -75,7 +75,7 @@ impl ResponseError for CustomErrorResponse {

Below is an example for the `validator` crate

```rust
```rust,ignore
fn error_handler(errors: ::validator::ValidationErrors, req: &HttpRequest) -> actix_web::Error {
CustomErrorResponse {
custom_message: "My custom message".to_string(),
Expand Down Expand Up @@ -103,7 +103,7 @@ async fn main() -> std::io::Result<()> {

Below is an example for the `garde` crate

```rust
```rust,ignore
fn error_handler(errors: ::garde::Report, req: &HttpRequest) -> actix_web::Error {
CustomErrorResponse {
custom_message: "My custom message".to_string(),
Expand Down
50 changes: 49 additions & 1 deletion src/garde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ use thiserror::Error;
/// use actix_web::{post, web::{self, Json}, App};
/// use serde::Deserialize;
/// use garde::Validate;
/// use actix_web_validation::garde::Validated;
///
/// #[derive(Deserialize, Validate)]
/// #[derive(Debug, Deserialize, Validate)]
/// struct Info {
/// #[garde(length(min = 3))]
/// username: String,
Expand Down Expand Up @@ -176,3 +177,50 @@ where
self.app_data(GardeErrorHandler { handler })
}
}

#[cfg(test)]
mod test {
use super::*;
use actix_web::{http::header::ContentType, post, test, web::Json, App, Responder};
use garde::Validate;
use serde::{Deserialize, Serialize};

#[actix_web::test]
async fn should_validate_simple() {
#[derive(Debug, Deserialize, Serialize, Validate)]
struct ExamplePayload {
#[garde(length(min = 5))]
name: String,
}

#[post("/")]
async fn endpoint(v: Validated<Json<ExamplePayload>>) -> impl Responder {
assert!(v.name.len() > 4);
HttpResponse::Ok().body(())
}

let app = test::init_service(App::new().service(endpoint)).await;

// Valid request
let req = test::TestRequest::post()
.uri("/")
.insert_header(ContentType::plaintext())
.set_json(ExamplePayload {
name: "123456".to_string(),
})
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status().as_u16(), 200);

// Invalid request
let req = test::TestRequest::post()
.uri("/")
.insert_header(ContentType::plaintext())
.set_json(ExamplePayload {
name: "1234".to_string(),
})
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status().as_u16(), 400);
}
}
50 changes: 49 additions & 1 deletion src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ use validator::{ValidationError, ValidationErrors, ValidationErrorsKind};
/// use actix_web::{post, web::{self, Json}, App};
/// use serde::Deserialize;
/// use validator::Validate;
/// use actix_web_validation::validator::Validated;
///
/// #[derive(Deserialize, Validate)]
/// #[derive(Debug, Deserialize, Validate)]
/// struct Info {
/// #[validate(length(min = 5))]
/// username: String,
Expand Down Expand Up @@ -216,3 +217,50 @@ where
self.app_data(ValidatorErrorHandler { handler })
}
}

#[cfg(test)]
mod test {
use super::*;
use actix_web::{http::header::ContentType, post, test, web::Json, App, Responder};
use serde::{Deserialize, Serialize};
use validator::Validate;

#[actix_web::test]
async fn should_validate_simple() {
#[derive(Debug, Deserialize, Serialize, Validate)]
struct ExamplePayload {
#[validate(length(min = 5))]
name: String,
}

#[post("/")]
async fn endpoint(v: Validated<Json<ExamplePayload>>) -> impl Responder {
assert!(v.name.len() > 4);
HttpResponse::Ok().body(())
}

let app = test::init_service(App::new().service(endpoint)).await;

// Valid request
let req = test::TestRequest::post()
.uri("/")
.insert_header(ContentType::plaintext())
.set_json(ExamplePayload {
name: "123456".to_string(),
})
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status().as_u16(), 200);

// Invalid request
let req = test::TestRequest::post()
.uri("/")
.insert_header(ContentType::plaintext())
.set_json(ExamplePayload {
name: "1234".to_string(),
})
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status().as_u16(), 400);
}
}

0 comments on commit 13fc8cf

Please sign in to comment.