use rocket::State; use rocket_contrib::Json; use super::super::ListStore; use super::super::models::list::List; #[get("/", format = "application/json")] fn index(lists: State) -> Option>> { let lists = lists.read().unwrap(); Some(Json(lists.clone())) } #[get("/", format = "text/html")] fn show_html(list_id: String, lists: State) -> Option { let lists = lists.read().unwrap(); let list = lists.iter().find( |list| list.id == list_id )?; Some(list.to_html()) } #[get("/", format = "application/json")] fn show_json(list_id: String, lists: State) -> Option> { let lists = lists.read().unwrap(); let list = lists.iter().find( |list| list.id == list_id )?; Some(Json(list.clone())) } #[put("/", format = "application/json", data = "")] fn update(list_id: String, new_list: Json, lists: State) -> Option> { let mut lists = lists.write().unwrap(); let list = lists.iter_mut().find( |list| list.id == list_id )?; list.update_data(&new_list.data); Some(Json(list.clone())) } #[cfg(test)] mod tests { use rocket; use rocket::http::{Accept, ContentType, Status}; use rocket::local::Client; use serde_json; use super::*; #[test] fn index() { let client = Client::new(rocket(Some("test"))).unwrap(); // Try to get all the lists let mut res = client.get("/lists").header(Accept::JSON).dispatch(); assert_eq!(res.status(), Status::Ok); let body = res.body_string().unwrap(); let lists = serde_json::from_str::>(body.as_str()).unwrap(); assert_eq!(lists[0].id, "test"); assert_eq!(lists[0].index, 0); assert_eq!(lists[0].name, "Test"); assert_eq!(lists[0].data, "This is a test list\n\n* One\n* Two\n* Three\n"); // The mtime field can vary, don't test for it // The path field is private, also don't test for it // Cannot get the lists in HTML format let res = client.get("/lists").header(Accept::HTML).dispatch(); assert_eq!(res.status(), Status::NotFound); } #[test] fn show_html() { let client = Client::new(rocket(Some("test"))).unwrap(); // Try to get the list and verify the body let mut res = client.get("/lists/test").header(Accept::HTML).dispatch(); assert_eq!(res.status(), Status::Ok); let body = res.body_string().unwrap(); assert_eq!(body, r#"

This is a test list

  • One
  • Two
  • Three
"#); } #[test] fn show_json() { let client = Client::new(rocket(Some("test"))).unwrap(); // Try to get the list and verify the body let mut res = client.get("/lists/test").header(Accept::JSON).dispatch(); assert_eq!(res.status(), Status::Ok); let body = res.body_string().unwrap(); let list = serde_json::from_str::(body.as_str()).unwrap(); assert_eq!(list.id, "test"); assert_eq!(list.index, 0); assert_eq!(list.name, "Test"); assert_eq!(list.data, "This is a test list\n\n* One\n* Two\n* Three\n"); // The mtime field can vary, don't test for it // The path field is private, also don't test for it // Try to get a list that doesn't exist let res = client.get("/lists/doesntexit").header(Accept::JSON).dispatch(); assert_eq!(res.status(), Status::NotFound); // FIXME: Test that there is some kind of error in the JSON } #[test] fn update() { let client = Client::new(rocket(Some("test"))).unwrap(); // Try to get the list and determine what to change it to let mut res = client.get("/lists/updatable").header(Accept::JSON).dispatch(); let body = res.body_string().unwrap(); let list = serde_json::from_str::(body.as_str()).unwrap(); assert_eq!(list.data, "Some content"); // Try to change the list data, then verify it was changed let new_data = "New content"; let mut new_json: serde_json::Value = json!({ "id": "updatable", "index": 1, "data": new_data, "mtime": { "secs_since_epoch": 0, "nanos_since_epoch": 0 }, "name": "Updatable", "path": "test/lists/updatablelist" }); let res = client.put("/lists/updatable") .header(ContentType::JSON) .body(new_json.to_string()) .dispatch(); assert_eq!(res.status(), Status::Ok); let mut res = client.get("/lists/updatable") .header(Accept::JSON) .dispatch(); let body = res.body_string().unwrap(); let list = serde_json::from_str::(body.as_str()).unwrap(); assert_eq!(list.data, new_data); // ... and change it back *new_json.get_mut("data").unwrap() = json!("Some content"); let res = client.put("/lists/updatable") .header(ContentType::JSON) .body(new_json.to_string()) .dispatch(); assert_eq!(res.status(), Status::Ok); // Try to change a list that doesn't exist let res = client.put("/lists/doesntexit") .header(ContentType::JSON) .body(new_json.to_string()) .dispatch(); assert_eq!(res.status(), Status::NotFound); // Try to change a list without a proper body let res = client.put("/lists/updatable") .header(ContentType::JSON) .body(r#"{}"#) .dispatch(); assert_eq!(res.status(), Status::BadRequest); // Try to change a list without a proper type (i.e. not JSON) let res = client.put("/lists/updatable") .header(ContentType::Plain) .body("foo bar baz") .dispatch(); assert_eq!(res.status(), Status::NotFound); } }