Skip to content

Commit 24e6b17

Browse files
bidoubiwairevoire
andauthored
Update keys for v0.28.0 (#313)
* Update task api v0.28.0 * Update tests to be relevant with the structures where they are ran * Update types in code-samples * Remove clearAll task type * Add index_uid as an optional in the Tasks * Add comments on best builder implementation * Add execute function on get_tasks * Update code samples * Remove out of context comment * Fix tests * Fix pagination tests * Update HTTP methods for v0.28.0 * Fix clippy * Remove comment of task tests since the tests are now sucesful * Fix doc tests * Update keys for v0.28.0 * Fix get tasks inside index structure * Make description and name optional in keys * Fix none doc tests with new get_tasks api * Add from and limit in tasks params * Add warning on failing test * Update keys design * Update task API * Remove useless comment * Remove client as mandatory parameter for the keyUpdater * Add doc and tests on doc * Fix docs tests on keys in client * Fix docs tests * Remove dbg * Add with_uid filter * Add new actions on key creation * Remove new line at the start of docs * Fix clippy errors * Rename type in Task structure * Removed useless newlines * Fix typo in comment * Add missing semi-column * Improve doc comments * Fix Keys actions * Un hide assert in execute fonction of key * Remove useless comment * Remove flacky test * Use name parameter instead of hardcoded name in key tests * Update src/key.rs Co-authored-by: Tamo <[email protected]> Co-authored-by: Tamo <[email protected]>
1 parent 99f9e39 commit 24e6b17

File tree

3 files changed

+473
-248
lines changed

3 files changed

+473
-248
lines changed

src/client.rs

Lines changed: 97 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
errors::*,
33
indexes::*,
4-
key::{Key, KeyBuilder},
4+
key::{Key, KeyBuilder, KeyUpdater, KeysQuery, KeysResults},
55
request::*,
66
task_info::TaskInfo,
77
tasks::{Task, TasksQuery, TasksResults},
@@ -309,6 +309,40 @@ impl Client {
309309
}
310310
}
311311

312+
/// Get the API [Key]s from Meilisearch with parameters.
313+
/// See the [meilisearch documentation](https://docs.meilisearch.com/reference/api/keys.html#get-all-keys).
314+
///
315+
/// See also [Client::create_key] and [Client::get_key].
316+
///
317+
/// # Example
318+
///
319+
/// ```
320+
/// # use meilisearch_sdk::{client::*, errors::Error, key::KeysQuery};
321+
/// #
322+
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
323+
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
324+
/// #
325+
/// # futures::executor::block_on(async move {
326+
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
327+
/// let mut query = KeysQuery::new();
328+
/// query.with_limit(1);
329+
/// let keys = client.get_keys_with(&query).await.unwrap();
330+
///
331+
/// assert_eq!(keys.results.len(), 1);
332+
/// # });
333+
/// ```
334+
pub async fn get_keys_with(&self, keys_query: &KeysQuery) -> Result<KeysResults, Error> {
335+
let keys = request::<&KeysQuery, KeysResults>(
336+
&format!("{}/keys", self.host),
337+
&self.api_key,
338+
Method::Get(keys_query),
339+
200,
340+
)
341+
.await?;
342+
343+
Ok(keys)
344+
}
345+
312346
/// Get the API [Key]s from Meilisearch.
313347
/// See the [meilisearch documentation](https://docs.meilisearch.com/reference/api/keys.html#get-all-keys).
314348
///
@@ -325,26 +359,20 @@ impl Client {
325359
/// # futures::executor::block_on(async move {
326360
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
327361
/// let keys = client.get_keys().await.unwrap();
328-
/// assert!(keys.len() >= 2);
362+
///
363+
/// assert_eq!(keys.results.len(), 2);
329364
/// # });
330365
/// ```
331-
pub async fn get_keys(&self) -> Result<Vec<Key>, Error> {
332-
#[derive(Deserialize)]
333-
#[serde(rename_all = "camelCase")]
334-
pub struct Keys {
335-
#[serde(rename = "results")]
336-
pub inner: Vec<Key>,
337-
}
338-
339-
let keys = request::<(), Keys>(
366+
pub async fn get_keys(&self) -> Result<KeysResults, Error> {
367+
let keys = request::<(), KeysResults>(
340368
&format!("{}/keys", self.host),
341369
&self.api_key,
342370
Method::Get(()),
343371
200,
344372
)
345373
.await?;
346374

347-
Ok(keys.inner)
375+
Ok(keys)
348376
}
349377

350378
/// Get one API [Key] from Meilisearch.
@@ -362,11 +390,12 @@ impl Client {
362390
/// #
363391
/// # futures::executor::block_on(async move {
364392
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
365-
/// # let key = client.get_keys().await.unwrap().into_iter().find(|k| k.description.starts_with("Default Search API Key")).unwrap();
366-
/// let key_id = // enter your API key here, for the example we'll say we entered our search API key.
367-
/// # key.key;
393+
/// # let key = client.get_keys().await.unwrap().results.into_iter()
394+
/// .find(|k| k.name.as_ref().map_or(false, |name| name.starts_with("Default Search API Key")));
395+
/// let key_id = key.unwrap().key // enter your API key here, for the example we use the search API key.
368396
/// let key = client.get_key(key_id).await.unwrap();
369-
/// assert_eq!(key.description, "Default Search API Key (Use it to search from the frontend)");
397+
///
398+
/// assert_eq!(key.name, Some("Default Search API Key".to_string()));
370399
/// # });
371400
/// ```
372401
pub async fn get_key(&self, key: impl AsRef<str>) -> Result<Key, Error> {
@@ -394,14 +423,14 @@ impl Client {
394423
/// #
395424
/// # futures::executor::block_on(async move {
396425
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
397-
/// let key = KeyBuilder::new("delete_key");
426+
/// let key = KeyBuilder::new();
398427
/// let key = client.create_key(key).await.unwrap();
399428
/// let inner_key = key.key.clone();
400429
///
401430
/// client.delete_key(key).await.unwrap();
402431
///
403432
/// let keys = client.get_keys().await.unwrap();
404-
/// assert!(keys.iter().all(|key| key.key != inner_key));
433+
/// assert!(keys.results.iter().all(|key| key.key != inner_key));
405434
/// # });
406435
/// ```
407436
pub async fn delete_key(&self, key: impl AsRef<str>) -> Result<(), Error> {
@@ -429,11 +458,12 @@ impl Client {
429458
/// #
430459
/// # futures::executor::block_on(async move {
431460
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
432-
/// let mut key = KeyBuilder::new("create_key");
433-
/// key.with_index("*").with_action(Action::DocumentsAdd);
434-
/// let key = client.create_key(key).await.unwrap();
461+
/// let name = "create_key".to_string();
462+
/// let mut key = KeyBuilder::new();
463+
/// key.with_name(&name);
435464
///
436-
/// assert_eq!(key.description, "create_key");
465+
/// let key = client.create_key(key).await.unwrap();
466+
/// assert_eq!(key.name, Some(name));
437467
/// # client.delete_key(key).await.unwrap();
438468
/// # });
439469
/// ```
@@ -455,25 +485,26 @@ impl Client {
455485
/// # Example
456486
///
457487
/// ```
458-
/// # use meilisearch_sdk::{client::*, errors::Error, key::KeyBuilder};
488+
/// # use meilisearch_sdk::{client::*, errors::Error, key::KeyBuilder, key::KeyUpdater};
459489
/// #
460490
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
461491
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
462492
/// #
463493
/// # futures::executor::block_on(async move {
464494
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
465-
/// let key = KeyBuilder::new("update_key");
466-
/// let mut key = client.create_key(key).await.unwrap();
467-
/// assert!(key.indexes.is_empty());
495+
/// let new_key = KeyBuilder::new();
496+
/// let name = "my name".to_string();
497+
/// let mut new_key = client.create_key(new_key).await.unwrap();
498+
/// let mut key_update = KeyUpdater::new(new_key);
499+
/// key_update.with_name(&name);
468500
///
469-
/// key.indexes = vec!["*".to_string()];
470-
/// let key = client.update_key(key).await.unwrap();
471-
/// assert_eq!(key.indexes, vec!["*"]);
501+
/// let key = client.update_key(key_update).await.unwrap();
502+
/// assert_eq!(key.name, Some(name));
472503
/// # client.delete_key(key).await.unwrap();
473504
/// # });
474505
/// ```
475-
pub async fn update_key(&self, key: impl AsRef<Key>) -> Result<Key, Error> {
476-
request::<&Key, Key>(
506+
pub async fn update_key(&self, key: impl AsRef<KeyUpdater>) -> Result<Key, Error> {
507+
request::<&KeyUpdater, Key>(
477508
&format!("{}/keys/{}", self.host, key.as_ref().key),
478509
&self.api_key,
479510
Method::Patch(key.as_ref()),
@@ -814,33 +845,35 @@ mod tests {
814845
async fn test_get_tasks_with_params(client: Client) {
815846
let query = TasksQuery::new(&client);
816847
let tasks = client.get_tasks_with(&query).await.unwrap();
848+
817849
assert!(tasks.results.len() >= 2);
818850
}
819851

820852
#[meilisearch_test]
821853
async fn test_get_keys(client: Client) {
822854
let keys = client.get_keys().await.unwrap();
823-
assert!(keys.len() >= 2);
824-
assert!(keys.iter().any(
825-
|k| k.description != "Default Search API Key (Use it to search from the frontend)"
826-
));
827-
assert!(keys.iter().any(
828-
|k| k.description != "Default Admin API Key (Use it for all other operations. Caution! Do not use it on a public frontend)"
829-
));
855+
856+
assert!(keys.results.len() >= 2);
830857
}
831858

832859
#[meilisearch_test]
833-
async fn test_delete_key(client: Client, description: String) {
834-
let key = KeyBuilder::new(description);
860+
async fn test_delete_key(client: Client, name: String) {
861+
let mut key = KeyBuilder::new();
862+
key.with_name(&name);
835863
let key = client.create_key(key).await.unwrap();
836864

837865
client.delete_key(&key).await.unwrap();
838-
let keys = client.get_keys().await.unwrap();
839-
assert!(keys.iter().all(|k| k.key != key.key));
866+
let keys = KeysQuery::new()
867+
.with_limit(10000)
868+
.execute(&client)
869+
.await
870+
.unwrap();
871+
872+
assert!(keys.results.iter().all(|k| k.key != key.key));
840873
}
841874

842875
#[meilisearch_test]
843-
async fn test_error_delete_key(mut client: Client, description: String) {
876+
async fn test_error_delete_key(mut client: Client, name: String) {
844877
// ==> accessing a key that does not exist
845878
let error = client.delete_key("invalid_key").await.unwrap_err();
846879
assert!(matches!(
@@ -853,7 +886,8 @@ mod tests {
853886
));
854887

855888
// ==> executing the action without enough right
856-
let key = KeyBuilder::new(description);
889+
let mut key = KeyBuilder::new();
890+
key.with_name(&name);
857891
let key = client.create_key(key).await.unwrap();
858892

859893
let master_key = client.api_key.clone();
@@ -886,44 +920,33 @@ mod tests {
886920
}
887921

888922
#[meilisearch_test]
889-
async fn test_create_key(client: Client, description: String) {
923+
async fn test_create_key(client: Client, name: String) {
890924
let expires_at = OffsetDateTime::now_utc() + time::Duration::HOUR;
891-
let mut key = KeyBuilder::new(description.clone());
925+
let mut key = KeyBuilder::new();
892926
key.with_action(Action::DocumentsAdd)
927+
.with_name(&name)
893928
.with_expires_at(expires_at.clone())
929+
.with_description("a description")
894930
.with_index("*");
895931
let key = client.create_key(key).await.unwrap();
896932

897933
assert_eq!(key.actions, vec![Action::DocumentsAdd]);
898-
assert_eq!(key.description, description);
934+
assert_eq!(&key.name, &Some(name));
899935
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
900936
assert_eq!(
901937
key.expires_at.unwrap().unix_timestamp(),
902938
expires_at.unix_timestamp()
903939
);
904940
assert_eq!(key.indexes, vec!["*".to_string()]);
905941

906-
let keys = client.get_keys().await.unwrap();
907-
908-
let remote_key = keys.iter().find(|k| k.key == key.key).unwrap();
909-
910-
assert_eq!(remote_key.actions, vec![Action::DocumentsAdd]);
911-
assert_eq!(remote_key.description, description);
912-
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
913-
assert_eq!(
914-
remote_key.expires_at.unwrap().unix_timestamp(),
915-
expires_at.unix_timestamp()
916-
);
917-
assert_eq!(remote_key.indexes, vec!["*".to_string()]);
918-
919942
client.delete_key(key).await.unwrap();
920943
}
921944

922945
#[meilisearch_test]
923-
async fn test_error_create_key(mut client: Client, description: String) {
946+
async fn test_error_create_key(mut client: Client, name: String) {
924947
// ==> Invalid index name
925948
/* TODO: uncomment once meilisearch fix this bug: https://github.com/meilisearch/meilisearch/issues/2158
926-
let mut key = KeyBuilder::new(&description);
949+
let mut key = KeyBuilder::new();
927950
key.with_index("invalid index # / \\name with spaces");
928951
let error = client.create_key(key).await.unwrap_err();
929952
@@ -938,14 +961,16 @@ mod tests {
938961
*/
939962

940963
// ==> executing the action without enough right
941-
let no_right_key = KeyBuilder::new(&description);
964+
let mut no_right_key = KeyBuilder::new();
965+
no_right_key.with_name(&format!("{name}_1"));
942966
let no_right_key = client.create_key(no_right_key).await.unwrap();
943967

944968
// backup the master key for cleanup at the end of the test
945969
let master_client = client.clone();
946970
client.api_key = Arc::new(no_right_key.key.clone());
947971

948-
let key = KeyBuilder::new(&description);
972+
let mut key = KeyBuilder::new();
973+
key.with_name(format!("{name}_2"));
949974
let error = client.create_key(key).await.unwrap_err();
950975

951976
assert!(matches!(
@@ -963,84 +988,22 @@ mod tests {
963988

964989
#[meilisearch_test]
965990
async fn test_update_key(client: Client, description: String) {
966-
let expires_at = OffsetDateTime::now_utc() + time::Duration::HOUR;
967-
let key = KeyBuilder::new(description.clone());
991+
let mut key = KeyBuilder::new();
992+
key.with_name("test_update_key");
968993
let mut key = client.create_key(key).await.unwrap();
969994

970-
key.actions = vec![Action::DocumentsAdd];
971-
key.expires_at = Some(expires_at);
972-
key.indexes = vec!["*".to_string()];
973-
974-
let key = client.update_key(key).await.unwrap();
975-
976-
assert_eq!(key.actions, vec![Action::DocumentsAdd]);
977-
assert_eq!(key.description, description);
978-
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
979-
assert_eq!(
980-
key.expires_at.unwrap().unix_timestamp(),
981-
expires_at.unix_timestamp()
982-
);
983-
assert_eq!(key.indexes, vec!["*".to_string()]);
995+
let name = "new name".to_string();
996+
key.with_description(&description);
997+
key.with_name(&name);
984998

985-
let keys = client.get_keys().await.unwrap();
986-
987-
let remote_key = keys.iter().find(|k| k.key == key.key).unwrap();
999+
let key = key.update(&client).await.unwrap();
9881000

989-
assert_eq!(remote_key.actions, vec![Action::DocumentsAdd]);
990-
assert_eq!(remote_key.description, description);
991-
// We can't compare the two timestamp directly because of some nanoseconds imprecision with the floats
992-
assert_eq!(
993-
remote_key.expires_at.unwrap().unix_timestamp(),
994-
expires_at.unix_timestamp()
995-
);
996-
assert_eq!(remote_key.indexes, vec!["*".to_string()]);
1001+
assert_eq!(key.description, Some(description));
1002+
assert_eq!(key.name, Some(name));
9971003

9981004
client.delete_key(key).await.unwrap();
9991005
}
10001006

1001-
#[meilisearch_test]
1002-
async fn test_error_update_key(mut client: Client, description: String) {
1003-
let key = KeyBuilder::new(description.clone());
1004-
let key = client.create_key(key).await.unwrap();
1005-
1006-
// ==> Invalid index name
1007-
/* TODO: uncomment once meilisearch fix this bug: https://github.com/meilisearch/meilisearch/issues/2158
1008-
key.indexes = vec!["invalid index # / \\name with spaces".to_string()];
1009-
let error = client.update_key(key).await.unwrap_err();
1010-
1011-
assert!(matches!(
1012-
error,
1013-
Error::MeilisearchError {
1014-
error_code: ErrorCode::InvalidApiKeyIndexes,
1015-
error_type: ErrorType::InvalidRequest,
1016-
..
1017-
}
1018-
));
1019-
*/
1020-
1021-
// ==> executing the action without enough right
1022-
let no_right_key = KeyBuilder::new(&description);
1023-
let no_right_key = client.create_key(no_right_key).await.unwrap();
1024-
1025-
// backup the master key for cleanup at the end of the test
1026-
let master_client = client.clone();
1027-
client.api_key = Arc::new(no_right_key.key.clone());
1028-
1029-
let error = client.update_key(key).await.unwrap_err();
1030-
1031-
assert!(matches!(
1032-
error,
1033-
Error::Meilisearch(MeilisearchError {
1034-
error_code: ErrorCode::InvalidApiKey,
1035-
error_type: ErrorType::Auth,
1036-
..
1037-
})
1038-
));
1039-
1040-
// cleanup
1041-
master_client.delete_key(&*client.api_key).await.unwrap();
1042-
}
1043-
10441007
#[meilisearch_test]
10451008
async fn test_get_index(client: Client, index_uid: String) -> Result<(), Error> {
10461009
let task = client.create_index(&index_uid, None).await?;

0 commit comments

Comments
 (0)