aboutsummaryrefslogtreecommitdiff
path: root/src/routes/format_msg.rs
diff options
context:
space:
mode:
authorKevin J Hoerr <kjhoerr@protonmail.com>2019-11-04 14:06:58 -0500
committerKevin J Hoerr <kjhoerr@protonmail.com>2019-11-04 14:06:58 -0500
commit4117f797cec89927fe3363543b8c8b11a311b90c (patch)
tree3f7320ee5a81a2e760c9f87991d63771633e5865 /src/routes/format_msg.rs
parent0c1dce106e0fb211cb52b2a780febd2a1b5f0a47 (diff)
downloadaugust-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.rs124
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