diff --git a/gotham_restful/src/openapi/operation.rs b/gotham_restful/src/openapi/operation.rs index e949301..fc06e43 100644 --- a/gotham_restful/src/openapi/operation.rs +++ b/gotham_restful/src/openapi/operation.rs @@ -6,7 +6,7 @@ use crate::{ }; use super::SECURITY_NAME; use indexmap::IndexMap; -use mime::{Mime, STAR_STAR}; +use mime::Mime; use openapiv3::{ MediaType, Operation, Parameter, ParameterData, ParameterSchemaOrContent, ReferenceOr, ReferenceOr::Item, RequestBody as OARequestBody, Response, Responses, Schema, SchemaKind, @@ -148,7 +148,7 @@ impl<'a> OperationDescription<'a> let (operation_id, default_status, accepted_types, schema, params, body_schema, supported_types, requires_auth) = ( self.operation_id, self.default_status, self.accepted_types, self.schema, self.params, self.body_schema, self.supported_types, self.requires_auth); - let content = Self::schema_to_content(accepted_types.unwrap_or_else(|| vec![STAR_STAR]), schema); + let content = Self::schema_to_content(accepted_types.or_all_types(), schema); let mut responses : IndexMap> = IndexMap::new(); responses.insert(StatusCode::Code(default_status.as_u16()), Item(Response { @@ -159,7 +159,7 @@ impl<'a> OperationDescription<'a> let request_body = body_schema.map(|schema| Item(OARequestBody { description: None, - content: Self::schema_to_content(supported_types.unwrap_or_else(|| vec![STAR_STAR]), schema), + content: Self::schema_to_content(supported_types.or_all_types(), schema), required: true })); @@ -199,7 +199,7 @@ mod test { let types = NoContent::accepted_types(); let schema = ::schema(); - let content = OperationDescription::schema_to_content(types.unwrap_or_else(|| vec![STAR_STAR]), Item(schema.into_schema())); + let content = OperationDescription::schema_to_content(types.or_all_types(), Item(schema.into_schema())); assert!(content.is_empty()); } @@ -208,7 +208,7 @@ mod test { let types = Raw::<&str>::accepted_types(); let schema = as OpenapiType>::schema(); - let content = OperationDescription::schema_to_content(types.unwrap_or_else(|| vec![STAR_STAR]), Item(schema.into_schema())); + let content = OperationDescription::schema_to_content(types.or_all_types(), Item(schema.into_schema())); assert_eq!(content.len(), 1); let json = serde_json::to_string(&content.values().nth(0).unwrap()).unwrap(); assert_eq!(json, r#"{"schema":{"type":"string","format":"binary"}}"#); diff --git a/gotham_restful/src/result/mod.rs b/gotham_restful/src/result/mod.rs index 8399c7c..834bf46 100644 --- a/gotham_restful/src/result/mod.rs +++ b/gotham_restful/src/result/mod.rs @@ -2,7 +2,7 @@ use crate::Response; #[cfg(feature = "openapi")] use crate::OpenapiSchema; use futures_util::future::FutureExt; -use mime::Mime; +use mime::{Mime, STAR_STAR}; use serde::Serialize; use std::{ error::Error, @@ -26,6 +26,21 @@ pub use result::IntoResponseError; mod success; pub use success::Success; + +pub(crate) trait OrAllTypes +{ + fn or_all_types(self) -> Vec; +} + +impl OrAllTypes for Option> +{ + fn or_all_types(self) -> Vec + { + self.unwrap_or_else(|| vec![STAR_STAR]) + } +} + + /// A trait provided to convert a resource's result to json. pub trait ResourceResult { @@ -145,13 +160,11 @@ where mod test { use super::*; - use crate::{OpenapiType, StatusCode}; use futures_executor::block_on; - use mime::{APPLICATION_JSON, TEXT_PLAIN}; use thiserror::Error; #[derive(Debug, Default, Deserialize, Serialize)] - #[cfg_attr(feature = "openapi", derive(OpenapiType))] + #[cfg_attr(feature = "openapi", derive(crate::OpenapiType))] struct Msg { msg : String @@ -162,63 +175,16 @@ mod test struct MsgError; #[test] - fn resource_result_ok() + fn result_from_future() { - let ok : Result = Ok(Msg::default()); - let res = block_on(ok.into_response()).expect("didn't expect error response"); - assert_eq!(res.status, StatusCode::OK); - assert_eq!(res.mime, Some(APPLICATION_JSON)); - assert_eq!(res.full_body().unwrap(), r#"{"msg":""}"#.as_bytes()); - } - - #[test] - fn resource_result_err() - { - let err : Result = Err(MsgError::default()); - let res = block_on(err.into_response()).expect("didn't expect error response"); - assert_eq!(res.status, StatusCode::INTERNAL_SERVER_ERROR); - assert_eq!(res.mime, Some(APPLICATION_JSON)); - assert_eq!(res.full_body().unwrap(), format!(r#"{{"error":true,"message":"{}"}}"#, MsgError::default()).as_bytes()); - } - - #[test] - fn success_always_successfull() - { - let success : Success = Msg::default().into(); - let res = block_on(success.into_response()).expect("didn't expect error response"); - assert_eq!(res.status, StatusCode::OK); - assert_eq!(res.mime, Some(APPLICATION_JSON)); - assert_eq!(res.full_body().unwrap(), r#"{"msg":""}"#.as_bytes()); - } - - #[test] - fn no_content_has_empty_response() - { - let no_content = NoContent::default(); - let res = block_on(no_content.into_response()).expect("didn't expect error response"); - assert_eq!(res.status, StatusCode::NO_CONTENT); - assert_eq!(res.mime, None); - assert_eq!(res.full_body().unwrap(), &[] as &[u8]); - } - - #[test] - fn no_content_result() - { - let no_content : Result = Ok(NoContent::default()); - let res = block_on(no_content.into_response()).expect("didn't expect error response"); - assert_eq!(res.status, StatusCode::NO_CONTENT); - assert_eq!(res.mime, None); - assert_eq!(res.full_body().unwrap(), &[] as &[u8]); - } - - #[test] - fn raw_response() - { - let msg = "Test"; - let raw = Raw::new(msg, TEXT_PLAIN); - let res = block_on(raw.into_response()).expect("didn't expect error response"); - assert_eq!(res.status, StatusCode::OK); - assert_eq!(res.mime, Some(TEXT_PLAIN)); - assert_eq!(res.full_body().unwrap(), msg.as_bytes()); + let nc = NoContent::default(); + let res = block_on(nc.into_response()).unwrap(); + + let fut_nc = async move { NoContent::default() }.boxed(); + let fut_res = block_on(fut_nc.into_response()).unwrap(); + + assert_eq!(res.status, fut_res.status); + assert_eq!(res.mime, fut_res.mime); + assert_eq!(res.full_body().unwrap(), fut_res.full_body().unwrap()); } } diff --git a/gotham_restful/src/result/no_content.rs b/gotham_restful/src/result/no_content.rs index c04ea8d..f733118 100644 --- a/gotham_restful/src/result/no_content.rs +++ b/gotham_restful/src/result/no_content.rs @@ -103,4 +103,38 @@ where { NoContent::default_status() } -} \ No newline at end of file +} + + +#[cfg(test)] +mod test +{ + use super::*; + use futures_executor::block_on; + use gotham::hyper::StatusCode; + use thiserror::Error; + + #[derive(Debug, Default, Error)] + #[error("An Error")] + struct MsgError; + + #[test] + fn no_content_has_empty_response() + { + let no_content = NoContent::default(); + let res = block_on(no_content.into_response()).expect("didn't expect error response"); + assert_eq!(res.status, StatusCode::NO_CONTENT); + assert_eq!(res.mime, None); + assert_eq!(res.full_body().unwrap(), &[] as &[u8]); + } + + #[test] + fn no_content_result() + { + let no_content : Result = Ok(NoContent::default()); + let res = block_on(no_content.into_response()).expect("didn't expect error response"); + assert_eq!(res.status, StatusCode::NO_CONTENT); + assert_eq!(res.mime, None); + assert_eq!(res.full_body().unwrap(), &[] as &[u8]); + } +} diff --git a/gotham_restful/src/result/raw.rs b/gotham_restful/src/result/raw.rs index 95fafdf..f41ffe6 100644 --- a/gotham_restful/src/result/raw.rs +++ b/gotham_restful/src/result/raw.rs @@ -10,10 +10,11 @@ use mime::Mime; use openapiv3::{SchemaKind, StringFormat, StringType, Type, VariantOrUnknownOrEmpty}; use serde_json::error::Error as SerdeJsonError; use std::{ - fmt::{Debug, Display}, + fmt::Display, pin::Pin }; +#[derive(Debug)] pub struct Raw { pub raw : T, @@ -39,13 +40,6 @@ impl Clone for Raw } } -impl Debug for Raw -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Raw({:?}, {:?})", self.raw, self.mime) - } -} - impl> ResourceResult for Raw where Self : Send @@ -87,4 +81,24 @@ where { as ResourceResult>::schema() } -} \ No newline at end of file +} + + +#[cfg(test)] +mod test +{ + use super::*; + use futures_executor::block_on; + use mime::TEXT_PLAIN; + + #[test] + fn raw_response() + { + let msg = "Test"; + let raw = Raw::new(msg, TEXT_PLAIN); + let res = block_on(raw.into_response()).expect("didn't expect error response"); + assert_eq!(res.status, StatusCode::OK); + assert_eq!(res.mime, Some(TEXT_PLAIN)); + assert_eq!(res.full_body().unwrap(), msg.as_bytes()); + } +} diff --git a/gotham_restful/src/result/result.rs b/gotham_restful/src/result/result.rs index 5857812..5de2e44 100644 --- a/gotham_restful/src/result/result.rs +++ b/gotham_restful/src/result/result.rs @@ -56,4 +56,51 @@ where { R::schema() } -} \ No newline at end of file +} + + +#[cfg(test)] +mod test +{ + use super::*; + use crate::result::OrAllTypes; + use futures_executor::block_on; + use thiserror::Error; + + #[derive(Debug, Default, Deserialize, Serialize)] + #[cfg_attr(feature = "openapi", derive(crate::OpenapiType))] + struct Msg + { + msg : String + } + + #[derive(Debug, Default, Error)] + #[error("An Error")] + struct MsgError; + + #[test] + fn result_ok() + { + let ok : Result = Ok(Msg::default()); + let res = block_on(ok.into_response()).expect("didn't expect error response"); + assert_eq!(res.status, StatusCode::OK); + assert_eq!(res.mime, Some(APPLICATION_JSON)); + assert_eq!(res.full_body().unwrap(), r#"{"msg":""}"#.as_bytes()); + } + + #[test] + fn result_err() + { + let err : Result = Err(MsgError::default()); + let res = block_on(err.into_response()).expect("didn't expect error response"); + assert_eq!(res.status, StatusCode::INTERNAL_SERVER_ERROR); + assert_eq!(res.mime, Some(APPLICATION_JSON)); + assert_eq!(res.full_body().unwrap(), format!(r#"{{"error":true,"message":"{}"}}"#, MsgError::default()).as_bytes()); + } + + #[test] + fn success_accepts_json() + { + assert!(>::accepted_types().or_all_types().contains(&APPLICATION_JSON)) + } +} diff --git a/gotham_restful/src/result/success.rs b/gotham_restful/src/result/success.rs index 9931384..11b2f2b 100644 --- a/gotham_restful/src/result/success.rs +++ b/gotham_restful/src/result/success.rs @@ -41,6 +41,7 @@ fn read_all(_state: &mut State) -> Success { # } ``` */ +#[derive(Debug)] pub struct Success(T); impl AsMut for Success @@ -97,13 +98,6 @@ impl Copy for Success { } -impl Debug for Success -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Success({:?})", self.0) - } -} - impl Default for Success { fn default() -> Self @@ -134,3 +128,35 @@ where T::schema() } } + + +#[cfg(test)] +mod test +{ + use super::*; + use crate::result::OrAllTypes; + use futures_executor::block_on; + + #[derive(Debug, Default, Serialize)] + #[cfg_attr(feature = "openapi", derive(crate::OpenapiType))] + struct Msg + { + msg : String + } + + #[test] + fn success_always_successfull() + { + let success : Success = Msg::default().into(); + let res = block_on(success.into_response()).expect("didn't expect error response"); + assert_eq!(res.status, StatusCode::OK); + assert_eq!(res.mime, Some(APPLICATION_JSON)); + assert_eq!(res.full_body().unwrap(), r#"{"msg":""}"#.as_bytes()); + } + + #[test] + fn success_accepts_json() + { + assert!(>::accepted_types().or_all_types().contains(&APPLICATION_JSON)) + } +}