From f49de4ce508be5f93e0938e13a98de0848829a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=9CM=C3=9C=C5=9E?= <96421894+Tahinli@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:59:52 +0300 Subject: [PATCH] feat: :sparkles: is_follower, is_followed docs: :memo: is_follower, is_followed --- README.md | 6 +++- src/db/db_operations.rs | 8 +++++ src/db/db_utils.rs | 58 ++++++++++++++++++++++++++++++ src/routing.rs | 44 +++++++++++++++++++++++ src/tests/db_tests.rs | 79 ++++++++++++++++++++++++++++++++++++++++- src/utils.rs | 2 +- 6 files changed, 194 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ffaeedd..3b1c751 100644 --- a/README.md +++ b/README.md @@ -22,4 +22,8 @@ Unfollow User: "/unfollow/:follower/:followed" Ban User: "/ban/:victim/:judge" -Unban User: "/unban/:victim/:judge" \ No newline at end of file +Unban User: "/unban/:victim/:judge" + +Is Follower: "/is-follower/:follower/:follower" + +Is Followed: "/is-follower/:follower/:follower" \ No newline at end of file diff --git a/src/db/db_operations.rs b/src/db/db_operations.rs index cdd4098..5b5314f 100644 --- a/src/db/db_operations.rs +++ b/src/db/db_operations.rs @@ -100,3 +100,11 @@ pub async fn unban(victim: &String, judge: &String, db: &Surreal) -> Opt None => None, } } + +pub async fn is_follower(follower: &String, followed: &String, db: &Surreal) -> bool { + is_follower_by_username(follower, followed, db).await +} + +pub async fn is_followed(follower: &String, followed: &String, db: &Surreal) -> bool { + is_followed_by_username(follower, followed, db).await +} diff --git a/src/db/db_utils.rs b/src/db/db_utils.rs index f9917c4..2403459 100644 --- a/src/db/db_utils.rs +++ b/src/db/db_utils.rs @@ -475,3 +475,61 @@ pub async fn remove_all_banned_from(channel: Channel, db: &Surreal) -> O } search_channel_by_username(&channel.username, db).await } + +pub async fn is_follower_by_username( + follower: &String, + followed: &String, + db: &Surreal, +) -> bool { + match search_channel_by_username(follower, db).await { + Some(follower_channel) => match search_channel_by_username(followed, db).await { + Some(mut followed_channel) => { + followed_channel.follower_list.sort(); + match followed_channel + .follower_list + .binary_search(&follower_channel.id.unwrap().id) + { + Ok(_) => true, + Err(_) => false, + } + } + None => { + eprintln!("Error: Can't Check Is Follower | Followed Not Exists"); + false + } + }, + None => { + eprintln!("Error: Can't Check Is Follower | Follower Not Exists"); + false + } + } +} + +pub async fn is_followed_by_username( + follower: &String, + followed: &String, + db: &Surreal, +) -> bool { + match search_channel_by_username(follower, db).await { + Some(mut follower_channel) => match search_channel_by_username(followed, db).await { + Some(followed_channel) => { + follower_channel.followed_list.sort(); + match follower_channel + .followed_list + .binary_search(&followed_channel.id.unwrap().id) + { + Ok(_) => true, + Err(_) => false, + } + } + None => { + eprintln!("Error: Can't Check Is Follower | Followed Not Exists"); + false + } + }, + None => { + eprintln!("Error: Can't Check Is Follower | Follower Not Exists"); + false + } + } +} diff --git a/src/routing.rs b/src/routing.rs index 00ed022..59e1d19 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -24,6 +24,8 @@ pub async fn routing(State(state): State) -> Router { .route("/unfollow/:follower/:followed", get(unfollow)) .route("/ban/:victim/:judge", get(ban)) .route("/unban/:victim/:judge", get(unban)) + .route("/is-follower/:follower/:followed", get(is_follower)) + .route("/is-followed/:follower/:followed", get(is_followed)) .layer(CorsLayer::permissive()) .with_state(state.clone()) } @@ -157,3 +159,45 @@ async fn unban( None => (StatusCode::NOT_ACCEPTABLE, Json(serde_json::json!(""))), } } + +async fn is_follower( + Path((follower, followed)): Path<(String, String)>, + State(state): State, +) -> impl IntoResponse { + let is_follower = db_operations::is_follower(&follower, &followed, &state.db).await; + match is_follower { + true => { + let is_follower = serde_json::json!({ + "is_follower":true + }); + (StatusCode::OK, Json(is_follower)) + } + false => { + let is_follower = serde_json::json!({ + "is_follower":false + }); + (StatusCode::OK, Json(is_follower)) + } + } +} + +async fn is_followed( + Path((follower, followed)): Path<(String, String)>, + State(state): State, +) -> impl IntoResponse { + let is_followed: bool = db_operations::is_followed(&follower, &followed, &state.db).await; + match is_followed { + true => { + let is_followed = serde_json::json!({ + "is_followed":true + }); + (StatusCode::OK, Json(is_followed)) + } + false => { + let is_followed = serde_json::json!({ + "is_followed":false + }); + (StatusCode::OK, Json(is_followed)) + } + } +} diff --git a/src/tests/db_tests.rs b/src/tests/db_tests.rs index f133c47..c56a02c 100644 --- a/src/tests/db_tests.rs +++ b/src/tests/db_tests.rs @@ -1,3 +1,4 @@ + #[cfg(test)] use crate::db::db_operations::*; use tokio::test; @@ -6,7 +7,7 @@ use tokio::test; async fn create_connection_for_tests( db_name: &str, ) -> surrealdb::Surreal { - let connection = surrealdb::Surreal::new::("127.0.0.1:8000") + let connection = surrealdb::Surreal::new::("127.0.0.1:5000") .await .unwrap(); connection @@ -444,3 +445,79 @@ async fn test_search_id_noncreated() { let _cleaning = connection.query("DELETE channel;").await; } + +#[test] +async fn test_is_follower_already_follower() { + let connection = create_connection_for_tests("test_is_follower_already_follower").await; + let name_follower = &"Ahmet".to_string(); + let name_followed = &"Kaan".to_string(); + + let _follower = create(name_follower, &connection).await.unwrap(); + let _followed = create(name_followed, &connection).await.unwrap(); + + let _follower = follow(name_follower, name_followed, &connection) + .await + .unwrap(); + + assert_eq!( + is_follower(name_follower, name_followed, &connection).await, + true + ); + + let _cleaning = connection.query("DELETE channel;").await; +} + +#[test] +async fn test_is_follower_nonfollower() { + let connection = create_connection_for_tests("test_is_follower_nonfollower").await; + let name_follower = &"Ahmet".to_string(); + let name_followed = &"Kaan".to_string(); + + let _follower = create(name_follower, &connection).await.unwrap(); + let _followed = create(name_followed, &connection).await.unwrap(); + + assert_eq!( + is_follower(name_follower, name_followed, &connection).await, + false + ); + + let _cleaning = connection.query("DELETE channel;").await; +} + +#[test] +async fn test_is_followed_already_followed() { + let connection = create_connection_for_tests("test_is_followed_already_followed").await; + let name_follower = &"Ahmet".to_string(); + let name_followed = &"Kaan".to_string(); + + let _follower = create(name_follower, &connection).await.unwrap(); + let _followed = create(name_followed, &connection).await.unwrap(); + + let _follower = follow(name_follower, name_followed, &connection) + .await + .unwrap(); + + assert_eq!( + is_followed(name_follower, name_followed, &connection).await, + true + ); + + let _cleaning = connection.query("DELETE channel;").await; +} + +#[test] +async fn test_is_followed_nonfollowed() { + let connection = create_connection_for_tests("test_is_follower_nonfollowed").await; + let name_follower = &"Ahmet".to_string(); + let name_followed = &"Kaan".to_string(); + + let _follower = create(name_follower, &connection).await.unwrap(); + let _followed = create(name_followed, &connection).await.unwrap(); + + assert_eq!( + is_followed(name_follower, name_followed, &connection).await, + false + ); + + let _cleaning = connection.query("DELETE channel;").await; +} diff --git a/src/utils.rs b/src/utils.rs index a05e0c4..ea6e2d1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -24,7 +24,7 @@ pub async fn database_config() -> DataBaseConfig { let dirty: Vec<&str> = element.split(": ").collect(); configs_cleaned.push(dirty[1]); } - + DataBaseConfig { address: configs_cleaned[0].to_string(), username: configs_cleaned[1].to_string(),