fix(attendance): correct course_id column in slot queries, add patch_json helper
This commit is contained in:
@@ -4,6 +4,7 @@ use axum::{
|
||||
routing::{delete, get, patch, post},
|
||||
Json, Router,
|
||||
};
|
||||
use rand::Rng;
|
||||
use serde::Deserialize;
|
||||
use serde_json::{json, Value};
|
||||
use sqlx::SqlitePool;
|
||||
@@ -16,7 +17,6 @@ use crate::{
|
||||
|
||||
fn generate_code() -> String {
|
||||
const CHARS: &[u8] = b"ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||
use rand::Rng;
|
||||
let mut rng = rand::rng();
|
||||
(0..8)
|
||||
.map(|_| CHARS[rng.random_range(0..CHARS.len())] as char)
|
||||
@@ -132,7 +132,7 @@ async fn create_slot(
|
||||
.fetch_optional(&pool)
|
||||
.await?;
|
||||
if room.is_none() {
|
||||
return Err(AppError::NotFound);
|
||||
return Err(AppError::BadRequest("room_id does not exist".into()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ async fn update_slot_status(
|
||||
|
||||
// Fetch the slot + its session's course_id for access check
|
||||
let row: Option<(i64, Option<String>)> = sqlx::query_as(
|
||||
"SELECT s.id, sl.code
|
||||
"SELECT s.course_id, sl.code
|
||||
FROM slots sl
|
||||
JOIN sessions s ON s.id = sl.session_id
|
||||
WHERE sl.id = ?",
|
||||
@@ -284,7 +284,7 @@ pub fn router() -> Router<SqlitePool> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test_helpers::{build_test_app, delete, get, post_json};
|
||||
use crate::test_helpers::{build_test_app, delete, get, patch_json, post_json};
|
||||
use axum::http::StatusCode;
|
||||
use serde_json::{json, Value};
|
||||
use std::collections::HashSet;
|
||||
@@ -413,21 +413,13 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Open the slot
|
||||
use axum::http::Request;
|
||||
use http_body_util::BodyExt;
|
||||
use tower::ServiceExt;
|
||||
let req = Request::builder()
|
||||
.method("PATCH")
|
||||
.uri(format!("/api/admin/slots/{slot_id}/status"))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", &auth)
|
||||
.body(axum::body::Body::from(
|
||||
json!({"status": "open"}).to_string(),
|
||||
))
|
||||
.unwrap();
|
||||
let res = app.clone().oneshot(req).await.unwrap();
|
||||
assert_eq!(res.status(), StatusCode::OK);
|
||||
let body = res.into_body().collect().await.unwrap().to_bytes();
|
||||
let (status, body) = patch_json(
|
||||
app.clone(),
|
||||
&format!("/api/admin/slots/{slot_id}/status"),
|
||||
&auth,
|
||||
json!({"status": "open"}),
|
||||
).await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
let slot = serde_json::from_slice::<Value>(&body).unwrap();
|
||||
assert_eq!(slot["status"], "open");
|
||||
let code = slot["code"].as_str().unwrap();
|
||||
|
||||
@@ -64,6 +64,29 @@ pub async fn put_json(app: Router, uri: &str, auth: &str, body: serde_json::Valu
|
||||
(status, body)
|
||||
}
|
||||
|
||||
/// PATCH JSON body to the app (one-shot), returns (StatusCode, response body bytes).
|
||||
pub async fn patch_json(
|
||||
app: Router,
|
||||
uri: &str,
|
||||
auth: &str,
|
||||
body: serde_json::Value,
|
||||
) -> (StatusCode, bytes::Bytes) {
|
||||
let mut req = Request::builder()
|
||||
.method("PATCH")
|
||||
.uri(uri)
|
||||
.header("Content-Type", "application/json");
|
||||
if !auth.is_empty() {
|
||||
req = req.header("Authorization", auth);
|
||||
}
|
||||
let req = req
|
||||
.body(axum::body::Body::from(body.to_string()))
|
||||
.unwrap();
|
||||
let res = app.oneshot(req).await.unwrap();
|
||||
let status = res.status();
|
||||
let body = res.into_body().collect().await.unwrap().to_bytes();
|
||||
(status, body)
|
||||
}
|
||||
|
||||
/// GET from the app (one-shot), returns (StatusCode, response body bytes).
|
||||
pub async fn get(app: Router, path: &str, auth: &str) -> (StatusCode, bytes::Bytes) {
|
||||
let mut builder = Request::builder()
|
||||
|
||||
Reference in New Issue
Block a user