#[macro_use] extern crate jsonapi_rs; extern crate serde_json; extern crate serde; use serde::{Deserialize, Serialize}; use jsonapi_rs::array::JsonApiArray; use jsonapi_rs::model::*; mod helper; use helper::read_json_file; #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Author { id: String, name: String, books: Vec, } jsonapi_model!(Author; "authors"; has many books); #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Book { id: String, title: String, first_chapter: Chapter, chapters: Vec } jsonapi_model!(Book; "books"; has one first_chapter; has many chapters); #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Chapter { id: String, title: String, ordering: i32, } jsonapi_model!(Chapter; "chapters"); #[test] fn to_jsonapi_document_and_back() { let book = Book { id: "1".into(), title: "The Fellowship of the Ring".into(), first_chapter: Chapter { id: "1".into(), title: "A Long-expected Party".into(), ordering: 1 }, chapters: vec![ Chapter { id: "1".into(), title: "A Long-expected Party".into(), ordering: 1 }, Chapter { id: "2".into(), title: "The Shadow of the Past".into(), ordering: 2 }, Chapter { id: "3".into(), title: "Three is Company".into(), ordering: 3 } ], }; let doc = book.to_jsonapi_document(); let json = serde_json::to_string(&doc).unwrap(); let book_doc: DocumentData = serde_json::from_str(&json) .expect("Book DocumentData should be created from the book json"); let book_again = Book::from_jsonapi_document(&book_doc) .expect("Book should be generated from the book_doc"); assert_eq!(book, book_again); } #[test] fn numeric_id() { #[derive(Debug, PartialEq, Serialize, Deserialize)] struct NumericChapter { id: i32, title: String, } jsonapi_model!(NumericChapter; "numeric_chapter"); let chapter = NumericChapter { id: 24, title: "The Riders of Rohan".into(), }; let (res, _) = chapter.to_jsonapi_resource(); assert_eq!(res.id, "24".to_string()); let doc = chapter.to_jsonapi_document(); assert!(doc.is_valid()); match &doc { JsonApiDocument::Error(_) => assert!(false), JsonApiDocument::Data(x) => { assert_eq!(x.data, Some(PrimaryData::Single(Box::new(res)))); } } let json = serde_json::to_string(&doc).unwrap(); let _num_doc: JsonApiDocument = serde_json::from_str(&json) .expect("NumericChapter JsonApiDocument should be created from the chapter json"); } #[test] fn test_vec_to_jsonapi_document() { let chapters = vec![ Chapter { id: "45".into(), title: "The Passing of the Grey Company".into(), ordering: 2, }, Chapter { id: "46".into(), title: "The Muster of Rohan".into(), ordering: 3, }, ]; let doc = vec_to_jsonapi_document(chapters); assert!(doc.is_valid()); } #[test] fn from_jsonapi_document() { let json = read_json_file("data/author_tolkien.json"); // TODO - is this the right thing that we want to test? Shold this cast into a JsonApiDocument // and detect if this was a data or an error? // Not sure that we want to immediately cast this into a "data" when we don't know if this isi // valid test file - it could be an error document for all we know... (that is equally valid) let author_doc: JsonApiDocument = serde_json::from_str(&json) .expect("Author DocumentData should be created from the author json"); // This assumes that the fixture we're using is a "valid" document with data match author_doc { JsonApiDocument::Error(_) => assert!(false), JsonApiDocument::Data(doc) => { let author = Author::from_jsonapi_document(&doc) .expect("Author should be generated from the author_doc"); let doc_again = author.to_jsonapi_document(); assert!(doc_again.is_valid()); } } }