summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/handlers.rs4
-rw-r--r--src/models.rs1
-rw-r--r--src/tests.rs45
3 files changed, 49 insertions, 1 deletions
diff --git a/src/handlers.rs b/src/handlers.rs
index 3c38724..5d31600 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -41,6 +41,7 @@ pub async fn list_measurements(
SELECT id, measured_at, metric_type, value, unit FROM measurement
WHERE ($1::timestamptz IS NULL OR measured_at >= $1)
AND ($2::timestamptz IS NULL OR measured_at < $2)
+ AND ($5::metric_type IS NULL OR metric_type = $5)
ORDER BY CASE WHEN $4 THEN measured_at END DESC,
measured_at ASC
LIMIT $3
@@ -48,7 +49,8 @@ pub async fn list_measurements(
query.from,
query.to,
limit,
- matches!(query.order, Order::Desc)
+ matches!(query.order, Order::Desc),
+ query.metric_type
)
.fetch_all(&pool)
.await?;
diff --git a/src/models.rs b/src/models.rs
index 102860b..15da87b 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -95,6 +95,7 @@ pub enum Order {
pub struct ListQuery {
pub from: Option<DateTime<Utc>>,
pub to: Option<DateTime<Utc>>,
+ pub metric_type: Option<MetricType>,
pub limit: Option<i64>,
#[serde(default)]
pub order: Order,
diff --git a/src/tests.rs b/src/tests.rs
index d2ee143..1f539bd 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -274,12 +274,57 @@ async fn list_combines_filters_with_order_and_limit(pool: PgPool) {
}
#[sqlx::test]
+async fn list_filters_by_metric_type(pool: PgPool) {
+ let app = router(pool);
+ let rows = [
+ ("2026-10-14T12:00:00Z", "BodyWeight", 70.0, "Kilogram"),
+ ("2026-10-15T12:00:00Z", "Waist", 80.0, "Centimeter"),
+ ("2026-10-16T12:00:00Z", "BodyWeight", 71.0, "Kilogram"),
+ ("2026-10-17T12:00:00Z", "Hip", 95.0, "Centimeter"),
+ ("2026-10-18T12:00:00Z", "BodyWeight", 72.0, "Kilogram"),
+ ];
+ for (measured_at, metric_type, value, unit) in rows {
+ let body = measurement(measured_at, metric_type, value, unit);
+ let (status, _, _) = send(&app, Method::POST, "/measurements", Some(body)).await;
+ assert_eq!(status, StatusCode::CREATED);
+ }
+ let cases = [
+ ("/measurements", vec![70.0, 80.0, 71.0, 95.0, 72.0]),
+ (
+ "/measurements?metric_type=BodyWeight",
+ vec![70.0, 71.0, 72.0],
+ ),
+ ("/measurements?metric_type=Waist", vec![80.0]),
+ ("/measurements?metric_type=Hip", vec![95.0]),
+ (
+ "/measurements?metric_type=BodyWeight&order=desc&limit=2",
+ vec![72.0, 71.0],
+ ),
+ (
+ "/measurements?metric_type=BodyWeight&from=2026-10-15T00:00:00Z&to=2026-10-18T00:00:00Z",
+ vec![71.0],
+ ),
+ (
+ "/measurements?metric_type=Hip&to=2026-10-17T00:00:00Z",
+ vec![],
+ ),
+ ];
+ for (uri, expected) in cases {
+ let (status, rows) = get_json(&app, uri).await;
+ assert_eq!(status, StatusCode::OK, "{uri}");
+ assert_eq!(values(&rows), expected, "{uri}");
+ }
+}
+
+#[sqlx::test]
async fn list_rejects_bad_queries(pool: PgPool) {
let app = router(pool);
let uris = [
"/measurements?limit=0",
"/measurements?limit=-1",
"/measurements?order=sideways",
+ "/measurements?metric_type=Nope",
+ "/measurements?metric_type=bodyweight",
"/measurements?from=bad",
"/measurements?from=2026-10-15",
"/measurements?to=2026-10-15T00:00:00",