document types
This commit is contained in:
@@ -23,6 +23,10 @@ struct DocumentInfo {
|
||||
deleted_at: Option<String>,
|
||||
issued_at: Option<String>,
|
||||
metadata: Value,
|
||||
#[serde(default)]
|
||||
document_type_id: Option<Uuid>,
|
||||
#[serde(default)]
|
||||
document_type: Option<DocumentTypeInfo>,
|
||||
tags: Vec<TagSummary>,
|
||||
#[serde(default)]
|
||||
correspondents: Vec<DocumentCorrespondentInfo>,
|
||||
@@ -57,6 +61,10 @@ struct DocumentAssetInfo {
|
||||
struct DocumentListItem {
|
||||
id: Uuid,
|
||||
#[serde(default)]
|
||||
document_type_id: Option<Uuid>,
|
||||
#[serde(default)]
|
||||
document_type: Option<DocumentTypeInfo>,
|
||||
#[serde(default)]
|
||||
current_version: Option<DocumentVersionPayload>,
|
||||
}
|
||||
|
||||
@@ -87,6 +95,12 @@ struct DocumentCorrespondentInfo {
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DocumentTypeInfo {
|
||||
id: Uuid,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct AnalyzeJobPayload {
|
||||
document_id: Uuid,
|
||||
@@ -1446,6 +1460,141 @@ async fn list_documents_by_status_filter() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn list_documents_filtered_by_document_type() -> Result<()> {
|
||||
let _lock = acquire_db_lock().await;
|
||||
let app = TestApp::new().await?;
|
||||
|
||||
let password = "doctypefilter";
|
||||
app.insert_user("doctypeuser", password, "admin").await?;
|
||||
let token = app.login_token("doctypeuser", password).await?;
|
||||
|
||||
let invoices_resp = app
|
||||
.post_json(
|
||||
"/api/document-types",
|
||||
&json!({"name": "Invoices"}),
|
||||
Some(&token),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(invoices_resp.status(), StatusCode::CREATED);
|
||||
let invoices_body = body_to_vec(invoices_resp.into_body()).await?;
|
||||
let invoices: DocumentTypeInfo = serde_json::from_slice(&invoices_body)?;
|
||||
|
||||
let receipts_resp = app
|
||||
.post_json(
|
||||
"/api/document-types",
|
||||
&json!({"name": "Receipts"}),
|
||||
Some(&token),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(receipts_resp.status(), StatusCode::CREATED);
|
||||
let receipts_body = body_to_vec(receipts_resp.into_body()).await?;
|
||||
let receipts: DocumentTypeInfo = serde_json::from_slice(&receipts_body)?;
|
||||
|
||||
let doc_a = app
|
||||
.upload_document(
|
||||
"/api/documents",
|
||||
"invoice-a.pdf",
|
||||
"application/pdf",
|
||||
b"invoice-a",
|
||||
None,
|
||||
&token,
|
||||
)
|
||||
.await?;
|
||||
let doc_a_body = body_to_vec(doc_a.into_body()).await?;
|
||||
let detail_a: DocumentDetail = serde_json::from_slice(&doc_a_body)?;
|
||||
|
||||
let doc_b = app
|
||||
.upload_document(
|
||||
"/api/documents",
|
||||
"receipt-b.pdf",
|
||||
"application/pdf",
|
||||
b"receipt-b",
|
||||
None,
|
||||
&token,
|
||||
)
|
||||
.await?;
|
||||
let doc_b_body = body_to_vec(doc_b.into_body()).await?;
|
||||
let detail_b: DocumentDetail = serde_json::from_slice(&doc_b_body)?;
|
||||
|
||||
let doc_c = app
|
||||
.upload_document(
|
||||
"/api/documents",
|
||||
"notes.txt",
|
||||
"text/plain",
|
||||
b"notes",
|
||||
None,
|
||||
&token,
|
||||
)
|
||||
.await?;
|
||||
let doc_c_body = body_to_vec(doc_c.into_body()).await?;
|
||||
let detail_c: DocumentDetail = serde_json::from_slice(&doc_c_body)?;
|
||||
|
||||
let assign_a = app
|
||||
.patch_json(
|
||||
&format!("/api/documents/{}", detail_a.document.id),
|
||||
&json!({"document_type_id": invoices.id}),
|
||||
Some(&token),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(assign_a.status(), StatusCode::OK);
|
||||
|
||||
let assign_b = app
|
||||
.patch_json(
|
||||
&format!("/api/documents/{}", detail_b.document.id),
|
||||
&json!({"document_type_id": receipts.id}),
|
||||
Some(&token),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(assign_b.status(), StatusCode::OK);
|
||||
|
||||
let invoices_resp = app
|
||||
.get(
|
||||
&format!("/api/documents?document_types={}", invoices.id),
|
||||
Some(&token),
|
||||
)
|
||||
.await?;
|
||||
assert!(invoices_resp.status().is_success());
|
||||
let invoices_list_body = body_to_vec(invoices_resp.into_body()).await?;
|
||||
let invoices_docs: Vec<DocumentListItem> = serde_json::from_slice(&invoices_list_body)?;
|
||||
assert_eq!(invoices_docs.len(), 1);
|
||||
assert_eq!(invoices_docs[0].id, detail_a.document.id);
|
||||
assert_eq!(invoices_docs[0].document_type_id, Some(invoices.id));
|
||||
|
||||
let receipts_resp = app
|
||||
.get(
|
||||
&format!("/api/documents?document_types={}", receipts.id),
|
||||
Some(&token),
|
||||
)
|
||||
.await?;
|
||||
assert!(receipts_resp.status().is_success());
|
||||
let receipts_list_body = body_to_vec(receipts_resp.into_body()).await?;
|
||||
let receipts_docs: Vec<DocumentListItem> = serde_json::from_slice(&receipts_list_body)?;
|
||||
assert_eq!(receipts_docs.len(), 1);
|
||||
assert_eq!(receipts_docs[0].id, detail_b.document.id);
|
||||
assert_eq!(receipts_docs[0].document_type_id, Some(receipts.id));
|
||||
|
||||
let combined_resp = app
|
||||
.get(
|
||||
&format!(
|
||||
"/api/documents?document_types={},{}",
|
||||
invoices.id, receipts.id
|
||||
),
|
||||
Some(&token),
|
||||
)
|
||||
.await?;
|
||||
assert!(combined_resp.status().is_success());
|
||||
let combined_body = body_to_vec(combined_resp.into_body()).await?;
|
||||
let combined_docs: Vec<DocumentListItem> = serde_json::from_slice(&combined_body)?;
|
||||
let combined_ids: Vec<Uuid> = combined_docs.iter().map(|doc| doc.id).collect();
|
||||
assert!(combined_ids.contains(&detail_a.document.id));
|
||||
assert!(combined_ids.contains(&detail_b.document.id));
|
||||
assert!(!combined_ids.contains(&detail_c.document.id));
|
||||
|
||||
app.cleanup().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn restore_document_to_original_and_custom_folder() -> Result<()> {
|
||||
let _lock = acquire_db_lock().await;
|
||||
|
||||
Reference in New Issue
Block a user