summaryrefslogtreecommitdiff
path: root/src/tests.rs
diff options
context:
space:
mode:
authorbatsumaru <>2026-10-16 15:17:17 +0900
committerbatsumaru <>2026-10-16 15:17:17 +0900
commitb49bb08c7a77fe4b29cf4ed0504c2f1c32a025e3 (patch)
treeea763ca8cb858768e8ac8179f0bd6e32978541b7 /src/tests.rs
parentad9a134daec1f73940e8deaeb6c2a481ce9d6520 (diff)
Update error responses
Diffstat (limited to 'src/tests.rs')
-rw-r--r--src/tests.rs115
1 files changed, 110 insertions, 5 deletions
diff --git a/src/tests.rs b/src/tests.rs
index 586f35a..5b21352 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -116,7 +116,10 @@ async fn create_returns_the_measurement_and_location(pool: PgPool) {
async fn create_rejects_bad_bodies(pool: PgPool) {
let app = router(pool);
let cases = [
- (json!({"metric_type": "Hip"}).to_string(), StatusCode::UNPROCESSABLE_ENTITY),
+ (
+ json!({"metric_type": "Hip"}).to_string(),
+ StatusCode::UNPROCESSABLE_ENTITY,
+ ),
(
measurement("2026-10-14T12:00:00Z", "Nope", 1.0, "Kilogram"),
StatusCode::UNPROCESSABLE_ENTITY,
@@ -219,8 +222,14 @@ async fn list_ranges_are_inclusive_of_both_days(pool: PgPool) {
let cases = [
("/measurements?from=2026-10-15", vec![2.0, 3.0, 4.0]),
("/measurements?to=2026-10-14", vec![1.0]),
- ("/measurements?from=2026-10-14&to=2026-10-15", vec![1.0, 2.0, 3.0]),
- ("/measurements?from=2026-10-15&to=2026-10-15", vec![2.0, 3.0]),
+ (
+ "/measurements?from=2026-10-14&to=2026-10-15",
+ vec![1.0, 2.0, 3.0],
+ ),
+ (
+ "/measurements?from=2026-10-15&to=2026-10-15",
+ vec![2.0, 3.0],
+ ),
("/measurements?from=2030-01-01", vec![]),
];
for (uri, expected) in cases {
@@ -236,7 +245,10 @@ async fn list_combines_filters_with_order_and_limit(pool: PgPool) {
seed(&app).await;
let cases = [
("/measurements?from=2026-10-15&limit=1", vec![2.0]),
- ("/measurements?from=2026-10-15&order=desc&limit=2", vec![4.0, 3.0]),
+ (
+ "/measurements?from=2026-10-15&order=desc&limit=2",
+ vec![4.0, 3.0],
+ ),
("/measurements?date=2026-10-15&order=desc", vec![3.0, 2.0]),
];
for (uri, expected) in cases {
@@ -350,8 +362,101 @@ async fn delete_is_idempotent(pool: PgPool) {
#[sqlx::test]
async fn old_paths_are_gone(pool: PgPool) {
let app = router(pool);
- for uri in ["/", "/all", "/search?from=2026-10-14", "/units", "/metric_types"] {
+ for uri in [
+ "/",
+ "/all",
+ "/search?from=2026-10-14",
+ "/units",
+ "/metric_types",
+ ] {
let (status, _) = get_json(&app, uri).await;
assert_eq!(status, StatusCode::NOT_FOUND, "{uri}");
}
}
+
+#[sqlx::test]
+async fn errors_have_a_json_body(pool: PgPool) {
+ let app = router(pool);
+ let missing = format!("/measurements/{}", Uuid::now_v7());
+ let valid = measurement("2026-10-14T12:00:00Z", "Waist", 80.0, "Centimeter");
+ let invalid_pair = measurement("2026-10-14T12:00:00Z", "Waist", 80.0, "Kilogram");
+ let cases = [
+ (
+ Method::GET,
+ "/measurements?limit=0".to_owned(),
+ None,
+ StatusCode::BAD_REQUEST,
+ ),
+ (
+ Method::GET,
+ "/measurements?order=sideways".to_owned(),
+ None,
+ StatusCode::BAD_REQUEST,
+ ),
+ (
+ Method::GET,
+ "/measurements?date=bad".to_owned(),
+ None,
+ StatusCode::BAD_REQUEST,
+ ),
+ (
+ Method::GET,
+ "/measurements/not-a-uuid".to_owned(),
+ None,
+ StatusCode::BAD_REQUEST,
+ ),
+ (Method::GET, missing.clone(), None, StatusCode::NOT_FOUND),
+ (Method::PUT, missing, Some(valid), StatusCode::NOT_FOUND),
+ (
+ Method::POST,
+ "/measurements".to_owned(),
+ Some("not json".to_owned()),
+ StatusCode::BAD_REQUEST,
+ ),
+ (
+ Method::POST,
+ "/measurements".to_owned(),
+ Some(invalid_pair),
+ StatusCode::UNPROCESSABLE_ENTITY,
+ ),
+ (Method::GET, "/nope".to_owned(), None, StatusCode::NOT_FOUND),
+ (
+ Method::PATCH,
+ "/measurements".to_owned(),
+ None,
+ StatusCode::METHOD_NOT_ALLOWED,
+ ),
+ ];
+ for (method, uri, body, expected) in cases {
+ let (status, _, body) = send(&app, method.clone(), &uri, body).await;
+ assert_eq!(status, expected, "{method} {uri}");
+ assert!(body["error"].is_string(), "{method} {uri}: {body}");
+ }
+}
+
+#[sqlx::test]
+async fn error_messages_explain_the_problem(pool: PgPool) {
+ let app = router(pool);
+ let cases = [
+ ("/measurements?limit=0", "limit must be positive"),
+ (
+ "/measurements?date=2026-10-15&from=2026-10-14",
+ "date can't be combined with from or to",
+ ),
+ (
+ "/measurements?from=2026-10-16&to=2026-10-14",
+ "from must not be after to",
+ ),
+ ];
+ for (uri, message) in cases {
+ let (_, body) = get_json(&app, uri).await;
+ assert_eq!(body["error"], message, "{uri}");
+ }
+ let body = measurement("2026-10-14T12:00:00Z", "Waist", 80.0, "Kilogram");
+ let (_, _, body) = send(&app, Method::POST, "/measurements", Some(body)).await;
+ let message = body["error"].as_str().unwrap();
+ assert!(
+ message.contains("Invalid pair Waist, Kilogram"),
+ "{message}"
+ );
+}