hive-agent: test the mark-done handler's 500 through an injected dial
post_mark_todos_done's body moves into mark_ids_done, which takes the per-id dial as a closure, so tests cover the 500 and 200 responses without reaching the live in-agent socket.
This commit is contained in:
parent
9a702d954e
commit
0472ed3ab5
1 changed files with 61 additions and 3 deletions
|
|
@ -8,6 +8,7 @@ use axum::{
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
use super::{AppState, SigintOutcome, error_response};
|
use super::{AppState, SigintOutcome, error_response};
|
||||||
|
|
||||||
|
|
@ -252,10 +253,23 @@ pub(super) async fn post_mark_todos_done(Form(form): Form<MarkTodosDoneForm>) ->
|
||||||
if ids.is_empty() {
|
if ids.is_empty() {
|
||||||
return error_response(StatusCode::BAD_REQUEST, "mark-done: no todo ids selected");
|
return error_response(StatusCode::BAD_REQUEST, "mark-done: no todo ids selected");
|
||||||
}
|
}
|
||||||
|
mark_ids_done(ids, |id| async move {
|
||||||
|
crate::todo_server::dial(&hive_agent_sock::Request::MarkTodoDone { id }).await
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The handler body behind `dial`, which answers one id's `MarkTodoDone`
|
||||||
|
/// (`None` when the store doesn't answer). Tests inject it so they never
|
||||||
|
/// reach the live in-agent socket.
|
||||||
|
async fn mark_ids_done<F, Fut>(ids: Vec<i64>, dial: F) -> Response
|
||||||
|
where
|
||||||
|
F: Fn(i64) -> Fut,
|
||||||
|
Fut: Future<Output = Option<hive_agent_sock::Response>>,
|
||||||
|
{
|
||||||
let mut answers = Vec::with_capacity(ids.len());
|
let mut answers = Vec::with_capacity(ids.len());
|
||||||
for id in ids {
|
for id in ids {
|
||||||
answers
|
answers.push(dial(id).await);
|
||||||
.push(crate::todo_server::dial(&hive_agent_sock::Request::MarkTodoDone { id }).await);
|
|
||||||
}
|
}
|
||||||
match settle_mark_done(answers) {
|
match settle_mark_done(answers) {
|
||||||
Ok(acked) => axum::Json(MarkTodosDoneBody { acked }).into_response(),
|
Ok(acked) => axum::Json(MarkTodosDoneBody { acked }).into_response(),
|
||||||
|
|
@ -303,7 +317,51 @@ struct MarkTodosDoneBody {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{accept_or_refuse, settle_mark_done};
|
use super::{accept_or_refuse, mark_ids_done, settle_mark_done};
|
||||||
|
|
||||||
|
async fn body_text(response: axum::response::Response) -> String {
|
||||||
|
let bytes = axum::body::to_bytes(response.into_body(), usize::MAX)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
String::from_utf8(bytes.to_vec()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn mark_done_handler_answers_500_with_the_message_when_the_store_does_not_answer() {
|
||||||
|
let response = mark_ids_done(vec![1, 2], |_| async { None }).await;
|
||||||
|
assert_eq!(
|
||||||
|
response.status(),
|
||||||
|
axum::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
);
|
||||||
|
let body = body_text(response).await;
|
||||||
|
assert!(body.contains("2 of 2 failed"), "{body}");
|
||||||
|
assert!(body.contains("did not answer"), "{body}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn mark_done_handler_answers_500_with_the_store_error() {
|
||||||
|
let response = mark_ids_done(vec![7], |_| async {
|
||||||
|
Some(hive_agent_sock::Response::Err {
|
||||||
|
message: "database is locked".to_owned(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
response.status(),
|
||||||
|
axum::http::StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
);
|
||||||
|
assert!(body_text(response).await.contains("database is locked"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn mark_done_handler_answers_200_with_the_acked_total() {
|
||||||
|
let response = mark_ids_done(vec![1, 2], |_| async {
|
||||||
|
Some(hive_agent_sock::Response::Acked { count: 1 })
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert_eq!(response.status(), axum::http::StatusCode::OK);
|
||||||
|
assert_eq!(body_text(response).await, r#"{"acked":2}"#);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mark_done_with_no_answer_is_an_error() {
|
fn mark_done_with_no_answer_is_an_error() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue