feat: unify object observation API

This commit is contained in:
2026-09-30 18:19:12 +09:00
parent 2e4196a1ec
commit ea7b0f00ea
32 changed files with 1035 additions and 1251 deletions
+19 -14
View File
@@ -6,12 +6,13 @@ use wip_client::{
};
use wip_https::http::{Response, StatusCode};
use wip_https::{
Limits, encode_fetch_interface_response, encode_fetch_response, encode_protocol_error_response,
Limits, encode_fetch_interface_response, encode_observe_response,
encode_protocol_error_response,
};
use wip_protocol::{
FetchInterfaceRequest, FetchInterfaceResponse, FetchRequest, INTERFACE_FORMAT_V1,
InterfaceDescriptor, Object, OperationDeclaration, ParameterDeclaration, ProtocolError,
ProtocolErrorCode, ProtocolInteraction, ReturnDeclaration, TypeExpr, Value,
FetchInterfaceRequest, FetchInterfaceResponse, INTERFACE_FORMAT_V1, InterfaceDescriptor,
Object, ObjectObservation, ObserveRequest, OperationDeclaration, ParameterDeclaration,
ProtocolError, ProtocolErrorCode, ProtocolInteraction, ReturnDeclaration, TypeExpr, Value,
};
fn limits() -> Limits {
@@ -76,7 +77,7 @@ fn malformed_json_unknown_fields_duplicates_and_invalid_success_are_invalid_resp
];
for body in cases {
let (mut client, session) = setup();
let request = client.prepare_fetch(&session, "/item").unwrap();
let request = client.prepare_observe(&session, "/item", 0).unwrap();
let error = client
.complete(request.id, response(StatusCode::OK, body))
.unwrap_err();
@@ -106,7 +107,7 @@ fn disallowed_code_and_status_success_contradictions_are_invalid_response() {
];
for (status, body) in cases {
let (mut client, session) = setup();
let request = client.prepare_fetch(&session, "/item").unwrap();
let request = client.prepare_observe(&session, "/item", 0).unwrap();
assert_eq!(
client
.complete(request.id, response(status, body))
@@ -120,13 +121,13 @@ fn disallowed_code_and_status_success_contradictions_are_invalid_response() {
#[test]
fn valid_error_envelope_is_authoritative_and_status_mismatch_is_diagnostic() {
let (mut client, session) = setup();
let request = client.prepare_fetch(&session, "/item").unwrap();
let request = client.prepare_observe(&session, "/item", 0).unwrap();
let error = ProtocolError {
code: ProtocolErrorCode::NotFound,
message: "missing".into(),
};
let mut encoded =
encode_protocol_error_response(ProtocolInteraction::Fetch, &error, limits()).unwrap();
encode_protocol_error_response(ProtocolInteraction::Observe, &error, limits()).unwrap();
*encoded.status_mut() = StatusCode::IM_A_TEAPOT;
assert_eq!(
@@ -146,7 +147,7 @@ fn valid_error_envelope_is_authoritative_and_status_mismatch_is_diagnostic() {
#[test]
fn non_success_without_valid_envelope_remains_transport_failure() {
let (mut client, session) = setup();
let request = client.prepare_fetch(&session, "/item").unwrap();
let request = client.prepare_observe(&session, "/item", 0).unwrap();
let error = client
.complete(
request.id,
@@ -176,15 +177,19 @@ fn unsupported_descriptor_format_is_distinct_from_invalid_response() {
#[test]
fn malformed_call_success_after_dispatch_is_outcome_unknown_and_stales_object() {
let (mut client, session) = setup();
let fetch = client.prepare_fetch(&session, "/item").unwrap();
let observation = client.prepare_observe(&session, "/item", 0).unwrap();
client
.complete(
fetch.id,
encode_fetch_response(
&FetchRequest {
observation.id,
encode_observe_response(
&ObserveRequest {
path: "/item".into(),
depth: 0,
},
&ObjectObservation {
object: object(),
children: None,
},
&object(),
limits(),
)
.unwrap(),