mirror of
https://github.com/RaisFast/raisfast.git
synced 2026-09-25 16:02:41 +00:00
218 lines
6.6 KiB
Rust
218 lines
6.6 KiB
Rust
use super::*;
|
|
|
|
async fn setup_with_post() -> (axum::Router, AppState, String, String) {
|
|
let (mut app, state) = test_app().await;
|
|
let author_id = create_author(&state.pool).await;
|
|
let tok = make_token(&author_id, "author");
|
|
let slug = create_published_post(&mut app, &tok).await;
|
|
(app, state, tok, slug)
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn guest_comment_success() {
|
|
let (mut app, _, _, slug) = setup_with_post().await;
|
|
let (status, body): (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json(
|
|
&format!("/api/v1/posts/{slug}/comments"),
|
|
json!({"content": "Nice!", "nickname": "Guest1", "email": "g@test.com"}),
|
|
),
|
|
)
|
|
.await;
|
|
assert!(status.is_success(), "{status} {body:?}");
|
|
assert_eq!(body["data"]["content"], "Nice!");
|
|
assert_eq!(body["data"]["nickname"], "Guest1");
|
|
assert!(body["data"]["author_id"].is_null());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn guest_comment_requires_nickname() {
|
|
let (mut app, _, _, slug) = setup_with_post().await;
|
|
let (status, body): (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json(
|
|
&format!("/api/v1/posts/{slug}/comments"),
|
|
json!({"content": "no nick"}),
|
|
),
|
|
)
|
|
.await;
|
|
assert_eq!(status, StatusCode::BAD_REQUEST);
|
|
assert_eq!(body["code"], 40000);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn authed_comment_success() {
|
|
let (mut app, _, _, slug) = setup_with_post().await;
|
|
let (tok, _) = register_and_login(&mut app, "cmtr@test.com", "cmtr", "Password123").await;
|
|
let (status, body): (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json_auth(
|
|
&format!("/api/v1/posts/{slug}/comments/authed"),
|
|
json!({"content": "Auth comment"}),
|
|
&tok,
|
|
),
|
|
)
|
|
.await;
|
|
assert!(status.is_success(), "{status} {body:?}");
|
|
assert_eq!(body["data"]["content"], "Auth comment");
|
|
assert!(body["data"]["author_id"].is_string());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn nested_comment() {
|
|
let (mut app, state, _, slug) = setup_with_post().await;
|
|
let (_, b1): (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json(
|
|
&format!("/api/v1/posts/{slug}/comments"),
|
|
json!({"content": "Parent", "nickname": "G1"}),
|
|
),
|
|
)
|
|
.await;
|
|
let pid = b1["data"]["id"].as_str().unwrap();
|
|
|
|
let approve_sql =
|
|
rust_blog::db::dialect::translate("UPDATE comments SET status = 'approved' WHERE id = ?");
|
|
sqlx::query(&approve_sql)
|
|
.bind(pid)
|
|
.execute(&state.pool)
|
|
.await
|
|
.unwrap();
|
|
|
|
let (status, body): (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json(
|
|
&format!("/api/v1/posts/{slug}/comments"),
|
|
json!({"content": "Reply", "nickname": "G2", "parent_id": pid}),
|
|
),
|
|
)
|
|
.await;
|
|
assert!(status.is_success(), "{status} {body:?}");
|
|
assert_eq!(body["data"]["parent_id"], pid);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn list_comments() {
|
|
let (mut app, state, _, slug) = setup_with_post().await;
|
|
let _: (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json(
|
|
&format!("/api/v1/posts/{slug}/comments"),
|
|
json!({"content": "C1", "nickname": "A"}),
|
|
),
|
|
)
|
|
.await;
|
|
let _: (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json(
|
|
&format!("/api/v1/posts/{slug}/comments"),
|
|
json!({"content": "C2", "nickname": "B"}),
|
|
),
|
|
)
|
|
.await;
|
|
|
|
sqlx::query("UPDATE comments SET status = 'approved' WHERE status = 'pending'")
|
|
.execute(&state.pool)
|
|
.await
|
|
.unwrap();
|
|
|
|
let (status, body): (StatusCode, Value) =
|
|
send(&mut app, get_req(&format!("/api/v1/posts/{slug}/comments"))).await;
|
|
assert!(status.is_success());
|
|
let items = body["data"]["items"].as_array().unwrap();
|
|
assert!(items.len() >= 2);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn delete_own_comment() {
|
|
let (mut app, _, _, slug) = setup_with_post().await;
|
|
let (tok, _) = register_and_login(&mut app, "delc@test.com", "delcuser", "Password123").await;
|
|
let (_, b): (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json_auth(
|
|
&format!("/api/v1/posts/{slug}/comments/authed"),
|
|
json!({"content": "mine"}),
|
|
&tok,
|
|
),
|
|
)
|
|
.await;
|
|
let cid = b["data"]["id"].as_str().unwrap();
|
|
let (status, _): (StatusCode, Value) = send(
|
|
&mut app,
|
|
delete_auth(&format!("/api/v1/comments/{cid}"), &tok),
|
|
)
|
|
.await;
|
|
assert!(status.is_success());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn delete_not_owner_forbidden() {
|
|
let (mut app, _, _, slug) = setup_with_post().await;
|
|
let (t1, _) = register_and_login(&mut app, "own@test.com", "own", "Password123").await;
|
|
let (t2, _) = register_and_login(&mut app, "str@test.com", "str", "Password123").await;
|
|
let (_, b): (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json_auth(
|
|
&format!("/api/v1/posts/{slug}/comments/authed"),
|
|
json!({"content": "x"}),
|
|
&t1,
|
|
),
|
|
)
|
|
.await;
|
|
let cid = b["data"]["id"].as_str().unwrap();
|
|
let (status, _): (StatusCode, Value) = send(
|
|
&mut app,
|
|
delete_auth(&format!("/api/v1/comments/{cid}"), &t2),
|
|
)
|
|
.await;
|
|
assert_eq!(status, StatusCode::FORBIDDEN);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn update_status_admin() {
|
|
let (mut app, state, _, slug) = setup_with_post().await;
|
|
let _: (StatusCode, Value) = send(
|
|
&mut app,
|
|
post_json(
|
|
&format!("/api/v1/posts/{slug}/comments"),
|
|
json!({"content": "mod me", "nickname": "G"}),
|
|
),
|
|
)
|
|
.await;
|
|
|
|
let cid: String = sqlx::query_scalar("SELECT id FROM comments WHERE content = 'mod me'")
|
|
.fetch_one(&state.pool)
|
|
.await
|
|
.unwrap();
|
|
|
|
let admin_id = create_admin(&state.pool).await;
|
|
let admin_tok = make_token(&admin_id, "admin");
|
|
let (status, _): (StatusCode, Value) = send(
|
|
&mut app,
|
|
put_json_auth(
|
|
&format!("/api/v1/comments/{cid}/status"),
|
|
json!({"status": "approved"}),
|
|
&admin_tok,
|
|
),
|
|
)
|
|
.await;
|
|
assert!(status.is_success());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn update_status_requires_admin() {
|
|
let (mut app, _, _, _) = setup_with_post().await;
|
|
let (tok, _) = register_and_login(&mut app, "na@test.com", "nauser", "Password123").await;
|
|
let fake = uuid::Uuid::now_v7().to_string();
|
|
let (status, _): (StatusCode, Value) = send(
|
|
&mut app,
|
|
put_json_auth(
|
|
&format!("/api/v1/comments/{fake}/status"),
|
|
json!({"status": "approved"}),
|
|
&tok,
|
|
),
|
|
)
|
|
.await;
|
|
assert_eq!(status, StatusCode::FORBIDDEN);
|
|
}
|