fix: keep object observations fresh after successful calls
This commit is contained in:
@@ -525,14 +525,147 @@ fn call_context_fixes_membership_validators_descriptor_and_result_validation() {
|
||||
client.interface(&session, "math").unwrap().descriptor,
|
||||
Some(descriptor(TypeExpr::String))
|
||||
);
|
||||
let observation = client.object(&session, "/item").unwrap();
|
||||
assert_eq!(observation.state, ObservationState::Fresh);
|
||||
assert_eq!(observation.validator, Some(b"object-v2".to_vec()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn successful_call_without_validator_preserves_observed_validator() {
|
||||
let mut client = client(8, 8, 8, 8);
|
||||
let session = client
|
||||
.open_session("https://example.test/wip", SecurityContext::new("subject"))
|
||||
.unwrap();
|
||||
observe_object(
|
||||
&mut client,
|
||||
&session,
|
||||
"/item",
|
||||
object("item", None, b"object-v1"),
|
||||
);
|
||||
observe_interface(
|
||||
&mut client,
|
||||
&session,
|
||||
FetchInterfaceResponse {
|
||||
interface: "math".into(),
|
||||
descriptor: descriptor(TypeExpr::Integer),
|
||||
validator: None,
|
||||
},
|
||||
);
|
||||
|
||||
let call = client
|
||||
.prepare_call(&session, "/item", "math", "calculate", args(1))
|
||||
.unwrap();
|
||||
let request = client
|
||||
.pending_call_context(call.id)
|
||||
.unwrap()
|
||||
.request()
|
||||
.clone();
|
||||
let fixed_descriptor = client
|
||||
.pending_call_context(call.id)
|
||||
.unwrap()
|
||||
.descriptor()
|
||||
.clone();
|
||||
client.mark_dispatched(call.id).unwrap();
|
||||
client
|
||||
.complete(
|
||||
call.id,
|
||||
encode_call_operation_response(
|
||||
&request,
|
||||
&fixed_descriptor,
|
||||
&CallOperationResponse {
|
||||
result: Value::Integer(2),
|
||||
validator: None,
|
||||
},
|
||||
wire_limits(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let observation = client.object(&session, "/item").unwrap();
|
||||
assert_eq!(observation.state, ObservationState::Fresh);
|
||||
assert_eq!(observation.validator, Some(b"object-v1".to_vec()));
|
||||
|
||||
let next = client
|
||||
.prepare_call(&session, "/item", "math", "calculate", args(2))
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
client.object(&session, "/item").unwrap().state,
|
||||
ObservationState::Stale
|
||||
client
|
||||
.pending_call_context(next.id)
|
||||
.unwrap()
|
||||
.request()
|
||||
.target
|
||||
.validator,
|
||||
Some(b"object-v1".to_vec())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn older_retrieval_cannot_restore_freshness_after_operation_completion() {
|
||||
fn newer_observation_prevents_older_success_validator_overwrite() {
|
||||
let mut client = client(8, 8, 8, 8);
|
||||
let session = client
|
||||
.open_session("https://example.test/wip", SecurityContext::new("subject"))
|
||||
.unwrap();
|
||||
observe_object(
|
||||
&mut client,
|
||||
&session,
|
||||
"/item",
|
||||
object("item", None, b"object-v1"),
|
||||
);
|
||||
observe_interface(
|
||||
&mut client,
|
||||
&session,
|
||||
FetchInterfaceResponse {
|
||||
interface: "math".into(),
|
||||
descriptor: descriptor(TypeExpr::Integer),
|
||||
validator: None,
|
||||
},
|
||||
);
|
||||
|
||||
let call = client
|
||||
.prepare_call(&session, "/item", "math", "calculate", args(1))
|
||||
.unwrap();
|
||||
let request = client
|
||||
.pending_call_context(call.id)
|
||||
.unwrap()
|
||||
.request()
|
||||
.clone();
|
||||
let fixed_descriptor = client
|
||||
.pending_call_context(call.id)
|
||||
.unwrap()
|
||||
.descriptor()
|
||||
.clone();
|
||||
client.mark_dispatched(call.id).unwrap();
|
||||
|
||||
observe_object(
|
||||
&mut client,
|
||||
&session,
|
||||
"/item",
|
||||
object("item", None, b"object-v3"),
|
||||
);
|
||||
client
|
||||
.complete(
|
||||
call.id,
|
||||
encode_call_operation_response(
|
||||
&request,
|
||||
&fixed_descriptor,
|
||||
&CallOperationResponse {
|
||||
result: Value::Integer(2),
|
||||
validator: Some(b"object-v2".to_vec()),
|
||||
},
|
||||
wire_limits(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let observation = client.object(&session, "/item").unwrap();
|
||||
assert_eq!(observation.state, ObservationState::Fresh);
|
||||
assert_eq!(observation.validator, Some(b"object-v3".to_vec()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn older_retrieval_cannot_overwrite_success_validator() {
|
||||
let mut client = client(8, 8, 8, 8);
|
||||
let session = client
|
||||
.open_session("https://example.test/wip", SecurityContext::new("subject"))
|
||||
@@ -583,10 +716,9 @@ fn older_retrieval_cannot_restore_freshness_after_operation_completion() {
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
client.object(&session, "/item").unwrap().state,
|
||||
ObservationState::Stale
|
||||
);
|
||||
let current = client.object(&session, "/item").unwrap();
|
||||
assert_eq!(current.state, ObservationState::Fresh);
|
||||
assert_eq!(current.validator, Some(b"object-v2".to_vec()));
|
||||
|
||||
client
|
||||
.complete(
|
||||
|
||||
Reference in New Issue
Block a user