use asx_rs::core::InteropMode;
use asx_rs::interop::{
BaseProfile, CanonicalizationPolicy, ProfileStack, ProfileValidationReport,
ProfileValidationResult, SecurityPolicy, ValidationPolicy,
};
use crate::pmode::{PMode, PModeRegistry};
pub const PROFILE_NAME: &str = "bdew_mako_as4";
pub const PROFILE_VERSION: &str = "2.0.0";
pub fn bdew_mako_profile_stack() -> ProfileStack {
ProfileStack {
base: BaseProfile {
name: PROFILE_NAME.to_string(),
version: PROFILE_VERSION.to_string(),
mode: InteropMode::Strict,
canonicalization: CanonicalizationPolicy::default(),
security: SecurityPolicy {
require_signature: true,
require_encryption: false,
},
validation: ValidationPolicy {
reject_ambiguous_headers: true,
enforce_payload_limits: true,
require_as2_mic: false,
},
},
extensions: Vec::new(),
overrides: Vec::new(),
partner_overrides: Vec::new(),
}
}
#[derive(Debug)]
pub struct BdewAs4Profile {
stack: ProfileStack,
registry: PModeRegistry,
}
impl Default for BdewAs4Profile {
fn default() -> Self {
Self::new()
}
}
impl BdewAs4Profile {
pub fn new() -> Self {
Self {
stack: bdew_mako_profile_stack(),
registry: PModeRegistry::new(),
}
}
pub fn profile_stack(&self) -> &ProfileStack {
&self.stack
}
pub fn registry(&self) -> &PModeRegistry {
&self.registry
}
pub fn register_pmode(&mut self, pmode: PMode) -> &mut Self {
self.registry.register(pmode);
self
}
pub fn resolve_pmode(&self, partner_gln: &str, service: &str, action: &str) -> Option<&PMode> {
self.registry.resolve(partner_gln, service, action)
}
pub fn validate(&self) -> ProfileValidationResult<ProfileValidationReport> {
self.stack.validate()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::constants;
use crate::pmode::{BdewAction, bdew_pmode};
#[test]
fn profile_stack_validates_without_errors() {
let stack = bdew_mako_profile_stack();
let report = stack
.validate()
.expect("BDEW base profile must pass validation");
assert!(
report.lints.is_empty(),
"no redundant-override lints expected"
);
}
#[test]
fn profile_stack_name_and_version() {
let stack = bdew_mako_profile_stack();
assert_eq!(stack.base.name, PROFILE_NAME);
assert_eq!(stack.base.version, PROFILE_VERSION);
}
#[test]
fn profile_stack_security_policy() {
let stack = bdew_mako_profile_stack();
assert!(
stack.base.security.require_signature,
"signing must be required"
);
assert!(
!stack.base.security.require_encryption,
"encryption must be optional (not required)"
);
}
#[test]
fn profile_stack_mode_is_strict() {
let stack = bdew_mako_profile_stack();
assert_eq!(stack.base.mode, InteropMode::Strict);
}
#[test]
fn profile_stack_no_as2_mic() {
let stack = bdew_mako_profile_stack();
assert!(
!stack.base.validation.require_as2_mic,
"AS2 MIC must not be required in an AS4 profile"
);
}
#[test]
fn bdew_as4_profile_register_and_resolve() {
let mut profile = BdewAs4Profile::new();
profile
.register_pmode(bdew_pmode("pm-u", "9900000000001", BdewAction::Utilmd))
.register_pmode(bdew_pmode("pm-a", "9900000000001", BdewAction::Aperak));
assert_eq!(profile.registry().len(), 2);
let pm = profile.resolve_pmode(
"9900000000001",
constants::SERVICE,
&BdewAction::Utilmd.as_uri(),
);
assert!(pm.is_some());
assert_eq!(pm.unwrap().id, "pm-u");
assert!(
profile
.resolve_pmode(
"9999999999999",
constants::SERVICE,
&BdewAction::Utilmd.as_uri()
)
.is_none()
);
}
#[test]
fn bdew_as4_profile_validates() {
let mut profile = BdewAs4Profile::new();
profile.register_pmode(bdew_pmode("pm-u", "9900000000001", BdewAction::Utilmd));
profile
.validate()
.expect("profile with registered P-Mode must validate");
}
#[test]
fn bdew_as4_profile_default_equals_new() {
let a = BdewAs4Profile::new();
let b = BdewAs4Profile::default();
assert_eq!(a.registry().len(), b.registry().len());
assert_eq!(a.profile_stack().base.name, b.profile_stack().base.name);
}
}