294 lines
11 KiB
Rust
294 lines
11 KiB
Rust
// file: crates/ksp-store-api/unit_tests/model/raw_conflict.rs
|
|
// version: 1
|
|
|
|
fn network(value: &str) -> std::option::Option<crate::RawNetworkId> {
|
|
return crate::RawNetworkId::new(value.to_owned()).ok();
|
|
}
|
|
|
|
fn transaction_reference(network: crate::RawNetworkId, signature_byte: u8) -> crate::RawTransactionReference {
|
|
return crate::RawTransactionReference::new(network, crate::RawTransactionSignature::new([signature_byte; 64]));
|
|
}
|
|
|
|
fn variant_reference(transaction: crate::RawTransactionReference, variant_id: u64) -> std::option::Option<crate::RawTransactionVariantReference> {
|
|
let variant_id = match crate::RawTransactionVariantId::try_new(variant_id) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
return std::option::Option::Some(crate::RawTransactionVariantReference::new(transaction, variant_id));
|
|
}
|
|
|
|
fn timestamp(value: u64) -> std::option::Option<crate::RawTimestamp> {
|
|
return crate::RawTimestamp::from_unix_millis(value).ok();
|
|
}
|
|
|
|
fn page() -> std::option::Option<crate::RawInspectionPageRequest> {
|
|
let limit = match crate::RawPageLimit::new(25) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
return std::option::Option::Some(crate::RawInspectionPageRequest::new(0, limit));
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_17_pre_002_conflict_and_variant_queries_enforce_network_scope() {
|
|
let mainnet = match network("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let devnet = match network("devnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let transaction = transaction_reference(devnet, 1);
|
|
let page = match page() {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
assert!(
|
|
crate::RawTransactionVariantInspectionQuery::try_new(
|
|
mainnet.clone(),
|
|
std::option::Option::Some(transaction.clone()),
|
|
crate::RawSortDirection::Ascending,
|
|
page,
|
|
)
|
|
.is_err()
|
|
);
|
|
assert!(
|
|
crate::RawTransactionConflictInspectionQuery::try_new(
|
|
mainnet,
|
|
std::option::Option::Some(crate::RawTransactionConflictStatus::Open),
|
|
std::option::Option::Some(transaction),
|
|
crate::RawSortDirection::Ascending,
|
|
page,
|
|
)
|
|
.is_err()
|
|
);
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_17_pre_002_action_request_requires_positive_double_revision_and_same_transaction_target() {
|
|
let mainnet = match network("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let transaction = transaction_reference(mainnet.clone(), 2);
|
|
let conflict = crate::RawTransactionConflictReference::new(transaction.clone());
|
|
let target = match variant_reference(transaction, 2) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
assert!(
|
|
crate::RawTransactionConflictActionRequest::try_new(conflict.clone(), 0, 1, crate::RawTransactionConflictAction::PromoteVariant(target.clone()),)
|
|
.is_err()
|
|
);
|
|
let other = transaction_reference(mainnet, 3);
|
|
let other_target = match variant_reference(other, 3) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
assert!(
|
|
crate::RawTransactionConflictActionRequest::try_new(conflict.clone(), 1, 1, crate::RawTransactionConflictAction::PromoteVariant(other_target),)
|
|
.is_err()
|
|
);
|
|
let request = crate::RawTransactionConflictActionRequest::try_new(
|
|
conflict,
|
|
5,
|
|
7,
|
|
crate::RawTransactionConflictAction::Resolve(crate::RawTransactionConflictResolution::PromoteVariant(target)),
|
|
);
|
|
assert!(request.is_ok());
|
|
let request = match request {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
assert_eq!(request.expected_conflict_revision(), 5);
|
|
assert_eq!(request.expected_canonical_revision(), 7);
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_17_pre_002_conflict_projection_enforces_status_resolution_and_conflict_relation() {
|
|
let mainnet = match network("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let transaction = transaction_reference(mainnet, 4);
|
|
let conflict = crate::RawTransactionConflictReference::new(transaction.clone());
|
|
let canonical = match variant_reference(transaction.clone(), 1) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let incoming = match variant_reference(transaction, 2) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let created_at = match timestamp(1_000) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let updated_at = match timestamp(2_000) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let open = crate::RawTransactionConflictSummary::try_new(
|
|
conflict.clone(),
|
|
crate::RawTransactionConflictStatus::Open,
|
|
3,
|
|
canonical.clone(),
|
|
2,
|
|
incoming.clone(),
|
|
crate::RawTransactionVariantRelation::Conflict,
|
|
crate::RawTransactionVariantRelationReason::CanonicalPayloadConflict,
|
|
std::option::Option::None,
|
|
std::option::Option::None,
|
|
2,
|
|
created_at,
|
|
updated_at,
|
|
);
|
|
assert!(open.is_ok());
|
|
let invalid_resolved = crate::RawTransactionConflictSummary::try_new(
|
|
conflict,
|
|
crate::RawTransactionConflictStatus::Resolved,
|
|
4,
|
|
canonical,
|
|
3,
|
|
incoming,
|
|
crate::RawTransactionVariantRelation::Exact,
|
|
crate::RawTransactionVariantRelationReason::ExactCanonicalContent,
|
|
std::option::Option::None,
|
|
std::option::Option::None,
|
|
2,
|
|
created_at,
|
|
updated_at,
|
|
);
|
|
assert!(invalid_resolved.is_err());
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_17_pre_002_conflict_detail_requires_unique_complete_participant_projection() {
|
|
let mainnet = match network("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let transaction = transaction_reference(mainnet, 5);
|
|
let conflict = crate::RawTransactionConflictReference::new(transaction.clone());
|
|
let canonical = match variant_reference(transaction.clone(), 1) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let incoming = match variant_reference(transaction, 2) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let created_at = match timestamp(1_000) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let updated_at = match timestamp(2_000) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let summary = crate::RawTransactionConflictSummary::try_new(
|
|
conflict,
|
|
crate::RawTransactionConflictStatus::Open,
|
|
2,
|
|
canonical.clone(),
|
|
1,
|
|
incoming.clone(),
|
|
crate::RawTransactionVariantRelation::Incomparable,
|
|
crate::RawTransactionVariantRelationReason::UnsupportedCanonicalDifference,
|
|
std::option::Option::None,
|
|
std::option::Option::None,
|
|
2,
|
|
created_at,
|
|
updated_at,
|
|
);
|
|
let summary = match summary {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let first = match crate::RawTransactionConflictParticipantSummary::try_new(canonical, 1, created_at) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let second = match crate::RawTransactionConflictParticipantSummary::try_new(incoming, 2, updated_at) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
assert!(crate::RawTransactionConflictDetail::try_new(summary, std::vec![first, second]).is_ok());
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_17_pre_002_history_event_requires_resolution_action_only_for_resolution_events() {
|
|
let mainnet = match network("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let transaction = transaction_reference(mainnet, 6);
|
|
let conflict = crate::RawTransactionConflictReference::new(transaction.clone());
|
|
let canonical = match variant_reference(transaction.clone(), 1) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let incoming = match variant_reference(transaction, 2) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let comparison = crate::RawTransactionVariantComparison::try_new(
|
|
crate::RawTransactionVariantRelation::Conflict,
|
|
crate::RawTransactionVariantRelationReason::CanonicalPayloadConflict,
|
|
);
|
|
let comparison = match comparison {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let at = match timestamp(1_000) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
assert!(
|
|
crate::RawTransactionConflictEventSummary::try_new(
|
|
conflict.clone(),
|
|
1,
|
|
crate::RawTransactionConflictEventKind::Opened,
|
|
crate::RawTransactionConflictEventOrigin::Automatic,
|
|
std::option::Option::Some(canonical.clone()),
|
|
std::option::Option::Some(incoming),
|
|
std::option::Option::Some(canonical.clone()),
|
|
std::option::Option::Some(comparison),
|
|
std::option::Option::None,
|
|
at,
|
|
)
|
|
.is_ok()
|
|
);
|
|
assert!(
|
|
crate::RawTransactionConflictEventSummary::try_new(
|
|
conflict,
|
|
2,
|
|
crate::RawTransactionConflictEventKind::ResolvedKeepCanonical,
|
|
crate::RawTransactionConflictEventOrigin::Operator,
|
|
std::option::Option::Some(canonical.clone()),
|
|
std::option::Option::None,
|
|
std::option::Option::Some(canonical),
|
|
std::option::Option::None,
|
|
std::option::Option::None,
|
|
at,
|
|
)
|
|
.is_err()
|
|
);
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_17_pre_002_action_outcomes_and_codes_are_stable_and_distinct() {
|
|
assert_eq!(crate::RawTransactionConflictResolutionAction::KeepCurrentCanonical.code(), "keep_current_canonical");
|
|
assert_eq!(crate::RawTransactionConflictEventKind::ParticipantAdded.code(), "participant_added");
|
|
assert_eq!(crate::RawTransactionConflictEventOrigin::Operator.code(), "operator");
|
|
assert_ne!(crate::RawTransactionConflictActionOutcome::Applied, crate::RawTransactionConflictActionOutcome::AlreadyAtTarget);
|
|
assert_ne!(crate::RawTransactionConflictActionOutcome::AlreadyAtTarget, crate::RawTransactionConflictActionOutcome::StaleRevision);
|
|
return;
|
|
}
|