From b4c3f6831d6599b669111d98ebbac7a440a22ee9 Mon Sep 17 00:00:00 2001 From: Abhijit Roy Date: Thu, 31 Oct 2024 04:32:59 +0530 Subject: [PATCH] Add todos module & its tests --- api-requests/auth.http | 8 ++-- api-requests/todos.http | 65 +++++++++++++++++++++++++++ src/lib.rs | 3 ++ src/todos.rs | 98 +++++++++++++++++++++++++++++++++++++++++ tests/todos.rs | 90 +++++++++++++++++++++++++++++++++++++ 5 files changed, 260 insertions(+), 4 deletions(-) create mode 100644 api-requests/todos.http create mode 100644 src/todos.rs create mode 100644 tests/todos.rs diff --git a/api-requests/auth.http b/api-requests/auth.http index a567559..5295f4e 100644 --- a/api-requests/auth.http +++ b/api-requests/auth.http @@ -1,8 +1,8 @@ -@host=https://dummyjson.com +@host=https://dummyjson.com/auth ### # @name LoginUser -POST {{host}}/auth/login +POST {{host}}/login Accept: application/json Content-Type: application/json @@ -15,7 +15,7 @@ Content-Type: application/json ### # @name GetUser @YOUR_ACCESS_TOKEN={{LoginUser.response.body.accessToken}} -GET {{host}}/auth/me +GET {{host}}/me Accept: application/json Content-Type: application/json Authorization: Bearer {{YOUR_ACCESS_TOKEN}} @@ -23,7 +23,7 @@ Authorization: Bearer {{YOUR_ACCESS_TOKEN}} ### # @name RefreshAuthSession @YOUR_REFRESH_TOKEN={{LoginUser.response.body.refreshToken}} -POST {{host}}/auth/refresh +POST {{host}}/refresh Accept: application/json Content-Type: application/json diff --git a/api-requests/todos.http b/api-requests/todos.http new file mode 100644 index 0000000..c22b29c --- /dev/null +++ b/api-requests/todos.http @@ -0,0 +1,65 @@ +@host=https://dummyjson.com/todos + +### +# @name GetAllTodos +GET {{host}} +Accept: application/json +Content-Type: application/json + +### +# @name GetTodoById +GET {{host}}/1 +Accept: application/json +Content-Type: application/json + +### +# @name GetRandomTodo +GET {{host}}/random +Accept: application/json +Content-Type: application/json + +### +# @name GetRandomTodos +GET {{host}}/random/3 +Accept: application/json +Content-Type: application/json + +### +# @name LimitSkipTodos +GET {{host}}?limit=3&skip=10 +Accept: application/json +Content-Type: application/json + +### +# @name GetAllTodosOfUser +GET {{host}}/user/1 +Accept: application/json +Content-Type: application/json + +### +# @name AddTodo +POST {{host}}/add +Accept: application/json +Content-Type: application/json + +{ + "todo": "Use DummyJSON in the project", + "completed": false, + "userId": 5 +} + +### +# @name UpdateTodo +PUT {{host}}/1 +Accept: application/json +Content-Type: application/json + +{ + "completed": true +} + +### +# @name DeleteTodo +DELETE {{host}}/1 +Accept: application/json +Content-Type: application/json diff --git a/src/lib.rs b/src/lib.rs index e9a86e1..f500a20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,9 @@ mod auth; +mod todos; + pub use auth::*; use reqwest::Client; +pub use todos::*; pub const API_BASE_URL: &str = "https://dummyjson.com"; diff --git a/src/todos.rs b/src/todos.rs new file mode 100644 index 0000000..fad480f --- /dev/null +++ b/src/todos.rs @@ -0,0 +1,98 @@ +//! Todos module +//! https://dummyjson.com/docs/todos + +use crate::{DummyJsonClient, API_BASE_URL}; +use once_cell::sync::Lazy; +use reqwest::Error; +use serde::Deserialize; +use serde_json::json; + +static TODOS_BASE_URL: Lazy = Lazy::new(|| format!("{}/todos", API_BASE_URL)); + +/// Todo +#[derive(Deserialize, Debug)] +pub struct Todo { + pub id: u32, + pub todo: String, + pub completed: bool, + #[serde(rename = "userId")] + pub user_id: u32, +} + +/// All Todos response +#[derive(Deserialize, Debug)] +pub struct AllTodos { + pub todos: Vec, + pub total: u32, + pub skip: u32, + pub limit: u32, +} + +/// Delete todo response +#[derive(Deserialize, Debug)] +pub struct DeleteTodoResponse { + #[serde(flatten)] + pub todo: Todo, + #[serde(rename = "isDeleted")] + pub is_deleted: bool, + #[serde(rename = "deletedOn")] + pub deleted_on: String, +} + +impl DummyJsonClient { + /// Get all todos + pub async fn get_all_todos(&self) -> Result { + let url = &*TODOS_BASE_URL; + self.client.get(url).send().await?.json().await + } + + /// Get todo by id + pub async fn get_todo_by_id(&self, id: u32) -> Result { + let url = format!("{}/{}", *TODOS_BASE_URL, id); + self.client.get(url).send().await?.json().await + } + + /// Get random todo + pub async fn get_random_todo(&self) -> Result { + let url = format!("{}/random", *TODOS_BASE_URL); + self.client.get(url).send().await?.json().await + } + + /// Get random todos + pub async fn get_random_todos(&self, count: u32) -> Result, Error> { + let url = format!("{}/random/{}", *TODOS_BASE_URL, count); + self.client.get(url).send().await?.json().await + } + + /// Limit and skip todos + pub async fn limit_skip_todos(&self, limit: u32, skip: u32) -> Result { + let url = format!("{}/?limit={}&skip={}", *TODOS_BASE_URL, limit, skip); + self.client.get(url).send().await?.json().await + } + + /// Get all todos of user + pub async fn get_all_todos_of_user(&self, user_id: u32) -> Result { + let url = format!("{}/user/{}", *TODOS_BASE_URL, user_id); + self.client.get(url).send().await?.json().await + } + + /// Add todo + pub async fn add_todo(&self, todo: &str, completed: bool, user_id: u32) -> Result { + let url = format!("{}/add", *TODOS_BASE_URL); + let payload = json!({ "todo": todo, "completed": completed, "userId": user_id }); + self.client.post(url).json(&payload).send().await?.json().await + } + + /// Update todo + pub async fn update_todo(&self, id: u32, completed: bool) -> Result { + let url = format!("{}/{}", *TODOS_BASE_URL, id); + let payload = json!({ "completed": completed }); + self.client.put(url).json(&payload).send().await?.json().await + } + + /// Delete todo + pub async fn delete_todo(&self, id: u32) -> Result { + let url = format!("{}/{}", *TODOS_BASE_URL, id); + self.client.delete(url).send().await?.json().await + } +} diff --git a/tests/todos.rs b/tests/todos.rs new file mode 100644 index 0000000..550ba9f --- /dev/null +++ b/tests/todos.rs @@ -0,0 +1,90 @@ +mod todos { + use dummy_json_rs::DummyJsonClient; + + #[tokio::test] + async fn get_all_todos() { + let client = DummyJsonClient::default(); + let response = client.get_all_todos().await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_todo_by_id() { + let client = DummyJsonClient::default(); + let response = client.get_todo_by_id(1).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_todo_by_id_fails_with_invalid_id() { + let client = DummyJsonClient::default(); + let response = client.get_todo_by_id(24332).await; + assert!(response.is_err()); + } + + #[tokio::test] + async fn get_random_todo() { + let client = DummyJsonClient::default(); + let response = client.get_random_todo().await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_random_todos() { + let client = DummyJsonClient::default(); + let response = client.get_random_todos(3).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn limit_skip_todos() { + let client = DummyJsonClient::default(); + let response = client.limit_skip_todos(3, 10).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn limit_skip_todos_get_all_todos() { + let client = DummyJsonClient::default(); + let response = client.limit_skip_todos(0, 0).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_all_todos_of_user() { + let client = DummyJsonClient::default(); + let response = client.get_all_todos_of_user(1).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn add_todo() { + let client = DummyJsonClient::default(); + let response = client.add_todo("Use DummyJSON in the project", false, 5).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn update_todo() { + let client = DummyJsonClient::default(); + let response = client.update_todo(1, true).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn delete_todo() { + let client = DummyJsonClient::default(); + let response = client.delete_todo(1).await; + // assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } +}