use super::*;
use chrono::{TimeZone as _, Utc};
fn at(y: i32, m: u32, d: u32) -> chrono::DateTime<Utc> {
Utc.with_ymd_and_hms(y, m, d, 0, 0, 0).unwrap()
}
#[test]
fn the_qualified_axis_round_trips_through_its_uris() {
assert_eq!(
TrustServiceStatus::from_uri(GRANTED_URI),
TrustServiceStatus::Granted
);
assert_eq!(
TrustServiceStatus::from_uri(WITHDRAWN_URI),
TrustServiceStatus::Withdrawn
);
assert_eq!(TrustServiceStatus::Granted.as_uri(), GRANTED_URI);
assert_eq!(TrustServiceStatus::Withdrawn.as_uri(), WITHDRAWN_URI);
}
#[test]
fn no_other_status_is_a_lesser_granted() {
for uri in [
"http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/undersupervision",
"http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/accredited",
"http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/recognisedatnationallevel",
"http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/setbynationallaw",
"http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/supervisionceased",
] {
let status = TrustServiceStatus::from_uri(uri);
assert!(
!status.is_granted(),
"{uri} is not qualified status under 910/2014"
);
assert_eq!(status.as_uri(), uri, "and it round-trips unchanged");
}
}
#[test]
fn an_unknown_status_is_readable_and_not_granted() {
let future = TrustServiceStatus::from_uri(
"http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/somethingaddedin2030",
);
assert!(!future.is_granted());
assert!(matches!(future, TrustServiceStatus::Other(_)));
}
#[test]
fn the_remote_seal_device_service_types_are_not_interchangeable() {
let qualified = TrustServiceType::new(TrustServiceType::REMOTE_QSEAL_CD_MANAGEMENT);
let plain = TrustServiceType::new(TrustServiceType::REMOTE_SEAL_CD_MANAGEMENT);
assert_ne!(qualified, plain);
assert!(qualified.looks_qualified());
assert!(
!plain.looks_qualified(),
"managing a non-qualified creation device is not the Art. 39a service"
);
}
#[test]
fn a_withdrawal_does_not_reach_back_to_seals_made_while_granted() {
let history = TrustServiceHistory::new(vec![
TrustServiceStatusPeriod {
status: TrustServiceStatus::Granted,
starting_at: at(2026, 1, 1),
},
TrustServiceStatusPeriod {
status: TrustServiceStatus::Withdrawn,
starting_at: at(2029, 6, 1),
},
]);
assert!(
history.was_granted_at(at(2027, 5, 1)),
"the seal was made while the provider held qualified status"
);
assert!(
!history.was_granted_at(at(2030, 1, 1)),
"and the provider does not hold it now"
);
}
#[test]
fn a_later_grant_does_not_qualify_an_earlier_seal() {
let history = TrustServiceHistory::new(vec![
TrustServiceStatusPeriod {
status: TrustServiceStatus::Withdrawn,
starting_at: at(2026, 1, 1),
},
TrustServiceStatusPeriod {
status: TrustServiceStatus::Granted,
starting_at: at(2029, 6, 1),
},
]);
assert!(
!history.was_granted_at(at(2027, 5, 1)),
"the provider was not qualified when this seal was made"
);
assert!(history.was_granted_at(at(2030, 1, 1)));
}
#[test]
fn unordered_periods_give_the_same_answer() {
let ordered = vec![
TrustServiceStatusPeriod {
status: TrustServiceStatus::Granted,
starting_at: at(2026, 1, 1),
},
TrustServiceStatusPeriod {
status: TrustServiceStatus::Withdrawn,
starting_at: at(2029, 6, 1),
},
];
let mut shuffled = ordered.clone();
shuffled.reverse();
for when in [at(2027, 5, 1), at(2030, 1, 1)] {
assert_eq!(
TrustServiceHistory::new(ordered.clone()).was_granted_at(when),
TrustServiceHistory::new(shuffled.clone()).was_granted_at(when),
);
}
}
#[test]
fn a_moment_before_the_history_is_unknown_not_withdrawn() {
let history = TrustServiceHistory::new(vec![TrustServiceStatusPeriod {
status: TrustServiceStatus::Granted,
starting_at: at(2026, 1, 1),
}]);
assert_eq!(history.status_at(at(2020, 1, 1)), None);
assert!(!history.was_granted_at(at(2020, 1, 1)));
assert_eq!(
history.status_at(at(2026, 1, 1)),
Some(&TrustServiceStatus::Granted),
"the boundary is inclusive: a status applies from the instant it starts"
);
}
#[test]
fn an_empty_history_is_unknown() {
let history = TrustServiceHistory::new(vec![]);
assert_eq!(history.status_at(at(2027, 1, 1)), None);
assert!(!history.was_granted_at(at(2027, 1, 1)));
}