use openidauthzen::*;
#[test]
fn page_should_omit_all_fields_when_none() {
let page = Page { token: None, limit: None, properties: None };
let json = serde_json::to_value(&page).unwrap();
assert!(json.as_object().unwrap().is_empty());
}
#[test]
fn page_should_serialize_token_and_limit() {
let page = Page {
token: Some("abc123".to_owned()),
limit: Some(10),
properties: None,
};
let json = serde_json::to_value(&page).unwrap();
assert_eq!(json["token"], "abc123");
assert_eq!(json["limit"], 10);
}
#[test]
fn page_should_include_properties_when_present() {
let page = Page {
token: None,
limit: None,
properties: Some(serde_json::json!({"sort": "asc"})),
};
let json = serde_json::to_value(&page).unwrap();
assert_eq!(json["properties"]["sort"], "asc");
}
#[test]
fn page_response_should_omit_all_fields_when_none() {
let pr = PageResponse {
next_token: None,
count: None,
total: None,
properties: None,
};
let json = serde_json::to_value(&pr).unwrap();
assert!(json.as_object().unwrap().is_empty());
}
#[test]
fn page_response_should_serialize_all_fields() {
let pr = PageResponse {
next_token: Some("a3M9NDU2O3N6PTI=".to_owned()),
count: Some(2),
total: Some(3),
properties: None,
};
let json = serde_json::to_value(&pr).unwrap();
assert_eq!(json["next_token"], "a3M9NDU2O3N6PTI=");
assert_eq!(json["count"], 2);
assert_eq!(json["total"], 3);
}
#[test]
fn page_response_should_roundtrip_spec_example() {
let json = r#"{"next_token": "a3M9NDU2O3N6PTI=", "count": 2, "total": 3}"#;
let pr: PageResponse = serde_json::from_str(json).unwrap();
assert_eq!(pr.next_token.as_deref(), Some("a3M9NDU2O3N6PTI="));
assert_eq!(pr.count, Some(2));
assert_eq!(pr.total, Some(3));
let roundtripped: PageResponse = serde_json::from_value(serde_json::to_value(&pr).unwrap()).unwrap();
assert_eq!(roundtripped, pr);
}
#[test]
fn subject_search_request_should_serialize_all_fields() {
let req = SubjectSearchRequest {
subject: Subject { subject_type: "user".to_owned(), id: None, properties: None },
action: Action { name: "can_read".to_owned(), properties: None },
resource: Resource { resource_type: "account".to_owned(), id: Some("123".to_owned()), properties: None },
context: Some({
let mut m = serde_json::Map::new();
m.insert("time".to_owned(), serde_json::json!("2024-10-26T01:22-07:00"));
m
}),
page: Some(Page { token: None, limit: Some(10), properties: None }),
};
let json = serde_json::to_value(&req).unwrap();
assert_eq!(json["subject"]["type"], "user");
assert_eq!(json["action"]["name"], "can_read");
assert_eq!(json["resource"]["id"], "123");
assert_eq!(json["page"]["limit"], 10);
}
#[test]
fn subject_search_request_should_omit_context_and_page_when_none() {
let req = SubjectSearchRequest {
subject: Subject { subject_type: "user".to_owned(), id: None, properties: None },
action: Action { name: "can_read".to_owned(), properties: None },
resource: Resource { resource_type: "account".to_owned(), id: Some("123".to_owned()), properties: None },
context: None,
page: None,
};
let json = serde_json::to_value(&req).unwrap();
assert!(json.get("context").is_none());
assert!(json.get("page").is_none());
}
#[test]
fn subject_search_request_should_roundtrip_spec_example() {
let json = r#"{
"subject": {"type": "user"},
"action": {"name": "can_read"},
"resource": {"type": "account", "id": "123"},
"context": {"time": "2024-10-26T01:22-07:00"}
}"#;
let req: SubjectSearchRequest = serde_json::from_str(json).unwrap();
assert_eq!(req.subject.subject_type, "user");
assert!(req.subject.id.is_none());
let roundtripped: SubjectSearchRequest = serde_json::from_value(serde_json::to_value(&req).unwrap()).unwrap();
assert_eq!(roundtripped, req);
}
#[test]
fn subject_search_response_should_serialize_results() {
let resp = SubjectSearchResponse {
results: vec![
Subject { subject_type: "user".to_owned(), id: Some("alice@example.com".to_owned()), properties: None },
Subject { subject_type: "user".to_owned(), id: Some("bob@example.com".to_owned()), properties: None },
],
page: None,
context: None,
};
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["results"].as_array().unwrap().len(), 2);
assert_eq!(json["results"][0]["id"], "alice@example.com");
}
#[test]
fn subject_search_response_should_omit_page_and_context_when_none() {
let resp = SubjectSearchResponse {
results: vec![],
page: None,
context: None,
};
let json = serde_json::to_value(&resp).unwrap();
assert!(json.get("page").is_none());
assert!(json.get("context").is_none());
}
#[test]
fn subject_search_response_should_include_pagination() {
let resp = SubjectSearchResponse {
results: vec![
Subject { subject_type: "user".to_owned(), id: Some("alice@example.com".to_owned()), properties: None },
],
page: Some(PageResponse {
next_token: Some("token123".to_owned()),
count: Some(1),
total: Some(5),
properties: None,
}),
context: None,
};
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["page"]["next_token"], "token123");
assert_eq!(json["page"]["count"], 1);
}
#[test]
fn resource_search_request_should_serialize_all_fields() {
let req = ResourceSearchRequest {
subject: Subject { subject_type: "user".to_owned(), id: Some("alice@example.com".to_owned()), properties: None },
action: Action { name: "can_read".to_owned(), properties: None },
resource: Resource { resource_type: "account".to_owned(), id: None, properties: None },
context: None,
page: None,
};
let json = serde_json::to_value(&req).unwrap();
assert_eq!(json["subject"]["id"], "alice@example.com");
assert_eq!(json["resource"]["type"], "account");
assert!(json["resource"].get("id").is_none());
}
#[test]
fn resource_search_request_should_omit_optional_fields_when_none() {
let req = ResourceSearchRequest {
subject: Subject { subject_type: "user".to_owned(), id: Some("alice@example.com".to_owned()), properties: None },
action: Action { name: "can_read".to_owned(), properties: None },
resource: Resource { resource_type: "account".to_owned(), id: None, properties: None },
context: None,
page: None,
};
let json = serde_json::to_value(&req).unwrap();
assert!(json.get("context").is_none());
assert!(json.get("page").is_none());
}
#[test]
fn resource_search_response_should_serialize_results() {
let resp = ResourceSearchResponse {
results: vec![
Resource { resource_type: "account".to_owned(), id: Some("123".to_owned()), properties: None },
Resource { resource_type: "account".to_owned(), id: Some("456".to_owned()), properties: None },
],
page: None,
context: None,
};
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["results"].as_array().unwrap().len(), 2);
assert_eq!(json["results"][1]["id"], "456");
}
#[test]
fn resource_search_response_should_include_pagination() {
let resp = ResourceSearchResponse {
results: vec![],
page: Some(PageResponse {
next_token: Some("".to_owned()),
count: Some(0),
total: Some(0),
properties: None,
}),
context: None,
};
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["page"]["next_token"], "");
}
#[test]
fn action_search_request_should_not_have_action_field() {
let req = ActionSearchRequest {
subject: Subject { subject_type: "user".to_owned(), id: Some("alice@example.com".to_owned()), properties: None },
resource: Resource { resource_type: "account".to_owned(), id: Some("123".to_owned()), properties: None },
context: None,
page: None,
};
let json = serde_json::to_value(&req).unwrap();
assert!(json.get("action").is_none());
}
#[test]
fn action_search_request_should_serialize_subject_and_resource() {
let req = ActionSearchRequest {
subject: Subject { subject_type: "user".to_owned(), id: Some("alice@example.com".to_owned()), properties: None },
resource: Resource { resource_type: "account".to_owned(), id: Some("123".to_owned()), properties: None },
context: None,
page: None,
};
let json = serde_json::to_value(&req).unwrap();
assert_eq!(json["subject"]["type"], "user");
assert_eq!(json["resource"]["id"], "123");
}
#[test]
fn action_search_request_should_omit_optional_fields_when_none() {
let req = ActionSearchRequest {
subject: Subject { subject_type: "user".to_owned(), id: Some("alice@example.com".to_owned()), properties: None },
resource: Resource { resource_type: "account".to_owned(), id: Some("123".to_owned()), properties: None },
context: None,
page: None,
};
let json = serde_json::to_value(&req).unwrap();
assert!(json.get("context").is_none());
assert!(json.get("page").is_none());
}
#[test]
fn action_search_response_should_serialize_results() {
let resp = ActionSearchResponse {
results: vec![
Action { name: "can_read".to_owned(), properties: None },
Action { name: "can_write".to_owned(), properties: None },
],
page: None,
context: None,
};
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["results"].as_array().unwrap().len(), 2);
assert_eq!(json["results"][0]["name"], "can_read");
assert_eq!(json["results"][1]["name"], "can_write");
}
#[test]
fn action_search_response_should_include_pagination() {
let resp = ActionSearchResponse {
results: vec![],
page: Some(PageResponse {
next_token: Some("next".to_owned()),
count: Some(0),
total: None,
properties: None,
}),
context: Some(serde_json::json!({"query_execution_time_ms": 42})),
};
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["page"]["next_token"], "next");
assert_eq!(json["context"]["query_execution_time_ms"], 42);
}