open-standards/openpay/crates/op-bin/tests/range_tree.rs
Transaction Science 5ae7e4ef86 ingest wave E: 3 crates · op-bin + smart-byte-tendermint + eoc-safety
OpenPay (1 crate, 1801 LOC, 57 tests)
  op-bin              BIN/IIN database + range matching + card-network
                      classification. 8-digit normalized prefix Bin +
                      BinRange. Sorted-vec interval tree with O(log N) point
                      lookup + overlap rejection. CardNetwork classify()
                      with structural rules (Visa 4, MC 51-55/2221-2720,
                      Amex 34/37, Discover, JCB, Diners, UnionPay, RuPay,
                      Mir, Troy, Maestro, Elo). Static prefix tables +
                      build_default_tree(). ISO/IEC 7812-1 Annex B Luhn
                      (validate / is_valid / check_digit). Card-type +
                      issuer-country + Durbin regulated-debit. PCI-safe:
                      8-digit cap, no full-PAN APIs.

Smart Byte (1 crate, ~1500 LOC, 20 tests)
  smart-byte-tendermint  BFT consensus. Step enum + Round + propose/prevote/
                         precommit/commit FSM with voting-power tallies.
                         ValidatorSet with 2/3+1 quorum, 1/3+1 trust
                         threshold, round-robin proposer. Block / Header /
                         Commit / CommitSig with Blake3 hashing. Light client
                         (sequential + skipping). ABCI Application trait +
                         EchoApp. DuplicateVoteEvidence + LightClientAttackEvidence.
                         IBC ClientState + ConsensusState + light-client
                         update.

EOC (1 crate, 2084 LOC, 23 tests)
  eoc-safety          AI safety primitives. RegexSet over 16 prompt-injection
                      signatures. 13-family jailbreak detector (DAN/DUDE/
                      Grandma/STAN/AIM/dev-mode/etc.). Presidio-style PII
                      redactor with Luhn-validated CC. Toxicity / bias /
                      NSFW classifier traits + heuristic baselines (5-axis
                      bias, 4-category NSFW with hard-reject for minors).
                      Constitutional AI critique→revise loop. Composable
                      InputGuard / OutputGuard pipelines. JSON-Schema-subset
                      output validator. Token-bucket rate limiter +
                      abuse-window detection. Red-team replay harness.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-24 16:52:07 -04:00

82 lines
2.6 KiB
Rust

//! Range-tree integration tests:
//! - the default tree built from `network_ranges` is internally
//! consistent (no overlaps),
//! - representative BINs across every supported network resolve
//! to the expected network,
//! - point lookups outside any range return `None`.
use op_bin::network_ranges::build_default_tree;
use op_bin::{Bin, CardNetwork};
#[test]
fn default_tree_constructs_disjoint() {
let tree = build_default_tree().expect("disjoint by construction");
assert!(tree.len() >= 25);
}
#[test]
fn known_bins_resolve_per_network() {
let tree = build_default_tree().expect("ok");
let cases: &[(&str, CardNetwork)] = &[
("411111", CardNetwork::Visa),
("510000", CardNetwork::Mastercard),
("222100", CardNetwork::Mastercard),
("340000", CardNetwork::Amex),
("370000", CardNetwork::Amex),
("601100", CardNetwork::Discover),
("352800", CardNetwork::Jcb),
("360000", CardNetwork::DinersClub),
("621234", CardNetwork::UnionPay),
("810000", CardNetwork::RuPay),
("220000", CardNetwork::Mir),
("979200", CardNetwork::Troy),
];
for (bin_str, expected) in cases {
let b = Bin::parse(bin_str).expect("valid");
let got = tree
.lookup(&b)
.unwrap_or_else(|| panic!("no range for {bin_str}"));
assert_eq!(
got.network, *expected,
"BIN {bin_str} expected {expected:?}, got {:?}",
got.network,
);
}
}
#[test]
fn unassigned_bin_returns_none() {
let tree = build_default_tree().expect("ok");
// 700000 is unassigned in the published BIN catalog.
let b = Bin::parse("700000").expect("ok");
assert!(tree.lookup(&b).is_none());
}
#[test]
fn boundary_half_open() {
let tree = build_default_tree().expect("ok");
// Mastercard classic range ends just before 56xxxxxx.
let last_mc = Bin::parse("559999").expect("ok");
assert_eq!(
tree.lookup(&last_mc).map(|r| r.network),
Some(CardNetwork::Mastercard),
);
// 56xxxxxx maps into the Maestro carve-out at 5612 only;
// 5600xx falls outside any registered range.
let outside_mc = Bin::parse("560000").expect("ok");
assert!(tree.lookup(&outside_mc).is_none());
}
#[test]
fn sorted_invariant_holds() {
let tree = build_default_tree().expect("ok");
let rs = tree.ranges();
for win in rs.windows(2) {
assert!(
win[0].high <= win[1].low,
"ranges out of order or overlapping: {:?} then {:?}",
win[0],
win[1],
);
}
}