3461: Bring v1 changes into main r=curquiza a=Kerollmops

Also bring back changes in milli (the remote repository) into main done during the pre-release

Co-authored-by: Loïc Lecrenier <loic.lecrenier@me.com>
Co-authored-by: bors[bot] <26634292+bors[bot]@users.noreply.github.com>
Co-authored-by: curquiza <curquiza@users.noreply.github.com>
Co-authored-by: Tamo <tamo@meilisearch.com>
Co-authored-by: Philipp Ahlner <philipp@ahlner.com>
Co-authored-by: Kerollmops <clement@meilisearch.com>
This commit is contained in:
bors[bot] 2023-02-07 11:27:27 +00:00 committed by GitHub
commit c88c3637b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
142 changed files with 7451 additions and 2398 deletions

View file

@ -205,7 +205,7 @@ async fn error_add_api_key_no_header() {
"message": "The Authorization header is missing. It must use the bearer authorization method.",
"code": "missing_authorization_header",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-authorization-header"
"link": "https://docs.meilisearch.com/errors#missing_authorization_header"
}
"###);
}
@ -228,7 +228,7 @@ async fn error_add_api_key_bad_key() {
"message": "The provided API key is invalid.",
"code": "invalid_api_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#invalid-api-key"
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
}
"###);
}
@ -248,10 +248,10 @@ async fn error_add_api_key_missing_parameter() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Json deserialize error: missing field `indexes` at ``",
"code": "bad_request",
"message": "Missing field `indexes`",
"code": "missing_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#missing_api_key_indexes"
}
"###);
@ -265,10 +265,10 @@ async fn error_add_api_key_missing_parameter() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Json deserialize error: missing field `actions` at ``",
"code": "bad_request",
"message": "Missing field `actions`",
"code": "missing_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#missing_api_key_actions"
}
"###);
@ -279,22 +279,13 @@ async fn error_add_api_key_missing_parameter() {
"actions": ["documents.add"],
});
let (response, code) = server.add_api_key(content).await;
meili_snap::snapshot!(code, @"201 Created");
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]", ".uid" => "[ignored]", ".key" => "[ignored]" }), @r###"
{
"name": null,
"description": "Indexing API key",
"key": "[ignored]",
"uid": "[ignored]",
"actions": [
"documents.add"
],
"indexes": [
"products"
],
"expiresAt": null,
"createdAt": "[ignored]",
"updatedAt": "[ignored]"
"message": "Missing field `expiresAt`",
"code": "missing_api_key_expires_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_api_key_expires_at"
}
"###);
}
@ -314,10 +305,10 @@ async fn error_add_api_key_invalid_parameters_description() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid type: Map `{\"name\":\"products\"}`, expected a String at `.description`.",
"message": "Invalid value type at `.description`: expected a string, but found an object: `{\"name\":\"products\"}`",
"code": "invalid_api_key_description",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-description"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_description"
}
"###);
}
@ -337,10 +328,10 @@ async fn error_add_api_key_invalid_parameters_name() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid type: Map `{\"name\":\"products\"}`, expected a String at `.name`.",
"message": "Invalid value type at `.name`: expected a string, but found an object: `{\"name\":\"products\"}`",
"code": "invalid_api_key_name",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-name"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_name"
}
"###);
}
@ -360,10 +351,10 @@ async fn error_add_api_key_invalid_parameters_indexes() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid type: Map `{\"name\":\"products\"}`, expected a Sequence at `.indexes`.",
"message": "Invalid value type at `.indexes`: expected an array, but found an object: `{\"name\":\"products\"}`",
"code": "invalid_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-indexes"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_indexes"
}
"###);
}
@ -386,10 +377,10 @@ async fn error_add_api_key_invalid_index_uids() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "`invalid index # / \\name with spaces` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_). at `.indexes[0]`.",
"message": "Invalid value at `.indexes[0]`: `invalid index # / \\name with spaces` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_).",
"code": "invalid_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-indexes"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_indexes"
}
"###);
}
@ -411,10 +402,10 @@ async fn error_add_api_key_invalid_parameters_actions() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid type: Map `{\"name\":\"products\"}`, expected a Sequence at `.actions`.",
"message": "Invalid value type at `.actions`: expected an array, but found an object: `{\"name\":\"products\"}`",
"code": "invalid_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-actions"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_actions"
}
"###);
@ -431,10 +422,10 @@ async fn error_add_api_key_invalid_parameters_actions() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Json deserialize error: unknown value `doc.add`, expected one of `*`, `search`, `documents.*`, `documents.add`, `documents.get`, `documents.delete`, `indexes.*`, `indexes.create`, `indexes.get`, `indexes.update`, `indexes.delete`, `indexes.swap`, `tasks.*`, `tasks.cancel`, `tasks.delete`, `tasks.get`, `settings.*`, `settings.get`, `settings.update`, `stats.*`, `stats.get`, `metrics.*`, `metrics.get`, `dumps.*`, `dumps.create`, `version`, `keys.create`, `keys.get`, `keys.update`, `keys.delete` at `.actions[0]`.",
"message": "Unknown value `doc.add` at `.actions[0]`: expected one of `*`, `search`, `documents.*`, `documents.add`, `documents.get`, `documents.delete`, `indexes.*`, `indexes.create`, `indexes.get`, `indexes.update`, `indexes.delete`, `indexes.swap`, `tasks.*`, `tasks.cancel`, `tasks.delete`, `tasks.get`, `settings.*`, `settings.get`, `settings.update`, `stats.*`, `stats.get`, `metrics.*`, `metrics.get`, `dumps.*`, `dumps.create`, `version`, `keys.create`, `keys.get`, `keys.update`, `keys.delete`",
"code": "invalid_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-actions"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_actions"
}
"###);
}
@ -455,10 +446,10 @@ async fn error_add_api_key_invalid_parameters_expires_at() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid type: Map `{\"name\":\"products\"}`, expected a String at `.expiresAt`.",
"message": "Invalid value type at `.expiresAt`: expected a string, but found an object: `{\"name\":\"products\"}`",
"code": "invalid_api_key_expires_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-expires-at"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_expires_at"
}
"###);
}
@ -478,10 +469,10 @@ async fn error_add_api_key_invalid_parameters_expires_at_in_the_past() {
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "`2010-11-13T00:00:00Z` is not a valid date. It should follow the RFC 3339 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'.\n at `.expiresAt`.",
"message": "Invalid value at `.expiresAt`: `2010-11-13T00:00:00Z` is not a valid date. It should follow the RFC 3339 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'.\n",
"code": "invalid_api_key_expires_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-expires-at"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_expires_at"
}
"###);
meili_snap::snapshot!(code, @"400 Bad Request");
@ -503,10 +494,10 @@ async fn error_add_api_key_invalid_parameters_uid() {
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid length: expected length 32 for simple format, found 13 at `.uid`.",
"message": "Invalid value at `.uid`: invalid length: expected length 32 for simple format, found 13",
"code": "invalid_api_key_uid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-uid"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_uid"
}
"###);
meili_snap::snapshot!(code, @"400 Bad Request");
@ -551,7 +542,7 @@ async fn error_add_api_key_parameters_uid_already_exist() {
"message": "`uid` field value `4bc0887a-0e41-4f3b-935d-0c451dcee9c8` is already an existing API key.",
"code": "api_key_already_exists",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#api-key-already-exists"
"link": "https://docs.meilisearch.com/errors#api_key_already_exists"
}
"###);
meili_snap::snapshot!(code, @"409 Conflict");
@ -697,7 +688,7 @@ async fn error_get_api_key_no_header() {
"message": "The Authorization header is missing. It must use the bearer authorization method.",
"code": "missing_authorization_header",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-authorization-header"
"link": "https://docs.meilisearch.com/errors#missing_authorization_header"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -716,7 +707,7 @@ async fn error_get_api_key_bad_key() {
"message": "The provided API key is invalid.",
"code": "invalid_api_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#invalid-api-key"
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
}
"###);
meili_snap::snapshot!(code, @"403 Forbidden");
@ -735,7 +726,7 @@ async fn error_get_api_key_not_found() {
"message": "API key `d0552b41d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4` not found.",
"code": "api_key_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#api-key-not-found"
"link": "https://docs.meilisearch.com/errors#api_key_not_found"
}
"###);
meili_snap::snapshot!(code, @"404 Not Found");
@ -799,7 +790,7 @@ async fn list_api_keys() {
"###);
meili_snap::snapshot!(code, @"201 Created");
let (response, code) = server.list_api_keys().await;
let (response, code) = server.list_api_keys("").await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".results[].createdAt" => "[ignored]", ".results[].updatedAt" => "[ignored]", ".results[].uid" => "[ignored]", ".results[].key" => "[ignored]" }), @r###"
{
"results": [
@ -873,13 +864,13 @@ async fn list_api_keys() {
async fn error_list_api_keys_no_header() {
let server = Server::new_auth().await;
let (response, code) = server.list_api_keys().await;
let (response, code) = server.list_api_keys("").await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "The Authorization header is missing. It must use the bearer authorization method.",
"code": "missing_authorization_header",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-authorization-header"
"link": "https://docs.meilisearch.com/errors#missing_authorization_header"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -890,13 +881,13 @@ async fn error_list_api_keys_bad_key() {
let mut server = Server::new_auth().await;
server.use_api_key("d4000bd7225f77d1eb22cc706ed36772bbc36767c016a27f76def7537b68600d");
let (response, code) = server.list_api_keys().await;
let (response, code) = server.list_api_keys("").await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "The provided API key is invalid.",
"code": "invalid_api_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#invalid-api-key"
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
}
"###);
meili_snap::snapshot!(code, @"403 Forbidden");
@ -973,7 +964,7 @@ async fn delete_api_key() {
"message": "[ignored]",
"code": "api_key_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#api-key-not-found"
"link": "https://docs.meilisearch.com/errors#api_key_not_found"
}
"###);
meili_snap::snapshot!(code, @"404 Not Found");
@ -992,7 +983,7 @@ async fn error_delete_api_key_no_header() {
"message": "The Authorization header is missing. It must use the bearer authorization method.",
"code": "missing_authorization_header",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-authorization-header"
"link": "https://docs.meilisearch.com/errors#missing_authorization_header"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -1011,7 +1002,7 @@ async fn error_delete_api_key_bad_key() {
"message": "The provided API key is invalid.",
"code": "invalid_api_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#invalid-api-key"
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
}
"###);
meili_snap::snapshot!(code, @"403 Forbidden");
@ -1030,7 +1021,7 @@ async fn error_delete_api_key_not_found() {
"message": "API key `d0552b41d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4` not found.",
"code": "api_key_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#api-key-not-found"
"link": "https://docs.meilisearch.com/errors#api_key_not_found"
}
"###);
meili_snap::snapshot!(code, @"404 Not Found");
@ -1089,14 +1080,14 @@ async fn patch_api_key_description() {
let uid = response["uid"].as_str().unwrap();
// Add a description
let content = json!({ "description": "Indexing API key" });
// Add a description and a name
let content = json!({ "description": "Indexing API key", "name": "bob" });
thread::sleep(time::Duration::new(1, 0));
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]", ".uid" => "[ignored]", ".key" => "[ignored]" }), @r###"
{
"name": null,
"name": "bob",
"description": "Indexing API key",
"key": "[ignored]",
"uid": "[ignored]",
@ -1128,7 +1119,7 @@ async fn patch_api_key_description() {
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]", ".uid" => "[ignored]", ".key" => "[ignored]" }), @r###"
{
"name": null,
"name": "bob",
"description": "Product API key",
"key": "[ignored]",
"uid": "[ignored]",
@ -1160,7 +1151,7 @@ async fn patch_api_key_description() {
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]", ".uid" => "[ignored]", ".key" => "[ignored]" }), @r###"
{
"name": null,
"name": "bob",
"description": null,
"key": "[ignored]",
"uid": "[ignored]",
@ -1242,15 +1233,15 @@ async fn patch_api_key_name() {
let created_at = response["createdAt"].as_str().unwrap();
let updated_at = response["updatedAt"].as_str().unwrap();
// Add a name
let content = json!({ "name": "Indexing API key" });
// Add a name and description
let content = json!({ "name": "Indexing API key", "description": "The doggoscription" });
thread::sleep(time::Duration::new(1, 0));
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]", ".uid" => "[ignored]", ".key" => "[ignored]" }), @r###"
{
"name": "Indexing API key",
"description": null,
"description": "The doggoscription",
"key": "[ignored]",
"uid": "[ignored]",
"actions": [
@ -1285,7 +1276,7 @@ async fn patch_api_key_name() {
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]", ".uid" => "[ignored]", ".key" => "[ignored]" }), @r###"
{
"name": "Product API key",
"description": null,
"description": "The doggoscription",
"key": "[ignored]",
"uid": "[ignored]",
"actions": [
@ -1311,13 +1302,13 @@ async fn patch_api_key_name() {
meili_snap::snapshot!(code, @"200 OK");
// Remove the name
let content = json!({ "name": serde_json::Value::Null });
let content = json!({ "name": null });
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]", ".uid" => "[ignored]", ".key" => "[ignored]" }), @r###"
{
"name": null,
"description": null,
"description": "The doggoscription",
"key": "[ignored]",
"uid": "[ignored]",
"actions": [
@ -1403,10 +1394,10 @@ async fn error_patch_api_key_indexes() {
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Json deserialize error: unknown field `indexes`, expected one of `description`, `name` at ``.",
"message": "Immutable field `indexes`: expected one of `description`, `name`",
"code": "immutable_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable-api-key-indexes"
"link": "https://docs.meilisearch.com/errors#immutable_api_key_indexes"
}
"###);
meili_snap::snapshot!(code, @"400 Bad Request");
@ -1480,10 +1471,10 @@ async fn error_patch_api_key_actions() {
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Json deserialize error: unknown field `actions`, expected one of `description`, `name` at ``.",
"message": "Immutable field `actions`: expected one of `description`, `name`",
"code": "immutable_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable-api-key-actions"
"link": "https://docs.meilisearch.com/errors#immutable_api_key_actions"
}
"###);
meili_snap::snapshot!(code, @"400 Bad Request");
@ -1549,10 +1540,10 @@ async fn error_patch_api_key_expiration_date() {
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Json deserialize error: unknown field `expiresAt`, expected one of `description`, `name` at ``.",
"message": "Immutable field `expiresAt`: expected one of `description`, `name`",
"code": "immutable_api_key_expires_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable-api-key-expires-at"
"link": "https://docs.meilisearch.com/errors#immutable_api_key_expires_at"
}
"###);
meili_snap::snapshot!(code, @"400 Bad Request");
@ -1574,7 +1565,7 @@ async fn error_patch_api_key_no_header() {
"message": "The Authorization header is missing. It must use the bearer authorization method.",
"code": "missing_authorization_header",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-authorization-header"
"link": "https://docs.meilisearch.com/errors#missing_authorization_header"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -1597,7 +1588,7 @@ async fn error_patch_api_key_bad_key() {
"message": "The provided API key is invalid.",
"code": "invalid_api_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#invalid-api-key"
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
}
"###);
meili_snap::snapshot!(code, @"403 Forbidden");
@ -1620,7 +1611,7 @@ async fn error_patch_api_key_not_found() {
"message": "API key `d0552b41d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4` not found.",
"code": "api_key_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#api-key-not-found"
"link": "https://docs.meilisearch.com/errors#api_key_not_found"
}
"###);
meili_snap::snapshot!(code, @"404 Not Found");
@ -1670,10 +1661,10 @@ async fn error_patch_api_key_indexes_invalid_parameters() {
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid type: Integer `13`, expected a String at `.description`.",
"message": "Invalid value type at `.description`: expected a string, but found a positive integer: `13`",
"code": "invalid_api_key_description",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-description"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_description"
}
"###);
meili_snap::snapshot!(code, @"400 Bad Request");
@ -1686,10 +1677,10 @@ async fn error_patch_api_key_indexes_invalid_parameters() {
let (response, code) = server.patch_api_key(&uid, content).await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "invalid type: Integer `13`, expected a String at `.name`.",
"message": "Invalid value type at `.name`: expected a string, but found a positive integer: `13`",
"code": "invalid_api_key_name",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-api-key-name"
"link": "https://docs.meilisearch.com/errors#invalid_api_key_name"
}
"###);
meili_snap::snapshot!(code, @"400 Bad Request");
@ -1705,7 +1696,7 @@ async fn error_access_api_key_routes_no_master_key_set() {
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -1716,7 +1707,7 @@ async fn error_access_api_key_routes_no_master_key_set() {
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -1727,18 +1718,18 @@ async fn error_access_api_key_routes_no_master_key_set() {
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
let (response, code) = server.list_api_keys().await;
let (response, code) = server.list_api_keys("").await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -1751,7 +1742,7 @@ async fn error_access_api_key_routes_no_master_key_set() {
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -1762,7 +1753,7 @@ async fn error_access_api_key_routes_no_master_key_set() {
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
@ -1773,18 +1764,18 @@ async fn error_access_api_key_routes_no_master_key_set() {
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");
let (response, code) = server.list_api_keys().await;
let (response, code) = server.list_api_keys("").await;
meili_snap::snapshot!(meili_snap::json_string!(response, { ".createdAt" => "[ignored]", ".updatedAt" => "[ignored]" }), @r###"
{
"message": "Meilisearch is running without a master key. To access this API endpoint, you must have set a master key at launch.",
"code": "missing_master_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#missing-master-key"
"link": "https://docs.meilisearch.com/errors#missing_master_key"
}
"###);
meili_snap::snapshot!(code, @"401 Unauthorized");

View file

@ -73,7 +73,7 @@ static INVALID_RESPONSE: Lazy<Value> = Lazy::new(|| {
json!({"message": "The provided API key is invalid.",
"code": "invalid_api_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#invalid-api-key"
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
})
});
@ -520,7 +520,7 @@ async fn error_creating_index_without_action() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
// try to create a index via add documents route

View file

@ -0,0 +1,438 @@
use meili_snap::*;
use serde_json::json;
use uuid::Uuid;
use crate::common::Server;
#[actix_rt::test]
async fn create_api_key_bad_description() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.add_api_key(json!({ "description": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.description`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_api_key_description",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_description"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_bad_name() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.add_api_key(json!({ "name": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.name`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_api_key_name",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_name"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_bad_uid() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
// bad type
let (response, code) = server.add_api_key(json!({ "uid": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.uid`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_api_key_uid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_uid"
}
"###);
// can't parse
let (response, code) = server.add_api_key(json!({ "uid": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value at `.uid`: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `o` at 2",
"code": "invalid_api_key_uid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_uid"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_bad_actions() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
// bad type
let (response, code) = server.add_api_key(json!({ "actions": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.actions`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_actions"
}
"###);
// can't parse
let (response, code) = server.add_api_key(json!({ "actions": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown value `doggo` at `.actions[0]`: expected one of `*`, `search`, `documents.*`, `documents.add`, `documents.get`, `documents.delete`, `indexes.*`, `indexes.create`, `indexes.get`, `indexes.update`, `indexes.delete`, `indexes.swap`, `tasks.*`, `tasks.cancel`, `tasks.delete`, `tasks.get`, `settings.*`, `settings.get`, `settings.update`, `stats.*`, `stats.get`, `metrics.*`, `metrics.get`, `dumps.*`, `dumps.create`, `version`, `keys.create`, `keys.get`, `keys.update`, `keys.delete`",
"code": "invalid_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_actions"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_bad_indexes() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
// bad type
let (response, code) = server.add_api_key(json!({ "indexes": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.indexes`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_indexes"
}
"###);
// can't parse
let (response, code) = server.add_api_key(json!({ "indexes": ["good doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value at `.indexes[0]`: `good doggo` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_).",
"code": "invalid_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_indexes"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_bad_expires_at() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
// bad type
let (response, code) = server.add_api_key(json!({ "expires_at": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown field `expires_at`: expected one of `description`, `name`, `uid`, `actions`, `indexes`, `expiresAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
// can't parse
let (response, code) = server.add_api_key(json!({ "expires_at": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown field `expires_at`: expected one of `description`, `name`, `uid`, `actions`, `indexes`, `expiresAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_missing_action() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) =
server.add_api_key(json!({ "indexes": ["doggo"], "expiresAt": null })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Missing field `actions`",
"code": "missing_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_api_key_actions"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_missing_indexes() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server
.add_api_key(json!({ "uid": Uuid::nil() , "actions": ["*"], "expiresAt": null }))
.await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Missing field `indexes`",
"code": "missing_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_api_key_indexes"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_missing_expires_at() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server
.add_api_key(json!({ "uid": Uuid::nil(), "actions": ["*"], "indexes": ["doggo"] }))
.await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Missing field `expiresAt`",
"code": "missing_api_key_expires_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_api_key_expires_at"
}
"###);
}
#[actix_rt::test]
async fn create_api_key_unexpected_field() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server
.add_api_key(json!({ "uid": Uuid::nil(), "actions": ["*"], "indexes": ["doggo"], "expiresAt": null, "doggo": "bork" }))
.await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown field `doggo`: expected one of `description`, `name`, `uid`, `actions`, `indexes`, `expiresAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
#[actix_rt::test]
async fn list_api_keys_bad_offset() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.list_api_keys("?offset=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `offset`: could not parse `doggo` as a positive integer",
"code": "invalid_api_key_offset",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_offset"
}
"###);
}
#[actix_rt::test]
async fn list_api_keys_bad_limit() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.list_api_keys("?limit=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `limit`: could not parse `doggo` as a positive integer",
"code": "invalid_api_key_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_limit"
}
"###);
}
#[actix_rt::test]
async fn list_api_keys_unexpected_field() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.list_api_keys("?doggo=no_limit").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown parameter `doggo`: expected one of `offset`, `limit`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_bad_description() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "description": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.description`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_api_key_description",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_description"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_bad_name() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "name": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.name`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_api_key_name",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_api_key_name"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_immutable_uid() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "uid": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `uid`: expected one of `description`, `name`",
"code": "immutable_api_key_uid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_api_key_uid"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_immutable_actions() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "actions": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `actions`: expected one of `description`, `name`",
"code": "immutable_api_key_actions",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_api_key_actions"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_immutable_indexes() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "indexes": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `indexes`: expected one of `description`, `name`",
"code": "immutable_api_key_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_api_key_indexes"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_immutable_expires_at() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "expiresAt": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `expiresAt`: expected one of `description`, `name`",
"code": "immutable_api_key_expires_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_api_key_expires_at"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_immutable_created_at() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "createdAt": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `createdAt`: expected one of `description`, `name`",
"code": "immutable_api_key_created_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_api_key_created_at"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_immutable_updated_at() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "updatedAt": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `updatedAt`: expected one of `description`, `name`",
"code": "immutable_api_key_updated_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_api_key_updated_at"
}
"###);
}
#[actix_rt::test]
async fn patch_api_keys_unknown_field() {
let mut server = Server::new_auth().await;
server.use_admin_key("MASTER_KEY").await;
let (response, code) = server.patch_api_key("doggo", json!({ "doggo": "bork" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown field `doggo`: expected one of `description`, `name`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}

View file

@ -1,5 +1,6 @@
mod api_keys;
mod authorization;
mod errors;
mod payload;
mod tenant_token;
@ -16,7 +17,7 @@ impl Server {
/// Fetch and use the default admin key for nexts http requests.
pub async fn use_admin_key(&mut self, master_key: impl AsRef<str>) {
self.use_api_key(master_key);
let (response, code) = self.list_api_keys().await;
let (response, code) = self.list_api_keys("").await;
assert_eq!(200, code, "{:?}", response);
let admin_key = &response["results"][1]["key"];
self.use_api_key(admin_key.as_str().unwrap());
@ -37,8 +38,8 @@ impl Server {
self.service.patch(url, content).await
}
pub async fn list_api_keys(&self) -> (Value, StatusCode) {
let url = "/keys";
pub async fn list_api_keys(&self, params: &str) -> (Value, StatusCode) {
let url = format!("/keys{params}");
self.service.get(url).await
}

View file

@ -37,7 +37,7 @@ async fn error_api_key_bad_content_types() {
);
assert_eq!(response["code"], "invalid_content_type");
assert_eq!(response["type"], "invalid_request");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid-content-type");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid_content_type");
// patch
let req = test::TestRequest::patch()
@ -59,7 +59,7 @@ async fn error_api_key_bad_content_types() {
);
assert_eq!(response["code"], "invalid_content_type");
assert_eq!(response["type"], "invalid_request");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid-content-type");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid_content_type");
}
#[actix_rt::test]
@ -96,7 +96,7 @@ async fn error_api_key_empty_content_types() {
);
assert_eq!(response["code"], "invalid_content_type");
assert_eq!(response["type"], "invalid_request");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid-content-type");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid_content_type");
// patch
let req = test::TestRequest::patch()
@ -118,7 +118,7 @@ async fn error_api_key_empty_content_types() {
);
assert_eq!(response["code"], "invalid_content_type");
assert_eq!(response["type"], "invalid_request");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid-content-type");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#invalid_content_type");
}
#[actix_rt::test]
@ -154,7 +154,7 @@ async fn error_api_key_missing_content_types() {
);
assert_eq!(response["code"], "missing_content_type");
assert_eq!(response["type"], "invalid_request");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#missing-content-type");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#missing_content_type");
// patch
let req = test::TestRequest::patch()
@ -175,7 +175,7 @@ async fn error_api_key_missing_content_types() {
);
assert_eq!(response["code"], "missing_content_type");
assert_eq!(response["type"], "invalid_request");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#missing-content-type");
assert_eq!(response["link"], "https://docs.meilisearch.com/errors#missing_content_type");
}
#[actix_rt::test]
@ -200,7 +200,7 @@ async fn error_api_key_empty_payload() {
assert_eq!(status_code, 400);
assert_eq!(response["code"], json!("missing_payload"));
assert_eq!(response["type"], json!("invalid_request"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing-payload"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload"));
assert_eq!(response["message"], json!(r#"A json payload is missing."#));
// patch
@ -217,7 +217,7 @@ async fn error_api_key_empty_payload() {
assert_eq!(status_code, 400);
assert_eq!(response["code"], json!("missing_payload"));
assert_eq!(response["type"], json!("invalid_request"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing-payload"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#missing_payload"));
assert_eq!(response["message"], json!(r#"A json payload is missing."#));
}
@ -243,7 +243,7 @@ async fn error_api_key_malformed_payload() {
assert_eq!(status_code, 400);
assert_eq!(response["code"], json!("malformed_payload"));
assert_eq!(response["type"], json!("invalid_request"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed-payload"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload"));
assert_eq!(
response["message"],
json!(
@ -265,7 +265,7 @@ async fn error_api_key_malformed_payload() {
assert_eq!(status_code, 400);
assert_eq!(response["code"], json!("malformed_payload"));
assert_eq!(response["type"], json!("invalid_request"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed-payload"));
assert_eq!(response["link"], json!("https://docs.meilisearch.com/errors#malformed_payload"));
assert_eq!(
response["message"],
json!(

View file

@ -56,7 +56,7 @@ static INVALID_RESPONSE: Lazy<Value> = Lazy::new(|| {
json!({"message": "The provided API key is invalid.",
"code": "invalid_api_key",
"type": "auth",
"link": "https://docs.meilisearch.com/errors#invalid-api-key"
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
})
});

View file

@ -63,6 +63,11 @@ impl Index<'_> {
self.service.post_encoded("/indexes", body, self.encoder).await
}
pub async fn update_raw(&self, body: Value) -> (Value, StatusCode) {
let url = format!("/indexes/{}", urlencode(self.uid.as_ref()));
self.service.patch_encoded(url, body, self.encoder).await
}
pub async fn update(&self, primary_key: Option<&str>) -> (Value, StatusCode) {
let body = json!({
"primaryKey": primary_key,
@ -132,7 +137,12 @@ impl Index<'_> {
self.service.get(url).await
}
pub async fn filtered_tasks(&self, types: &[&str], statuses: &[&str]) -> (Value, StatusCode) {
pub async fn filtered_tasks(
&self,
types: &[&str],
statuses: &[&str],
canceled_by: &[&str],
) -> (Value, StatusCode) {
let mut url = format!("/tasks?indexUids={}", self.uid);
if !types.is_empty() {
let _ = write!(url, "&types={}", types.join(","));
@ -140,6 +150,9 @@ impl Index<'_> {
if !statuses.is_empty() {
let _ = write!(url, "&statuses={}", statuses.join(","));
}
if !canceled_by.is_empty() {
let _ = write!(url, "&canceledBy={}", canceled_by.join(","));
}
self.service.get(url).await
}
@ -155,6 +168,11 @@ impl Index<'_> {
self.service.get(url).await
}
pub async fn get_all_documents_raw(&self, options: &str) -> (Value, StatusCode) {
let url = format!("/indexes/{}/documents{}", urlencode(self.uid.as_ref()), options);
self.service.get(url).await
}
pub async fn get_all_documents(&self, options: GetAllDocumentsOptions) -> (Value, StatusCode) {
let mut url = format!("/indexes/{}/documents?", urlencode(self.uid.as_ref()));
if let Some(limit) = options.limit {
@ -187,6 +205,11 @@ impl Index<'_> {
self.service.post_encoded(url, serde_json::to_value(&ids).unwrap(), self.encoder).await
}
pub async fn delete_batch_raw(&self, body: Value) -> (Value, StatusCode) {
let url = format!("/indexes/{}/documents/delete-batch", urlencode(self.uid.as_ref()));
self.service.post_encoded(url, body, self.encoder).await
}
pub async fn settings(&self) -> (Value, StatusCode) {
let url = format!("/indexes/{}/settings", urlencode(self.uid.as_ref()));
self.service.get(url).await
@ -289,8 +312,8 @@ impl Index<'_> {
eprintln!("Error with post search");
resume_unwind(e);
}
let (response, code) = self.search_get(query).await;
let query = yaup::to_string(&query).unwrap();
let (response, code) = self.search_get(&query).await;
if let Err(e) = catch_unwind(move || test(response, code)) {
eprintln!("Error with get search");
resume_unwind(e);
@ -302,9 +325,8 @@ impl Index<'_> {
self.service.post_encoded(url, query, self.encoder).await
}
pub async fn search_get(&self, query: Value) -> (Value, StatusCode) {
let params = yaup::to_string(&query).unwrap();
let url = format!("/indexes/{}/search?{}", urlencode(self.uid.as_ref()), params);
pub async fn search_get(&self, query: &str) -> (Value, StatusCode) {
let url = format!("/indexes/{}/search?{}", urlencode(self.uid.as_ref()), query);
self.service.get(url).await
}

View file

@ -95,10 +95,18 @@ impl Server {
self.index_with_encoder(uid, Encoder::Plain)
}
pub async fn create_index(&self, body: Value) -> (Value, StatusCode) {
self.service.post("/indexes", body).await
}
pub fn index_with_encoder(&self, uid: impl AsRef<str>, encoder: Encoder) -> Index<'_> {
Index { uid: uid.as_ref().to_string(), service: &self.service, encoder }
}
pub async fn list_indexes_raw(&self, parameters: &str) -> (Value, StatusCode) {
self.service.get(format!("/indexes{parameters}")).await
}
pub async fn list_indexes(
&self,
offset: Option<usize>,
@ -132,8 +140,8 @@ impl Server {
self.service.get("/tasks").await
}
pub async fn tasks_filter(&self, filter: Value) -> (Value, StatusCode) {
self.service.get(format!("/tasks?{}", yaup::to_string(&filter).unwrap())).await
pub async fn tasks_filter(&self, filter: &str) -> (Value, StatusCode) {
self.service.get(format!("/tasks?{}", filter)).await
}
pub async fn get_dump_status(&self, uid: &str) -> (Value, StatusCode) {
@ -148,14 +156,12 @@ impl Server {
self.service.post("/swap-indexes", value).await
}
pub async fn cancel_tasks(&self, value: Value) -> (Value, StatusCode) {
self.service
.post(format!("/tasks/cancel?{}", yaup::to_string(&value).unwrap()), json!(null))
.await
pub async fn cancel_tasks(&self, value: &str) -> (Value, StatusCode) {
self.service.post(format!("/tasks/cancel?{}", value), json!(null)).await
}
pub async fn delete_tasks(&self, value: Value) -> (Value, StatusCode) {
self.service.delete(format!("/tasks?{}", yaup::to_string(&value).unwrap())).await
pub async fn delete_tasks(&self, value: &str) -> (Value, StatusCode) {
self.service.delete(format!("/tasks?{}", value)).await
}
pub async fn wait_task(&self, update_id: u64) -> Value {

View file

@ -88,7 +88,7 @@ async fn error_json_bad_content_type() {
"message": r#"A Content-Type header is missing. Accepted values for the Content-Type header are: `application/json`"#,
"code": "missing_content_type",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing-content-type",
"link": "https://docs.meilisearch.com/errors#missing_content_type",
}),
"when calling the route `{}` with no content-type",
route,
@ -117,7 +117,7 @@ async fn error_json_bad_content_type() {
"message": expected_error_message,
"code": "invalid_content_type",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-content-type",
"link": "https://docs.meilisearch.com/errors#invalid_content_type",
}),
"when calling the route `{}` with a content-type of `{}`",
route,

File diff suppressed because it is too large Load diff

View file

@ -95,7 +95,7 @@ async fn error_delete_batch_unexisting_index() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
assert_eq!(code, 202);

View file

@ -0,0 +1,99 @@
use meili_snap::*;
use serde_json::json;
use crate::common::Server;
#[actix_rt::test]
async fn get_all_documents_bad_offset() {
let server = Server::new().await;
let index = server.index("test");
let (response, code) = index.get_all_documents_raw("?offset").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `offset`: could not parse `` as a positive integer",
"code": "invalid_document_offset",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_offset"
}
"###);
let (response, code) = index.get_all_documents_raw("?offset=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `offset`: could not parse `doggo` as a positive integer",
"code": "invalid_document_offset",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_offset"
}
"###);
let (response, code) = index.get_all_documents_raw("?offset=-1").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `offset`: could not parse `-1` as a positive integer",
"code": "invalid_document_offset",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_offset"
}
"###);
}
#[actix_rt::test]
async fn get_all_documents_bad_limit() {
let server = Server::new().await;
let index = server.index("test");
let (response, code) = index.get_all_documents_raw("?limit").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `limit`: could not parse `` as a positive integer",
"code": "invalid_document_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_limit"
}
"###);
let (response, code) = index.get_all_documents_raw("?limit=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `limit`: could not parse `doggo` as a positive integer",
"code": "invalid_document_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_limit"
}
"###);
let (response, code) = index.get_all_documents_raw("?limit=-1").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `limit`: could not parse `-1` as a positive integer",
"code": "invalid_document_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_document_limit"
}
"###);
}
#[actix_rt::test]
async fn delete_documents_batch() {
let server = Server::new().await;
let index = server.index("test");
let (response, code) = index.delete_batch_raw(json!("doggo")).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Json deserialize error: invalid type: string \"doggo\", expected a sequence at line 1 column 7",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}

View file

@ -27,7 +27,7 @@ async fn error_get_unexisting_document() {
"message": "Document `1` not found.",
"code": "document_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#document-not-found"
"link": "https://docs.meilisearch.com/errors#document_not_found"
});
assert_eq!(response, expected_response);
@ -90,7 +90,7 @@ async fn error_get_unexisting_index_all_documents() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
assert_eq!(response, expected_response);

View file

@ -1,4 +1,5 @@
mod add_documents;
mod delete_documents;
mod errors;
mod get_documents;
mod update_documents;

View file

@ -13,7 +13,7 @@ async fn error_document_update_create_index_bad_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",
"link": "https://docs.meilisearch.com/errors#invalid-index-uid"
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
});
assert_eq!(code, 400);
@ -167,7 +167,7 @@ async fn error_update_documents_bad_document_id() {
assert_eq!(response["error"]["type"], json!("invalid_request"));
assert_eq!(
response["error"]["link"],
json!("https://docs.meilisearch.com/errors#invalid-document-id")
json!("https://docs.meilisearch.com/errors#invalid_document_id")
);
}
@ -193,6 +193,6 @@ async fn error_update_documents_missing_document_id() {
assert_eq!(response["error"]["type"], "invalid_request");
assert_eq!(
response["error"]["link"],
"https://docs.meilisearch.com/errors#missing-document-id"
"https://docs.meilisearch.com/errors#missing_document_id"
);
}

View file

@ -98,14 +98,14 @@ async fn import_dump_v1_movie_with_settings() {
assert_eq!(code, 200);
assert_eq!(
settings,
json!({ "displayedAttributes": ["genres", "id", "overview", "poster", "release_date", "title"], "searchableAttributes": ["title", "overview"], "filterableAttributes": ["genres"], "sortableAttributes": [], "rankingRules": ["typo", "words", "proximity", "attribute", "exactness"], "stopWords": ["of", "the"], "synonyms": {}, "distinctAttribute": null, "typoTolerance": {"enabled": true, "minWordSizeForTypos": { "oneTypo": 5, "twoTypos": 9 }, "disableOnWords": [], "disableOnAttributes": [] }, "faceting": { "maxValuesPerFacet": 100 }, "pagination": { "maxTotalHits": 1000 } })
json!({ "displayedAttributes": ["genres", "id", "overview", "poster", "release_date", "title"], "searchableAttributes": ["title", "overview"], "filterableAttributes": ["genres"], "sortableAttributes": ["genres"], "rankingRules": ["typo", "words", "proximity", "attribute", "exactness"], "stopWords": ["of", "the"], "synonyms": {}, "distinctAttribute": null, "typoTolerance": {"enabled": true, "minWordSizeForTypos": { "oneTypo": 5, "twoTypos": 9 }, "disableOnWords": [], "disableOnAttributes": [] }, "faceting": { "maxValuesPerFacet": 100 }, "pagination": { "maxTotalHits": 1000 } })
);
let (tasks, code) = index.list_tasks().await;
assert_eq!(code, 200);
assert_eq!(
tasks,
json!({ "results": [{ "uid": 1, "indexUid": "indexUID", "status": "succeeded", "type": "settingsUpdate", "canceledBy": null, "details": { "displayedAttributes": ["genres", "id", "overview", "poster", "release_date", "title"], "searchableAttributes": ["title", "overview"], "filterableAttributes": ["genres"], "stopWords": ["of", "the"] }, "error": null, "duration": "PT7.288826907S", "enqueuedAt": "2021-09-08T09:34:40.882977Z", "startedAt": "2021-09-08T09:34:40.883073093Z", "finishedAt": "2021-09-08T09:34:48.1719Z"}, { "uid": 0, "indexUid": "indexUID", "status": "succeeded", "type": "documentAdditionOrUpdate", "canceledBy": null, "details": { "receivedDocuments": 0, "indexedDocuments": 31968 }, "error": null, "duration": "PT9.090735774S", "enqueuedAt": "2021-09-08T09:34:16.036101Z", "startedAt": "2021-09-08T09:34:16.261191226Z", "finishedAt": "2021-09-08T09:34:25.351927Z" }], "limit": 20, "from": 1, "next": null })
json!({ "results": [{ "uid": 1, "indexUid": "indexUID", "status": "succeeded", "type": "settingsUpdate", "canceledBy": null, "details": { "displayedAttributes": ["genres", "id", "overview", "poster", "release_date", "title"], "searchableAttributes": ["title", "overview"], "filterableAttributes": ["genres"], "sortableAttributes": ["genres"], "stopWords": ["of", "the"] }, "error": null, "duration": "PT7.288826907S", "enqueuedAt": "2021-09-08T09:34:40.882977Z", "startedAt": "2021-09-08T09:34:40.883073093Z", "finishedAt": "2021-09-08T09:34:48.1719Z"}, { "uid": 0, "indexUid": "indexUID", "status": "succeeded", "type": "documentAdditionOrUpdate", "canceledBy": null, "details": { "receivedDocuments": 0, "indexedDocuments": 31968 }, "error": null, "duration": "PT9.090735774S", "enqueuedAt": "2021-09-08T09:34:16.036101Z", "startedAt": "2021-09-08T09:34:16.261191226Z", "finishedAt": "2021-09-08T09:34:25.351927Z" }], "limit": 20, "from": 1, "next": null })
);
// finally we're just going to check that we can still get a few documents by id
@ -161,7 +161,7 @@ async fn import_dump_v1_rubygems_with_settings() {
assert_eq!(code, 200);
assert_eq!(
settings,
json!({"displayedAttributes": ["description", "id", "name", "summary", "total_downloads", "version"], "searchableAttributes": ["name", "summary"], "filterableAttributes": ["version"], "sortableAttributes": [], "rankingRules": ["typo", "words", "fame:desc", "proximity", "attribute", "exactness", "total_downloads:desc"], "stopWords": [], "synonyms": {}, "distinctAttribute": null, "typoTolerance": {"enabled": true, "minWordSizeForTypos": {"oneTypo": 5, "twoTypos": 9}, "disableOnWords": [], "disableOnAttributes": [] }, "faceting": { "maxValuesPerFacet": 100 }, "pagination": { "maxTotalHits": 1000 }})
json!({"displayedAttributes": ["description", "id", "name", "summary", "total_downloads", "version"], "searchableAttributes": ["name", "summary"], "filterableAttributes": ["version"], "sortableAttributes": ["version"], "rankingRules": ["typo", "words", "fame:desc", "proximity", "attribute", "exactness", "total_downloads:desc"], "stopWords": [], "synonyms": {}, "distinctAttribute": null, "typoTolerance": {"enabled": true, "minWordSizeForTypos": {"oneTypo": 5, "twoTypos": 9}, "disableOnWords": [], "disableOnAttributes": [] }, "faceting": { "maxValuesPerFacet": 100 }, "pagination": { "maxTotalHits": 1000 }})
);
let (tasks, code) = index.list_tasks().await;
@ -811,7 +811,7 @@ async fn import_dump_v5() {
assert_eq!(code, 200);
assert_eq!(stats, expected_stats);
let (keys, code) = server.list_api_keys().await;
let (keys, code) = server.list_api_keys("").await;
assert_eq!(code, 200);
let key = &keys["results"][0];

View file

@ -1,6 +1,7 @@
use actix_web::http::header::ContentType;
use actix_web::test;
use http::header::ACCEPT_ENCODING;
use meili_snap::{json_string, snapshot};
use serde_json::{json, Value};
use crate::common::encoder::Encoder;
@ -176,7 +177,7 @@ async fn error_create_existing_index() {
"message": "Index `test` already exists.",
"code": "index_already_exists",
"type": "invalid_request",
"link":"https://docs.meilisearch.com/errors#index-already-exists"
"link":"https://docs.meilisearch.com/errors#index_already_exists"
});
assert_eq!(response["error"], expected_response);
@ -188,13 +189,13 @@ async fn error_create_with_invalid_index_uid() {
let index = server.index("test test#!");
let (response, code) = index.create(None).await;
let expected_response = json!({
"message": "`test test#!` 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",
"link": "https://docs.meilisearch.com/errors#invalid-index-uid"
});
assert_eq!(response, expected_response);
assert_eq!(code, 400);
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value at `.uid`: `test test#!` 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",
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}

View file

@ -35,7 +35,7 @@ async fn error_delete_unexisting_index() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
let response = index.wait_task(0).await;

View file

@ -0,0 +1,265 @@
use meili_snap::*;
use serde_json::json;
use crate::common::Server;
#[actix_rt::test]
async fn get_indexes_bad_offset() {
let server = Server::new().await;
let (response, code) = server.list_indexes_raw("?offset=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `offset`: could not parse `doggo` as a positive integer",
"code": "invalid_index_offset",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_index_offset"
}
"###);
}
#[actix_rt::test]
async fn get_indexes_bad_limit() {
let server = Server::new().await;
let (response, code) = server.list_indexes_raw("?limit=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `limit`: could not parse `doggo` as a positive integer",
"code": "invalid_index_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_index_limit"
}
"###);
}
#[actix_rt::test]
async fn get_indexes_unknown_field() {
let server = Server::new().await;
let (response, code) = server.list_indexes_raw("?doggo=nolimit").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown parameter `doggo`: expected one of `offset`, `limit`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
#[actix_rt::test]
async fn create_index_missing_uid() {
let server = Server::new().await;
let (response, code) = server.create_index(json!({ "primaryKey": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Missing field `uid`",
"code": "missing_index_uid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing_index_uid"
}
"###);
}
#[actix_rt::test]
async fn create_index_bad_uid() {
let server = Server::new().await;
let (response, code) = server.create_index(json!({ "uid": "the best doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value at `.uid`: `the best doggo` 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",
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
let (response, code) = server.create_index(json!({ "uid": true })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.uid`: expected a string, but found a boolean: `true`",
"code": "invalid_index_uid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}
#[actix_rt::test]
async fn create_index_bad_primary_key() {
let server = Server::new().await;
let (response, code) = server
.create_index(json!({ "uid": "doggo", "primaryKey": ["the", "best", "doggo"] }))
.await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.primaryKey`: expected a string, but found an array: `[\"the\",\"best\",\"doggo\"]`",
"code": "invalid_index_primary_key",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_index_primary_key"
}
"###);
}
#[actix_rt::test]
async fn create_index_unknown_field() {
let server = Server::new().await;
let (response, code) = server.create_index(json!({ "uid": "doggo", "doggo": "bernese" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown field `doggo`: expected one of `uid`, `primaryKey`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
#[actix_rt::test]
async fn get_index_bad_uid() {
let server = Server::new().await;
let index = server.index("the good doggo");
let (response, code) = index.get().await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`the good doggo` 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",
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}
#[actix_rt::test]
async fn update_index_bad_primary_key() {
let server = Server::new().await;
let index = server.index("doggo");
let (response, code) = index.update_raw(json!({ "primaryKey": ["doggo"] })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.primaryKey`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_index_primary_key",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_index_primary_key"
}
"###);
}
#[actix_rt::test]
async fn update_index_immutable_uid() {
let server = Server::new().await;
let index = server.index("doggo");
let (response, code) = index.update_raw(json!({ "uid": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `uid`: expected one of `primaryKey`",
"code": "immutable_index_uid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_index_uid"
}
"###);
}
#[actix_rt::test]
async fn update_index_immutable_created_at() {
let server = Server::new().await;
let index = server.index("doggo");
let (response, code) = index.update_raw(json!({ "createdAt": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `createdAt`: expected one of `primaryKey`",
"code": "immutable_index_created_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_index_created_at"
}
"###);
}
#[actix_rt::test]
async fn update_index_immutable_updated_at() {
let server = Server::new().await;
let index = server.index("doggo");
let (response, code) = index.update_raw(json!({ "updatedAt": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Immutable field `updatedAt`: expected one of `primaryKey`",
"code": "immutable_index_updated_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#immutable_index_updated_at"
}
"###);
}
#[actix_rt::test]
async fn update_index_unknown_field() {
let server = Server::new().await;
let index = server.index("doggo");
let (response, code) = index.update_raw(json!({ "doggo": "bork" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown field `doggo`: expected one of `primaryKey`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
#[actix_rt::test]
async fn update_index_bad_uid() {
let server = Server::new().await;
let index = server.index("the good doggo");
let (response, code) = index.update_raw(json!({ "primaryKey": "doggo" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`the good doggo` 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",
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}
#[actix_rt::test]
async fn delete_index_bad_uid() {
let server = Server::new().await;
let index = server.index("the good doggo");
let (response, code) = index.delete().await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`the good doggo` 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",
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}

View file

@ -1,3 +1,4 @@
use meili_snap::{json_string, snapshot};
use serde_json::{json, Value};
use crate::common::Server;
@ -34,7 +35,7 @@ async fn error_get_unexisting_index() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
assert_eq!(response, expected_response);
@ -182,15 +183,13 @@ async fn get_invalid_index_uid() {
let index = server.index("this is not a valid index name");
let (response, code) = index.get().await;
assert_eq!(code, 404);
assert_eq!(
response,
json!(
{
"message": "Index `this is not a valid index name` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
})
);
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`this is not a valid index name` 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",
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}

View file

@ -1,5 +1,6 @@
mod create_index;
mod delete_index;
mod errors;
mod get_index;
mod stats;
mod update_index;

View file

@ -55,7 +55,7 @@ async fn error_get_stats_unexisting_index() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
assert_eq!(response, expected_response);

View file

@ -98,7 +98,7 @@ async fn error_update_existing_primary_key() {
"message": "Index already has a primary key: `id`.",
"code": "index_primary_key_already_exists",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-primary-key-already-exists"
"link": "https://docs.meilisearch.com/errors#index_primary_key_already_exists"
});
assert_eq!(response["error"], expected_response);
@ -117,7 +117,7 @@ async fn error_update_unexisting_index() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
assert_eq!(response["error"], expected_response);

View file

@ -8,6 +8,7 @@ mod search;
mod settings;
mod snapshot;
mod stats;
mod swap_indexes;
mod tasks;
// Tests are isolated by features in different modules to allow better readability, test

View file

@ -13,7 +13,7 @@ async fn search_unexisting_index() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
});
index
@ -46,10 +46,10 @@ async fn search_bad_q() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: Sequence `[\"doggo\"]`, expected a String at `.q`.",
"message": "Invalid value type at `.q`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_search_q",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-q"
"link": "https://docs.meilisearch.com/errors#invalid_search_q"
}
"###);
// Can't make the `q` fail with a get search since it'll accept anything as a string.
@ -64,21 +64,21 @@ async fn search_bad_offset() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Integer at `.offset`.",
"message": "Invalid value type at `.offset`: expected a positive integer, but found a string: `\"doggo\"`",
"code": "invalid_search_offset",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-offset"
"link": "https://docs.meilisearch.com/errors#invalid_search_offset"
}
"###);
let (response, code) = index.search_get(json!({"offset": "doggo"})).await;
let (response, code) = index.search_get("offset=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.offset`.",
"message": "Invalid value in parameter `offset`: could not parse `doggo` as a positive integer",
"code": "invalid_search_offset",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-offset"
"link": "https://docs.meilisearch.com/errors#invalid_search_offset"
}
"###);
}
@ -92,21 +92,21 @@ async fn search_bad_limit() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Integer at `.limit`.",
"message": "Invalid value type at `.limit`: expected a positive integer, but found a string: `\"doggo\"`",
"code": "invalid_search_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-limit"
"link": "https://docs.meilisearch.com/errors#invalid_search_limit"
}
"###);
let (response, code) = index.search_get(json!({"limit": "doggo"})).await;
let (response, code) = index.search_get("limit=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.limit`.",
"message": "Invalid value in parameter `limit`: could not parse `doggo` as a positive integer",
"code": "invalid_search_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-limit"
"link": "https://docs.meilisearch.com/errors#invalid_search_limit"
}
"###);
}
@ -120,21 +120,21 @@ async fn search_bad_page() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Integer at `.page`.",
"message": "Invalid value type at `.page`: expected a positive integer, but found a string: `\"doggo\"`",
"code": "invalid_search_page",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-page"
"link": "https://docs.meilisearch.com/errors#invalid_search_page"
}
"###);
let (response, code) = index.search_get(json!({"page": "doggo"})).await;
let (response, code) = index.search_get("page=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.page`.",
"message": "Invalid value in parameter `page`: could not parse `doggo` as a positive integer",
"code": "invalid_search_page",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-page"
"link": "https://docs.meilisearch.com/errors#invalid_search_page"
}
"###);
}
@ -148,21 +148,21 @@ async fn search_bad_hits_per_page() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Integer at `.hitsPerPage`.",
"message": "Invalid value type at `.hitsPerPage`: expected a positive integer, but found a string: `\"doggo\"`",
"code": "invalid_search_hits_per_page",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-hits-per-page"
"link": "https://docs.meilisearch.com/errors#invalid_search_hits_per_page"
}
"###);
let (response, code) = index.search_get(json!({"hitsPerPage": "doggo"})).await;
let (response, code) = index.search_get("hitsPerPage=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.hitsPerPage`.",
"message": "Invalid value in parameter `hitsPerPage`: could not parse `doggo` as a positive integer",
"code": "invalid_search_hits_per_page",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-hits-per-page"
"link": "https://docs.meilisearch.com/errors#invalid_search_hits_per_page"
}
"###);
}
@ -176,10 +176,10 @@ async fn search_bad_attributes_to_crop() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.attributesToCrop`.",
"message": "Invalid value type at `.attributesToCrop`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_search_attributes_to_crop",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-attributes-to-crop"
"link": "https://docs.meilisearch.com/errors#invalid_search_attributes_to_crop"
}
"###);
// Can't make the `attributes_to_crop` fail with a get search since it'll accept anything as an array of strings.
@ -194,21 +194,21 @@ async fn search_bad_crop_length() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Integer at `.cropLength`.",
"message": "Invalid value type at `.cropLength`: expected a positive integer, but found a string: `\"doggo\"`",
"code": "invalid_search_crop_length",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-crop-length"
"link": "https://docs.meilisearch.com/errors#invalid_search_crop_length"
}
"###);
let (response, code) = index.search_get(json!({"cropLength": "doggo"})).await;
let (response, code) = index.search_get("cropLength=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.cropLength`.",
"message": "Invalid value in parameter `cropLength`: could not parse `doggo` as a positive integer",
"code": "invalid_search_crop_length",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-crop-length"
"link": "https://docs.meilisearch.com/errors#invalid_search_crop_length"
}
"###);
}
@ -222,10 +222,10 @@ async fn search_bad_attributes_to_highlight() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.attributesToHighlight`.",
"message": "Invalid value type at `.attributesToHighlight`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_search_attributes_to_highlight",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-attributes-to-highlight"
"link": "https://docs.meilisearch.com/errors#invalid_search_attributes_to_highlight"
}
"###);
// Can't make the `attributes_to_highlight` fail with a get search since it'll accept anything as an array of strings.
@ -251,7 +251,7 @@ async fn search_bad_filter() {
"message": "Invalid syntax for the filter parameter: `expected String, Array, found: true`.",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
}
"###);
// Can't make the `filter` fail with a get search since it'll accept anything as a strings.
@ -266,10 +266,10 @@ async fn search_bad_sort() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.sort`.",
"message": "Invalid value type at `.sort`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_search_sort",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-sort"
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
}
"###);
// Can't make the `sort` fail with a get search since it'll accept anything as a strings.
@ -284,21 +284,21 @@ async fn search_bad_show_matches_position() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Boolean at `.showMatchesPosition`.",
"message": "Invalid value type at `.showMatchesPosition`: expected a boolean, but found a string: `\"doggo\"`",
"code": "invalid_search_show_matches_position",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-show-matches-position"
"link": "https://docs.meilisearch.com/errors#invalid_search_show_matches_position"
}
"###);
let (response, code) = index.search_get(json!({"showMatchesPosition": "doggo"})).await;
let (response, code) = index.search_get("showMatchesPosition=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "provided string was not `true` or `false` at `.showMatchesPosition`.",
"message": "Invalid value in parameter `showMatchesPosition`: could not parse `doggo` as a boolean, expected either `true` or `false`",
"code": "invalid_search_show_matches_position",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-show-matches-position"
"link": "https://docs.meilisearch.com/errors#invalid_search_show_matches_position"
}
"###);
}
@ -312,15 +312,136 @@ async fn search_bad_facets() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.facets`.",
"message": "Invalid value type at `.facets`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-facets"
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
// Can't make the `attributes_to_highlight` fail with a get search since it'll accept anything as an array of strings.
}
#[actix_rt::test]
async fn search_non_filterable_facets() {
let server = Server::new().await;
let index = server.index("test");
index.update_settings(json!({"filterableAttributes": ["title"]})).await;
// Wait for the settings update to complete
index.wait_task(0).await;
let (response, code) = index.search_post(json!({"facets": ["doggo"]})).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, attribute `doggo` is not filterable. The available filterable attribute is `title`.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
let (response, code) = index.search_get("facets=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, attribute `doggo` is not filterable. The available filterable attribute is `title`.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
}
#[actix_rt::test]
async fn search_non_filterable_facets_multiple_filterable() {
let server = Server::new().await;
let index = server.index("test");
index.update_settings(json!({"filterableAttributes": ["title", "genres"]})).await;
index.wait_task(0).await;
let (response, code) = index.search_post(json!({"facets": ["doggo"]})).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, attribute `doggo` is not filterable. The available filterable attributes are `genres, title`.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
let (response, code) = index.search_get("facets=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, attribute `doggo` is not filterable. The available filterable attributes are `genres, title`.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
}
#[actix_rt::test]
async fn search_non_filterable_facets_no_filterable() {
let server = Server::new().await;
let index = server.index("test");
index.update_settings(json!({"filterableAttributes": []})).await;
index.wait_task(0).await;
let (response, code) = index.search_post(json!({"facets": ["doggo"]})).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, this index does not have configured filterable attributes.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
let (response, code) = index.search_get("facets=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, this index does not have configured filterable attributes.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
}
#[actix_rt::test]
async fn search_non_filterable_facets_multiple_facets() {
let server = Server::new().await;
let index = server.index("test");
index.update_settings(json!({"filterableAttributes": ["title", "genres"]})).await;
index.wait_task(0).await;
let (response, code) = index.search_post(json!({"facets": ["doggo", "neko"]})).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, attributes `doggo, neko` are not filterable. The available filterable attributes are `genres, title`.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
let (response, code) = index.search_get("facets=doggo,neko").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid facet distribution, attributes `doggo, neko` are not filterable. The available filterable attributes are `genres, title`.",
"code": "invalid_search_facets",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_facets"
}
"###);
}
#[actix_rt::test]
async fn search_bad_highlight_pre_tag() {
let server = Server::new().await;
@ -330,10 +451,10 @@ async fn search_bad_highlight_pre_tag() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: Sequence `[\"doggo\"]`, expected a String at `.highlightPreTag`.",
"message": "Invalid value type at `.highlightPreTag`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_search_highlight_pre_tag",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-highlight-pre-tag"
"link": "https://docs.meilisearch.com/errors#invalid_search_highlight_pre_tag"
}
"###);
// Can't make the `highlight_pre_tag` fail with a get search since it'll accept anything as a strings.
@ -348,10 +469,10 @@ async fn search_bad_highlight_post_tag() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: Sequence `[\"doggo\"]`, expected a String at `.highlightPostTag`.",
"message": "Invalid value type at `.highlightPostTag`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_search_highlight_post_tag",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-highlight-post-tag"
"link": "https://docs.meilisearch.com/errors#invalid_search_highlight_post_tag"
}
"###);
// Can't make the `highlight_post_tag` fail with a get search since it'll accept anything as a strings.
@ -366,10 +487,10 @@ async fn search_bad_crop_marker() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: Sequence `[\"doggo\"]`, expected a String at `.cropMarker`.",
"message": "Invalid value type at `.cropMarker`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_search_crop_marker",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-crop-marker"
"link": "https://docs.meilisearch.com/errors#invalid_search_crop_marker"
}
"###);
// Can't make the `crop_marker` fail with a get search since it'll accept anything as a strings.
@ -384,21 +505,32 @@ async fn search_bad_matching_strategy() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Json deserialize error: unknown value `doggo`, expected one of `last`, `all` at `.matchingStrategy`.",
"message": "Unknown value `doggo` at `.matchingStrategy`: expected one of `last`, `all`",
"code": "invalid_search_matching_strategy",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-matching-strategy"
"link": "https://docs.meilisearch.com/errors#invalid_search_matching_strategy"
}
"###);
let (response, code) = index.search_get(json!({"matchingStrategy": "doggo"})).await;
let (response, code) = index.search_post(json!({"matchingStrategy": {"doggo": "doggo"}})).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Json deserialize error: unknown value `doggo`, expected one of `last`, `all` at `.matchingStrategy`.",
"message": "Invalid value type at `.matchingStrategy`: expected a string, but found an object: `{\"doggo\":\"doggo\"}`",
"code": "invalid_search_matching_strategy",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-matching-strategy"
"link": "https://docs.meilisearch.com/errors#invalid_search_matching_strategy"
}
"###);
let (response, code) = index.search_get("matchingStrategy=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown value `doggo` for parameter `matchingStrategy`: expected one of `last`, `all`",
"code": "invalid_search_matching_strategy",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_search_matching_strategy"
}
"###);
}
@ -418,7 +550,7 @@ async fn filter_invalid_syntax_object() {
"message": "Was expecting an operation `=`, `!=`, `>=`, `>`, `<=`, `<`, `IN`, `NOT IN`, `TO`, `EXISTS`, `NOT EXISTS`, `_geoRadius`, or `_geoBoundingBox` at `title & Glass`.\n1:14 title & Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": "title & Glass"}), |response, code| {
@ -443,7 +575,7 @@ async fn filter_invalid_syntax_array() {
"message": "Was expecting an operation `=`, `!=`, `>=`, `>`, `<=`, `<`, `IN`, `NOT IN`, `TO`, `EXISTS`, `NOT EXISTS`, `_geoRadius`, or `_geoBoundingBox` at `title & Glass`.\n1:14 title & Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": ["title & Glass"]}), |response, code| {
@ -468,7 +600,7 @@ async fn filter_invalid_syntax_string() {
"message": "Found unexpected characters at the end of the filter: `XOR title = Glass`. You probably forgot an `OR` or an `AND` rule.\n15:32 title = Glass XOR title = Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": "title = Glass XOR title = Glass"}), |response, code| {
@ -493,7 +625,7 @@ async fn filter_invalid_attribute_array() {
"message": "Attribute `many` is not filterable. Available filterable attributes are: `title`.\n1:5 many = Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": ["many = Glass"]}), |response, code| {
@ -518,7 +650,7 @@ async fn filter_invalid_attribute_string() {
"message": "Attribute `many` is not filterable. Available filterable attributes are: `title`.\n1:5 many = Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": "many = Glass"}), |response, code| {
@ -543,7 +675,7 @@ async fn filter_reserved_geo_attribute_array() {
"message": "`_geo` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance)` or `_geoBoundingBox([latitude, longitude], [latitude, longitude])` built-in rules to filter on `_geo` field coordinates.\n1:5 _geo = Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": ["_geo = Glass"]}), |response, code| {
@ -568,7 +700,7 @@ async fn filter_reserved_geo_attribute_string() {
"message": "`_geo` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance)` or `_geoBoundingBox([latitude, longitude], [latitude, longitude])` built-in rules to filter on `_geo` field coordinates.\n1:5 _geo = Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": "_geo = Glass"}), |response, code| {
@ -593,7 +725,7 @@ async fn filter_reserved_attribute_array() {
"message": "`_geoDistance` is a reserved keyword and thus can't be used as a filter expression.\n1:13 _geoDistance = Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": ["_geoDistance = Glass"]}), |response, code| {
@ -618,7 +750,7 @@ async fn filter_reserved_attribute_string() {
"message": "`_geoDistance` is a reserved keyword and thus can't be used as a filter expression.\n1:13 _geoDistance = Glass",
"code": "invalid_search_filter",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-filter"
"link": "https://docs.meilisearch.com/errors#invalid_search_filter"
});
index
.search(json!({"filter": "_geoDistance = Glass"}), |response, code| {
@ -643,7 +775,7 @@ async fn sort_geo_reserved_attribute() {
"message": "`_geo` is a reserved keyword and thus can't be used as a sort expression. Use the _geoPoint(latitude, longitude) built-in rule to sort on _geo field coordinates.",
"code": "invalid_search_sort",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-sort"
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
});
index
.search(
@ -673,7 +805,7 @@ async fn sort_reserved_attribute() {
"message": "`_geoDistance` is a reserved keyword and thus can't be used as a sort expression.",
"code": "invalid_search_sort",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-sort"
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
});
index
.search(
@ -703,7 +835,7 @@ async fn sort_unsortable_attribute() {
"message": "Attribute `title` is not sortable. Available sortable attributes are: `id`.",
"code": "invalid_search_sort",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-sort"
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
});
index
.search(
@ -733,7 +865,7 @@ async fn sort_invalid_syntax() {
"message": "Invalid syntax for the sort parameter: expected expression ending by `:asc` or `:desc`, found `title`.",
"code": "invalid_search_sort",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-sort"
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
});
index
.search(
@ -767,7 +899,7 @@ async fn sort_unset_ranking_rule() {
"message": "The sort ranking rule must be specified in the ranking rules settings to use the sort parameter at search time.",
"code": "invalid_search_sort",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-search-sort"
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
});
index
.search(

View file

@ -12,10 +12,10 @@ async fn settings_bad_displayed_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.displayedAttributes`.",
"message": "Invalid value type at `.displayedAttributes`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_displayed_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-displayed-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_displayed_attributes"
}
"###);
@ -23,10 +23,10 @@ async fn settings_bad_displayed_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at ``.",
"message": "Invalid value type: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_displayed_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-displayed-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_displayed_attributes"
}
"###);
}
@ -40,10 +40,10 @@ async fn settings_bad_searchable_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.searchableAttributes`.",
"message": "Invalid value type at `.searchableAttributes`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_searchable_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-searchable-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_searchable_attributes"
}
"###);
@ -51,10 +51,10 @@ async fn settings_bad_searchable_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at ``.",
"message": "Invalid value type: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_searchable_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-searchable-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_searchable_attributes"
}
"###);
}
@ -68,10 +68,10 @@ async fn settings_bad_filterable_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.filterableAttributes`.",
"message": "Invalid value type at `.filterableAttributes`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_filterable_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-filterable-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_filterable_attributes"
}
"###);
@ -79,10 +79,10 @@ async fn settings_bad_filterable_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at ``.",
"message": "Invalid value type: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_filterable_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-filterable-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_filterable_attributes"
}
"###);
}
@ -96,10 +96,10 @@ async fn settings_bad_sortable_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.sortableAttributes`.",
"message": "Invalid value type at `.sortableAttributes`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_sortable_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-sortable-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_sortable_attributes"
}
"###);
@ -107,10 +107,10 @@ async fn settings_bad_sortable_attributes() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at ``.",
"message": "Invalid value type: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_sortable_attributes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-sortable-attributes"
"link": "https://docs.meilisearch.com/errors#invalid_settings_sortable_attributes"
}
"###);
}
@ -124,10 +124,10 @@ async fn settings_bad_ranking_rules() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.rankingRules`.",
"message": "Invalid value type at `.rankingRules`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_ranking_rules",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-ranking-rules"
"link": "https://docs.meilisearch.com/errors#invalid_settings_ranking_rules"
}
"###);
@ -135,10 +135,10 @@ async fn settings_bad_ranking_rules() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at ``.",
"message": "Invalid value type: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_ranking_rules",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-ranking-rules"
"link": "https://docs.meilisearch.com/errors#invalid_settings_ranking_rules"
}
"###);
}
@ -152,10 +152,10 @@ async fn settings_bad_stop_words() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at `.stopWords`.",
"message": "Invalid value type at `.stopWords`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_stop_words",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-stop-words"
"link": "https://docs.meilisearch.com/errors#invalid_settings_stop_words"
}
"###);
@ -163,10 +163,10 @@ async fn settings_bad_stop_words() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Sequence at ``.",
"message": "Invalid value type: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_settings_stop_words",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-stop-words"
"link": "https://docs.meilisearch.com/errors#invalid_settings_stop_words"
}
"###);
}
@ -180,10 +180,10 @@ async fn settings_bad_synonyms() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at `.synonyms`.",
"message": "Invalid value type at `.synonyms`: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_synonyms",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-synonyms"
"link": "https://docs.meilisearch.com/errors#invalid_settings_synonyms"
}
"###);
@ -191,10 +191,10 @@ async fn settings_bad_synonyms() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at ``.",
"message": "Invalid value type: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_synonyms",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-synonyms"
"link": "https://docs.meilisearch.com/errors#invalid_settings_synonyms"
}
"###);
}
@ -208,10 +208,10 @@ async fn settings_bad_distinct_attribute() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: Sequence `[\"doggo\"]`, expected a String at `.distinctAttribute`.",
"message": "Invalid value type at `.distinctAttribute`: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_settings_distinct_attribute",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-distinct-attribute"
"link": "https://docs.meilisearch.com/errors#invalid_settings_distinct_attribute"
}
"###);
@ -219,10 +219,10 @@ async fn settings_bad_distinct_attribute() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: Sequence `[\"doggo\"]`, expected a String at ``.",
"message": "Invalid value type: expected a string, but found an array: `[\"doggo\"]`",
"code": "invalid_settings_distinct_attribute",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-distinct-attribute"
"link": "https://docs.meilisearch.com/errors#invalid_settings_distinct_attribute"
}
"###);
}
@ -236,10 +236,22 @@ async fn settings_bad_typo_tolerance() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at `.typoTolerance`.",
"message": "Invalid value type at `.typoTolerance`: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_typo_tolerance",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-typo-tolerance"
"link": "https://docs.meilisearch.com/errors#invalid_settings_typo_tolerance"
}
"###);
let (response, code) =
index.update_settings(json!({ "typoTolerance": { "minWordSizeForTypos": "doggo" }})).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `.typoTolerance.minWordSizeForTypos`: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_typo_tolerance",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_settings_typo_tolerance"
}
"###);
@ -247,10 +259,25 @@ async fn settings_bad_typo_tolerance() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at ``.",
"message": "Invalid value type: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_typo_tolerance",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-typo-tolerance"
"link": "https://docs.meilisearch.com/errors#invalid_settings_typo_tolerance"
}
"###);
let (response, code) = index
.update_settings_typo_tolerance(
json!({ "typoTolerance": { "minWordSizeForTypos": "doggo" }}),
)
.await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Unknown field `typoTolerance`: expected one of `enabled`, `minWordSizeForTypos`, `disableOnWords`, `disableOnAttributes`",
"code": "invalid_settings_typo_tolerance",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_settings_typo_tolerance"
}
"###);
}
@ -264,10 +291,10 @@ async fn settings_bad_faceting() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at `.faceting`.",
"message": "Invalid value type at `.faceting`: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_faceting",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-faceting"
"link": "https://docs.meilisearch.com/errors#invalid_settings_faceting"
}
"###);
@ -275,10 +302,10 @@ async fn settings_bad_faceting() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at ``.",
"message": "Invalid value type: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_faceting",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-faceting"
"link": "https://docs.meilisearch.com/errors#invalid_settings_faceting"
}
"###);
}
@ -292,10 +319,10 @@ async fn settings_bad_pagination() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at `.pagination`.",
"message": "Invalid value type at `.pagination`: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_pagination",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-pagination"
"link": "https://docs.meilisearch.com/errors#invalid_settings_pagination"
}
"###);
@ -303,10 +330,10 @@ async fn settings_bad_pagination() {
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid type: String `\"doggo\"`, expected a Map at ``.",
"message": "Invalid value type: expected an object, but found a string: `\"doggo\"`",
"code": "invalid_settings_pagination",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-pagination"
"link": "https://docs.meilisearch.com/errors#invalid_settings_pagination"
}
"###);
}

View file

@ -185,7 +185,7 @@ async fn error_update_setting_unexisting_index_invalid_uid() {
"message": "`test##! ` 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",
"link": "https://docs.meilisearch.com/errors#invalid-index-uid"
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}
@ -282,10 +282,10 @@ async fn error_set_invalid_ranking_rules() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "`manyTheFish` ranking rule is invalid. Valid ranking rules are words, typo, sort, proximity, attribute, exactness and custom ranking rules. at `.rankingRules[0]`.",
"message": "Invalid value at `.rankingRules[0]`: `manyTheFish` ranking rule is invalid. Valid ranking rules are words, typo, sort, proximity, attribute, exactness and custom ranking rules.",
"code": "invalid_settings_ranking_rules",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-ranking-rules"
"link": "https://docs.meilisearch.com/errors#invalid_settings_ranking_rules"
}
"###);
}

View file

@ -0,0 +1,94 @@
use meili_snap::*;
use serde_json::json;
use crate::common::Server;
#[actix_rt::test]
async fn swap_indexes_bad_format() {
let server = Server::new().await;
let (response, code) = server.index_swap(json!("doggo")).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type: expected an array, but found a string: `\"doggo\"`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
let (response, code) = server.index_swap(json!(["doggo"])).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `[0]`: expected an object, but found a string: `\"doggo\"`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
#[actix_rt::test]
async fn swap_indexes_bad_indexes() {
let server = Server::new().await;
let (response, code) = server.index_swap(json!([{ "indexes": "doggo"}])).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value type at `[0].indexes`: expected an array, but found a string: `\"doggo\"`",
"code": "invalid_swap_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_swap_indexes"
}
"###);
let (response, code) = server.index_swap(json!([{ "indexes": ["doggo"]}])).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Two indexes must be given for each swap. The list `[\"doggo\"]` contains 1 indexes.",
"code": "invalid_swap_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_swap_indexes"
}
"###);
let (response, code) =
server.index_swap(json!([{ "indexes": ["doggo", "crabo", "croco"]}])).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Two indexes must be given for each swap. The list `[\"doggo\", \"crabo\", \"croco\"]` contains 3 indexes.",
"code": "invalid_swap_indexes",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_swap_indexes"
}
"###);
let (response, code) = server.index_swap(json!([{ "indexes": ["doggo", "doggo"]}])).await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Indexes must be declared only once during a swap. `doggo` was specified several times.",
"code": "invalid_swap_duplicate_index_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_swap_duplicate_index_found"
}
"###);
let (response, code) = server
.index_swap(json!([{ "indexes": ["doggo", "catto"]}, { "indexes": ["girafo", "doggo"]}]))
.await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Indexes must be declared only once during a swap. `doggo` was specified several times.",
"code": "invalid_swap_duplicate_index_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_swap_duplicate_index_found"
}
"###);
}

View file

@ -0,0 +1,357 @@
mod errors;
use meili_snap::{json_string, snapshot};
use serde_json::json;
use crate::common::{GetAllDocumentsOptions, Server};
#[actix_rt::test]
async fn swap_indexes() {
let server = Server::new().await;
let a = server.index("a");
let (_, code) = a.add_documents(json!({ "id": 1, "index": "a"}), None).await;
snapshot!(code, @"202 Accepted");
let b = server.index("b");
let (res, code) = b.add_documents(json!({ "id": 1, "index": "b"}), None).await;
snapshot!(code, @"202 Accepted");
snapshot!(res["taskUid"], @"1");
server.wait_task(1).await;
let (tasks, code) = server.tasks().await;
snapshot!(code, @"200 OK");
snapshot!(json_string!(tasks, { ".results[].duration" => "[duration]", ".results[].enqueuedAt" => "[date]", ".results[].startedAt" => "[date]", ".results[].finishedAt" => "[date]" }), @r###"
{
"results": [
{
"uid": 1,
"indexUid": "b",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 0,
"indexUid": "a",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
],
"limit": 20,
"from": 1,
"next": null
}
"###);
let (res, code) = server.index_swap(json!([{ "indexes": ["a", "b"] }])).await;
snapshot!(code, @"202 Accepted");
snapshot!(res["taskUid"], @"2");
server.wait_task(2).await;
let (tasks, code) = server.tasks().await;
snapshot!(code, @"200 OK");
// Notice how the task 0 which was initially representing the creation of the index `A` now represents the creation of the index `B`.
snapshot!(json_string!(tasks, { ".results[].duration" => "[duration]", ".results[].enqueuedAt" => "[date]", ".results[].startedAt" => "[date]", ".results[].finishedAt" => "[date]" }), @r###"
{
"results": [
{
"uid": 2,
"indexUid": null,
"status": "succeeded",
"type": "indexSwap",
"canceledBy": null,
"details": {
"swaps": [
{
"indexes": [
"a",
"b"
]
}
]
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 1,
"indexUid": "a",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 0,
"indexUid": "b",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
],
"limit": 20,
"from": 2,
"next": null
}
"###);
// BUT, the data in `a` should now points to the data that was in `b`.
// And the opposite is true as well
let (res, _) = a.get_all_documents(GetAllDocumentsOptions::default()).await;
snapshot!(res["results"], @r###"[{"id":1,"index":"b"}]"###);
let (res, _) = b.get_all_documents(GetAllDocumentsOptions::default()).await;
snapshot!(res["results"], @r###"[{"id":1,"index":"a"}]"###);
// ================
// And now we're going to attempt the famous and dangerous DOUBLE index swap 🤞
let c = server.index("c");
let (res, code) = c.add_documents(json!({ "id": 1, "index": "c"}), None).await;
snapshot!(code, @"202 Accepted");
snapshot!(res["taskUid"], @"3");
let d = server.index("d");
let (res, code) = d.add_documents(json!({ "id": 1, "index": "d"}), None).await;
snapshot!(code, @"202 Accepted");
snapshot!(res["taskUid"], @"4");
server.wait_task(4).await;
// ensure the index creation worked properly
let (tasks, code) = server.tasks_filter("limit=2").await;
snapshot!(code, @"200 OK");
snapshot!(json_string!(tasks, { ".results[].duration" => "[duration]", ".results[].enqueuedAt" => "[date]", ".results[].startedAt" => "[date]", ".results[].finishedAt" => "[date]" }), @r###"
{
"results": [
{
"uid": 4,
"indexUid": "d",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 3,
"indexUid": "c",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
],
"limit": 2,
"from": 4,
"next": 2
}
"###);
// It's happening 😲
let (res, code) =
server.index_swap(json!([{ "indexes": ["a", "b"] }, { "indexes": ["c", "d"] } ])).await;
snapshot!(res["taskUid"], @"5");
snapshot!(code, @"202 Accepted");
server.wait_task(5).await;
// ensure the index creation worked properly
let (tasks, code) = server.tasks().await;
snapshot!(code, @"200 OK");
// What should we check for each tasks in this test:
// Task number;
// 0. should have the indexUid `a` again
// 1. should have the indexUid `b` again
// 2. stays unchanged
// 3. now have the indexUid `d` instead of `c`
// 4. now have the indexUid `c` instead of `d`
snapshot!(json_string!(tasks, { ".results[].duration" => "[duration]", ".results[].enqueuedAt" => "[date]", ".results[].startedAt" => "[date]", ".results[].finishedAt" => "[date]" }), @r###"
{
"results": [
{
"uid": 5,
"indexUid": null,
"status": "succeeded",
"type": "indexSwap",
"canceledBy": null,
"details": {
"swaps": [
{
"indexes": [
"a",
"b"
]
},
{
"indexes": [
"c",
"d"
]
}
]
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 4,
"indexUid": "c",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 3,
"indexUid": "d",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 2,
"indexUid": null,
"status": "succeeded",
"type": "indexSwap",
"canceledBy": null,
"details": {
"swaps": [
{
"indexes": [
"b",
"a"
]
}
]
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 1,
"indexUid": "b",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
},
{
"uid": 0,
"indexUid": "a",
"status": "succeeded",
"type": "documentAdditionOrUpdate",
"canceledBy": null,
"details": {
"receivedDocuments": 1,
"indexedDocuments": 1
},
"error": null,
"duration": "[duration]",
"enqueuedAt": "[date]",
"startedAt": "[date]",
"finishedAt": "[date]"
}
],
"limit": 20,
"from": 5,
"next": null
}
"###);
// - The data in `a` should point to `a`.
// - The data in `b` should point to `b`.
// - The data in `c` should point to `d`.
// - The data in `d` should point to `c`.
let (res, _) = a.get_all_documents(GetAllDocumentsOptions::default()).await;
snapshot!(res["results"], @r###"[{"id":1,"index":"a"}]"###);
let (res, _) = b.get_all_documents(GetAllDocumentsOptions::default()).await;
snapshot!(res["results"], @r###"[{"id":1,"index":"b"}]"###);
let (res, _) = c.get_all_documents(GetAllDocumentsOptions::default()).await;
snapshot!(res["results"], @r###"[{"id":1,"index":"d"}]"###);
let (res, _) = d.get_all_documents(GetAllDocumentsOptions::default()).await;
snapshot!(res["results"], @r###"[{"id":1,"index":"c"}]"###);
}

View file

@ -1,5 +1,4 @@
use meili_snap::*;
use serde_json::json;
use crate::common::Server;
@ -7,36 +6,47 @@ use crate::common::Server;
async fn task_bad_uids() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"uids": "doggo"})).await;
let (response, code) = server.tasks_filter("uids=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.uids`.",
"message": "Invalid value in parameter `uids`: could not parse `doggo` as a positive integer",
"code": "invalid_task_uids",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-uids"
"link": "https://docs.meilisearch.com/errors#invalid_task_uids"
}
"###);
let (response, code) = server.cancel_tasks(json!({"uids": "doggo"})).await;
let (response, code) = server.cancel_tasks("uids=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.uids`.",
"message": "Invalid value in parameter `uids`: could not parse `doggo` as a positive integer",
"code": "invalid_task_uids",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-uids"
"link": "https://docs.meilisearch.com/errors#invalid_task_uids"
}
"###);
let (response, code) = server.delete_tasks(json!({"uids": "doggo"})).await;
let (response, code) = server.delete_tasks("uids=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.uids`.",
"message": "Invalid value in parameter `uids`: could not parse `doggo` as a positive integer",
"code": "invalid_task_uids",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-uids"
"link": "https://docs.meilisearch.com/errors#invalid_task_uids"
}
"###);
let (response, code) = server.delete_tasks("uids=1,dogo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Invalid value in parameter `uids[1]`: could not parse `dogo` as a positive integer",
"code": "invalid_task_uids",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_task_uids"
}
"###);
}
@ -45,36 +55,36 @@ async fn task_bad_uids() {
async fn task_bad_canceled_by() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"canceledBy": "doggo"})).await;
let (response, code) = server.tasks_filter("canceledBy=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.canceledBy`.",
"message": "Invalid value in parameter `canceledBy`: could not parse `doggo` as a positive integer",
"code": "invalid_task_canceled_by",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-canceled-by"
"link": "https://docs.meilisearch.com/errors#invalid_task_canceled_by"
}
"###);
let (response, code) = server.cancel_tasks(json!({"canceledBy": "doggo"})).await;
let (response, code) = server.cancel_tasks("canceledBy=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.canceledBy`.",
"message": "Invalid value in parameter `canceledBy`: could not parse `doggo` as a positive integer",
"code": "invalid_task_canceled_by",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-canceled-by"
"link": "https://docs.meilisearch.com/errors#invalid_task_canceled_by"
}
"###);
let (response, code) = server.delete_tasks(json!({"canceledBy": "doggo"})).await;
let (response, code) = server.delete_tasks("canceledBy=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.canceledBy`.",
"message": "Invalid value in parameter `canceledBy`: could not parse `doggo` as a positive integer",
"code": "invalid_task_canceled_by",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-canceled-by"
"link": "https://docs.meilisearch.com/errors#invalid_task_canceled_by"
}
"###);
}
@ -83,36 +93,36 @@ async fn task_bad_canceled_by() {
async fn task_bad_types() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"types": "doggo"})).await;
let (response, code) = server.tasks_filter("types=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is not a type. Available types are `documentAdditionOrUpdate`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`. at `.types`.",
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
"code": "invalid_task_types",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-types"
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
}
"###);
let (response, code) = server.cancel_tasks(json!({"types": "doggo"})).await;
let (response, code) = server.cancel_tasks("types=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is not a type. Available types are `documentAdditionOrUpdate`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`. at `.types`.",
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
"code": "invalid_task_types",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-types"
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
}
"###);
let (response, code) = server.delete_tasks(json!({"types": "doggo"})).await;
let (response, code) = server.delete_tasks("types=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is not a type. Available types are `documentAdditionOrUpdate`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`. at `.types`.",
"message": "Invalid value in parameter `types`: `doggo` is not a valid task type. Available types are `documentAdditionOrUpdate`, `documentDeletion`, `settingsUpdate`, `indexCreation`, `indexDeletion`, `indexUpdate`, `indexSwap`, `taskCancelation`, `taskDeletion`, `dumpCreation`, `snapshotCreation`.",
"code": "invalid_task_types",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-types"
"link": "https://docs.meilisearch.com/errors#invalid_task_types"
}
"###);
}
@ -121,36 +131,36 @@ async fn task_bad_types() {
async fn task_bad_statuses() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"statuses": "doggo"})).await;
let (response, code) = server.tasks_filter("statuses=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is not a status. Available status are `enqueued`, `processing`, `succeeded`, `failed`, `canceled`. at `.statuses`.",
"message": "Invalid value in parameter `statuses`: `doggo` is not a valid task status. Available statuses are `enqueued`, `processing`, `succeeded`, `failed`, `canceled`.",
"code": "invalid_task_statuses",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-statuses"
"link": "https://docs.meilisearch.com/errors#invalid_task_statuses"
}
"###);
let (response, code) = server.cancel_tasks(json!({"statuses": "doggo"})).await;
let (response, code) = server.cancel_tasks("statuses=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is not a status. Available status are `enqueued`, `processing`, `succeeded`, `failed`, `canceled`. at `.statuses`.",
"message": "Invalid value in parameter `statuses`: `doggo` is not a valid task status. Available statuses are `enqueued`, `processing`, `succeeded`, `failed`, `canceled`.",
"code": "invalid_task_statuses",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-statuses"
"link": "https://docs.meilisearch.com/errors#invalid_task_statuses"
}
"###);
let (response, code) = server.delete_tasks(json!({"statuses": "doggo"})).await;
let (response, code) = server.delete_tasks("statuses=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is not a status. Available status are `enqueued`, `processing`, `succeeded`, `failed`, `canceled`. at `.statuses`.",
"message": "Invalid value in parameter `statuses`: `doggo` is not a valid task status. Available statuses are `enqueued`, `processing`, `succeeded`, `failed`, `canceled`.",
"code": "invalid_task_statuses",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-statuses"
"link": "https://docs.meilisearch.com/errors#invalid_task_statuses"
}
"###);
}
@ -159,36 +169,36 @@ async fn task_bad_statuses() {
async fn task_bad_index_uids() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"indexUids": "the good doggo"})).await;
let (response, code) = server.tasks_filter("indexUids=the%20good%20doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`the good doggo` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_). at `.indexUids`.",
"message": "Invalid value in parameter `indexUids`: `the good doggo` 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",
"link": "https://docs.meilisearch.com/errors#invalid-index-uid"
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
let (response, code) = server.cancel_tasks(json!({"indexUids": "the good doggo"})).await;
let (response, code) = server.cancel_tasks("indexUids=the%20good%20doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`the good doggo` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_). at `.indexUids`.",
"message": "Invalid value in parameter `indexUids`: `the good doggo` 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",
"link": "https://docs.meilisearch.com/errors#invalid-index-uid"
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
let (response, code) = server.delete_tasks(json!({"indexUids": "the good doggo"})).await;
let (response, code) = server.delete_tasks("indexUids=the%20good%20doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`the good doggo` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_). at `.indexUids`.",
"message": "Invalid value in parameter `indexUids`: `the good doggo` 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",
"link": "https://docs.meilisearch.com/errors#invalid-index-uid"
"link": "https://docs.meilisearch.com/errors#invalid_index_uid"
}
"###);
}
@ -197,36 +207,36 @@ async fn task_bad_index_uids() {
async fn task_bad_limit() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"limit": "doggo"})).await;
let (response, code) = server.tasks_filter("limit=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.limit`.",
"message": "Invalid value in parameter `limit`: could not parse `doggo` as a positive integer",
"code": "invalid_task_limit",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-limit"
"link": "https://docs.meilisearch.com/errors#invalid_task_limit"
}
"###);
let (response, code) = server.cancel_tasks(json!({"limit": "doggo"})).await;
let (response, code) = server.cancel_tasks("limit=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Json deserialize error: unknown field `limit`, expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt` at ``.",
"message": "Unknown parameter `limit`: expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
let (response, code) = server.delete_tasks(json!({"limit": "doggo"})).await;
let (response, code) = server.delete_tasks("limit=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Json deserialize error: unknown field `limit`, expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt` at ``.",
"message": "Unknown parameter `limit`: expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
@ -235,36 +245,36 @@ async fn task_bad_limit() {
async fn task_bad_from() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"from": "doggo"})).await;
let (response, code) = server.tasks_filter("from=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "invalid digit found in string at `.from`.",
"message": "Invalid value in parameter `from`: could not parse `doggo` as a positive integer",
"code": "invalid_task_from",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-from"
"link": "https://docs.meilisearch.com/errors#invalid_task_from"
}
"###);
let (response, code) = server.cancel_tasks(json!({"from": "doggo"})).await;
let (response, code) = server.cancel_tasks("from=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Json deserialize error: unknown field `from`, expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt` at ``.",
"message": "Unknown parameter `from`: expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
let (response, code) = server.delete_tasks(json!({"from": "doggo"})).await;
let (response, code) = server.delete_tasks("from=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "Json deserialize error: unknown field `from`, expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt` at ``.",
"message": "Unknown parameter `from`: expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
}
@ -273,36 +283,36 @@ async fn task_bad_from() {
async fn task_bad_after_enqueued_at() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"afterEnqueuedAt": "doggo"})).await;
let (response, code) = server.tasks_filter("afterEnqueuedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterEnqueuedAt`.",
"message": "Invalid value in parameter `afterEnqueuedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_enqueued_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-enqueued-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_enqueued_at"
}
"###);
let (response, code) = server.cancel_tasks(json!({"afterEnqueuedAt": "doggo"})).await;
let (response, code) = server.cancel_tasks("afterEnqueuedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterEnqueuedAt`.",
"message": "Invalid value in parameter `afterEnqueuedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_enqueued_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-enqueued-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_enqueued_at"
}
"###);
let (response, code) = server.delete_tasks(json!({"afterEnqueuedAt": "doggo"})).await;
let (response, code) = server.delete_tasks("afterEnqueuedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterEnqueuedAt`.",
"message": "Invalid value in parameter `afterEnqueuedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_enqueued_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-enqueued-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_enqueued_at"
}
"###);
}
@ -311,36 +321,36 @@ async fn task_bad_after_enqueued_at() {
async fn task_bad_before_enqueued_at() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"beforeEnqueuedAt": "doggo"})).await;
let (response, code) = server.tasks_filter("beforeEnqueuedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeEnqueuedAt`.",
"message": "Invalid value in parameter `beforeEnqueuedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_enqueued_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-enqueued-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_enqueued_at"
}
"###);
let (response, code) = server.cancel_tasks(json!({"beforeEnqueuedAt": "doggo"})).await;
let (response, code) = server.cancel_tasks("beforeEnqueuedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeEnqueuedAt`.",
"message": "Invalid value in parameter `beforeEnqueuedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_enqueued_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-enqueued-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_enqueued_at"
}
"###);
let (response, code) = server.delete_tasks(json!({"beforeEnqueuedAt": "doggo"})).await;
let (response, code) = server.delete_tasks("beforeEnqueuedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeEnqueuedAt`.",
"message": "Invalid value in parameter `beforeEnqueuedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_enqueued_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-enqueued-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_enqueued_at"
}
"###);
}
@ -349,36 +359,36 @@ async fn task_bad_before_enqueued_at() {
async fn task_bad_after_started_at() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"afterStartedAt": "doggo"})).await;
let (response, code) = server.tasks_filter("afterStartedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterStartedAt`.",
"message": "Invalid value in parameter `afterStartedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_started_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-started-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_started_at"
}
"###);
let (response, code) = server.cancel_tasks(json!({"afterStartedAt": "doggo"})).await;
let (response, code) = server.cancel_tasks("afterStartedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterStartedAt`.",
"message": "Invalid value in parameter `afterStartedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_started_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-started-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_started_at"
}
"###);
let (response, code) = server.delete_tasks(json!({"afterStartedAt": "doggo"})).await;
let (response, code) = server.delete_tasks("afterStartedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterStartedAt`.",
"message": "Invalid value in parameter `afterStartedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_started_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-started-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_started_at"
}
"###);
}
@ -387,36 +397,36 @@ async fn task_bad_after_started_at() {
async fn task_bad_before_started_at() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"beforeStartedAt": "doggo"})).await;
let (response, code) = server.tasks_filter("beforeStartedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeStartedAt`.",
"message": "Invalid value in parameter `beforeStartedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_started_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-started-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_started_at"
}
"###);
let (response, code) = server.cancel_tasks(json!({"beforeStartedAt": "doggo"})).await;
let (response, code) = server.cancel_tasks("beforeStartedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeStartedAt`.",
"message": "Invalid value in parameter `beforeStartedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_started_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-started-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_started_at"
}
"###);
let (response, code) = server.delete_tasks(json!({"beforeStartedAt": "doggo"})).await;
let (response, code) = server.delete_tasks("beforeStartedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeStartedAt`.",
"message": "Invalid value in parameter `beforeStartedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_started_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-started-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_started_at"
}
"###);
}
@ -425,36 +435,36 @@ async fn task_bad_before_started_at() {
async fn task_bad_after_finished_at() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"afterFinishedAt": "doggo"})).await;
let (response, code) = server.tasks_filter("afterFinishedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterFinishedAt`.",
"message": "Invalid value in parameter `afterFinishedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_finished_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-finished-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_finished_at"
}
"###);
let (response, code) = server.cancel_tasks(json!({"afterFinishedAt": "doggo"})).await;
let (response, code) = server.cancel_tasks("afterFinishedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterFinishedAt`.",
"message": "Invalid value in parameter `afterFinishedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_finished_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-finished-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_finished_at"
}
"###);
let (response, code) = server.delete_tasks(json!({"afterFinishedAt": "doggo"})).await;
let (response, code) = server.delete_tasks("afterFinishedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.afterFinishedAt`.",
"message": "Invalid value in parameter `afterFinishedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_after_finished_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-after-finished-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_after_finished_at"
}
"###);
}
@ -463,36 +473,36 @@ async fn task_bad_after_finished_at() {
async fn task_bad_before_finished_at() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!({"beforeFinishedAt": "doggo"})).await;
let (response, code) = server.tasks_filter("beforeFinishedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeFinishedAt`.",
"message": "Invalid value in parameter `beforeFinishedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_finished_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-finished-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_finished_at"
}
"###);
let (response, code) = server.cancel_tasks(json!({"beforeFinishedAt": "doggo"})).await;
let (response, code) = server.cancel_tasks("beforeFinishedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeFinishedAt`.",
"message": "Invalid value in parameter `beforeFinishedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_finished_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-finished-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_finished_at"
}
"###);
let (response, code) = server.delete_tasks(json!({"beforeFinishedAt": "doggo"})).await;
let (response, code) = server.delete_tasks("beforeFinishedAt=doggo").await;
snapshot!(code, @"400 Bad Request");
snapshot!(json_string!(response), @r###"
{
"message": "`doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeFinishedAt`.",
"message": "Invalid value in parameter `beforeFinishedAt`: `doggo` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_finished_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-finished-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_finished_at"
}
"###);
}

View file

@ -19,7 +19,7 @@ async fn error_get_unexisting_task_status() {
"message": "Task `1` not found.",
"code": "task_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#task-not-found"
"link": "https://docs.meilisearch.com/errors#task_not_found"
});
assert_eq!(response, expected_response);
@ -115,7 +115,7 @@ async fn list_tasks_status_filtered() {
.add_documents(serde_json::from_str(include_str!("../assets/test_set.json")).unwrap(), None)
.await;
let (response, code) = index.filtered_tasks(&[], &["succeeded"]).await;
let (response, code) = index.filtered_tasks(&[], &["succeeded"], &[]).await;
assert_eq!(code, 200, "{}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 1);
@ -126,7 +126,7 @@ async fn list_tasks_status_filtered() {
index.wait_task(1).await;
let (response, code) = index.filtered_tasks(&[], &["succeeded"]).await;
let (response, code) = index.filtered_tasks(&[], &["succeeded"], &[]).await;
assert_eq!(code, 200, "{}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 2);
}
@ -141,16 +141,31 @@ async fn list_tasks_type_filtered() {
.add_documents(serde_json::from_str(include_str!("../assets/test_set.json")).unwrap(), None)
.await;
let (response, code) = index.filtered_tasks(&["indexCreation"], &[]).await;
let (response, code) = index.filtered_tasks(&["indexCreation"], &[], &[]).await;
assert_eq!(code, 200, "{}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 1);
let (response, code) =
index.filtered_tasks(&["indexCreation", "documentAdditionOrUpdate"], &[]).await;
index.filtered_tasks(&["indexCreation", "documentAdditionOrUpdate"], &[], &[]).await;
assert_eq!(code, 200, "{}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 2);
}
#[actix_rt::test]
async fn list_tasks_invalid_canceled_by_filter() {
let server = Server::new().await;
let index = server.index("test");
index.create(None).await;
index.wait_task(0).await;
index
.add_documents(serde_json::from_str(include_str!("../assets/test_set.json")).unwrap(), None)
.await;
let (response, code) = index.filtered_tasks(&[], &[], &["0"]).await;
assert_eq!(code, 200, "{}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 0);
}
#[actix_rt::test]
async fn list_tasks_status_and_type_filtered() {
let server = Server::new().await;
@ -161,7 +176,7 @@ async fn list_tasks_status_and_type_filtered() {
.add_documents(serde_json::from_str(include_str!("../assets/test_set.json")).unwrap(), None)
.await;
let (response, code) = index.filtered_tasks(&["indexCreation"], &["failed"]).await;
let (response, code) = index.filtered_tasks(&["indexCreation"], &["failed"], &[]).await;
assert_eq!(code, 200, "{}", response);
assert_eq!(response["results"].as_array().unwrap().len(), 0);
@ -169,6 +184,7 @@ async fn list_tasks_status_and_type_filtered() {
.filtered_tasks(
&["indexCreation", "documentAdditionOrUpdate"],
&["succeeded", "processing", "enqueued"],
&[],
)
.await;
assert_eq!(code, 200, "{}", response);
@ -179,47 +195,47 @@ async fn list_tasks_status_and_type_filtered() {
async fn get_task_filter_error() {
let server = Server::new().await;
let (response, code) = server.tasks_filter(json!( { "lol": "pied" })).await;
let (response, code) = server.tasks_filter("lol=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "Json deserialize error: unknown field `lol`, expected one of `limit`, `from`, `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt` at ``.",
"message": "Unknown parameter `lol`: expected one of `limit`, `from`, `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
let (response, code) = server.tasks_filter(json!( { "uids": "pied" })).await;
let (response, code) = server.tasks_filter("uids=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "invalid digit found in string at `.uids`.",
"message": "Invalid value in parameter `uids`: could not parse `pied` as a positive integer",
"code": "invalid_task_uids",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-uids"
"link": "https://docs.meilisearch.com/errors#invalid_task_uids"
}
"###);
let (response, code) = server.tasks_filter(json!( { "from": "pied" })).await;
let (response, code) = server.tasks_filter("from=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "invalid digit found in string at `.from`.",
"message": "Invalid value in parameter `from`: could not parse `pied` as a positive integer",
"code": "invalid_task_from",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-from"
"link": "https://docs.meilisearch.com/errors#invalid_task_from"
}
"###);
let (response, code) = server.tasks_filter(json!( { "beforeStartedAt": "pied" })).await;
let (response, code) = server.tasks_filter("beforeStartedAt=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "`pied` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format. at `.beforeStartedAt`.",
"message": "Invalid value in parameter `beforeStartedAt`: `pied` is an invalid date-time. It should follow the YYYY-MM-DD or RFC 3339 date-time format.",
"code": "invalid_task_before_started_at",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-before-started-at"
"link": "https://docs.meilisearch.com/errors#invalid_task_before_started_at"
}
"###);
}
@ -228,36 +244,36 @@ async fn get_task_filter_error() {
async fn delete_task_filter_error() {
let server = Server::new().await;
let (response, code) = server.delete_tasks(json!(null)).await;
let (response, code) = server.delete_tasks("").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "Query parameters to filter the tasks to delete are missing. Available query parameters are: `uids`, `indexUids`, `statuses`, `types`, `beforeEnqueuedAt`, `afterEnqueuedAt`, `beforeStartedAt`, `afterStartedAt`, `beforeFinishedAt`, `afterFinishedAt`.",
"message": "Query parameters to filter the tasks to delete are missing. Available query parameters are: `uids`, `indexUids`, `statuses`, `types`, `canceledBy`, `beforeEnqueuedAt`, `afterEnqueuedAt`, `beforeStartedAt`, `afterStartedAt`, `beforeFinishedAt`, `afterFinishedAt`.",
"code": "missing_task_filters",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing-task-filters"
"link": "https://docs.meilisearch.com/errors#missing_task_filters"
}
"###);
let (response, code) = server.delete_tasks(json!({ "lol": "pied" })).await;
let (response, code) = server.delete_tasks("lol=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "Json deserialize error: unknown field `lol`, expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt` at ``.",
"message": "Unknown parameter `lol`: expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
let (response, code) = server.delete_tasks(json!({ "uids": "pied" })).await;
let (response, code) = server.delete_tasks("uids=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "invalid digit found in string at `.uids`.",
"message": "Invalid value in parameter `uids`: could not parse `pied` as a positive integer",
"code": "invalid_task_uids",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-uids"
"link": "https://docs.meilisearch.com/errors#invalid_task_uids"
}
"###);
}
@ -266,36 +282,36 @@ async fn delete_task_filter_error() {
async fn cancel_task_filter_error() {
let server = Server::new().await;
let (response, code) = server.cancel_tasks(json!(null)).await;
let (response, code) = server.cancel_tasks("").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "Query parameters to filter the tasks to cancel are missing. Available query parameters are: `uids`, `indexUids`, `statuses`, `types`, `beforeEnqueuedAt`, `afterEnqueuedAt`, `beforeStartedAt`, `afterStartedAt`, `beforeFinishedAt`, `afterFinishedAt`.",
"message": "Query parameters to filter the tasks to cancel are missing. Available query parameters are: `uids`, `indexUids`, `statuses`, `types`, `canceledBy`, `beforeEnqueuedAt`, `afterEnqueuedAt`, `beforeStartedAt`, `afterStartedAt`, `beforeFinishedAt`, `afterFinishedAt`.",
"code": "missing_task_filters",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#missing-task-filters"
"link": "https://docs.meilisearch.com/errors#missing_task_filters"
}
"###);
let (response, code) = server.cancel_tasks(json!({ "lol": "pied" })).await;
let (response, code) = server.cancel_tasks("lol=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "Json deserialize error: unknown field `lol`, expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt` at ``.",
"message": "Unknown parameter `lol`: expected one of `uids`, `canceledBy`, `types`, `statuses`, `indexUids`, `afterEnqueuedAt`, `beforeEnqueuedAt`, `afterStartedAt`, `beforeStartedAt`, `afterFinishedAt`, `beforeFinishedAt`",
"code": "bad_request",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#bad-request"
"link": "https://docs.meilisearch.com/errors#bad_request"
}
"###);
let (response, code) = server.cancel_tasks(json!({ "uids": "pied" })).await;
let (response, code) = server.cancel_tasks("uids=pied").await;
assert_eq!(code, 400, "{}", response);
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "invalid digit found in string at `.uids`.",
"message": "Invalid value in parameter `uids`: could not parse `pied` as a positive integer",
"code": "invalid_task_uids",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-task-uids"
"link": "https://docs.meilisearch.com/errors#invalid_task_uids"
}
"###);
}
@ -350,7 +366,7 @@ async fn test_summarized_document_addition_or_update() {
index.add_documents(json!({ "id": 42, "content": "doggos & fluff" }), None).await;
index.wait_task(0).await;
let (task, _) = index.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -374,7 +390,7 @@ async fn test_summarized_document_addition_or_update() {
index.add_documents(json!({ "id": 42, "content": "doggos & fluff" }), Some("id")).await;
index.wait_task(1).await;
let (task, _) = index.get_task(1).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -403,7 +419,7 @@ async fn test_summarized_delete_batch() {
index.delete_batch(vec![1, 2, 3]).await;
index.wait_task(0).await;
let (task, _) = index.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -420,7 +436,7 @@ async fn test_summarized_delete_batch() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
@ -433,7 +449,7 @@ async fn test_summarized_delete_batch() {
index.delete_batch(vec![42]).await;
index.wait_task(2).await;
let (task, _) = index.get_task(2).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -462,7 +478,7 @@ async fn test_summarized_delete_document() {
index.delete_document(1).await;
index.wait_task(0).await;
let (task, _) = index.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -479,7 +495,7 @@ async fn test_summarized_delete_document() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
@ -492,7 +508,7 @@ async fn test_summarized_delete_document() {
index.delete_document(42).await;
index.wait_task(2).await;
let (task, _) = index.get_task(2).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -523,17 +539,17 @@ async fn test_summarized_settings_update() {
meili_snap::snapshot!(code, @"400 Bad Request");
meili_snap::snapshot!(meili_snap::json_string!(response), @r###"
{
"message": "`custom` ranking rule is invalid. Valid ranking rules are words, typo, sort, proximity, attribute, exactness and custom ranking rules. at `.rankingRules[0]`.",
"message": "Invalid value at `.rankingRules[0]`: `custom` ranking rule is invalid. Valid ranking rules are words, typo, sort, proximity, attribute, exactness and custom ranking rules.",
"code": "invalid_settings_ranking_rules",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-ranking-rules"
"link": "https://docs.meilisearch.com/errors#invalid_settings_ranking_rules"
}
"###);
index.update_settings(json!({ "displayedAttributes": ["doggos", "name"], "filterableAttributes": ["age", "nb_paw_pads"], "sortableAttributes": ["iq"] })).await;
index.wait_task(0).await;
let (task, _) = index.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -571,7 +587,7 @@ async fn test_summarized_index_creation() {
index.create(None).await;
index.wait_task(0).await;
let (task, _) = index.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -594,7 +610,7 @@ async fn test_summarized_index_creation() {
index.create(Some("doggos")).await;
index.wait_task(1).await;
let (task, _) = index.get_task(1).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -610,7 +626,7 @@ async fn test_summarized_index_creation() {
"message": "Index `test` already exists.",
"code": "index_already_exists",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-already-exists"
"link": "https://docs.meilisearch.com/errors#index_already_exists"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
@ -627,7 +643,7 @@ async fn test_summarized_index_deletion() {
index.delete().await;
index.wait_task(0).await;
let (task, _) = index.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -643,7 +659,7 @@ async fn test_summarized_index_deletion() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
@ -657,7 +673,7 @@ async fn test_summarized_index_deletion() {
index.delete().await;
index.wait_task(2).await;
let (task, _) = index.get_task(2).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -681,7 +697,7 @@ async fn test_summarized_index_deletion() {
index.delete().await;
index.wait_task(2).await;
let (task, _) = index.get_task(2).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -710,7 +726,7 @@ async fn test_summarized_index_update() {
index.update(None).await;
index.wait_task(0).await;
let (task, _) = index.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -726,7 +742,7 @@ async fn test_summarized_index_update() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
@ -738,7 +754,7 @@ async fn test_summarized_index_update() {
index.update(Some("bones")).await;
index.wait_task(1).await;
let (task, _) = index.get_task(1).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -754,7 +770,7 @@ async fn test_summarized_index_update() {
"message": "Index `test` not found.",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#index-not-found"
"link": "https://docs.meilisearch.com/errors#index_not_found"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
@ -769,7 +785,7 @@ async fn test_summarized_index_update() {
index.update(None).await;
index.wait_task(3).await;
let (task, _) = index.get_task(3).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -792,7 +808,7 @@ async fn test_summarized_index_update() {
index.update(Some("bones")).await;
index.wait_task(4).await;
let (task, _) = index.get_task(4).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -823,7 +839,7 @@ async fn test_summarized_index_swap() {
.await;
server.wait_task(0).await;
let (task, _) = server.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -844,9 +860,9 @@ async fn test_summarized_index_swap() {
},
"error": {
"message": "Indexes `cattos`, `doggos` not found.",
"code": "invalid_swap_indexes",
"code": "index_not_found",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-swap-indexes"
"link": "https://docs.meilisearch.com/errors#index_not_found"
},
"duration": "[duration]",
"enqueuedAt": "[date]",
@ -864,7 +880,7 @@ async fn test_summarized_index_swap() {
.await;
server.wait_task(3).await;
let (task, _) = server.get_task(3).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -899,10 +915,10 @@ async fn test_summarized_task_cancelation() {
// to avoid being flaky we're only going to cancel an already finished task :(
index.create(None).await;
index.wait_task(0).await;
server.cancel_tasks(json!({ "uids": [0] })).await;
server.cancel_tasks("uids=0").await;
index.wait_task(1).await;
let (task, _) = index.get_task(1).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -932,10 +948,10 @@ async fn test_summarized_task_deletion() {
// to avoid being flaky we're only going to delete an already finished task :(
index.create(None).await;
index.wait_task(0).await;
server.delete_tasks(json!({ "uids": [0] })).await;
server.delete_tasks("uids=0").await;
index.wait_task(1).await;
let (task, _) = index.get_task(1).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{
@ -964,7 +980,7 @@ async fn test_summarized_dump_creation() {
server.create_dump().await;
server.wait_task(0).await;
let (task, _) = server.get_task(0).await;
assert_json_snapshot!(task,
assert_json_snapshot!(task,
{ ".details.dumpUid" => "[dumpUid]", ".duration" => "[duration]", ".enqueuedAt" => "[date]", ".startedAt" => "[date]", ".finishedAt" => "[date]" },
@r###"
{