diff options
Diffstat (limited to 'src/routes/format_msg.rs')
| -rw-r--r-- | src/routes/format_msg.rs | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/routes/format_msg.rs b/src/routes/format_msg.rs new file mode 100644 index 0000000..d7a6f05 --- /dev/null +++ b/src/routes/format_msg.rs @@ -0,0 +1,124 @@ +use actix_web::{http::StatusCode, Error, HttpRequest, HttpResponse, Responder}; +use serde::Serialize; + +pub struct FormatMsg<T> { + pub message: T, + pub code: StatusCode, +} + +impl<T> FormatMsg<T> { + /// Deconstruct to an inner value + pub fn into_inner(self) -> T { + self.message + } + + pub fn ok(message: T) -> Self { + FormatMsg { + message: message, + code: StatusCode::OK, + } + } +} + +impl<T: Serialize> Responder for FormatMsg<T> { + type Error = Error; + type Future = Result<HttpResponse, Error>; + + fn respond_to(self, _: &HttpRequest) -> Self::Future { + let body = match serde_json::to_string(&self.message) { + Ok(body) => body, + Err(e) => return Err(e.into()), + }; + + Ok(HttpResponse::build(self.code) + .content_type("application/json") + .body(body)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use routes::*; + use routes::tests::*; + use serde::ser::{Error, Serializer}; + + #[test] + fn test_into_inner() { + // Arrange + let msg = NotUnderstood {path: vec![]}; + let msg_ref = msg.clone(); + let formatted = FormatMsg { + message: msg.as_outgoing(), + code: StatusCode::OK, + }; + + // Act + let result = formatted.into_inner(); + + // Assert + assert_eq!(result.result_type, "NOT_UNDERSTOOD"); + assert_eq!(result.content, msg_ref); + } + + #[test] + fn test_ok() { + // Arrange + let msg = NotUnderstood {path: vec![]}; + let msg_ref = msg.clone(); + + // Act + let result = FormatMsg::ok(msg); + + // Assert + assert_eq!(result.message, msg_ref); + assert_eq!(result.code, StatusCode::OK); + } + + #[test] + fn test_responder() { + // Arrange + let msg = NotUnderstood {path: vec![]}; + let msg_ref = msg.clone(); + let formatted = FormatMsg { + message: msg, + code: StatusCode::NOT_FOUND, + }; + let request = gen_request("/api/404", None); + + // Act + let result = &formatted.respond_to(&request).unwrap(); + + // Assert + assert_eq!(result.status(), StatusCode::NOT_FOUND); + assert_eq!(result.headers().get("content-type").unwrap(), "application/json"); + + let content = get_message::<NotUnderstood>(result); + assert_eq!(content, msg_ref); + } + + struct InvalidMessage {} + + impl Serialize for InvalidMessage { + fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error> where S: Serializer { + Err(Error::custom("oops".to_string())) + } + } + + #[test] + fn test_responder_serde_error() { + // Arrange + let msg = InvalidMessage {}; + let formatted = FormatMsg { + message: msg, + code: StatusCode::NOT_FOUND, + }; + let request = gen_request("/api/404", None); + + // Act + let result = formatted.respond_to(&request); + + // Assert + assert!(result.is_err()); + } +}
\ No newline at end of file |
