ic_http_certification/tree/
certification_tree_entry.rsuse super::certification_tree_path::{HttpCertificationPath, InnerTreePath};
use crate::HttpCertification;
use std::borrow::Cow;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HttpCertificationTreeEntry<'a> {
pub path: Cow<'a, HttpCertificationPath<'a>>,
pub certification: Cow<'a, HttpCertification>,
}
impl<'a> HttpCertificationTreeEntry<'a> {
pub fn new(
path: impl Into<Cow<'a, HttpCertificationPath<'a>>>,
certification: impl Into<Cow<'a, HttpCertification>>,
) -> Self {
Self {
path: path.into(),
certification: certification.into(),
}
}
pub(super) fn to_tree_path(&self) -> InnerTreePath {
let mut tree_path = vec![];
tree_path.append(&mut self.path.to_tree_path());
tree_path.append(&mut self.certification.to_tree_path());
tree_path
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
request_hash, response_hash, DefaultCelBuilder, DefaultResponseCertification, HttpRequest,
HttpResponse, StatusCode, CERTIFICATE_EXPRESSION_HEADER_NAME,
};
use ic_representation_independent_hash::hash;
use rstest::*;
use rstest_reuse::*;
#[template]
#[rstest]
#[case(HttpCertificationPath::exact("/foo/bar"), vec!["foo", "bar", "<$>"])]
#[case(HttpCertificationPath::wildcard("/foo/bar"), vec!["foo", "bar", "<*>"])]
fn certification_paths(
#[case] path: HttpCertificationPath<'static>,
#[case] expected: Vec<&str>,
) {
}
#[apply(certification_paths)]
fn skip_certification_path(
#[case] path: HttpCertificationPath<'static>,
#[case] expected: Vec<&str>,
) {
let cel_expr = DefaultCelBuilder::skip_certification().to_string();
let cel_expr_hash = hash(cel_expr.as_bytes());
let certification = HttpCertification::skip();
let entry = HttpCertificationTreeEntry::new(&path, certification);
let result = entry.to_tree_path();
let path_segments: Vec<_> = expected
.into_iter()
.map(|segment| segment.as_bytes().to_vec())
.collect();
let expected = vec![cel_expr_hash.to_vec().to_owned()];
let expected: Vec<_> = path_segments
.into_iter()
.chain(expected.into_iter())
.collect();
assert_eq!(result, expected);
}
#[apply(certification_paths)]
fn response_only_certification_path(
#[case] path: HttpCertificationPath<'static>,
#[case] expected: Vec<&str>,
) {
let cel_expr = DefaultCelBuilder::response_only_certification()
.with_response_certification(DefaultResponseCertification::certified_response_headers(
vec![],
))
.build();
let cel_expr_hash = hash(cel_expr.to_string().as_bytes());
let response = HttpResponse::builder()
.with_status_code(StatusCode::OK)
.with_headers(vec![(
CERTIFICATE_EXPRESSION_HEADER_NAME.to_string(),
cel_expr.to_string(),
)])
.build();
let expected_response_hash = response_hash(&response, &cel_expr.response, None);
let certification = HttpCertification::response_only(&cel_expr, &response, None).unwrap();
let entry = HttpCertificationTreeEntry::new(&path, certification);
let result = entry.to_tree_path();
let path_segments: Vec<_> = expected
.into_iter()
.map(|segment| segment.as_bytes().to_vec())
.collect();
let expected = vec![
cel_expr_hash.to_vec().to_owned(),
"".as_bytes().to_vec(),
expected_response_hash.to_vec(),
];
let expected: Vec<_> = path_segments
.into_iter()
.chain(expected.into_iter())
.collect();
assert_eq!(result, expected);
}
#[apply(certification_paths)]
fn full_certification_path(
#[case] path: HttpCertificationPath<'static>,
#[case] expected: Vec<&str>,
) {
let cel_expr = DefaultCelBuilder::full_certification().build();
let cel_expr_hash = hash(cel_expr.to_string().as_bytes());
let request = HttpRequest::get("/index.html").build();
let expected_request_hash = request_hash(&request, &cel_expr.request).unwrap();
let response = HttpResponse::builder()
.with_status_code(StatusCode::OK)
.with_headers(vec![(
CERTIFICATE_EXPRESSION_HEADER_NAME.to_string(),
cel_expr.to_string(),
)])
.build();
let expected_response_hash = response_hash(&response, &cel_expr.response, None);
let certification = HttpCertification::full(&cel_expr, &request, &response, None).unwrap();
let entry = HttpCertificationTreeEntry::new(&path, certification);
let result = entry.to_tree_path();
let path_segments: Vec<_> = expected
.into_iter()
.map(|segment| segment.as_bytes().to_vec())
.collect();
let expected = vec![
cel_expr_hash.to_vec().to_owned(),
expected_request_hash.to_vec(),
expected_response_hash.to_vec(),
];
let expected: Vec<_> = path_segments
.into_iter()
.chain(expected.into_iter())
.collect();
assert_eq!(result, expected);
}
}