Files
khadhroony-solana-project/crates/ksp-store-api/unit_tests/model/raw_conflict.rs
2026-09-24 10:55:34 +02:00

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;
}