diff --git a/src/api/v1/gists.rs b/src/api/v1/gists.rs index 6d8c9ad..fbe01cc 100644 --- a/src/api/v1/gists.rs +++ b/src/api/v1/gists.rs @@ -49,6 +49,7 @@ pub fn services(cfg: &mut web::ServiceConfig) { cfg.service(get_file); cfg.service(post_comment); cfg.service(get_comment); + cfg.service(get_gist_comments); } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -186,6 +187,31 @@ async fn get_comment( } } +#[my_codegen::get(path = "crate::V1_API_ROUTES.gist.get_gist_comments")] +async fn get_gist_comments( + path: web::Path, + id: Identity, + db: crate::DB, +) -> ServiceResult { + let gist = db.get_gist(&path.gist).await?; + + match gist.visibility { + GistVisibility::Public | GistVisibility::Unlisted => { + let comments = db.get_comments_on_gist(&path.gist).await?; + Ok(HttpResponse::Ok().json(comments)) + } + GistVisibility::Private => { + if let Some(username) = id.identity() { + if gist.owner == username { + let comments = db.get_comments_on_gist(&path.gist).await?; + return Ok(HttpResponse::Ok().json(comments)); + } + }; + Err(ServiceError::GistNotFound) + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -587,5 +613,76 @@ mod tests { assert_eq!(comment.comment, comment_payload.comment); } } + + /* + * +++++++++++++++++++++++++++++++++++ + * GET GIST COMMENT + * +++++++++++++++++++++++++++++++++++ + */ + + // gist not found + let mut get_gist_comments_component = PostCommentPath { + gist: "gistdoesntexist".into(), + username: NAME.into(), + }; + let get_comment_path = V1_API_ROUTES + .gist + .get_gist_comments(&get_gist_comments_component); + println!("getting comments; gist doesn't exist"); + let resp = get_request!(&app, &get_comment_path); + assert_eq!(resp.status(), ServiceError::GistNotFound.status_code()); + let resp_err: ErrorToResponse = test::read_body_json(resp).await; + assert_eq!(resp_err.error, format!("{}", ServiceError::GistNotFound)); + + // private gist + get_gist_comments_component.gist = private.clone(); + let get_comment_path = V1_API_ROUTES + .gist + .get_gist_comments(&get_gist_comments_component); + println!("getting comments; private gist"); + let resp = get_request!(&app, &get_comment_path); + assert_eq!(resp.status(), ServiceError::GistNotFound.status_code()); + let resp_err: ErrorToResponse = test::read_body_json(resp).await; + assert_eq!(resp_err.error, format!("{}", ServiceError::GistNotFound)); + + for (_comment_id, comment_payload, gist, visibility) in comment_ids.iter() { + let component = PostCommentPath { + gist: gist.into(), + username: NAME.into(), + }; + + if visibility == &GistVisibility::Private { + println!("getting comments; private gist but user==owner"); + let path = V1_API_ROUTES.gist.get_gist_comments(&component); + let resp = get_request!(&app, &path, cookies.clone()); + assert_eq!(resp.status(), StatusCode::OK); + let mut comment: Vec = test::read_body_json(resp).await; + assert_eq!( + comment.pop().as_ref().unwrap().comment, + comment_payload.comment + ); + + println!("getting comments; private gist but user is unauthenticated"); + let resp = get_request!(&app, &path); + assert_eq!(resp.status(), ServiceError::GistNotFound.status_code()); + let resp_err: ErrorToResponse = test::read_body_json(resp).await; + assert_eq!(resp_err.error, format!("{}", ServiceError::GistNotFound)); + + println!("getting comments; private gist but user != owner"); + let resp = get_request!(&app, &path, cookies2.clone()); + assert_eq!(resp.status(), ServiceError::GistNotFound.status_code()); + let err: ErrorToResponse = test::read_body_json(resp).await; + assert_eq!(err.error, format!("{}", ServiceError::GistNotFound)); + } else { + let path = V1_API_ROUTES.gist.get_gist_comments(&component); + let resp = get_request!(&app, &path, cookies.clone()); + assert_eq!(resp.status(), StatusCode::OK); + let mut comment: Vec = test::read_body_json(resp).await; + assert_eq!( + comment.pop().as_ref().unwrap().comment, + comment_payload.comment + ); + } + } } } diff --git a/src/api/v1/routes.rs b/src/api/v1/routes.rs index 392c5f5..9282ea9 100644 --- a/src/api/v1/routes.rs +++ b/src/api/v1/routes.rs @@ -75,6 +75,8 @@ pub struct Gist { pub post_comment: &'static str, /// get comment pub get_comment: &'static str, + /// get gist comments + pub get_gist_comments: &'static str, } impl Gist { @@ -84,11 +86,13 @@ impl Gist { let get_file = "/api/v1/gist/profile/{username}/{gist}/contents/{file}"; let post_comment = "/api/v1/gist/profile/{username}/{gist}/comments"; let get_comment = "/api/v1/gist/profile/{username}/{gist}/comment/{comment_id}"; + let get_gist_comments = post_comment; Gist { new, get_file, post_comment, get_comment, + get_gist_comments, } } @@ -108,6 +112,11 @@ impl Gist { .replace("{gist}", &components.gist) } + /// get post_comment route with placeholders replaced with values provided. + pub fn get_gist_comments(&self, components: &PostCommentPath) -> String { + self.get_post_comment_route(components) + } + /// get post_comment route with placeholders replaced with values provided. pub fn get_get_comment_route(&self, components: &GetCommentPath) -> String { self.get_comment @@ -214,6 +223,7 @@ mod tests { const COMMENT_ID: i64 = 5; let get_file = format!("/api/v1/gist/profile/{NAME}/{GIST}/contents/{FILE}"); let post_comment = format!("/api/v1/gist/profile/{NAME}/{GIST}/comments"); + let get_gist_comments = format!("/api/v1/gist/profile/{NAME}/{GIST}/comments"); let get_comment = format!("/api/v1/gist/profile/{NAME}/{GIST}/comment/{COMMENT_ID}"); let get_file_component = GetFilePath { @@ -241,5 +251,14 @@ mod tests { get_comment, ROUTES.gist.get_get_comment_route(&get_comment_path) ); + + let get_gist_comments_path = PostCommentPath { + gist: GIST.into(), + username: NAME.into(), + }; + assert_eq!( + get_gist_comments, + ROUTES.gist.get_post_comment_route(&get_gist_comments_path) + ); } }