87 lines
2.8 KiB
Rust
87 lines
2.8 KiB
Rust
use remora_contracts::{AttemptOutcomeRequestDto, EventFrameDto, JobFailureDto, JobSubmissionDto};
|
|
use serde::Deserialize;
|
|
use serde_json::Value;
|
|
|
|
#[derive(Deserialize)]
|
|
struct Corpus {
|
|
job_submissions: Vec<Value>,
|
|
event_frames: Vec<Value>,
|
|
attempt_outcomes: Vec<Value>,
|
|
job_failures: Vec<Value>,
|
|
}
|
|
|
|
#[test]
|
|
fn mutable_dtos_round_trip_the_shared_corpus() {
|
|
let corpus: Corpus =
|
|
serde_json::from_str(include_str!("../../../contracts/golden/domain.json")).unwrap();
|
|
for value in corpus.job_submissions {
|
|
let dto: JobSubmissionDto = serde_json::from_value(value.clone()).unwrap();
|
|
assert_eq!(serde_json::to_value(dto).unwrap(), value);
|
|
}
|
|
for value in corpus.event_frames {
|
|
let dto: EventFrameDto = serde_json::from_value(value.clone()).unwrap();
|
|
assert_eq!(serde_json::to_value(dto).unwrap(), value);
|
|
}
|
|
for value in corpus.attempt_outcomes {
|
|
let dto: AttemptOutcomeRequestDto = serde_json::from_value(value.clone()).unwrap();
|
|
assert_eq!(serde_json::to_value(dto).unwrap(), value);
|
|
}
|
|
for value in corpus.job_failures {
|
|
let dto: JobFailureDto = serde_json::from_value(value.clone()).unwrap();
|
|
assert_eq!(serde_json::to_value(dto).unwrap(), value);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn dto_bindings_reject_cross_field_and_nullability_violations() {
|
|
let contradictory_failures = [
|
|
serde_json::json!({
|
|
"class": "source_not_found",
|
|
"message": "missing",
|
|
"retryable": true
|
|
}),
|
|
serde_json::json!({
|
|
"class": "transient_target",
|
|
"message": "unavailable",
|
|
"retryable": false
|
|
}),
|
|
];
|
|
for value in contradictory_failures {
|
|
assert!(serde_json::from_value::<JobFailureDto>(value).is_err());
|
|
}
|
|
|
|
let null_optional = serde_json::json!({
|
|
"source": {
|
|
"kind": "http",
|
|
"url": "https://example.invalid/file",
|
|
"result_path": "file.bin"
|
|
},
|
|
"label": null
|
|
});
|
|
assert!(serde_json::from_value::<JobSubmissionDto>(null_optional).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_bindings_reject_values_outside_the_schema() {
|
|
let invalid = [
|
|
serde_json::json!({
|
|
"schema_version": 2,
|
|
"kind": "heartbeat",
|
|
"event_id": "event_0001",
|
|
"sequence": 1,
|
|
"cursor": "cursor-value-0001",
|
|
"occurred_at": "2026-07-15T00:00:00Z"
|
|
}),
|
|
serde_json::json!({
|
|
"schema_version": 1,
|
|
"kind": "heartbeat",
|
|
"event_id": "event_0001",
|
|
"sequence": 0,
|
|
"cursor": "short",
|
|
"occurred_at": "not-a-date"
|
|
}),
|
|
];
|
|
for value in invalid {
|
|
assert!(serde_json::from_value::<EventFrameDto>(value).is_err());
|
|
}
|
|
}
|