mod common; use serde_json::json; use wiremock::matchers::{body_json, method, path}; use wiremock::{Mock, MockServer, ResponseTemplate}; fn sample_document(id: &str, title: &str) -> serde_json::Value { json!({ "id": id, "collectionId": "col-1", "title": title, "text": "Hello world", "urlId": "abc123", }) } #[tokio::test] async fn documents_info_by_id() { let server = MockServer::start().await; let client = common::client_for(&server).await; Mock::given(method("POST")) .and(path("/api/documents.info")) .and(body_json(json!({ "id": "doc-1" }))) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "ok": true, "data": sample_document("doc-1", "Welcome") }))) .mount(&server) .await; let document = client.documents().info("doc-1").await.unwrap(); assert_eq!(document.title, "Welcome"); assert_eq!(document.collection_id.unwrap().as_str(), "col-1"); } #[tokio::test] async fn documents_list_returns_page() { let server = MockServer::start().await; let client = common::client_for(&server).await; Mock::given(method("POST")) .and(path("/api/documents.list")) .and(body_json(json!({ "limit": 2, "collectionId": "col-1" }))) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "ok": true, "data": [sample_document("doc-1", "One"), sample_document("doc-2", "Two")], "pagination": { "limit": 2, "offset": 0 } }))) .mount(&server) .await; let page = client .documents() .list() .collection_id("col-1") .limit(2) .send() .await .unwrap(); assert_eq!(page.items.len(), 2); assert_eq!(page.items[0].title, "One"); assert_eq!(page.pagination.limit, Some(2)); } #[tokio::test] async fn documents_create_sends_title_and_collection() { let server = MockServer::start().await; let client = common::client_for(&server).await; Mock::given(method("POST")) .and(path("/api/documents.create")) .and(body_json( json!({ "title": "New Doc", "collectionId": "col-1", "publish": true }), )) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "ok": true, "data": sample_document("doc-3", "New Doc") }))) .mount(&server) .await; let document = client .documents() .create("New Doc") .collection_id("col-1") .publish(true) .send() .await .unwrap(); assert_eq!(document.id.as_str(), "doc-3"); } #[tokio::test] async fn documents_update_sends_only_set_fields() { let server = MockServer::start().await; let client = common::client_for(&server).await; Mock::given(method("POST")) .and(path("/api/documents.update")) .and(body_json(json!({ "id": "doc-1", "title": "Renamed" }))) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "ok": true, "data": sample_document("doc-1", "Renamed") }))) .mount(&server) .await; let document = client .documents() .update("doc-1") .title("Renamed") .send() .await .unwrap(); assert_eq!(document.title, "Renamed"); } #[tokio::test] async fn documents_delete_ignores_response_shape() { let server = MockServer::start().await; let client = common::client_for(&server).await; Mock::given(method("POST")) .and(path("/api/documents.delete")) .and(body_json(json!({ "id": "doc-1", "permanent": false }))) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "success": true }))) .mount(&server) .await; client.documents().delete("doc-1", false).await.unwrap(); } #[tokio::test] async fn documents_search_returns_ranked_results() { let server = MockServer::start().await; let client = common::client_for(&server).await; Mock::given(method("POST")) .and(path("/api/documents.search")) .and(body_json(json!({ "query": "hiring" }))) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "ok": true, "data": [ { "context": "our hiring practices", "ranking": 1.5, "document": sample_document("doc-4", "Hiring Guide") } ], "pagination": { "limit": 25, "offset": 0 } }))) .mount(&server) .await; let page = client.documents().search("hiring").send().await.unwrap(); assert_eq!(page.items.len(), 1); assert_eq!(page.items[0].document.title, "Hiring Guide"); }