This commit is contained in:
2025-10-10 09:39:58 +02:00
parent 4a428b9af6
commit ddce0e39b3
36 changed files with 6410 additions and 1419 deletions
+107 -9
View File
@@ -11,6 +11,7 @@ use uuid::Uuid;
struct DocumentDetail {
document: DocumentInfo,
current_version: DocumentVersion,
assets: Vec<DocumentAssetInfo>,
}
#[derive(Deserialize)]
@@ -24,10 +25,17 @@ struct DocumentInfo {
#[derive(Deserialize)]
struct DocumentVersion {
id: Uuid,
s3_key: String,
size_bytes: i64,
}
#[derive(Deserialize)]
struct DocumentAssetInfo {
id: Uuid,
asset_type: String,
}
#[derive(Deserialize)]
struct DocumentListItem {
id: Uuid,
@@ -40,13 +48,23 @@ struct DocumentDownload {
filename: String,
}
#[derive(Deserialize)]
struct BulkReanalyze {
queued: usize,
}
#[derive(Deserialize)]
struct AnalyzeJobPayload {
document_id: Uuid,
document_version_id: Uuid,
#[serde(default)]
force: bool,
}
#[tokio::test]
async fn upload_and_list_document() -> Result<()> {
let _lock = acquire_db_lock().await;
let Some(app) = TestApp::new().await? else {
eprintln!("skipping test: TEST_DATABASE_URL not set");
return Ok(());
};
let app = TestApp::new().await?;
let password = "passw0rd";
app.insert_user("dana", password, "admin").await?;
@@ -63,7 +81,7 @@ async fn upload_and_list_document() -> Result<()> {
&token,
)
.await?;
assert_eq!(upload.status(), StatusCode::OK);
assert_eq!(upload.status(), StatusCode::CREATED);
let body = body_to_vec(upload.into_body()).await?;
let detail: DocumentDetail = serde_json::from_slice(&body)?;
@@ -72,6 +90,7 @@ async fn upload_and_list_document() -> Result<()> {
assert_eq!(detail.document.deleted_at, None);
assert!(detail.document.tags.is_empty());
assert_eq!(detail.current_version.size_bytes, file_bytes.len() as i64);
assert!(detail.assets.is_empty());
let stored = app
.storage()
@@ -79,6 +98,7 @@ async fn upload_and_list_document() -> Result<()> {
.await
.expect("object stored");
assert_eq!(stored.bytes, file_bytes);
assert_eq!(app.storage().object_count().await, 1);
let response = app.get("/api/documents", Some(&token)).await?;
assert_eq!(response.status(), StatusCode::OK);
@@ -108,10 +128,7 @@ async fn upload_and_list_document() -> Result<()> {
#[tokio::test]
async fn duplicate_and_restore_document() -> Result<()> {
let _lock = acquire_db_lock().await;
let Some(app) = TestApp::new().await? else {
eprintln!("skipping test: TEST_DATABASE_URL not set");
return Ok(());
};
let app = TestApp::new().await?;
let password = "pass1234";
app.insert_user("sam", password, "admin").await?;
@@ -128,6 +145,7 @@ async fn duplicate_and_restore_document() -> Result<()> {
&token,
)
.await?;
assert_eq!(first.status(), StatusCode::CREATED);
let first_body = body_to_vec(first.into_body()).await?;
let first_detail: DocumentDetail = serde_json::from_slice(&first_body)?;
@@ -147,6 +165,8 @@ async fn duplicate_and_restore_document() -> Result<()> {
assert_eq!(first_detail.document.id, second_detail.document.id);
assert_eq!(second_detail.document.deleted_at, None);
assert!(second_detail.assets.is_empty());
assert_eq!(app.storage().object_count().await, 1);
let delete = app
.delete(
@@ -166,11 +186,89 @@ async fn duplicate_and_restore_document() -> Result<()> {
&token,
)
.await?;
assert_eq!(third.status(), StatusCode::OK);
let third_body = body_to_vec(third.into_body()).await?;
let third_detail: DocumentDetail = serde_json::from_slice(&third_body)?;
assert_eq!(third_detail.document.id, first_detail.document.id);
assert_eq!(third_detail.document.deleted_at, None);
assert_eq!(app.storage().object_count().await, 1);
app.cleanup().await?;
Ok(())
}
#[tokio::test]
async fn bulk_reanalyze_documents() -> Result<()> {
let _lock = acquire_db_lock().await;
let app = TestApp::new().await?;
let password = "bulkpass";
app.insert_user("alex", password, "admin").await?;
let token = app.login_token("alex", password).await?;
app.clear_jobs().await?;
let first_bytes = b"first doc";
let first = app
.upload_document(
"/api/documents",
"first.txt",
"text/plain",
first_bytes,
None,
&token,
)
.await?;
assert_eq!(first.status(), StatusCode::CREATED);
let first_body = body_to_vec(first.into_body()).await?;
let first_detail: DocumentDetail = serde_json::from_slice(&first_body)?;
let second_bytes = b"second doc";
let second = app
.upload_document(
"/api/documents",
"second.txt",
"text/plain",
second_bytes,
None,
&token,
)
.await?;
assert_eq!(second.status(), StatusCode::CREATED);
let second_body = body_to_vec(second.into_body()).await?;
let second_detail: DocumentDetail = serde_json::from_slice(&second_body)?;
app.clear_jobs().await?;
let response = app
.post_json(
"/api/documents/reanalyze",
&serde_json::json!({}),
Some(&token),
)
.await?;
assert_eq!(response.status(), StatusCode::ACCEPTED);
let body = body_to_vec(response.into_body()).await?;
let bulk: BulkReanalyze = serde_json::from_slice(&body)?;
assert_eq!(bulk.queued, 2);
let jobs = app.jobs_by_type("analyze-document").await?;
assert_eq!(jobs.len(), 2);
let mut payload_docs = Vec::new();
for job in jobs {
let payload: AnalyzeJobPayload = serde_json::from_value(job.payload)?;
assert!(payload.force);
payload_docs.push((payload.document_id, payload.document_version_id));
}
let mut expected = vec![
(first_detail.document.id, first_detail.current_version.id),
(second_detail.document.id, second_detail.current_version.id),
];
payload_docs.sort();
expected.sort();
assert_eq!(payload_docs, expected);
app.cleanup().await?;
Ok(())