Skip to content
Draft
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
b2fa94b
test(browser): require protocol identity registry
seonghobae Aug 9, 2026
0e5917a
style(browser): apply canonical rustfmt
seonghobae Aug 9, 2026
bcc8f10
feat(browser): implement authority registry
seonghobae Aug 9, 2026
2e4c359
test(browser): close registry coverage gaps
seonghobae Aug 9, 2026
1a1027f
test(browser): satisfy strict clippy contracts
seonghobae Aug 9, 2026
938ae8c
style(browser): apply canonical registry test formatting
seonghobae Aug 9, 2026
76cddbc
test(browser): keep fixture origin errors local
seonghobae Aug 9, 2026
4ea14a1
ci: surface exact browser-registry coverage gaps
seonghobae Aug 9, 2026
b298111
test(browser): require bounded authority identifier capacity
seonghobae Aug 10, 2026
f528f6a
feat(browser): bound registry identifier capacity
seonghobae Aug 10, 2026
eaadbf5
test(browser): cover exact registry denial branches
seonghobae Aug 10, 2026
235fd1f
test(browser): keep origin mismatch fixture deterministic
seonghobae Aug 10, 2026
2276b4c
style(browser): format authority registry regression
seonghobae Aug 10, 2026
930b3a8
refactor(browser): preserve fallible invariants without uncovered pro…
seonghobae Aug 10, 2026
c78dc70
fix(browser): satisfy strict clippy on invariant side effects
seonghobae Aug 10, 2026
39966aa
test(browser): cover repeated node binding in unit crate
seonghobae Aug 10, 2026
f3130ea
test(browser): run repeated binding in unit crate
seonghobae Aug 10, 2026
45ed9bc
test(browser): use non-panicking unit origin fixture
seonghobae Aug 10, 2026
c30e2e4
test(browser): fix unit origin fixture conversion
seonghobae Aug 10, 2026
78ba71b
test(browser): exercise public default and error contracts
seonghobae Aug 10, 2026
504f8cf
test(browser): cover unit-crate session authority failures
seonghobae Aug 10, 2026
b539539
test(core): remove synthetic coverage-only error branches
seonghobae Aug 10, 2026
c30c76e
Merge branch 'main' into feat/browser-authority-registry
opencode-agent[bot] Aug 10, 2026
9e635e8
test(browser): derive identifier boundary from public contract
seonghobae Aug 10, 2026
c0da8bd
test(core): require versioned browser protocol capability descriptor
seonghobae Aug 12, 2026
d7ad355
feat(core): add browser protocol capability descriptor
seonghobae Aug 12, 2026
c1e6404
feat(core): export browser protocol descriptor
seonghobae Aug 12, 2026
698218f
test(core): cover non-ASCII protocol metadata rejection
seonghobae Aug 12, 2026
723a092
docs(changelog): record browser protocol descriptor
seonghobae Aug 12, 2026
61164ce
test(core): require explicit browser protocol revision
seonghobae Aug 12, 2026
e1cc2c8
feat(core): bind browser protocol revision explicitly
seonghobae Aug 12, 2026
8d2549c
test(core): require canonical browser capability ordering
seonghobae Aug 12, 2026
7a3e8f4
fix(core): canonicalize browser capability set ordering
seonghobae Aug 12, 2026
5dd9635
test(browser): require registry authority teardown
seonghobae Aug 14, 2026
cf9581a
fix(browser): retire registry authority state
seonghobae Aug 14, 2026
f577a78
style(browser): apply canonical rustfmt
seonghobae Aug 14, 2026
2abb5ff
Merge branch 'main' into feat/browser-authority-registry
github-actions[bot] Aug 14, 2026
0c4ae8d
test(core): remove redundant registry coverage module wiring
seonghobae Aug 15, 2026
ab9e16f
test(core): remove redundant registry coverage module
seonghobae Aug 15, 2026
03dac28
test(core): restore unit-binary registry coverage
seonghobae Aug 15, 2026
9fc407b
merge: align browser protocol capabilities with current authority
seonghobae Aug 15, 2026
a0986fe
test(core): require standard public validation errors
seonghobae Aug 15, 2026
5c6d0ed
fix(core): expose standard validation errors
seonghobae Aug 15, 2026
15048b1
fix(core): wire public validation error contracts
seonghobae Aug 15, 2026
2f1e7cd
test(core): use standard validation errors without expect
seonghobae Aug 15, 2026
8bd82c4
refactor(core): make contract exports explicit
seonghobae Aug 15, 2026
d242b23
test(core): require explicit sha256 digest prefix
seonghobae Aug 15, 2026
90227c5
fix(core): clarify sha256 digest prefix
seonghobae Aug 15, 2026
c7ab7a1
merge: align protocol capability descriptor with current browser auth…
seonghobae Aug 15, 2026
2203d60
test(core): preserve origin-bound expiring extension grants
seonghobae Aug 17, 2026
14cc3f5
fix(core): preserve protected extension grant authority
seonghobae Aug 17, 2026
8ab27e5
merge(main): reconcile extension authority baseline
seonghobae Aug 17, 2026
c146e3e
fix(core): delegate missing extension grant evaluation
seonghobae Aug 17, 2026
8a4b4c2
style(core): apply canonical extension authority formatting
seonghobae Aug 17, 2026
e62c0ce
chore(core): align browser protocol descriptor with current authority…
seonghobae Aug 17, 2026
b55716d
test(core): require extension grant task binding
seonghobae Aug 17, 2026
d043af9
fix(core): bind extension grants to Agent Task identity
seonghobae Aug 17, 2026
a4830c2
style(core): apply canonical task-authority formatting
seonghobae Aug 17, 2026
b45ab7b
docs(adr): record active task-bound extension authority
seonghobae Aug 17, 2026
692cf58
docs(changelog): record task-bound extension grants
seonghobae Aug 17, 2026
74b16b0
merge(browser): align protocol descriptor with current authority regi…
seonghobae Aug 17, 2026
1a13007
docs(changelog): restore protocol descriptor entry after stack alignment
seonghobae Aug 17, 2026
1c6a208
test(browser): keep failed node allocation transactional
seonghobae Aug 20, 2026
8d51ea3
fix(browser): keep failed node binding transactional
seonghobae Aug 20, 2026
b9e9f3a
style(browser): format transactional node binding
seonghobae Aug 20, 2026
0428a97
test(browser): cover fail-closed registry invariants
seonghobae Aug 20, 2026
8bf7803
test(browser): reject forged or retired node handles
seonghobae Aug 20, 2026
d5705f8
fix(browser): revalidate live node authority in registry
seonghobae Aug 20, 2026
0d12ad5
style(browser): apply canonical node validation formatting
seonghobae Aug 20, 2026
1248ccf
test(browser): close registry coverage gaps
seonghobae Aug 20, 2026
1d9e7c5
test(browser): reject cross-registry node-handle reuse
seonghobae Aug 22, 2026
1fa6fec
test(browser): reject forged matching registry handles
seonghobae Aug 22, 2026
4a828ed
fix(browser): bind node handles to registry instances
seonghobae Aug 22, 2026
2dbcb03
test(browser): cover registry authority invariants
seonghobae Aug 22, 2026
76651a5
style(browser): apply canonical Rust formatting
seonghobae Aug 22, 2026
724305f
test(browser): cover corrupt zero node authority
seonghobae Aug 22, 2026
94de6c2
test(browser): require same-document node retirement
seonghobae Aug 22, 2026
2c08bca
style(browser): apply canonical rustfmt to node retirement regression
seonghobae Aug 22, 2026
8587c8f
feat(browser): revoke same-document node authority
seonghobae Aug 22, 2026
77df987
test(core): cover node retirement and epoch exhaustion
seonghobae Aug 22, 2026
e8c105c
fix(core): purge duplicate node aliases on retirement
seonghobae Aug 22, 2026
1e5f85a
test(core): cover session retirement unit branches
seonghobae Aug 22, 2026
28e417a
fix(core): restore canonical browser registry source
seonghobae Aug 22, 2026
42068e7
test(core): cover session retirement unit branches
seonghobae Aug 22, 2026
32f058f
test(core): cover duplicate context and identifier bounds
seonghobae Aug 22, 2026
755cb39
test(core): cover direct registry fail-closed branches
seonghobae Aug 22, 2026
0edb86a
test(core): cover allocation and rotation error regions
seonghobae Aug 22, 2026
556c986
test(core): close remaining registry coverage region
seonghobae Aug 22, 2026
da4ccc8
docs(adr): cite primary MV3 authority sources
seonghobae Aug 22, 2026
eb29cad
test(browser): hide session membership from unissued node handles
seonghobae Aug 23, 2026
a8b03e0
fix(browser): authenticate node issuance before registry lookup
seonghobae Aug 23, 2026
c0ef5d5
docs(changelog): record node-handle oracle hardening
seonghobae Aug 23, 2026
eb992a4
test(browser): cover authenticated retired-authority failures
seonghobae Aug 23, 2026
8093169
test(browser): apply canonical formatting
seonghobae Aug 23, 2026
7020dbe
test(browser): cover issued context-session corruption
seonghobae Aug 23, 2026
3a29725
test(browser): cover context-origin corruption
seonghobae Aug 23, 2026
281737b
repair(browser): restore registry source after transport corruption
seonghobae Aug 23, 2026
c8a357c
test(browser): cover corrupted origin authority rejection
seonghobae Aug 23, 2026
562b4b7
style(browser): apply canonical Rust formatting
seonghobae Aug 23, 2026
8452f7d
fix(browser): restore current registry branch before coverage repair
seonghobae Aug 23, 2026
4cbcb03
test(browser): cover missing pinned origin authority
seonghobae Aug 23, 2026
f71c1ca
test(core): reject empty-hex browser IPv4 authorities
seonghobae Aug 23, 2026
0a73431
fix(core): reject empty-hex browser IPv4 authorities
seonghobae Aug 23, 2026
5157366
docs(changelog): record empty-hex origin hardening
seonghobae Aug 23, 2026
4e9b92b
chore(stack): realign protocol descriptor on browser authority
seonghobae Aug 23, 2026
3c88d51
docs(changelog): preserve protocol descriptor after stack realignment
seonghobae Aug 23, 2026
3795b5b
merge(main): converge browser authority registry onto protected main
seonghobae Aug 24, 2026
cfa82c6
fix(core): disambiguate private contract types after main convergence
seonghobae Aug 24, 2026
344233d
style(core): apply canonical import formatting
seonghobae Aug 24, 2026
93ce1e7
fix(core): avoid module-inception lint after main convergence
seonghobae Aug 24, 2026
56e7b5e
chore(browser): restack protocol descriptor on authority registry
seonghobae Aug 24, 2026
4943b82
docs(browser): restore protocol descriptor changelog
seonghobae Aug 24, 2026
01fd68f
fix(browser): export protocol descriptor at crate boundary
seonghobae Aug 24, 2026
378a9f2
style(browser): apply canonical protocol export formatting
seonghobae Aug 24, 2026
1a79f3b
Merge pull request #106 from ContextualWisdomLab/feat/browser-protoco…
seonghobae Aug 26, 2026
7dd457a
Merge branch 'main' into feat/browser-authority-registry
seonghobae Aug 27, 2026
451dc3e
test(core): reproduce non-digit origin port acceptance
seonghobae Aug 27, 2026
2682179
fix(core): reject non-digit origin port prefixes
seonghobae Aug 27, 2026
b533768
merge(main): refresh browser authority base
seonghobae Aug 27, 2026
90dc4a5
style(core): restore canonical source termination
seonghobae Aug 27, 2026
5cd2733
fix(core): preserve secret-delivery value contract
seonghobae Aug 27, 2026
1ef0d27
test(policy): bind extension isolation to agent task
seonghobae Aug 27, 2026
53c8a9b
test(policy): bind secret isolation to agent task
seonghobae Aug 27, 2026
eccf562
test(policy): bind mutation isolation to agent task
seonghobae Aug 27, 2026
3c6bcd4
docs: record browser authority contract changes
seonghobae Aug 27, 2026
c376ed8
chore(browser): adopt current protected main without product-tree cha…
seonghobae Sep 3, 2026
8c97b09
merge(main): refresh browser authority registry base
seonghobae Sep 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ All notable changes to OriginWeave are documented in this file. The format follo

### Added

- Bound explicit extension-to-Agent grants to a nonzero host-assigned Agent Task identity, so a grant that otherwise matches extension, session, browsing context, origin, expiry, and capability fails closed when reused by a different task.
- Bound explicit extension-to-Agent grants to exclusive trusted-time expiry in addition to extension identity, session, browsing context, and canonical origin, so a same-origin grant cannot be reused at or after the deadline.
- Bound explicit extension-to-Agent grants to the exact canonical origin in addition to extension identity, session, and browsing context, so a same-session navigation or port change cannot reuse the grant.
- Added a bounded browser-protocol authority registry that maps opaque session, browsing-context, and node identifiers to registry-local identities, rotates document epochs, and revalidates live node handles before actions.
- Rust workspace for independently reusable core, policy, destination, network, TLS, resource, and evidence modules.
- Canonical HTTPS and loopback-origin boundary with case-normalized schemes and hosts, default-port normalization, IPv4/IPv6 handling, browser-special numeric-host rejection, and explicit malformed-input errors.
- Typed browser actions, capabilities, risk classes, execution modes, robots decisions, secret-delivery contracts, immutable canonical action-intent digests, and intent-bound approval scopes.
Expand Down
871 changes: 871 additions & 0 deletions crates/originweave-core/src/browser_registry.rs

Large diffs are not rendered by default.

371 changes: 371 additions & 0 deletions crates/originweave-core/src/browser_registry_coverage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
use crate::{
BrowserAuthorityRegistry, BrowserRegistryError, BrowserSessionId, DocumentEpoch,
ObservedNodeHandle, Origin,
};

fn values<T, E>(result: Result<T, E>) -> Vec<T> {
result.into_iter().collect()
}

#[test]
fn repeated_node_binding_exercises_the_unit_crate_existing_node_path() {
let mut registry = BrowserAuthorityRegistry::new();
let sessions = values(registry.register_session("unit-session"));
assert_eq!(sessions.len(), 1);
let session = sessions[0];
let repeated_sessions = values(registry.register_session("unit-session"));
assert_eq!(repeated_sessions, sessions);

let contexts = values(registry.register_context(session, "unit-context"));
assert_eq!(contexts.len(), 1);
let repeated_contexts = values(registry.register_context(session, "unit-context"));
assert_eq!(repeated_contexts, contexts);
let context = contexts[0];

let origins = values(Origin::parse("http://127.0.0.1:43127"));
assert_eq!(origins.len(), 1);
let origin = &origins[0];

let first = values(registry.bind_node(session, context, origin, "unit-node"));
let repeated = values(registry.bind_node(session, context, origin, "unit-node"));
assert_eq!(first.len(), 1);
assert_eq!(repeated.len(), 1);
assert_eq!(first[0], repeated[0]);
assert_eq!(registry.validate_node_handle(&first[0]), Ok(()));

let epochs = values(DocumentEpoch::new(1));
assert_eq!(epochs.len(), 1);
let forged = values(ObservedNodeHandle::new(
session,
context,
origin.clone(),
epochs[0],
first[0].node_id() + 1,
));
assert_eq!(forged.len(), 1);
assert_eq!(
registry.validate_node_handle(&forged[0]),
Err(BrowserRegistryError::UnknownNodeAuthority)
);

let mismatched_origins = values(Origin::parse("http://localhost:43127"));
assert_eq!(mismatched_origins.len(), 1);
let mismatched = values(ObservedNodeHandle::new(
session,
context,
mismatched_origins[0].clone(),
epochs[0],
first[0].node_id(),
));
assert_eq!(mismatched.len(), 1);
assert_eq!(
registry.validate_node_handle(&mismatched[0]),
Err(BrowserRegistryError::UnknownNodeAuthority)
);
}

#[test]
fn node_validation_rejects_each_missing_authority_boundary() {
let mut registry = BrowserAuthorityRegistry::new();
assert_eq!(
registry.register_session(""),
Err(BrowserRegistryError::InvalidExternalIdentifier)
);
let oversized_identifier = "x".repeat(513);
assert_eq!(
registry.register_session(&oversized_identifier),
Err(BrowserRegistryError::InvalidExternalIdentifier)
);
let known_sessions = values(registry.register_session("validation-session"));
let attacker_sessions = values(registry.register_session("validation-attacker"));
assert_eq!(known_sessions.len(), 1);
assert_eq!(attacker_sessions.len(), 1);
let known = known_sessions[0];
let attacker = attacker_sessions[0];
let contexts = values(registry.register_context(known, "validation-context"));
assert_eq!(contexts.len(), 1);
let context = contexts[0];
let origins = values(Origin::parse("http://127.0.0.1:43127"));
assert_eq!(origins.len(), 1);
let origin = origins[0].clone();
let epochs = values(registry.current_epoch(context));
assert_eq!(epochs.len(), 1);
let epoch = epochs[0];

let unknown_sessions = values(BrowserSessionId::new(999));
assert_eq!(unknown_sessions.len(), 1);
let unknown_handle = values(ObservedNodeHandle::new(
unknown_sessions[0],
context,
origin.clone(),
epoch,
1,
));
assert_eq!(unknown_handle.len(), 1);
assert_eq!(
registry.validate_node_handle(&unknown_handle[0]),
Err(BrowserRegistryError::UnknownBrowserSession)
);

let mismatched_handle = values(ObservedNodeHandle::new(
attacker,
context,
origin.clone(),
epoch,
1,
));
assert_eq!(mismatched_handle.len(), 1);
assert_eq!(
registry.validate_node_handle(&mismatched_handle[0]),
Err(BrowserRegistryError::UnknownNodeAuthority)
);

let unbound_handle = values(ObservedNodeHandle::new(
known,
context,
origin.clone(),
epoch,
1,
));
assert_eq!(unbound_handle.len(), 1);
assert_eq!(
registry.validate_node_handle(&unbound_handle[0]),
Err(BrowserRegistryError::UnknownNodeAuthority)
);

assert_eq!(registry.remove_context(context), Ok(()));
assert_eq!(
registry.validate_node_handle(&unbound_handle[0]),
Err(BrowserRegistryError::UnknownBrowsingContext)
);
}

#[test]
fn session_authority_failures_are_exercised_in_the_unit_crate() {
let mut registry = BrowserAuthorityRegistry::new();
let unknown_sessions = values(BrowserSessionId::new(999));
assert_eq!(unknown_sessions.len(), 1);
let unknown = unknown_sessions[0];
assert_eq!(
registry.register_context(unknown, "unknown-context"),
Err(BrowserRegistryError::UnknownBrowserSession)
);

let owner_sessions = values(registry.register_session("owner-session"));
let attacker_sessions = values(registry.register_session("attacker-session"));
assert_eq!(owner_sessions.len(), 1);
assert_eq!(attacker_sessions.len(), 1);
let owner = owner_sessions[0];
let attacker = attacker_sessions[0];

let contexts = values(registry.register_context(owner, "owner-context"));
let origins = values(Origin::parse("http://127.0.0.1:43127"));
assert_eq!(contexts.len(), 1);
assert_eq!(origins.len(), 1);
let context = contexts[0];

assert_eq!(
registry.bind_node(attacker, context, &origins[0], "unit-node"),
Err(BrowserRegistryError::ContextSessionMismatch {
expected: owner,
actual: attacker,
})
);
}

#[test]
fn direct_fail_closed_registry_paths_are_exercised_in_the_unit_crate() {
let mut registry = BrowserAuthorityRegistry::new();
let unknown_sessions = values(BrowserSessionId::new(999));
assert_eq!(unknown_sessions.len(), 1);
let unknown = unknown_sessions[0];

let sessions = values(registry.register_session("direct-path-session"));
assert_eq!(sessions.len(), 1);
let session = sessions[0];
let contexts = values(registry.register_context(session, "direct-path-context"));
assert_eq!(contexts.len(), 1);
let context = contexts[0];
let origins = values(Origin::parse("http://127.0.0.1:43127"));
let changed_origins = values(Origin::parse("http://localhost:43127"));
assert_eq!(origins.len(), 1);
assert_eq!(changed_origins.len(), 1);

assert_eq!(
registry.bind_node(unknown, context, &origins[0], "unknown-session-node"),
Err(BrowserRegistryError::UnknownBrowserSession)
);
assert_eq!(
values(registry.bind_node(session, context, &origins[0], "live-node")).len(),
1
);
assert_eq!(
registry.bind_node(session, context, &changed_origins[0], "changed-origin-node"),
Err(BrowserRegistryError::OriginChangedWithoutDocumentAdvance)
);

assert_eq!(registry.remove_context(context), Ok(()));
assert_eq!(
registry.remove_context(context),
Err(BrowserRegistryError::UnknownBrowsingContext)
);
}

#[test]
fn unit_cfg_allocation_rotation_and_retirement_edges_are_exercised() {
let mut registry = BrowserAuthorityRegistry::with_identifier_limit(1);
let sessions = values(registry.register_session("capacity-session"));
assert_eq!(sessions.len(), 1);
let session = sessions[0];
assert_eq!(
registry.register_session("capacity-session-two"),
Err(BrowserRegistryError::IdentifierSpaceExhausted)
);

let contexts = values(registry.register_context(session, "capacity-context"));
assert_eq!(contexts.len(), 1);
let context = contexts[0];
assert_eq!(
registry.register_context(session, "capacity-context-two"),
Err(BrowserRegistryError::IdentifierSpaceExhausted)
);

let origins = values(Origin::parse("http://127.0.0.1:43127"));
assert_eq!(origins.len(), 1);
let origin = &origins[0];
let handles = values(registry.bind_node(session, context, origin, "capacity-node"));
assert_eq!(handles.len(), 1);
let handle = &handles[0];
assert_eq!(
registry.bind_node(session, context, origin, "capacity-node-two"),
Err(BrowserRegistryError::IdentifierSpaceExhausted)
);

let forged = values(ObservedNodeHandle::new(
session,
context,
origin.clone(),
handle.document_epoch(),
handle.node_id() + 1,
));
assert_eq!(forged.len(), 1);
assert_eq!(
registry.remove_node(&forged[0]),
Err(BrowserRegistryError::UnknownNodeAuthority)
);

let next_epochs = values(registry.advance_document(context));
assert_eq!(next_epochs.len(), 1);
assert_eq!(next_epochs[0].value(), 2);
assert_eq!(registry.remove_context(context), Ok(()));
assert_eq!(
registry.advance_document(context),
Err(BrowserRegistryError::UnknownBrowsingContext)
);
}

#[test]
fn unit_cfg_adapter_surface_exercises_accessors_equality_default_and_errors() {
let mut registry = BrowserAuthorityRegistry::default();
let sessions = values(registry.register_session("adapter-surface-session"));
assert_eq!(sessions.len(), 1);
let session = sessions[0];
let contexts = values(registry.register_context(session, "adapter-surface-context"));
assert_eq!(contexts.len(), 1);
let context = contexts[0];
let origins = values(Origin::parse("http://127.0.0.1:43127"));
assert_eq!(origins.len(), 1);
let origin = origins[0].clone();
let handles = values(registry.bind_node(session, context, &origin, "adapter-surface-node"));
assert_eq!(handles.len(), 1);
let handle = &handles[0];

assert_eq!(handle.browser_session(), session);
assert_eq!(handle.browsing_context(), context);
assert_eq!(handle.origin(), &origin);
assert_eq!(handle.document_epoch().value(), 1);
assert_ne!(handle.node_id(), 0);

let unregistered_same = values(ObservedNodeHandle::new(
session,
context,
origin.clone(),
handle.document_epoch(),
handle.node_id(),
));
assert_eq!(unregistered_same.len(), 1);
let second_unregistered_same = values(ObservedNodeHandle::new(
session,
context,
origin.clone(),
handle.document_epoch(),
handle.node_id(),
));
assert_eq!(second_unregistered_same.len(), 1);
assert_ne!(*handle, unregistered_same[0]);
assert_eq!(unregistered_same[0], second_unregistered_same[0]);

let unregistered_other = values(ObservedNodeHandle::new(
session,
context,
origin.clone(),
handle.document_epoch(),
handle.node_id() + 1,
));
assert_eq!(unregistered_other.len(), 1);
assert_ne!(unregistered_same[0], unregistered_other[0]);

assert_eq!(
registry.validate_node_handle(&unregistered_same[0]),
Err(BrowserRegistryError::UnknownNodeAuthority)
);
assert_eq!(registry.remove_node(handle), Ok(()));
assert_eq!(
registry.validate_node_handle(handle),
Err(BrowserRegistryError::UnknownNodeAuthority)
);
assert_eq!(registry.remove_context(context), Ok(()));
assert_eq!(
registry.bind_node(session, context, &origin, "retired-context-node"),
Err(BrowserRegistryError::UnknownBrowsingContext)
);

let display_cases = [
BrowserRegistryError::InvalidExternalIdentifier,
BrowserRegistryError::UnknownBrowserSession,
BrowserRegistryError::UnknownBrowsingContext,
BrowserRegistryError::ContextSessionMismatch {
expected: session,
actual: session,
},
BrowserRegistryError::OriginChangedWithoutDocumentAdvance,
BrowserRegistryError::UnknownNodeAuthority,
BrowserRegistryError::IdentifierSpaceExhausted,
BrowserRegistryError::DocumentEpochExhausted,
BrowserRegistryError::InternalAuthorityInvariant,
];
for error in display_cases {
assert!(!error.to_string().is_empty());
}
}

#[test]
fn session_retirement_covers_unit_success_and_unknown_paths() {
let mut registry = BrowserAuthorityRegistry::new();
let sessions = values(registry.register_session("retirement-unit-session"));
assert_eq!(sessions.len(), 1);
let session = sessions[0];
let contexts = values(registry.register_context(session, "retirement-unit-context"));
assert_eq!(contexts.len(), 1);
let context = contexts[0];

assert_eq!(registry.remove_session(session), Ok(()));
assert_eq!(
registry.current_epoch(context),
Err(BrowserRegistryError::UnknownBrowsingContext)
);
assert_eq!(
registry.remove_session(session),
Err(BrowserRegistryError::UnknownBrowserSession)
);
}
Loading
Loading