mod utils;
use rocket::http::{hyper::header, ContentType, Status};
use std::str::FromStr;
use test_context::test_context;
use tracing_test::traced_test;
use utils::{authorization, if_match, v2, MyTestContext};
use xapi_rs::{Aggregates, MyError, MyLanguageTag, Verb, VerbUI};
const VOIDED: &str = "http://adlnet.gov/expapi/verbs/voided";
#[test_context(MyTestContext)]
#[traced_test]
#[test]
fn test_valid_verb_alias(ctx: &mut MyTestContext) -> Result<(), MyError> {
let client = &ctx.client;
let req = client
.get("/extensions/verbs?iri=voided")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
assert_eq!(resp.content_type(), Some(ContentType::JSON));
let etag = resp.headers().get_one("Etag").expect("Missing Etag header");
assert_eq!(etag, "\"72-124846515289569516978801612129812838702\"");
let actual = resp.into_json::<Verb>().unwrap();
let en = MyLanguageTag::from_str("en")?;
assert_eq!(actual.id(), VOIDED);
assert_eq!(actual.display(&en).unwrap(), "voided");
Ok(())
}
#[test_context(MyTestContext)]
#[traced_test]
#[test]
fn test_valid_verb_iri(ctx: &mut MyTestContext) -> Result<(), MyError> {
let client = &ctx.client;
let req = client
.get(format!("/extensions/verbs?iri={}", VOIDED))
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
assert_eq!(resp.content_type(), Some(ContentType::JSON));
let etag = resp.headers().get_one("Etag").expect("Missing Etag header");
assert_eq!(etag, "\"72-124846515289569516978801612129812838702\"");
let actual = resp.into_json::<Verb>().unwrap();
let en = MyLanguageTag::from_str("en")?;
assert_eq!(actual.id(), VOIDED);
assert_eq!(actual.display(&en).unwrap(), "voided");
Ok(())
}
#[test_context(MyTestContext)]
#[traced_test]
#[test]
fn test_invalid_verb_alias(ctx: &mut MyTestContext) -> Result<(), MyError> {
let client = &ctx.client;
let req = client
.get("/extensions/verbs?iri=bewitched")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::NotFound);
Ok(())
}
#[test_context(MyTestContext)]
#[traced_test]
#[test]
fn test_invalid_verb_iri(ctx: &mut MyTestContext) -> Result<(), MyError> {
let client = &ctx.client;
let req = client
.get("/extensions/verbs?iri=ftp://bewitched")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::NotFound);
Ok(())
}
#[test_context(MyTestContext)]
#[traced_test]
#[test]
fn test_extension(ctx: &mut MyTestContext) -> Result<(), MyError> {
let client = &ctx.client;
let req = client
.get("/extensions/verbs/aggregates")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let aggregates_before = resp
.into_json::<Aggregates>()
.expect("Failed deserializing Aggregates");
let count_orig = aggregates_before.count();
assert_eq!(count_orig, 26);
let req = client
.post("/extensions/verbs/")
.body(r#"{"id":"http://adlnet.gov/expapi/verbs/answered","display":{"en":"whatever"}}"#)
.header(ContentType::JSON)
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::BadRequest);
const FLUMMOXED1: &str =
r#"{"id":"http://adlnet.gov/expapi/verbs/flummoxed","display":{"en":"whatever"}}"#;
const ETAG1: &str = "\"77-208188899287117226296122896605541617230\"";
const FLUMMOXED2: &str = r#"{"id":"http://adlnet.gov/expapi/verbs/flummoxed","display":{"en":"whatever","fr":"boff"}}"#;
const ETAG2: &str = "\"89-251683726746422182589889707996896257963\"";
const FLUMMOXED3: &str =
r#"{"id":"http://adlnet.gov/expapi/verbs/flummoxed","display":{"fr":"n'importe quoi"}}"#;
const ETAG3: &str = "\"99-252586577325935500065388981999838727903\"";
let req = client
.post("/extensions/verbs/")
.body(FLUMMOXED1)
.header(ContentType::JSON)
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let req = client
.get("/extensions/verbs?iri=flummoxed")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let etag_hdr = resp.headers().get_one(header::ETAG.as_str());
assert!(etag_hdr.is_some());
let etag = etag_hdr.expect("Missing ETag header");
assert_eq!(etag, ETAG1);
let v = resp
.into_string()
.expect("Failed coercing response to a string");
assert_eq!(v, FLUMMOXED1);
let req = client
.put("/extensions/verbs/")
.body(FLUMMOXED2)
.header(ContentType::JSON)
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Conflict);
let req = client
.put("/extensions/verbs/")
.body(FLUMMOXED2)
.header(ContentType::JSON)
.header(if_match(ETAG1))
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::NoContent);
let etag_hdr = resp.headers().get_one(header::ETAG.as_str());
assert!(etag_hdr.is_some());
let etag = etag_hdr.expect("Missing ETag header");
assert_eq!(etag, ETAG2);
let req = client
.get("/extensions/verbs?iri=flummoxed")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let etag_hdr = resp.headers().get_one(header::ETAG.as_str());
assert!(etag_hdr.is_some());
let etag = etag_hdr.expect("Missing ETag header");
assert_eq!(etag, ETAG2);
let json = resp
.into_string()
.expect("Failed coercing response to a string");
assert_eq!(json, FLUMMOXED2);
let req = client
.get("/extensions/verbs/aggregates")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let aggregates_after = resp
.into_json::<Aggregates>()
.expect("Failed deserializing Aggregates");
assert_eq!(aggregates_after.count(), count_orig + 1);
let req = client
.get("/extensions/verbs/?language=en&start=27")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let list = resp
.into_json::<Vec<VerbUI>>()
.expect("Failed deserializing VerbUI list");
assert_eq!(list.len(), 1);
let ui = &list[0];
assert_eq!(ui.display(), "whatever");
let req = client
.get("/extensions/verbs/?language=fr&start=27")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let ui = &resp.into_json::<Vec<VerbUI>>().unwrap()[0];
assert_eq!(ui.display(), "boff");
let req = client
.patch("/extensions/verbs/")
.body(FLUMMOXED3)
.header(ContentType::JSON)
.header(if_match(ETAG2))
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::NoContent);
let etag_hdr = resp.headers().get_one(header::ETAG.as_str());
assert!(etag_hdr.is_some());
let etag = etag_hdr.expect("Missing ETag header");
assert_eq!(etag, ETAG3);
let req = client
.get("/extensions/verbs/?language=en&start=27")
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let list = resp
.into_json::<Vec<VerbUI>>()
.expect("Failed deserializing VerbUI list");
assert_eq!(list.len(), 1);
let ui = &list[0];
assert_eq!(ui.display(), "whatever");
let url = format!("/extensions/verbs/{}", ui.rid());
let req = client
.get(url)
.header(v2())
.header(authorization());
let resp = req.dispatch();
assert_eq!(resp.status(), Status::Ok);
let v = resp.into_json::<Verb>().expect("Failed deserializing Verb");
let fr = MyLanguageTag::from_str("fr").expect("Failed converting 'fr' to Language Tag");
assert_eq!(v.display(&fr), Some("n'importe quoi"));
let en = MyLanguageTag::from_str("en").expect("Failed converting 'en' to Language Tag");
assert_eq!(v.display(&en), Some("whatever"));
Ok(())
}