190 lines
6.1 KiB
Rust
190 lines
6.1 KiB
Rust
use rocket::State;
|
|
use rocket_contrib::Json;
|
|
use super::super::NoteStore;
|
|
use super::super::models::note::Note;
|
|
|
|
#[get("/", format = "application/json")]
|
|
fn index(notes: State<NoteStore>) -> Option<Json<Vec<Note>>> {
|
|
let notes = notes.read().unwrap();
|
|
Some(Json(notes.clone()))
|
|
}
|
|
|
|
#[get("/<note_id>", format = "text/html")]
|
|
fn show_html(note_id: String, notes: State<NoteStore>) -> Option<String> {
|
|
let notes = notes.read().unwrap();
|
|
let note = notes.iter().find(|note| note.id == note_id)?;
|
|
Some(note.to_html())
|
|
}
|
|
|
|
#[get("/<note_id>", format = "application/json")]
|
|
fn show_json(note_id: String, notes: State<NoteStore>) -> Option<Json<Note>> {
|
|
let notes = notes.read().unwrap();
|
|
let note = notes.iter().find(|note| note.id == note_id)?;
|
|
Some(Json(note.clone()))
|
|
}
|
|
|
|
#[put("/<note_id>", format = "application/json", data = "<new_note>")]
|
|
fn update(note_id: String, new_note: Json<Note>, notes: State<NoteStore>) -> Option<Json<Note>> {
|
|
let mut notes = notes.write().unwrap();
|
|
let note = notes.iter_mut().find(|note| note.id == note_id)?;
|
|
note.update_data(&new_note.data);
|
|
Some(Json(note.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 notes
|
|
let mut res = client.get("/notes").header(Accept::JSON).dispatch();
|
|
assert_eq!(res.status(), Status::Ok);
|
|
|
|
let body = res.body_string().unwrap();
|
|
let notes = serde_json::from_str::<Vec<Note>>(body.as_str()).unwrap();
|
|
assert_eq!(notes[0].id, "test");
|
|
assert_eq!(notes[0].index, 0);
|
|
assert_eq!(notes[0].name, "Test");
|
|
assert_eq!(
|
|
notes[0].data,
|
|
"This is a test note\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 notes in HTML format
|
|
let res = client.get("/notes").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 note and verify the body
|
|
let mut res = client.get("/notes/test").header(Accept::HTML).dispatch();
|
|
assert_eq!(res.status(), Status::Ok);
|
|
|
|
let body = res.body_string().unwrap();
|
|
assert_eq!(
|
|
body,
|
|
r#"<p>This is a test note</p>
|
|
<ul>
|
|
<li>One</li>
|
|
<li>Two</li>
|
|
<li>Three</li>
|
|
</ul>
|
|
"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn show_json() {
|
|
let client = Client::new(rocket(Some("test"))).unwrap();
|
|
|
|
// Try to get the note and verify the body
|
|
let mut res = client.get("/notes/test").header(Accept::JSON).dispatch();
|
|
assert_eq!(res.status(), Status::Ok);
|
|
|
|
let body = res.body_string().unwrap();
|
|
let note = serde_json::from_str::<Note>(body.as_str()).unwrap();
|
|
assert_eq!(note.id, "test");
|
|
assert_eq!(note.index, 0);
|
|
assert_eq!(note.name, "Test");
|
|
assert_eq!(note.data, "This is a test note\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 note that doesn't exist
|
|
let res = client
|
|
.get("/notes/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 note and determine what to change it to
|
|
let mut res = client
|
|
.get("/notes/updatable")
|
|
.header(Accept::JSON)
|
|
.dispatch();
|
|
let body = res.body_string().unwrap();
|
|
let note = serde_json::from_str::<Note>(body.as_str()).unwrap();
|
|
assert_eq!(note.data, "Some content");
|
|
|
|
// Try to change the note 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/notes/updatablenote"
|
|
});
|
|
let res = client
|
|
.put("/notes/updatable")
|
|
.header(ContentType::JSON)
|
|
.body(new_json.to_string())
|
|
.dispatch();
|
|
assert_eq!(res.status(), Status::Ok);
|
|
|
|
let mut res = client
|
|
.get("/notes/updatable")
|
|
.header(Accept::JSON)
|
|
.dispatch();
|
|
let body = res.body_string().unwrap();
|
|
let note = serde_json::from_str::<Note>(body.as_str()).unwrap();
|
|
assert_eq!(note.data, new_data);
|
|
|
|
// ... and change it back
|
|
*new_json.get_mut("data").unwrap() = json!("Some content");
|
|
let res = client
|
|
.put("/notes/updatable")
|
|
.header(ContentType::JSON)
|
|
.body(new_json.to_string())
|
|
.dispatch();
|
|
assert_eq!(res.status(), Status::Ok);
|
|
|
|
// Try to change a note that doesn't exist
|
|
let res = client
|
|
.put("/notes/doesntexit")
|
|
.header(ContentType::JSON)
|
|
.body(new_json.to_string())
|
|
.dispatch();
|
|
assert_eq!(res.status(), Status::NotFound);
|
|
|
|
// Try to change a note without a proper body
|
|
let res = client
|
|
.put("/notes/updatable")
|
|
.header(ContentType::JSON)
|
|
.body(r#"{}"#)
|
|
.dispatch();
|
|
assert_eq!(res.status(), Status::BadRequest);
|
|
|
|
// Try to change a note without a proper type (i.e. not JSON)
|
|
let res = client
|
|
.put("/notes/updatable")
|
|
.header(ContentType::Plain)
|
|
.body("foo bar baz")
|
|
.dispatch();
|
|
assert_eq!(res.status(), Status::NotFound);
|
|
}
|
|
}
|