Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
httpd: Add reactions and edits to patches
Sebastian Martinez committed 2 years ago
commit 994f52d6541f7bd3e082746e39801d01da030b14
parent 8cb8398be99c3054dcb5b1a2bb59dd00b65baff9
4 files changed +267 -7
modified radicle-httpd/src/api/v1/projects.rs
@@ -662,6 +662,14 @@ async fn patch_update_handler(
        patch::Action::ReviewEdit { review, summary } => {
            patch.edit_review(review, summary, &signer)?;
        }
+
        patch::Action::ReviewComment {
+
            review,
+
            body,
+
            reply_to,
+
            ..
+
        } => {
+
            patch.review_comment(review, body, None, reply_to, &signer)?;
+
        }
        patch::Action::ReviewCommentEdit {
            review,
            comment,
@@ -669,6 +677,17 @@ async fn patch_update_handler(
        } => {
            patch.edit_review_comment(review, comment, body, &signer)?;
        }
+
        patch::Action::ReviewCommentReact {
+
            review,
+
            comment,
+
            reaction,
+
            active,
+
        } => {
+
            patch.react_review_comment(review, comment, reaction, active, &signer)?;
+
        }
+
        patch::Action::ReviewCommentRedact { review, comment } => {
+
            patch.redact_review_comment(review, comment, &signer)?;
+
        }
        patch::Action::Label { labels } => {
            patch.label(labels, &signer)?;
        }
@@ -702,6 +721,24 @@ async fn patch_update_handler(
        } => {
            patch.comment(revision, body, reply_to, &signer)?;
        }
+
        patch::Action::RevisionCommentEdit {
+
            revision,
+
            comment,
+
            body,
+
        } => {
+
            patch.comment_edit(revision, comment, body, &signer)?;
+
        }
+
        patch::Action::RevisionCommentReact {
+
            revision,
+
            comment,
+
            reaction,
+
            active,
+
        } => {
+
            patch.comment_react(revision, comment, reaction, active, &signer)?;
+
        }
+
        patch::Action::RevisionCommentRedact { revision, comment } => {
+
            patch.comment_redact(revision, comment, &signer)?;
+
        }
        _ => {
            todo!();
        }
@@ -2315,7 +2352,38 @@ mod routes {
        .await;

        assert_eq!(response.status(), StatusCode::OK);
+
        let comment_react_body = serde_json::to_vec(&json!({
+
          "type": "revision.comment.react",
+
          "revision": CONTRIBUTOR_PATCH_ID,
+
          "comment": CONTRIBUTOR_COMMENT_1,
+
          "reaction": "🚀",
+
          "active": true
+
        }))
+
        .unwrap();
+
        patch(
+
            &app,
+
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
+
            Some(Body::from(comment_react_body)),
+
            Some(SESSION_ID.to_string()),
+
        )
+
        .await;
+

+
        let comment_edit = serde_json::to_vec(&json!({
+
          "type": "revision.comment.edit",
+
          "revision": CONTRIBUTOR_PATCH_ID,
+
          "comment": CONTRIBUTOR_COMMENT_1,
+
          "body": "EDIT: This is a root level comment"
+
        }))
+
        .unwrap();
+
        let response = patch(
+
            &app,
+
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
+
            Some(Body::from(comment_edit)),
+
            Some(SESSION_ID.to_string()),
+
        )
+
        .await;

+
        assert_eq!(response.status(), StatusCode::OK);
        let reply_body = serde_json::to_vec(&json!({
          "type": "revision.comment",
          "revision": CONTRIBUTOR_PATCH_ID,
@@ -2355,10 +2423,10 @@ mod routes {
              "revisions": [
                {
                  "id": CONTRIBUTOR_PATCH_ID,
-
                  "description": "change `hello world` in README to something else",
                  "author": {
                    "id": CONTRIBUTOR_DID,
                  },
+
                  "description": "change `hello world` in README to something else",
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -2370,8 +2438,8 @@ mod routes {
                      "author": {
                        "id": CONTRIBUTOR_DID,
                      },
-
                      "body": "This is a root level comment",
-
                      "reactions": [],
+
                      "body": "EDIT: This is a root level comment",
+
                      "reactions": [["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8","🚀"]],
                      "timestamp": TIMESTAMP,
                      "replyTo": null,
                    },
@@ -2417,6 +2485,51 @@ mod routes {

        assert_eq!(response.status(), StatusCode::OK);

+
        let review_comment_body = serde_json::to_vec(&json!({
+
          "type": "review.comment",
+
          "review": CONTRIBUTOR_PATCH_REVIEW,
+
          "body": "This is a comment on a review"
+
        }))
+
        .unwrap();
+
        patch(
+
            &app,
+
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
+
            Some(Body::from(review_comment_body)),
+
            Some(SESSION_ID.to_string()),
+
        )
+
        .await;
+

+
        let review_comment_edit_body = serde_json::to_vec(&json!({
+
          "type": "review.comment.edit",
+
          "review": CONTRIBUTOR_PATCH_REVIEW,
+
          "comment": CONTRIBUTOR_COMMENT_3,
+
          "body": "EDIT: This is a comment on a review"
+
        }))
+
        .unwrap();
+
        patch(
+
            &app,
+
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
+
            Some(Body::from(review_comment_edit_body)),
+
            Some(SESSION_ID.to_string()),
+
        )
+
        .await;
+

+
        let review_react_body = serde_json::to_vec(&json!({
+
          "type": "review.comment.react",
+
          "review": CONTRIBUTOR_PATCH_REVIEW,
+
          "comment": CONTRIBUTOR_COMMENT_3,
+
          "reaction": "🚀",
+
          "active": true
+
        }))
+
        .unwrap();
+
        patch(
+
            &app,
+
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
+
            Some(Body::from(review_react_body)),
+
            Some(SESSION_ID.to_string()),
+
        )
+
        .await;
+

        let response = get(
            &app,
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
@@ -2439,10 +2552,10 @@ mod routes {
              "revisions": [
                {
                  "id": CONTRIBUTOR_PATCH_ID,
-
                  "description": "change `hello world` in README to something else",
                  "author": {
                    "id": CONTRIBUTOR_DID,
                  },
+
                  "description": "change `hello world` in README to something else",
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -2457,7 +2570,19 @@ mod routes {
                      },
                      "verdict": "accept",
                      "summary": "A small review",
-
                      "comments": [],
+
                      "comments": [[
+
                        "dd9743bb964ba22399548c86a3c1765020d58f48",
+
                        {
+
                          "author": "z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8",
+
                          "reactions": [
+
                            [
+
                              "z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8",
+
                              "🚀",
+
                            ],
+
                          ],
+
                          "body": "EDIT: This is a comment on a review",
+
                        },
+
                      ]],
                      "timestamp": TIMESTAMP,
                    },
                  ],
modified radicle-httpd/src/test.rs
@@ -43,8 +43,10 @@ pub const CONTRIBUTOR_DID: &str = "did:key:z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1
pub const CONTRIBUTOR_NID: &str = "z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8";
pub const CONTRIBUTOR_ISSUE_ID: &str = "7466975f0bef37b459887824a9655f3e78262522";
pub const CONTRIBUTOR_PATCH_ID: &str = "e651ae5869a2c1ac8ad4f6deae4cc835656ffa25";
+
pub const CONTRIBUTOR_PATCH_REVIEW: &str = "ee3eeba95f4ec418b3d0714e18e0d1ff605dc0e6";
pub const CONTRIBUTOR_COMMENT_1: &str = "d0bb75b2c72ab8b5486d39f6cf5f41f104b63cb1";
-
pub const CONTRIBUTOR_COMMENT_2: &str = "2a4ec5bcb1be09c1f2213f418c0159fff894b989";
+
pub const CONTRIBUTOR_COMMENT_2: &str = "227947fa41420e363752357b2edd54d3ccadf7b3";
+
pub const CONTRIBUTOR_COMMENT_3: &str = "dd9743bb964ba22399548c86a3c1765020d58f48";

/// Create a new profile.
pub fn profile(home: &Path, seed: [u8; 32]) -> radicle::Profile {
modified radicle/src/cob/patch.rs
@@ -1160,6 +1160,45 @@ impl store::Transaction<Patch> {
        })
    }

+
    /// Edit a comment on a patch revision.
+
    pub fn comment_edit<S: ToString>(
+
        &mut self,
+
        revision: RevisionId,
+
        comment: CommentId,
+
        body: S,
+
    ) -> Result<(), store::Error> {
+
        self.push(Action::RevisionCommentEdit {
+
            revision,
+
            comment,
+
            body: body.to_string(),
+
        })
+
    }
+

+
    /// React a comment on a patch revision.
+
    pub fn comment_react(
+
        &mut self,
+
        revision: RevisionId,
+
        comment: CommentId,
+
        reaction: Reaction,
+
        active: bool,
+
    ) -> Result<(), store::Error> {
+
        self.push(Action::RevisionCommentReact {
+
            revision,
+
            comment,
+
            reaction,
+
            active,
+
        })
+
    }
+

+
    /// Redact a comment on a patch revision.
+
    pub fn comment_redact(
+
        &mut self,
+
        revision: RevisionId,
+
        comment: CommentId,
+
    ) -> Result<(), store::Error> {
+
        self.push(Action::RevisionCommentRedact { revision, comment })
+
    }
+

    /// Comment on a review.
    pub fn review_comment<S: ToString>(
        &mut self,
@@ -1190,6 +1229,31 @@ impl store::Transaction<Patch> {
        })
    }

+
    /// React to a review comment.
+
    pub fn react_review_comment(
+
        &mut self,
+
        review: EntryId,
+
        comment: EntryId,
+
        reaction: Reaction,
+
        active: bool,
+
    ) -> Result<(), store::Error> {
+
        self.push(Action::ReviewCommentReact {
+
            review,
+
            comment,
+
            reaction,
+
            active,
+
        })
+
    }
+

+
    /// Redact a review comment.
+
    pub fn redact_review_comment(
+
        &mut self,
+
        review: EntryId,
+
        comment: EntryId,
+
    ) -> Result<(), store::Error> {
+
        self.push(Action::ReviewCommentRedact { review, comment })
+
    }
+

    /// Review a patch revision.
    pub fn review(
        &mut self,
@@ -1342,6 +1406,45 @@ where
        self.transaction("Comment", signer, |tx| tx.comment(revision, body, reply_to))
    }

+
    /// Edit a comment on a patch revision.
+
    pub fn comment_edit<G: Signer, S: ToString>(
+
        &mut self,
+
        revision: RevisionId,
+
        comment: CommentId,
+
        body: S,
+
        signer: &G,
+
    ) -> Result<EntryId, Error> {
+
        self.transaction("Edit comment", signer, |tx| {
+
            tx.comment_edit(revision, comment, body)
+
        })
+
    }
+

+
    /// React to a comment on a patch revision.
+
    pub fn comment_react<G: Signer>(
+
        &mut self,
+
        revision: RevisionId,
+
        comment: CommentId,
+
        reaction: Reaction,
+
        active: bool,
+
        signer: &G,
+
    ) -> Result<EntryId, Error> {
+
        self.transaction("React comment", signer, |tx| {
+
            tx.comment_react(revision, comment, reaction, active)
+
        })
+
    }
+

+
    /// Redact a comment on a patch revision.
+
    pub fn comment_redact<G: Signer>(
+
        &mut self,
+
        revision: RevisionId,
+
        comment: CommentId,
+
        signer: &G,
+
    ) -> Result<EntryId, Error> {
+
        self.transaction("Redact comment", signer, |tx| {
+
            tx.comment_redact(revision, comment)
+
        })
+
    }
+

    /// Comment on a line of code as part of a review.
    pub fn review_comment<G: Signer, S: ToString>(
        &mut self,
@@ -1369,6 +1472,32 @@ where
        })
    }

+
    /// React to a review comment.
+
    pub fn react_review_comment<G: Signer>(
+
        &mut self,
+
        review: EntryId,
+
        comment: EntryId,
+
        reaction: Reaction,
+
        active: bool,
+
        signer: &G,
+
    ) -> Result<EntryId, Error> {
+
        self.transaction("React review comment", signer, |tx| {
+
            tx.react_review_comment(review, comment, reaction, active)
+
        })
+
    }
+

+
    /// React to a review comment.
+
    pub fn redact_review_comment<G: Signer>(
+
        &mut self,
+
        review: EntryId,
+
        comment: EntryId,
+
        signer: &G,
+
    ) -> Result<EntryId, Error> {
+
        self.transaction("React review comment", signer, |tx| {
+
            tx.redact_review_comment(review, comment)
+
        })
+
    }
+

    /// Review a patch revision.
    pub fn review<G: Signer>(
        &mut self,
modified radicle/src/cob/thread.rs
@@ -84,7 +84,11 @@ impl<T: Serialize> Serialize for Comment<T> {
        }
        state.serialize_field("reactions", &self.reactions)?;
        state.serialize_field("body", self.body())?;
-
        state.serialize_field("embeds", self.embeds())?;
+

+
        let embeds = self.embeds();
+
        if !embeds.is_empty() {
+
            state.serialize_field("embeds", self.embeds())?;
+
        }
        state.end()
    }
}