diff --git a/libs/client-api/src/http_publish.rs b/libs/client-api/src/http_publish.rs index 39a7122e..c8049faa 100644 --- a/libs/client-api/src/http_publish.rs +++ b/libs/client-api/src/http_publish.rs @@ -1,5 +1,6 @@ use database_entity::dto::UpdatePublishNamespace; use reqwest::Method; +use serde_json::json; use shared_entity::response::{AppResponse, AppResponseError}; use crate::Client; @@ -38,4 +39,52 @@ impl Client { AppResponse::<()>::from_response(resp).await?.into_error() } + + pub async fn publish_collab( + &self, + workspace_id: &str, + doc_name: &str, + metadata: T, + ) -> Result<(), AppResponseError> + where + T: serde::Serialize, + { + let url = format!( + "{}/api/workspace/{}/publish/{}", + self.base_url, workspace_id, doc_name + ); + + let resp = self + .http_client_with_auth(Method::PUT, &url) + .await? + .json(&metadata) + .send() + .await?; + + AppResponse::<()>::from_response(resp).await?.into_error() + } + + pub async fn get_publish_collab( + &self, + workspace_id: &str, + doc_name: &str, + ) -> Result + where + T: serde::de::DeserializeOwned + 'static, + { + let url = format!( + "{}/api/workspace/{}/publish/{}", + self.base_url, workspace_id, doc_name + ); + + let resp = self + .cloud_client + .get(&url) + .send() + .await? + .error_for_status()? + .json::() + .await?; + Ok(resp) + } } diff --git a/libs/database/src/workspace.rs b/libs/database/src/workspace.rs index 5979d3d8..8b14517a 100644 --- a/libs/database/src/workspace.rs +++ b/libs/database/src/workspace.rs @@ -2,12 +2,10 @@ use database_entity::dto::{ AFRole, AFWorkspaceInvitation, AFWorkspaceInvitationStatus, AFWorkspaceSettings, }; use futures_util::stream::BoxStream; -use sqlx::{ - types::{uuid, Uuid}, - Executor, PgPool, Postgres, Transaction, -}; +use sqlx::{types::uuid, Executor, PgPool, Postgres, Transaction}; use std::{collections::HashMap, ops::DerefMut}; use tracing::{event, instrument}; +use uuid::Uuid; use crate::pg_row::AFWorkspaceMemberPermRow; use crate::pg_row::{ @@ -925,7 +923,7 @@ pub async fn insert_or_replace_publish_collab_meta<'a, E: Executor<'a, Database doc_name, publisher_uuid, workspace_id, - metadata + metadata, ) .execute(executor) .await?; @@ -946,7 +944,7 @@ pub async fn select_publish_collab_meta<'a, E: Executor<'a, Database = Postgres> workspace_id: &Uuid, doc_name: &str, ) -> Result { - let res = sqlx::query_scalar!( + let res = sqlx::query!( r#" SELECT metadata FROM af_published_collab @@ -958,8 +956,8 @@ pub async fn select_publish_collab_meta<'a, E: Executor<'a, Database = Postgres> ) .fetch_one(executor) .await?; - - Ok(res) + let metadata: serde_json::Value = res.metadata; + Ok(metadata) } #[inline] diff --git a/src/api/workspace.rs b/src/api/workspace.rs index 3e43a45b..74038cd2 100644 --- a/src/api/workspace.rs +++ b/src/api/workspace.rs @@ -1017,11 +1017,10 @@ async fn get_published_collab_blob_handler( async fn put_publish_collab_handler( path_param: web::Path<(Uuid, String)>, user_uuid: UserUuid, - payload: String, + metadata: Json, state: Data, ) -> Result>> { let (workspace_id, doc_name) = path_param.into_inner(); - let metadata = serde_json::Value::from(payload); biz::workspace::ops::publish_collab( &state.pg_pool, &workspace_id, @@ -1036,11 +1035,11 @@ async fn put_publish_collab_handler( async fn get_publish_collab_handler( path_param: web::Path<(Uuid, String)>, state: Data, -) -> Result>> { +) -> Result> { let (workspace_id, doc_name) = path_param.into_inner(); let metadata = biz::workspace::ops::get_published_collab(&state.pg_pool, &workspace_id, &doc_name).await?; - Ok(Json(AppResponse::Ok().with_data(metadata))) + Ok(Json(metadata)) } async fn put_publish_collab_blob_handler( diff --git a/tests/workspace/publish.rs b/tests/workspace/publish.rs index be856f42..f639dd00 100644 --- a/tests/workspace/publish.rs +++ b/tests/workspace/publish.rs @@ -1,4 +1,4 @@ -use client_api_test::generate_unique_registered_user_client; +use client_api_test::{generate_unique_registered_user_client, localhost_client}; #[tokio::test] async fn test_get_publish_namespace_not_set() { @@ -65,6 +65,41 @@ async fn test_set_publish_namespace_set() { } } +#[tokio::test] +async fn test_publish_doc() { + #[derive(serde::Serialize, serde::Deserialize)] + struct Metadata { + title: String, + } + + let (c, _user) = generate_unique_registered_user_client().await; + let workspace_id = get_first_workspace_string(&c).await; + let my_namespace = uuid::Uuid::new_v4().to_string(); + c.set_workspace_publish_namespace(&workspace_id.to_string(), my_namespace) + .await + .unwrap(); + + c.publish_collab( + &workspace_id, + "my_doc", + Metadata { + title: "my_title".to_string(), + }, + ) + .await + .unwrap(); + + { + // Non login user should be able to view the published collab metadata + let non_login = localhost_client(); + let published_collab = non_login + .get_publish_collab::(&workspace_id, "my_doc") + .await + .unwrap(); + assert_eq!(published_collab.title, "my_title"); + } +} + async fn get_first_workspace_string(c: &client_api::Client) -> String { c.get_workspaces() .await