mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-10-31 07:56:28 +00:00 
			
		
		
		
	Merge branch 'main' of github.com:meilisearch/meilisearch into CNLHC/change_json_error_message
This commit is contained in:
		| @@ -257,7 +257,7 @@ async fn error_add_api_key_missing_parameter() { | ||||
|         "message": "`indexes` field is mandatory.", | ||||
|         "code": "missing_parameter", | ||||
|         "type": "invalid_request", | ||||
|         "link":"https://docs.meilisearch.com/errors#missing_parameter" | ||||
|         "link": "https://docs.meilisearch.com/errors#missing_parameter" | ||||
|     }); | ||||
|  | ||||
|     assert_eq!(response, expected_response); | ||||
| @@ -275,7 +275,7 @@ async fn error_add_api_key_missing_parameter() { | ||||
|         "message": "`actions` field is mandatory.", | ||||
|         "code": "missing_parameter", | ||||
|         "type": "invalid_request", | ||||
|         "link":"https://docs.meilisearch.com/errors#missing_parameter" | ||||
|         "link": "https://docs.meilisearch.com/errors#missing_parameter" | ||||
|     }); | ||||
|  | ||||
|     assert_eq!(response, expected_response); | ||||
| @@ -293,7 +293,7 @@ async fn error_add_api_key_missing_parameter() { | ||||
|         "message": "`expiresAt` field is mandatory.", | ||||
|         "code": "missing_parameter", | ||||
|         "type": "invalid_request", | ||||
|         "link":"https://docs.meilisearch.com/errors#missing_parameter" | ||||
|         "link": "https://docs.meilisearch.com/errors#missing_parameter" | ||||
|     }); | ||||
|  | ||||
|     assert_eq!(response, expected_response); | ||||
| @@ -316,7 +316,7 @@ async fn error_add_api_key_invalid_parameters_description() { | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": r#"description field value `{"name":"products"}` is invalid. It should be a string or specified as a null value."#, | ||||
|         "message": r#"`description` field value `{"name":"products"}` is invalid. It should be a string or specified as a null value."#, | ||||
|         "code": "invalid_api_key_description", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_description" | ||||
| @@ -342,7 +342,7 @@ async fn error_add_api_key_invalid_parameters_indexes() { | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": r#"indexes field value `{"name":"products"}` is invalid. It should be an array of string representing index names."#, | ||||
|         "message": r#"`indexes` field value `{"name":"products"}` is invalid. It should be an array of string representing index names."#, | ||||
|         "code": "invalid_api_key_indexes", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_indexes" | ||||
| @@ -366,7 +366,7 @@ async fn error_add_api_key_invalid_parameters_actions() { | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": r#"actions field value `{"name":"products"}` is invalid. It should be an array of string representing action names."#, | ||||
|         "message": r#"`actions` field value `{"name":"products"}` is invalid. It should be an array of string representing action names."#, | ||||
|         "code": "invalid_api_key_actions", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_actions" | ||||
| @@ -386,7 +386,7 @@ async fn error_add_api_key_invalid_parameters_actions() { | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": r#"actions field value `["doc.add"]` is invalid. It should be an array of string representing action names."#, | ||||
|         "message": r#"`actions` field value `["doc.add"]` is invalid. It should be an array of string representing action names."#, | ||||
|         "code": "invalid_api_key_actions", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_actions" | ||||
| @@ -412,7 +412,7 @@ async fn error_add_api_key_invalid_parameters_expires_at() { | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": r#"expiresAt field value `{"name":"products"}` is invalid. It should be in ISO-8601 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DDTHH:MM:SS'."#, | ||||
|         "message": r#"`expiresAt` field value `{"name":"products"}` is invalid. 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'."#, | ||||
|         "code": "invalid_api_key_expires_at", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_expires_at" | ||||
| @@ -438,7 +438,7 @@ async fn error_add_api_key_invalid_parameters_expires_at_in_the_past() { | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": r#"expiresAt field value `"2010-11-13T00:00:00Z"` is invalid. It should be in ISO-8601 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DDTHH:MM:SS'."#, | ||||
|         "message": r#"`expiresAt` field value `"2010-11-13T00:00:00Z"` is invalid. 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'."#, | ||||
|         "code": "invalid_api_key_expires_at", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_expires_at" | ||||
| @@ -1213,7 +1213,7 @@ async fn error_patch_api_key_indexes_invalid_parameters() { | ||||
|     let (response, code) = server.patch_api_key(&key, content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": "description field value `13` is invalid. It should be a string or specified as a null value.", | ||||
|         "message": "`description` field value `13` is invalid. It should be a string or specified as a null value.", | ||||
|         "code": "invalid_api_key_description", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_description" | ||||
| @@ -1230,7 +1230,7 @@ async fn error_patch_api_key_indexes_invalid_parameters() { | ||||
|     let (response, code) = server.patch_api_key(&key, content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": "indexes field value `13` is invalid. It should be an array of string representing index names.", | ||||
|         "message": "`indexes` field value `13` is invalid. It should be an array of string representing index names.", | ||||
|         "code": "invalid_api_key_indexes", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_indexes" | ||||
| @@ -1246,7 +1246,7 @@ async fn error_patch_api_key_indexes_invalid_parameters() { | ||||
|     let (response, code) = server.patch_api_key(&key, content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": "actions field value `13` is invalid. It should be an array of string representing action names.", | ||||
|         "message": "`actions` field value `13` is invalid. It should be an array of string representing action names.", | ||||
|         "code": "invalid_api_key_actions", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_actions" | ||||
| @@ -1262,7 +1262,7 @@ async fn error_patch_api_key_indexes_invalid_parameters() { | ||||
|     let (response, code) = server.patch_api_key(&key, content).await; | ||||
|  | ||||
|     let expected_response = json!({ | ||||
|         "message": "expiresAt field value `13` is invalid. It should be in ISO-8601 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DDTHH:MM:SS'.", | ||||
|         "message": "`expiresAt` field value `13` is invalid. 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'.", | ||||
|         "code": "invalid_api_key_expires_at", | ||||
|         "type": "invalid_request", | ||||
|         "link": "https://docs.meilisearch.com/errors#invalid_api_key_expires_at" | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| use crate::common::Server; | ||||
| use chrono::{Duration, Utc}; | ||||
| use ::time::format_description::well_known::Rfc3339; | ||||
| use maplit::{hashmap, hashset}; | ||||
| use once_cell::sync::Lazy; | ||||
| use serde_json::{json, Value}; | ||||
| use std::collections::{HashMap, HashSet}; | ||||
| use time::{Duration, OffsetDateTime}; | ||||
|  | ||||
| pub static AUTHORIZATIONS: Lazy<HashMap<(&'static str, &'static str), HashSet<&'static str>>> = | ||||
|     Lazy::new(|| { | ||||
| @@ -76,7 +77,7 @@ async fn error_access_expired_key() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["products"], | ||||
|         "actions": ALL_ACTIONS.clone(), | ||||
|         "expiresAt": (Utc::now() + Duration::seconds(1)), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::seconds(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -106,7 +107,7 @@ async fn error_access_unauthorized_index() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["sales"], | ||||
|         "actions": ALL_ACTIONS.clone(), | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -137,7 +138,7 @@ async fn error_access_unauthorized_action() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["products"], | ||||
|         "actions": [], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -174,7 +175,7 @@ async fn access_authorized_restricted_index() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["products"], | ||||
|         "actions": [], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -213,7 +214,7 @@ async fn access_authorized_no_index_restriction() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "actions": [], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -263,7 +264,7 @@ async fn access_authorized_stats_restricted_index() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["products"], | ||||
|         "actions": ["stats.get"], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|     assert_eq!(code, 201); | ||||
| @@ -303,7 +304,7 @@ async fn access_authorized_stats_no_index_restriction() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "actions": ["stats.get"], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|     assert_eq!(code, 201); | ||||
| @@ -343,7 +344,7 @@ async fn list_authorized_indexes_restricted_index() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["products"], | ||||
|         "actions": ["indexes.get"], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|     assert_eq!(code, 201); | ||||
| @@ -384,7 +385,7 @@ async fn list_authorized_indexes_no_index_restriction() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "actions": ["indexes.get"], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|     assert_eq!(code, 201); | ||||
| @@ -424,7 +425,7 @@ async fn list_authorized_tasks_restricted_index() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["products"], | ||||
|         "actions": ["tasks.get"], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|     assert_eq!(code, 201); | ||||
| @@ -464,7 +465,7 @@ async fn list_authorized_tasks_no_index_restriction() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "actions": ["tasks.get"], | ||||
|         "expiresAt": Utc::now() + Duration::hours(1), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
|     assert_eq!(code, 201); | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| use crate::common::Server; | ||||
| use chrono::{Duration, Utc}; | ||||
| use ::time::format_description::well_known::Rfc3339; | ||||
| use maplit::hashmap; | ||||
| use once_cell::sync::Lazy; | ||||
| use serde_json::{json, Value}; | ||||
| use std::collections::HashMap; | ||||
| use time::{Duration, OffsetDateTime}; | ||||
|  | ||||
| use super::authorization::{ALL_ACTIONS, AUTHORIZATIONS}; | ||||
|  | ||||
| @@ -63,22 +64,22 @@ static ACCEPTED_KEYS: Lazy<Vec<Value>> = Lazy::new(|| { | ||||
|         json!({ | ||||
|             "indexes": ["*"], | ||||
|             "actions": ["*"], | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|         json!({ | ||||
|             "indexes": ["*"], | ||||
|             "actions": ["search"], | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|         json!({ | ||||
|             "indexes": ["sales"], | ||||
|             "actions": ["*"], | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|         json!({ | ||||
|             "indexes": ["sales"], | ||||
|             "actions": ["search"], | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|     ] | ||||
| }); | ||||
| @@ -89,23 +90,23 @@ static REFUSED_KEYS: Lazy<Vec<Value>> = Lazy::new(|| { | ||||
|         json!({ | ||||
|             "indexes": ["*"], | ||||
|             "actions": ALL_ACTIONS.iter().cloned().filter(|a| *a != "search" && *a != "*").collect::<Vec<_>>(), | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|         json!({ | ||||
|             "indexes": ["sales"], | ||||
|             "actions": ALL_ACTIONS.iter().cloned().filter(|a| *a != "search" && *a != "*").collect::<Vec<_>>(), | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|         // bad index | ||||
|         json!({ | ||||
|             "indexes": ["products"], | ||||
|             "actions": ["*"], | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|         json!({ | ||||
|             "indexes": ["products"], | ||||
|             "actions": ["search"], | ||||
|             "expiresAt": Utc::now() + Duration::days(1) | ||||
|             "expiresAt": (OffsetDateTime::now_utc() + Duration::days(1)).format(&Rfc3339).unwrap() | ||||
|         }), | ||||
|     ] | ||||
| }); | ||||
| @@ -204,19 +205,19 @@ async fn search_authorized_simple_token() { | ||||
|     let tenant_tokens = vec![ | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!(["*"]), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": {}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!(["sales"]), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {}}), | ||||
| @@ -253,19 +254,19 @@ async fn search_authorized_filter_token() { | ||||
|     let tenant_tokens = vec![ | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {"filter": "color = blue"}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": {"filter": "color = blue"}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {"filter": ["color = blue"]}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": {"filter": ["color = blue"]}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         // filter on sales should override filters on * | ||||
|         hashmap! { | ||||
| @@ -273,28 +274,28 @@ async fn search_authorized_filter_token() { | ||||
|                 "*": {"filter": "color = green"}, | ||||
|                 "sales": {"filter": "color = blue"} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({ | ||||
|                 "*": {}, | ||||
|                 "sales": {"filter": "color = blue"} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({ | ||||
|                 "*": {"filter": "color = green"}, | ||||
|                 "sales": {"filter": ["color = blue"]} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({ | ||||
|                 "*": {}, | ||||
|                 "sales": {"filter": ["color = blue"]} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|     ]; | ||||
|  | ||||
| @@ -307,19 +308,19 @@ async fn filter_search_authorized_filter_token() { | ||||
|     let tenant_tokens = vec![ | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {"filter": "color = blue"}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": {"filter": "color = blue"}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {"filter": ["color = blue"]}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": {"filter": ["color = blue"]}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         // filter on sales should override filters on * | ||||
|         hashmap! { | ||||
| @@ -327,28 +328,28 @@ async fn filter_search_authorized_filter_token() { | ||||
|                 "*": {"filter": "color = green"}, | ||||
|                 "sales": {"filter": "color = blue"} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({ | ||||
|                 "*": {}, | ||||
|                 "sales": {"filter": "color = blue"} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({ | ||||
|                 "*": {"filter": "color = green"}, | ||||
|                 "sales": {"filter": ["color = blue"]} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({ | ||||
|                 "*": {}, | ||||
|                 "sales": {"filter": ["color = blue"]} | ||||
|             }), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|     ]; | ||||
|  | ||||
| @@ -361,27 +362,27 @@ async fn error_search_token_forbidden_parent_key() { | ||||
|     let tenant_tokens = vec![ | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": Value::Null}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!(["*"]), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": {}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": Value::Null}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!(["sales"]), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|     ]; | ||||
|  | ||||
| @@ -395,11 +396,11 @@ async fn error_search_forbidden_token() { | ||||
|         // bad index | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"products": {}}), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!(["products"]), | ||||
|             "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"products": {}}), | ||||
| @@ -416,27 +417,27 @@ async fn error_search_forbidden_token() { | ||||
|         // expired token | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": {}}), | ||||
|             "exp" => json!((Utc::now() - Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() - Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"*": Value::Null}), | ||||
|             "exp" => json!((Utc::now() - Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() - Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!(["*"]), | ||||
|             "exp" => json!((Utc::now() - Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() - Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": {}}), | ||||
|             "exp" => json!((Utc::now() - Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() - Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!({"sales": Value::Null}), | ||||
|             "exp" => json!((Utc::now() - Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() - Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|         hashmap! { | ||||
|             "searchRules" => json!(["sales"]), | ||||
|             "exp" => json!((Utc::now() - Duration::hours(1)).timestamp()) | ||||
|             "exp" => json!((OffsetDateTime::now_utc() - Duration::hours(1)).unix_timestamp()) | ||||
|         }, | ||||
|     ]; | ||||
|  | ||||
| @@ -452,7 +453,7 @@ async fn error_access_forbidden_routes() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "actions": ["*"], | ||||
|         "expiresAt": (Utc::now() + Duration::hours(1)), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -463,7 +464,7 @@ async fn error_access_forbidden_routes() { | ||||
|  | ||||
|     let tenant_token = hashmap! { | ||||
|         "searchRules" => json!(["*"]), | ||||
|         "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|         "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|     }; | ||||
|     let web_token = generate_tenant_token(&key, tenant_token); | ||||
|     server.use_api_key(&web_token); | ||||
| @@ -487,7 +488,7 @@ async fn error_access_expired_parent_key() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "actions": ["*"], | ||||
|         "expiresAt": (Utc::now() + Duration::seconds(1)), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::seconds(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -498,7 +499,7 @@ async fn error_access_expired_parent_key() { | ||||
|  | ||||
|     let tenant_token = hashmap! { | ||||
|         "searchRules" => json!(["*"]), | ||||
|         "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|         "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|     }; | ||||
|     let web_token = generate_tenant_token(&key, tenant_token); | ||||
|     server.use_api_key(&web_token); | ||||
| @@ -529,7 +530,7 @@ async fn error_access_modified_token() { | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "actions": ["*"], | ||||
|         "expiresAt": (Utc::now() + Duration::hours(1)), | ||||
|         "expiresAt": (OffsetDateTime::now_utc() + Duration::hours(1)).format(&Rfc3339).unwrap(), | ||||
|     }); | ||||
|  | ||||
|     let (response, code) = server.add_api_key(content).await; | ||||
| @@ -540,7 +541,7 @@ async fn error_access_modified_token() { | ||||
|  | ||||
|     let tenant_token = hashmap! { | ||||
|         "searchRules" => json!(["products"]), | ||||
|         "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|         "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|     }; | ||||
|     let web_token = generate_tenant_token(&key, tenant_token); | ||||
|     server.use_api_key(&web_token); | ||||
| @@ -554,7 +555,7 @@ async fn error_access_modified_token() { | ||||
|  | ||||
|     let tenant_token = hashmap! { | ||||
|         "searchRules" => json!(["*"]), | ||||
|         "exp" => json!((Utc::now() + Duration::hours(1)).timestamp()) | ||||
|         "exp" => json!((OffsetDateTime::now_utc() + Duration::hours(1)).unix_timestamp()) | ||||
|     }; | ||||
|  | ||||
|     let alt = generate_tenant_token(&key, tenant_token); | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| use crate::common::{GetAllDocumentsOptions, Server}; | ||||
| use actix_web::test; | ||||
| use chrono::DateTime; | ||||
| use meilisearch_http::{analytics, create_app}; | ||||
| use serde_json::{json, Value}; | ||||
| use time::{format_description::well_known::Rfc3339, OffsetDateTime}; | ||||
|  | ||||
| /// This is the basic usage of our API and every other tests uses the content-type application/json | ||||
| #[actix_rt::test] | ||||
| @@ -568,9 +568,9 @@ async fn add_documents_no_index_creation() { | ||||
|     assert_eq!(response["details"]["indexedDocuments"], 1); | ||||
|  | ||||
|     let processed_at = | ||||
|         DateTime::parse_from_rfc3339(response["finishedAt"].as_str().unwrap()).unwrap(); | ||||
|         OffsetDateTime::parse(response["finishedAt"].as_str().unwrap(), &Rfc3339).unwrap(); | ||||
|     let enqueued_at = | ||||
|         DateTime::parse_from_rfc3339(response["enqueuedAt"].as_str().unwrap()).unwrap(); | ||||
|         OffsetDateTime::parse(response["enqueuedAt"].as_str().unwrap(), &Rfc3339).unwrap(); | ||||
|     assert!(processed_at > enqueued_at); | ||||
|  | ||||
|     // index was created, and primary key was infered. | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| use crate::common::Server; | ||||
| use chrono::DateTime; | ||||
| use serde_json::json; | ||||
| use time::{format_description::well_known::Rfc3339, OffsetDateTime}; | ||||
|  | ||||
| #[actix_rt::test] | ||||
| async fn update_primary_key() { | ||||
| @@ -25,8 +25,10 @@ async fn update_primary_key() { | ||||
|     assert!(response.get("createdAt").is_some()); | ||||
|     assert!(response.get("updatedAt").is_some()); | ||||
|  | ||||
|     let created_at = DateTime::parse_from_rfc3339(response["createdAt"].as_str().unwrap()).unwrap(); | ||||
|     let updated_at = DateTime::parse_from_rfc3339(response["updatedAt"].as_str().unwrap()).unwrap(); | ||||
|     let created_at = | ||||
|         OffsetDateTime::parse(response["createdAt"].as_str().unwrap(), &Rfc3339).unwrap(); | ||||
|     let updated_at = | ||||
|         OffsetDateTime::parse(response["updatedAt"].as_str().unwrap(), &Rfc3339).unwrap(); | ||||
|     assert!(created_at < updated_at); | ||||
|  | ||||
|     assert_eq!(response["primaryKey"], "primary"); | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| use serde_json::json; | ||||
| use time::{format_description::well_known::Rfc3339, OffsetDateTime}; | ||||
|  | ||||
| use crate::common::Server; | ||||
|  | ||||
| @@ -57,11 +58,15 @@ async fn stats() { | ||||
|  | ||||
|     index.wait_task(1).await; | ||||
|  | ||||
|     let timestamp = OffsetDateTime::now_utc(); | ||||
|     let (response, code) = server.stats().await; | ||||
|  | ||||
|     assert_eq!(code, 200); | ||||
|     assert!(response["databaseSize"].as_u64().unwrap() > 0); | ||||
|     assert!(response.get("lastUpdate").is_some()); | ||||
|     let last_update = | ||||
|         OffsetDateTime::parse(response["lastUpdate"].as_str().unwrap(), &Rfc3339).unwrap(); | ||||
|     assert!(last_update - timestamp < time::Duration::SECOND); | ||||
|  | ||||
|     assert_eq!(response["indexes"]["test"]["numberOfDocuments"], 2); | ||||
|     assert!(response["indexes"]["test"]["isIndexing"] == false); | ||||
|     assert_eq!(response["indexes"]["test"]["fieldDistribution"]["id"], 2); | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| use crate::common::Server; | ||||
| use chrono::{DateTime, Utc}; | ||||
| use serde_json::json; | ||||
| use time::format_description::well_known::Rfc3339; | ||||
| use time::OffsetDateTime; | ||||
|  | ||||
| #[actix_rt::test] | ||||
| async fn error_get_task_unexisting_index() { | ||||
| @@ -98,7 +99,8 @@ macro_rules! assert_valid_summarized_task { | ||||
|         assert_eq!($response["status"], "enqueued"); | ||||
|         assert_eq!($response["type"], $task_type); | ||||
|         let date = $response["enqueuedAt"].as_str().expect("missing date"); | ||||
|         date.parse::<DateTime<Utc>>().unwrap(); | ||||
|  | ||||
|         OffsetDateTime::parse(date, &Rfc3339).unwrap(); | ||||
|     }}; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user