Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I22c7237877862acbf931ce4c662bd2816a6a6964
150 lines
3.9 KiB
Rust
150 lines
3.9 KiB
Rust
mod common;
|
|
|
|
use axum::http::StatusCode;
|
|
use common::{
|
|
delete_authed,
|
|
get,
|
|
get_authed,
|
|
patch_json_authed,
|
|
post_json_authed,
|
|
put_json_authed,
|
|
response_body,
|
|
setup_app,
|
|
setup_app_with_auth,
|
|
};
|
|
use tower::ServiceExt;
|
|
|
|
#[tokio::test]
|
|
async fn backlinks_for_nonexistent_media() {
|
|
let app = setup_app().await;
|
|
let fake_id = uuid::Uuid::now_v7();
|
|
let resp = app
|
|
.oneshot(get(&format!("/api/v1/media/{fake_id}/backlinks")))
|
|
.await
|
|
.unwrap();
|
|
// Should return OK with empty list, or NOT_FOUND
|
|
assert!(
|
|
resp.status() == StatusCode::OK || resp.status() == StatusCode::NOT_FOUND
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn outgoing_links_for_nonexistent_media() {
|
|
let app = setup_app().await;
|
|
let fake_id = uuid::Uuid::now_v7();
|
|
let resp = app
|
|
.oneshot(get(&format!("/api/v1/media/{fake_id}/outgoing-links")))
|
|
.await
|
|
.unwrap();
|
|
assert!(
|
|
resp.status() == StatusCode::OK || resp.status() == StatusCode::NOT_FOUND
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn notes_graph_empty() {
|
|
let (app, _, _, viewer) = setup_app_with_auth().await;
|
|
let resp = app
|
|
.clone()
|
|
.oneshot(get_authed("/api/v1/notes/graph", &viewer))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(resp.status(), StatusCode::OK);
|
|
let body = response_body(resp).await;
|
|
// Fresh database: graph must be empty.
|
|
if let Some(arr) = body.as_array() {
|
|
assert!(arr.is_empty(), "graph should be empty, got {arr:?}");
|
|
} else if let Some(obj) = body.as_object() {
|
|
// Accept an object if the schema uses {nodes:[], edges:[]} style.
|
|
let nodes_empty = obj
|
|
.get("nodes")
|
|
.and_then(|v| v.as_array())
|
|
.is_none_or(std::vec::Vec::is_empty);
|
|
let edges_empty = obj
|
|
.get("edges")
|
|
.and_then(|v| v.as_array())
|
|
.is_none_or(std::vec::Vec::is_empty);
|
|
assert!(
|
|
nodes_empty && edges_empty,
|
|
"graph should be empty, got {obj:?}"
|
|
);
|
|
} else {
|
|
panic!("expected array or object, got {body}");
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn unresolved_count_zero() {
|
|
let app = setup_app().await;
|
|
let resp = app
|
|
.oneshot(get("/api/v1/notes/unresolved-count"))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(resp.status(), StatusCode::OK);
|
|
let body = response_body(resp).await;
|
|
// Fresh database has no unresolved links.
|
|
let count = body["count"]
|
|
.as_u64()
|
|
.expect("response should have a numeric 'count' field");
|
|
assert_eq!(count, 0, "expected zero unresolved links in fresh database");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn reindex_links_requires_editor() {
|
|
let (app, _, _, viewer) = setup_app_with_auth().await;
|
|
let fake_id = uuid::Uuid::now_v7();
|
|
let resp = app
|
|
.clone()
|
|
.oneshot(post_json_authed(
|
|
&format!("/api/v1/media/{fake_id}/reindex-links"),
|
|
"{}",
|
|
&viewer,
|
|
))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn update_media_requires_editor() {
|
|
let (app, _, _, viewer) = setup_app_with_auth().await;
|
|
let fake_id = uuid::Uuid::now_v7();
|
|
let resp = app
|
|
.clone()
|
|
.oneshot(patch_json_authed(
|
|
&format!("/api/v1/media/{fake_id}"),
|
|
r#"{"title":"new title"}"#,
|
|
&viewer,
|
|
))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn delete_media_requires_editor() {
|
|
let (app, _, _, viewer) = setup_app_with_auth().await;
|
|
let fake_id = uuid::Uuid::now_v7();
|
|
let resp = app
|
|
.clone()
|
|
.oneshot(delete_authed(&format!("/api/v1/media/{fake_id}"), &viewer))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn update_sync_device_requires_editor() {
|
|
let (app, _, _, viewer) = setup_app_with_auth().await;
|
|
let fake_id = uuid::Uuid::now_v7();
|
|
let resp = app
|
|
.clone()
|
|
.oneshot(put_json_authed(
|
|
&format!("/api/v1/sync/devices/{fake_id}"),
|
|
r#"{"name":"renamed"}"#,
|
|
&viewer,
|
|
))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
|
}
|