Document media type and deletion conflicts

This commit is contained in:
2026-09-18 18:56:06 +09:00
parent bbd949e57f
commit 7a4a988208
3 changed files with 63 additions and 6 deletions
+2 -2
View File
@@ -159,7 +159,7 @@ pub trait ServerApi {
status = 201,
alternate_status = 200,
error_status = 400,
additional_error_statuses = [401, 403, 404, 409, 413, 422, 500],
additional_error_statuses = [401, 403, 404, 409, 413, 415, 422, 500],
bearer_auth = true,
browser_auth = true,
normalize_body_errors = true
@@ -5236,7 +5236,7 @@ mod openapi_artifact_tests {
serde_json::json!([])
);
for status in [
"200", "201", "400", "401", "403", "404", "409", "413", "422", "500",
"200", "201", "400", "401", "403", "404", "409", "413", "415", "422", "500",
] {
assert!(
repository_create["responses"][status].is_object(),
+50 -3
View File
@@ -1688,11 +1688,11 @@ async fn authorize_scoped_workspace_request(
.map_err(server_error_response)?
.is_some_and(|workspace| workspace.state == "active")
{
return Err((
return Err(repository_api_rejection(
&request_path,
StatusCode::CONFLICT,
"Workspace is deleting and no longer accepts mutations",
)
.into_response());
));
}
return Ok(());
}
@@ -19113,6 +19113,24 @@ mod tests {
}
}
#[tokio::test]
async fn repository_conflict_rejections_use_the_typed_error_contract() {
let response = repository_api_rejection(
"/api/w/workspace-test/repositories",
StatusCode::CONFLICT,
"Workspace is deleting and no longer accepts mutations",
);
assert_eq!(response.status(), StatusCode::CONFLICT);
let body: server_api::RepositoryApiError =
serde_json::from_slice(&to_bytes(response.into_body(), usize::MAX).await.unwrap())
.unwrap();
assert_eq!(body.error, "Conflict");
assert_eq!(
body.message,
"Workspace is deleting and no longer accepts mutations"
);
}
#[test]
fn backend_resource_timeout_maps_to_gateway_timeout() {
assert_eq!(
@@ -22968,6 +22986,35 @@ mod tests {
.is_ok()
);
let unsupported_media_type = app
.clone()
.oneshot(
Request::builder()
.method(Method::POST)
.uri(&repositories_uri)
.header(
axum::http::header::COOKIE,
"yoi_workspace_session=browser-session-auth",
)
.header(ORIGIN, &expected_origin)
.body(Body::from("{}"))
.unwrap(),
)
.await
.unwrap();
assert_eq!(
unsupported_media_type.status(),
StatusCode::UNSUPPORTED_MEDIA_TYPE
);
assert!(
serde_json::from_slice::<server_api::RepositoryApiError>(
&to_bytes(unsupported_media_type.into_body(), usize::MAX)
.await
.unwrap()
)
.is_ok()
);
let oversized = app
.clone()
.oneshot(
+11 -1
View File
@@ -353,7 +353,7 @@
"info": {
"title": "Yoi Server API",
"version": "0.1.0",
"x-yoi-source-digest": "sha256:37e4ff70a1e2a6fb75a514b03a6d14306ca7fc96ef53a3271186f29acc558e00"
"x-yoi-source-digest": "sha256:bac8ba9340cf541183e96715dd4ccd8367f965cdcfc398e6d5091f26a903e1ef"
},
"openapi": "3.1.0",
"paths": {
@@ -710,6 +710,16 @@
},
"description": "Error response"
},
"415": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RepositoryApiError"
}
}
},
"description": "Error response"
},
"422": {
"content": {
"application/json": {