diff options
| author | Kevin J Hoerr <kjhoerr@protonmail.com> | 2019-11-04 14:06:58 -0500 |
|---|---|---|
| committer | Kevin J Hoerr <kjhoerr@protonmail.com> | 2019-11-04 14:06:58 -0500 |
| commit | 4117f797cec89927fe3363543b8c8b11a311b90c (patch) | |
| tree | 3f7320ee5a81a2e760c9f87991d63771633e5865 /src/routes/format_msg.rs | |
| parent | 0c1dce106e0fb211cb52b2a780febd2a1b5f0a47 (diff) | |
| download | august-offensive-4117f797cec89927fe3363543b8c8b11a311b90c.tar.gz august-offensive-4117f797cec89927fe3363543b8c8b11a311b90c.tar.bz2 august-offensive-4117f797cec89927fe3363543b8c8b11a311b90c.zip | |
Move FormatMsg to routes and add unit tests
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 |
