refactorize the test suite of the add_documents module to use snapshot tests when possible

This commit is contained in:
Tamo 2023-01-24 11:27:51 +01:00
parent d963c2ce55
commit a3f1b8fdb9

View File

@ -1,4 +1,5 @@
use actix_web::test; use actix_web::test;
use meili_snap::{json_string, snapshot};
use serde_json::{json, Value}; use serde_json::{json, Value};
use time::format_description::well_known::Rfc3339; use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime; use time::OffsetDateTime;
@ -30,8 +31,17 @@ async fn add_documents_test_json_content_types() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202); snapshot!(status_code, @"202 Accepted");
assert_eq!(response["taskUid"], 0); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 0,
"indexUid": "dog",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -43,8 +53,17 @@ async fn add_documents_test_json_content_types() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202); snapshot!(status_code, @"202 Accepted");
assert_eq!(response["taskUid"], 1); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 1,
"indexUid": "dog",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
} }
/// Here we try to send a single document instead of an array with a single document inside. /// Here we try to send a single document instead of an array with a single document inside.
@ -69,8 +88,17 @@ async fn add_single_document_test_json_content_types() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202); snapshot!(status_code, @"202 Accepted");
assert_eq!(response["taskUid"], 0); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 0,
"indexUid": "dog",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -82,8 +110,17 @@ async fn add_single_document_test_json_content_types() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202); snapshot!(status_code, @"202 Accepted");
assert_eq!(response["taskUid"], 1); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 1,
"indexUid": "dog",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
} }
/// Here we try sending encoded (compressed) document request /// Here we try sending encoded (compressed) document request
@ -110,8 +147,17 @@ async fn add_single_document_gzip_encoded() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202); snapshot!(status_code, @"202 Accepted");
assert_eq!(response["taskUid"], 0); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 0,
"indexUid": "dog",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -124,8 +170,17 @@ async fn add_single_document_gzip_encoded() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 202); snapshot!(status_code, @"202 Accepted");
assert_eq!(response["taskUid"], 1); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 1,
"indexUid": "dog",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
} }
/// Here we try document request with every encoding /// Here we try document request with every encoding
@ -184,16 +239,16 @@ async fn error_add_documents_test_bad_content_types() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 415); snapshot!(status_code, @"415 Unsupported Media Type");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The Content-Type `text/plain` is invalid. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`"# "message": "The Content-Type `text/plain` is invalid. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`",
) "code": "invalid_content_type",
); "type": "invalid_request",
assert_eq!(response["code"], "invalid_content_type"); "link": "https://docs.meilisearch.com/errors#invalid_content_type"
assert_eq!(response["type"], "invalid_request"); }
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid_content_type"); "###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -205,16 +260,16 @@ async fn error_add_documents_test_bad_content_types() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 415); snapshot!(status_code, @"415 Unsupported Media Type");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The Content-Type `text/plain` is invalid. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`"# "message": "The Content-Type `text/plain` is invalid. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`",
) "code": "invalid_content_type",
); "type": "invalid_request",
assert_eq!(response["code"], "invalid_content_type"); "link": "https://docs.meilisearch.com/errors#invalid_content_type"
assert_eq!(response["type"], "invalid_request"); }
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid_content_type"); "###);
} }
/// missing content-type must be refused /// missing content-type must be refused
@ -239,16 +294,16 @@ async fn error_add_documents_test_no_content_type() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 415); snapshot!(status_code, @"415 Unsupported Media Type");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"A Content-Type header is missing. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`"# "message": "A Content-Type header is missing. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`",
) "code": "missing_content_type",
); "type": "invalid_request",
assert_eq!(response["code"], "missing_content_type"); "link": "https://docs.meilisearch.com/errors#missing_content_type"
assert_eq!(response["type"], "invalid_request"); }
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#missing_content_type"); "###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -259,16 +314,16 @@ async fn error_add_documents_test_no_content_type() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 415); snapshot!(status_code, @"415 Unsupported Media Type");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"A Content-Type header is missing. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`"# "message": "A Content-Type header is missing. Accepted values for the Content-Type header are: `application/json`, `application/x-ndjson`, `text/csv`",
) "code": "missing_content_type",
); "type": "invalid_request",
assert_eq!(response["code"], "missing_content_type"); "link": "https://docs.meilisearch.com/errors#missing_content_type"
assert_eq!(response["type"], "invalid_request"); }
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#missing_content_type"); "###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -288,16 +343,16 @@ async fn error_add_malformed_csv_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The `csv` payload provided is malformed: `CSV error: record 1 (line: 2, byte: 12): found record with 3 fields, but the previous record has 2 fields`."# "message": "The `csv` payload provided is malformed: `CSV error: record 1 (line: 2, byte: 12): found record with 3 fields, but the previous record has 2 fields`.",
) "code": "malformed_payload",
); "type": "invalid_request",
assert_eq!(response["code"], json!("malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
assert_eq!(response["type"], json!("invalid_request")); }
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -309,16 +364,16 @@ async fn error_add_malformed_csv_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The `csv` payload provided is malformed: `CSV error: record 1 (line: 2, byte: 12): found record with 3 fields, but the previous record has 2 fields`."# "message": "The `csv` payload provided is malformed: `CSV error: record 1 (line: 2, byte: 12): found record with 3 fields, but the previous record has 2 fields`.",
) "code": "malformed_payload",
); "type": "invalid_request",
assert_eq!(response["code"], json!("malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
assert_eq!(response["type"], json!("invalid_request")); }
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -338,16 +393,16 @@ async fn error_add_malformed_json_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The `json` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 1 column 14`."# "message": "The `json` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 1 column 14`.",
) "code": "malformed_payload",
); "type": "invalid_request",
assert_eq!(response["code"], json!("malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
assert_eq!(response["type"], json!("invalid_request")); }
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -359,16 +414,16 @@ async fn error_add_malformed_json_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The `json` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 1 column 14`."# "message": "The `json` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 1 column 14`.",
) "code": "malformed_payload",
); "type": "invalid_request",
assert_eq!(response["code"], json!("malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
assert_eq!(response["type"], json!("invalid_request")); }
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "###);
// truncate // truncate
@ -384,16 +439,16 @@ async fn error_add_malformed_json_documents() {
let res = test::call_service(&app, req).await; let res = test::call_service(&app, req).await;
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The `json` payload provided is malformed. `Couldn't serialize document value: data are neither an object nor a list of objects`."# "message": "The `json` payload provided is malformed. `Couldn't serialize document value: data are neither an object nor a list of objects`.",
) "code": "malformed_payload",
); "type": "invalid_request",
assert_eq!(response["code"], json!("malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
assert_eq!(response["type"], json!("invalid_request")); }
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "###);
// add one more char to the long string to test if the truncating works. // add one more char to the long string to test if the truncating works.
let document = format!("\"{}m\"", long); let document = format!("\"{}m\"", long);
@ -405,14 +460,16 @@ async fn error_add_malformed_json_documents() {
let res = test::call_service(&app, req).await; let res = test::call_service(&app, req).await;
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!("The `json` payload provided is malformed. `Couldn't serialize document value: data are neither an object nor a list of objects`.") {
); "message": "The `json` payload provided is malformed. `Couldn't serialize document value: data are neither an object nor a list of objects`.",
assert_eq!(response["code"], json!("malformed_payload")); "code": "malformed_payload",
assert_eq!(response["type"], json!("invalid_request")); "type": "invalid_request",
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -432,16 +489,16 @@ async fn error_add_malformed_ndjson_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!( {
r#"The `ndjson` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 2 column 2`."# "message": "The `ndjson` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 2 column 2`.",
) "code": "malformed_payload",
); "type": "invalid_request",
assert_eq!(response["code"], json!("malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
assert_eq!(response["type"], json!("invalid_request")); }
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -453,14 +510,16 @@ async fn error_add_malformed_ndjson_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!( snapshot!(json_string!(response),
response["message"], @r###"
json!("The `ndjson` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 2 column 2`.") {
); "message": "The `ndjson` payload provided is malformed. `Couldn't serialize document value: key must be a string at line 2 column 2`.",
assert_eq!(response["code"], json!("malformed_payload")); "code": "malformed_payload",
assert_eq!(response["type"], json!("invalid_request")); "type": "invalid_request",
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload")); "link": "https://docs.meilisearch.com/errors#malformed_payload"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -480,11 +539,16 @@ async fn error_add_missing_payload_csv_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!(response["message"], json!(r#"A csv payload is missing."#)); snapshot!(json_string!(response),
assert_eq!(response["code"], json!("missing_payload")); @r###"
assert_eq!(response["type"], json!("invalid_request")); {
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload")); "message": "A csv payload is missing.",
"code": "missing_payload",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_payload"
}
"###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -496,11 +560,16 @@ async fn error_add_missing_payload_csv_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!(response["message"], json!(r#"A csv payload is missing."#)); snapshot!(json_string!(response),
assert_eq!(response["code"], json!("missing_payload")); @r###"
assert_eq!(response["type"], json!("invalid_request")); {
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload")); "message": "A csv payload is missing.",
"code": "missing_payload",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_payload"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -520,11 +589,16 @@ async fn error_add_missing_payload_json_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!(response["message"], json!(r#"A json payload is missing."#)); snapshot!(json_string!(response),
assert_eq!(response["code"], json!("missing_payload")); @r###"
assert_eq!(response["type"], json!("invalid_request")); {
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload")); "message": "A json payload is missing.",
"code": "missing_payload",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_payload"
}
"###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -536,11 +610,16 @@ async fn error_add_missing_payload_json_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!(response["message"], json!(r#"A json payload is missing."#)); snapshot!(json_string!(response),
assert_eq!(response["code"], json!("missing_payload")); @r###"
assert_eq!(response["type"], json!("invalid_request")); {
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload")); "message": "A json payload is missing.",
"code": "missing_payload",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_payload"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -560,11 +639,16 @@ async fn error_add_missing_payload_ndjson_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!(response["message"], json!(r#"A ndjson payload is missing."#)); snapshot!(json_string!(response),
assert_eq!(response["code"], json!("missing_payload")); @r###"
assert_eq!(response["type"], json!("invalid_request")); {
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload")); "message": "A ndjson payload is missing.",
"code": "missing_payload",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_payload"
}
"###);
// put // put
let req = test::TestRequest::put() let req = test::TestRequest::put()
@ -576,11 +660,16 @@ async fn error_add_missing_payload_ndjson_documents() {
let status_code = res.status(); let status_code = res.status();
let body = test::read_body(res).await; let body = test::read_body(res).await;
let response: Value = serde_json::from_slice(&body).unwrap_or_default(); let response: Value = serde_json::from_slice(&body).unwrap_or_default();
assert_eq!(status_code, 400); snapshot!(status_code, @"400 Bad Request");
assert_eq!(response["message"], json!(r#"A ndjson payload is missing."#)); snapshot!(json_string!(response),
assert_eq!(response["code"], json!("missing_payload")); @r###"
assert_eq!(response["type"], json!("invalid_request")); {
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload")); "message": "A ndjson payload is missing.",
"code": "missing_payload",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_payload"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -596,26 +685,32 @@ async fn add_documents_no_index_creation() {
]); ]);
let (response, code) = index.add_documents(documents, None).await; let (response, code) = index.add_documents(documents, None).await;
assert_eq!(code, 202); snapshot!(code, @"202 Accepted");
assert_eq!(response["taskUid"], 0); assert_eq!(response["taskUid"], 0);
/*
* currently we dont check these field to stay ISO with meilisearch
* assert_eq!(response["status"], "pending");
* assert_eq!(response["meta"]["type"], "DocumentsAddition");
* assert_eq!(response["meta"]["format"], "Json");
* assert_eq!(response["meta"]["primaryKey"], Value::Null);
* assert!(response.get("enqueuedAt").is_some());
*/
index.wait_task(0).await; index.wait_task(0).await;
let (response, code) = index.get_task(0).await; let (response, code) = index.get_task(0).await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["status"], "succeeded"); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
assert_eq!(response["uid"], 0); @r###"
assert_eq!(response["type"], "documentAdditionOrUpdate"); {
assert_eq!(response["details"]["receivedDocuments"], 1); "uid": 0,
assert_eq!(response["details"]["indexedDocuments"], 1); "indexUid": "test",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
"###);
let processed_at = let processed_at =
OffsetDateTime::parse(response["finishedAt"].as_str().unwrap(), &Rfc3339).unwrap(); OffsetDateTime::parse(response["finishedAt"].as_str().unwrap(), &Rfc3339).unwrap();
@ -625,7 +720,7 @@ async fn add_documents_no_index_creation() {
// index was created, and primary key was inferred. // index was created, and primary key was inferred.
let (response, code) = index.get().await; let (response, code) = index.get().await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["primaryKey"], "id"); assert_eq!(response["primaryKey"], "id");
} }
@ -635,15 +730,16 @@ async fn error_document_add_create_index_bad_uid() {
let index = server.index("883 fj!"); let index = server.index("883 fj!");
let (response, code) = index.add_documents(json!([{"id": 1}]), None).await; let (response, code) = index.add_documents(json!([{"id": 1}]), None).await;
let expected_response = json!({ snapshot!(code, @"400 Bad Request");
"message": "`883 fj!` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_).", snapshot!(json_string!(response),
"code": "invalid_index_uid", @r###"
"type": "invalid_request", {
"link": "https://docs.meilisearch.com/errors#invalid_index_uid" "message": "`883 fj!` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_).",
}); "code": "invalid_index_uid",
"type": "invalid_request",
assert_eq!(code, 400); "link": "https://docs.meilisearch.com/errors#invalid_index_uid"
assert_eq!(response, expected_response); }
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -658,21 +754,53 @@ async fn document_addition_with_primary_key() {
} }
]); ]);
let (response, code) = index.add_documents(documents, Some("primary")).await; let (response, code) = index.add_documents(documents, Some("primary")).await;
assert_eq!(code, 202, "response: {}", response); snapshot!(code, @"202 Accepted");
snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 0,
"indexUid": "test",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
index.wait_task(0).await; index.wait_task(0).await;
let (response, code) = index.get_task(0).await; let (response, code) = index.get_task(0).await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["status"], "succeeded"); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
assert_eq!(response["uid"], 0); @r###"
assert_eq!(response["type"], "documentAdditionOrUpdate"); {
assert_eq!(response["details"]["receivedDocuments"], 1); "uid": 0,
assert_eq!(response["details"]["indexedDocuments"], 1); "indexUid": "test",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
"###);
let (response, code) = index.get().await; let (response, code) = index.get().await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["primaryKey"], "primary"); snapshot!(json_string!(response, { ".createdAt" => "[date]", ".updatedAt" => "[date]" }),
@r###"
{
"uid": "test",
"createdAt": "[date]",
"updatedAt": "[date]",
"primaryKey": "primary"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -688,7 +816,17 @@ async fn replace_document() {
]); ]);
let (response, code) = index.add_documents(documents, None).await; let (response, code) = index.add_documents(documents, None).await;
assert_eq!(code, 202, "response: {}", response); snapshot!(code,@"202 Accepted");
snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"taskUid": 0,
"indexUid": "test",
"status": "enqueued",
"type": "documentAdditionOrUpdate",
"enqueuedAt": "[date]"
}
"###);
index.wait_task(0).await; index.wait_task(0).await;
@ -700,17 +838,41 @@ async fn replace_document() {
]); ]);
let (_response, code) = index.add_documents(documents, None).await; let (_response, code) = index.add_documents(documents, None).await;
assert_eq!(code, 202); snapshot!(code,@"202 Accepted");
index.wait_task(1).await; index.wait_task(1).await;
let (response, code) = index.get_task(1).await; let (response, code) = index.get_task(1).await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["status"], "succeeded"); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"uid": 1,
"indexUid": "test",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
"###);
let (response, code) = index.get_document(1, None).await; let (response, code) = index.get_document(1, None).await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response.to_string(), r##"{"doc_id":1,"other":"bar"}"##); snapshot!(json_string!(response),
@r###"
{
"doc_id": 1,
"other": "bar"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -718,7 +880,7 @@ async fn add_no_documents() {
let server = Server::new().await; let server = Server::new().await;
let index = server.index("test"); let index = server.index("test");
let (_response, code) = index.add_documents(json!([]), None).await; let (_response, code) = index.add_documents(json!([]), None).await;
assert_eq!(code, 202); snapshot!(code, @"202 Accepted");
} }
#[actix_rt::test] #[actix_rt::test]
@ -769,20 +931,31 @@ async fn error_add_documents_bad_document_id() {
index.add_documents(documents, None).await; index.add_documents(documents, None).await;
index.wait_task(1).await; index.wait_task(1).await;
let (response, code) = index.get_task(1).await; let (response, code) = index.get_task(1).await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["status"], json!("failed")); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
assert_eq!( @r###"
response["error"]["message"], {
json!( "uid": 1,
r#"Document identifier `"foo & bar"` is invalid. A document identifier can be of type integer or string, only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and underscores (_)."# "indexUid": "test",
) "status": "failed",
); "type": "documentAdditionOrUpdate",
assert_eq!(response["error"]["code"], json!("invalid_document_id")); "canceledBy": null,
assert_eq!(response["error"]["type"], json!("invalid_request")); "details": {
assert_eq!( "receivedDocuments": 1,
response["error"]["link"], "indexedDocuments": 1
json!("https://docs.meilisearch.com/errors#invalid_document_id") },
); "error": {
"message": "Document identifier `\"foo & bar\"` is invalid. A document identifier can be of type integer or string, only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and underscores (_).",
"code": "invalid_document_id",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_id"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -799,18 +972,31 @@ async fn error_add_documents_missing_document_id() {
index.add_documents(documents, None).await; index.add_documents(documents, None).await;
index.wait_task(1).await; index.wait_task(1).await;
let (response, code) = index.get_task(1).await; let (response, code) = index.get_task(1).await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["status"], "failed"); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
assert_eq!( @r###"
response["error"]["message"], {
json!(r#"Document doesn't have a `docid` attribute: `{"id":"11","content":"foobar"}`."#) "uid": 1,
); "indexUid": "test",
assert_eq!(response["error"]["code"], json!("missing_document_id")); "status": "failed",
assert_eq!(response["error"]["type"], json!("invalid_request")); "type": "documentAdditionOrUpdate",
assert_eq!( "canceledBy": null,
response["error"]["link"], "details": {
json!("https://docs.meilisearch.com/errors#missing_document_id") "receivedDocuments": 1,
); "indexedDocuments": 1
},
"error": {
"message": "Document doesn't have a `docid` attribute: `{\"id\":\"11\",\"content\":\"foobar\"}`.",
"code": "missing_document_id",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_document_id"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -831,22 +1017,14 @@ async fn error_document_field_limit_reached() {
let documents = json!([big_object]); let documents = json!([big_object]);
let (_response, code) = index.update_documents(documents, Some("id")).await; let (_response, code) = index.update_documents(documents, Some("id")).await;
assert_eq!(code, 202); snapshot!(code, @"202");
index.wait_task(0).await; index.wait_task(0).await;
let (response, code) = index.get_task(0).await; let (response, code) = index.get_task(0).await;
assert_eq!(code, 200); snapshot!(code, @"200");
// Documents without a primary key are not accepted. // Documents without a primary key are not accepted.
assert_eq!(response["status"], "failed"); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@"");
let expected_error = json!({
"message": "A document cannot contain more than 65,535 fields.",
"code": "document_fields_limit_reached",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#document_fields_limit_reached"
});
assert_eq!(response["error"], expected_error);
} }
#[actix_rt::test] #[actix_rt::test]
@ -866,8 +1044,31 @@ async fn add_documents_invalid_geo_field() {
index.add_documents(documents, None).await; index.add_documents(documents, None).await;
index.wait_task(2).await; index.wait_task(2).await;
let (response, code) = index.get_task(2).await; let (response, code) = index.get_task(2).await;
assert_eq!(code, 200); snapshot!(code, @"200 OK");
assert_eq!(response["status"], "failed"); snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###"
{
"uid": 2,
"indexUid": "test",
"status": "failed",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": {
"message": "The `_geo` field in the document with the id: `11` is not an object. Was expecting an object with the `_geo.lat` and `_geo.lng` fields but instead got `\"foobar\"`.",
"code": "invalid_document_geo_field",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_geo_field"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -885,15 +1086,16 @@ async fn error_add_documents_payload_size() {
let documents = json!(documents); let documents = json!(documents);
let (response, code) = index.add_documents(documents, None).await; let (response, code) = index.add_documents(documents, None).await;
let expected_response = json!({ snapshot!(code, @"413 Payload Too Large");
"message": "The provided payload reached the size limit.", snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
"code": "payload_too_large", @r###"
"type": "invalid_request", {
"link": "https://docs.meilisearch.com/errors#payload_too_large" "message": "The provided payload reached the size limit.",
}); "code": "payload_too_large",
"type": "invalid_request",
assert_eq!(response, expected_response); "link": "https://docs.meilisearch.com/errors#payload_too_large"
assert_eq!(code, 413); }
"###);
} }
#[actix_rt::test] #[actix_rt::test]
@ -913,7 +1115,7 @@ async fn error_primary_key_inference() {
let (response, code) = index.get_task(0).await; let (response, code) = index.get_task(0).await;
assert_eq!(code, 200); assert_eq!(code, 200);
insta::assert_json_snapshot!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }, snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###" @r###"
{ {
"uid": 0, "uid": 0,
@ -953,7 +1155,7 @@ async fn error_primary_key_inference() {
let (response, code) = index.get_task(1).await; let (response, code) = index.get_task(1).await;
assert_eq!(code, 200); assert_eq!(code, 200);
insta::assert_json_snapshot!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }, snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###" @r###"
{ {
"uid": 1, "uid": 1,
@ -991,7 +1193,7 @@ async fn error_primary_key_inference() {
let (response, code) = index.get_task(2).await; let (response, code) = index.get_task(2).await;
assert_eq!(code, 200); assert_eq!(code, 200);
insta::assert_json_snapshot!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }, snapshot!(json_string!(response, { ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" }),
@r###" @r###"
{ {
"uid": 2, "uid": 2,