Skip to content

Commit

Permalink
Add test for date types in actix params (#758)
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvdb authored Sep 15, 2023
1 parent 1b3479e commit d7280eb
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 2 deletions.
4 changes: 2 additions & 2 deletions scripts/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ for crate in $crates; do
$CARGO test -p utoipa --features openapi_extensions,preserve_order,preserve_path_order,debug
elif [[ "$crate" == "utoipa-gen" ]]; then
$CARGO test -p utoipa-gen --features utoipa/actix_extras,chrono,decimal,utoipa/uuid,uuid,utoipa/ulid,ulid,utoipa/url,url,utoipa/time,time,utoipa/repr,utoipa/smallvec,smallvec,rc_schema,utoipa/rc_schema

$CARGO test -p utoipa-gen --test schema_derive_test --features decimal_float

$CARGO test -p utoipa-gen --test path_derive_auto_into_responses --features auto_into_responses,utoipa/uuid,uuid
$CARGO test -p utoipa-gen --test path_derive_actix --test path_parameter_derive_actix --features actix_extras,utoipa/uuid,uuid
$CARGO test -p utoipa-gen --test path_derive_actix --test path_parameter_derive_actix --features actix_extras,utoipa/uuid,uuid,utoipa/chrono,chrono,utoipa/time,time
$CARGO test -p utoipa-gen --test path_derive_auto_into_responses_actix --features actix_extras,utoipa/auto_into_responses,utoipa/uuid,uuid

$CARGO test -p utoipa-gen --test path_derive_rocket --features rocket_extras
Expand Down
132 changes: 132 additions & 0 deletions utoipa-gen/tests/path_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,138 @@ fn derive_path_with_security_requirements() {
}
}

#[test]
fn derive_path_with_datetime_format_query_parameter() {
#[derive(serde::Deserialize, utoipa::ToSchema)]
struct Since {
/// Some date
#[allow(dead_code)]
date: String,
/// Some time
#[allow(dead_code)]
time: String,
}

/// This is test operation
///
/// This is long description for test operation
#[utoipa::path(
get,
path = "/foo/{id}/{start}",
responses(
(status = 200, description = "success response")
),
params(
("id" = i64, Path, description = "Foo database id"),
("start" = String, Path, description = "Datetime since foo is updated", format = DateTime)
)
)]
#[allow(unused)]
async fn get_foos_by_id_date() -> String {
"".to_string()
}

let operation: Value = test_api_fn_doc! {
get_foos_by_id_date,
operation: get,
path: "/foo/{id}/{start}"
};

let parameters: &Value = operation.get("parameters").unwrap();

assert_json_eq!(
parameters,
json!([
{
"description": "Foo database id",
"in": "path",
"name": "id",
"required": true,
"schema": {
"format": "int64",
"type": "integer",
}
},
{
"description": "Datetime since foo is updated",
"in": "path",
"name": "start",
"required": true,
"schema": {
"format": "date-time",
"type": "string",
}
}
])
);
}

#[test]
fn derive_path_with_datetime_format_path_parameter() {
#[derive(serde::Deserialize, utoipa::ToSchema)]
struct Since {
/// Some date
#[allow(dead_code)]
date: String,
/// Some time
#[allow(dead_code)]
time: String,
}

/// This is test operation
///
/// This is long description for test operation
#[utoipa::path(
get,
path = "/foo/{id}",
responses(
(status = 200, description = "success response")
),
params(
("id" = i64, description = "Foo database id"),
("start" = String, Query, description = "Datetime since foo is updated", format = DateTime)
)
)]
#[allow(unused)]
async fn get_foos_by_id_date() -> String {
"".to_string()
}

let operation: Value = test_api_fn_doc! {
get_foos_by_id_date,
operation: get,
path: "/foo/{id}"
};

let parameters: &Value = operation.get("parameters").unwrap();

assert_json_eq!(
parameters,
json!([
{
"description": "Foo database id",
"in": "path",
"name": "id",
"required": true,
"schema": {
"format": "int64",
"type": "integer",
}
},
{
"description": "Datetime since foo is updated",
"in": "query",
"name": "start",
"required": true,
"schema": {
"format": "date-time",
"type": "string",
}
}
])
);
}

#[test]
fn derive_path_with_parameter_schema() {
#[derive(serde::Deserialize, utoipa::ToSchema)]
Expand Down
109 changes: 109 additions & 0 deletions utoipa-gen/tests/path_parameter_derive_actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,112 @@ fn derive_params_from_method_args_actix_success() {
"[1].schema.format" = r#"null"#, "Parameter schema format"
};
}

#[test]
fn derive_path_with_date_params_implicit() {
mod mod_derive_path_with_date_params {
use actix_web::{get, web, HttpResponse, Responder};
use chrono::{DateTime, Utc};
use serde_json::json;
use time::Date;

#[utoipa::path(
responses(
(status = 200, description = "success response")
),
params(
("start_date", description = "Start date filter"),
("end_date", description = "End date filter"),
)
)]
#[get("/visitors/v1/{start_date}/{end_date}")]
#[allow(unused)]
async fn get_foo_by_date(path: web::Path<(Date, DateTime<Utc>)>) -> impl Responder {
let (start_date, end_date) = path.into_inner();
HttpResponse::Ok()
.json(json!({ "params": &format!("{:?} {:?}", start_date, end_date) }))
}
}

#[derive(OpenApi, Default)]
#[openapi(paths(mod_derive_path_with_date_params::get_foo_by_date))]
struct ApiDoc;

let doc = serde_json::to_value(ApiDoc::openapi()).unwrap();
let parameters = doc
.pointer("/paths/~1visitors~1v1~1{start_date}~1{end_date}/get/parameters")
.unwrap();

common::assert_json_array_len(parameters, 2);
assert_value! {parameters=>
"[0].in" = r#""path""#, "Parameter in"
"[0].name" = r#""start_date""#, "Parameter name"
"[0].description" = r#""Start date filter""#, "Parameter description"
"[0].required" = r#"true"#, "Parameter required"
"[0].deprecated" = r#"null"#, "Parameter deprecated"
"[0].schema.type" = r#""string""#, "Parameter schema type"
"[0].schema.format" = r#""date""#, "Parameter schema format"

"[1].in" = r#""path""#, "Parameter in"
"[1].name" = r#""end_date""#, "Parameter name"
"[1].description" = r#""End date filter""#, "Parameter description"
"[1].required" = r#"true"#, "Parameter required"
"[1].deprecated" = r#"null"#, "Parameter deprecated"
"[1].schema.type" = r#""string""#, "Parameter schema type"
"[1].schema.format" = r#""date-time""#, "Parameter schema format"
};
}

#[test]
fn derive_path_with_date_params_explicit_ignored() {
mod mod_derive_path_with_date_params {
use actix_web::{get, web, HttpResponse, Responder};
use serde_json::json;
use time::Date;

#[utoipa::path(
responses(
(status = 200, description = "success response")
),
params(
("start_date", description = "Start date filter", format = Date),
("end_date", description = "End date filter", format = DateTime),
)
)]
#[get("/visitors/v1/{start_date}/{end_date}")]
#[allow(unused)]
async fn get_foo_by_date(path: web::Path<(Date, String)>) -> impl Responder {
let (start_date, end_date) = path.into_inner();
HttpResponse::Ok()
.json(json!({ "params": &format!("{:?} {:?}", start_date, end_date) }))
}
}

#[derive(OpenApi, Default)]
#[openapi(paths(mod_derive_path_with_date_params::get_foo_by_date))]
struct ApiDoc;

let doc = serde_json::to_value(ApiDoc::openapi()).unwrap();
let parameters = doc
.pointer("/paths/~1visitors~1v1~1{start_date}~1{end_date}/get/parameters")
.unwrap();

common::assert_json_array_len(parameters, 2);
assert_value! {parameters=>
"[0].in" = r#""path""#, "Parameter in"
"[0].name" = r#""start_date""#, "Parameter name"
"[0].description" = r#""Start date filter""#, "Parameter description"
"[0].required" = r#"true"#, "Parameter required"
"[0].deprecated" = r#"null"#, "Parameter deprecated"
"[0].schema.type" = r#""string""#, "Parameter schema type"
"[0].schema.format" = r#""date""#, "Parameter schema format"

"[1].in" = r#""path""#, "Parameter in"
"[1].name" = r#""end_date""#, "Parameter name"
"[1].description" = r#""End date filter""#, "Parameter description"
"[1].required" = r#"true"#, "Parameter required"
"[1].deprecated" = r#"null"#, "Parameter deprecated"
"[1].schema.type" = r#""string""#, "Parameter schema type"
"[1].schema.format" = r#"null"#, "Parameter schema format"
};
}

0 comments on commit d7280eb

Please sign in to comment.