diff --git a/src/models/commits.rs b/src/models/commits.rs index e65c8beb..8712d91a 100644 --- a/src/models/commits.rs +++ b/src/models/commits.rs @@ -1,4 +1,4 @@ -use super::*; +use super::{reactions::ReactionContent, *}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] @@ -20,7 +20,20 @@ pub struct Comment { pub created_at: chrono::DateTime, #[serde(skip_serializing_if = "Option::is_none")] pub updated_at: Option>, - pub author_association: String, + pub author_association: AuthorAssociation, + #[serde(skip_serializing_if = "Option::is_none")] + pub reactions: Option, +} + +/// Reactions summary of a comment +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub struct CommentReactions { + pub url: Url, + pub total_count: u64, + #[serde(flatten)] + pub reactions: Option>, } /// Commit Comparison diff --git a/src/models/webhook_events.rs b/src/models/webhook_events.rs index b1f5a35d..4e3925f4 100644 --- a/src/models/webhook_events.rs +++ b/src/models/webhook_events.rs @@ -983,14 +983,39 @@ pub struct InstallationEventRepository { mod tests { use chrono::TimeZone; + use crate::models::AuthorAssociation; + use super::payload::*; use super::*; + #[test] + fn deserialize_commit_comment_created() { + let json = include_str!("../../tests/resources/commit_comment_created_webhook_event.json"); + let event = WebhookEvent::try_from_header_and_body("commit_comment", json).unwrap(); + let WebhookEventPayload::CommitComment(commit_comment_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; + assert_eq!( + commit_comment_event.action, + CommitCommentWebhookEventAction::Created + ); + assert_eq!( + commit_comment_event.comment.author_association, + AuthorAssociation::Owner + ); + assert_eq!( + commit_comment_event.comment.body.as_deref(), + Some("@gagbo-test-app[bot] compare-tag v0.1") + ); + } + #[test] fn deserialize_installation_created() { let json = include_str!("../../tests/resources/installation_created_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("installation", json).unwrap(); - let WebhookEventPayload::Installation(install_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::Installation(install_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( install_event.action, InstallationWebhookEventAction::Created @@ -1003,7 +1028,9 @@ mod tests { fn deserialize_installation_deleted() { let json = include_str!("../../tests/resources/installation_deleted_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("installation", json).unwrap(); - let WebhookEventPayload::Installation(install_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::Installation(install_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( install_event.action, InstallationWebhookEventAction::Deleted @@ -1018,8 +1045,15 @@ mod tests { "../../tests/resources/installation_new_permissions_accepted_webhook_event.json" ); let event = WebhookEvent::try_from_header_and_body("installation", json).unwrap(); - let WebhookEventPayload::Installation(ref install_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; - let Some(EventInstallation::Full(installation)) = event.installation else {panic!("event is missing a fully described installation object {:?}", event)}; + let WebhookEventPayload::Installation(ref install_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; + let Some(EventInstallation::Full(installation)) = event.installation else { + panic!( + "event is missing a fully described installation object {:?}", + event + ) + }; assert_eq!( install_event.action, InstallationWebhookEventAction::NewPermissionsAccepted @@ -1046,7 +1080,11 @@ mod tests { ); let event = WebhookEvent::try_from_header_and_body("installation_repositories", json).unwrap(); - let WebhookEventPayload::InstallationRepositories(install_repositories_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::InstallationRepositories(install_repositories_event) = + event.specific + else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( install_repositories_event.action, InstallationRepositoriesWebhookEventAction::Removed @@ -1062,7 +1100,9 @@ mod tests { fn deserialize_issue_comment_created() { let json = include_str!("../../tests/resources/issue_comment_created_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("issue_comment", json).unwrap(); - let WebhookEventPayload::IssueComment(issue_comment_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::IssueComment(issue_comment_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( issue_comment_event.action, IssueCommentWebhookEventAction::Created @@ -1074,7 +1114,9 @@ mod tests { fn deserialize_issue_comment_deleted() { let json = include_str!("../../tests/resources/issue_comment_deleted_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("issue_comment", json).unwrap(); - let WebhookEventPayload::IssueComment(issue_comment_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::IssueComment(issue_comment_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( issue_comment_event.action, IssueCommentWebhookEventAction::Deleted @@ -1085,7 +1127,9 @@ mod tests { fn deserialize_issue_comment_edited() { let json = include_str!("../../tests/resources/issue_comment_edited_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("issue_comment", json).unwrap(); - let WebhookEventPayload::IssueComment(issue_comment_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::IssueComment(issue_comment_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( issue_comment_event.action, IssueCommentWebhookEventAction::Edited @@ -1097,7 +1141,9 @@ mod tests { fn deserialize_issues_labeled() { let json = include_str!("../../tests/resources/issues_labeled_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("issues", json).unwrap(); - let WebhookEventPayload::Issues(issues_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::Issues(issues_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!(issues_event.action, IssuesWebhookEventAction::Labeled); } @@ -1105,7 +1151,9 @@ mod tests { fn deserialize_issues_opened() { let json = include_str!("../../tests/resources/issues_opened_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("issues", json).unwrap(); - let WebhookEventPayload::Issues(issues_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::Issues(issues_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!(issues_event.action, IssuesWebhookEventAction::Opened); } @@ -1113,7 +1161,9 @@ mod tests { fn deserialize_ping() { let json = include_str!("../../tests/resources/ping_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("ping", json).unwrap(); - let WebhookEventPayload::Ping(ping_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::Ping(ping_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!(ping_event.hook.unwrap().id, 423885699); } @@ -1121,7 +1171,9 @@ mod tests { fn deserialize_pull_request_closed() { let json = include_str!("../../tests/resources/pull_request_closed_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("pull_request", json).unwrap(); - let WebhookEventPayload::PullRequest(pull_request_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::PullRequest(pull_request_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( pull_request_event.action, PullRequestWebhookEventAction::Closed @@ -1133,7 +1185,9 @@ mod tests { fn deserialize_pull_request_opened() { let json = include_str!("../../tests/resources/pull_request_opened_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("pull_request", json).unwrap(); - let WebhookEventPayload::PullRequest(pull_request_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::PullRequest(pull_request_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( pull_request_event.action, PullRequestWebhookEventAction::Opened @@ -1145,7 +1199,9 @@ mod tests { let json = include_str!("../../tests/resources/pull_request_synchronize_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("pull_request", json).unwrap(); - let WebhookEventPayload::PullRequest(pull_request_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::PullRequest(pull_request_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( pull_request_event.action, PullRequestWebhookEventAction::Synchronize @@ -1156,7 +1212,9 @@ mod tests { fn deserialize_repository_deleted() { let json = include_str!("../../tests/resources/repository_deleted_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("repository", json).unwrap(); - let WebhookEventPayload::Repository(repository_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::Repository(repository_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert_eq!( repository_event.action, RepositoryWebhookEventAction::Deleted @@ -1167,7 +1225,9 @@ mod tests { fn deserialize_push() { let json = include_str!("../../tests/resources/push_webhook_event.json"); let event = WebhookEvent::try_from_header_and_body("push", json).unwrap(); - let WebhookEventPayload::Push(push_event) = event.specific else {panic!(" event is of the wrong type {:?}", event)}; + let WebhookEventPayload::Push(push_event) = event.specific else { + panic!(" event is of the wrong type {:?}", event) + }; assert!(push_event.created); } } diff --git a/src/models/webhook_events/payload/commit_comment.rs b/src/models/webhook_events/payload/commit_comment.rs index caa1c0ae..ccffa996 100644 --- a/src/models/webhook_events/payload/commit_comment.rs +++ b/src/models/webhook_events/payload/commit_comment.rs @@ -1,15 +1,11 @@ -use std::collections::HashMap; - +use crate::models::commits::Comment; use serde::{Deserialize, Serialize}; -use url::Url; - -use crate::models::{reactions::ReactionContent, Author, AuthorAssociation, CommentId}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] pub struct CommitCommentWebhookEventPayload { pub action: CommitCommentWebhookEventAction, - pub comment: CommitComment, + pub comment: Comment, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -18,23 +14,3 @@ pub struct CommitCommentWebhookEventPayload { pub enum CommitCommentWebhookEventAction { Created, } - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub struct CommitComment { - pub author_association: AuthorAssociation, - pub body: String, - pub commit_id: String, - pub created_at: String, - pub html_url: Url, - pub id: CommentId, - pub line: Option, - pub node_id: String, - pub path: Option, - pub position: Option, - pub reactions: Option>, - pub updated_at: String, - pub url: Url, - pub user: Option, -} diff --git a/tests/resources/commit_comment_created_webhook_event.json b/tests/resources/commit_comment_created_webhook_event.json new file mode 100644 index 00000000..f5584336 --- /dev/null +++ b/tests/resources/commit_comment_created_webhook_event.json @@ -0,0 +1,173 @@ +{ + "action": "created", + "comment": { + "url": "https://api.github.com/repos/gagbo/app-test-repo/comments/126171404", + "html_url": "https://github.com/gagbo/app-test-repo/commit/5a722779076a943e9e8ccc502566c411f6481b4a#commitcomment-126171404", + "id": 126171404, + "node_id": "CC_kwDOKIoqtM4HhTkM", + "user": { + "login": "gagbo", + "id": 10496163, + "node_id": "MDQ6VXNlcjEwNDk2MTYz", + "avatar_url": "https://avatars.githubusercontent.com/u/10496163?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gagbo", + "html_url": "https://github.com/gagbo", + "followers_url": "https://api.github.com/users/gagbo/followers", + "following_url": "https://api.github.com/users/gagbo/following{/other_user}", + "gists_url": "https://api.github.com/users/gagbo/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gagbo/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gagbo/subscriptions", + "organizations_url": "https://api.github.com/users/gagbo/orgs", + "repos_url": "https://api.github.com/users/gagbo/repos", + "events_url": "https://api.github.com/users/gagbo/events{/privacy}", + "received_events_url": "https://api.github.com/users/gagbo/received_events", + "type": "User", + "site_admin": false + }, + "position": null, + "line": null, + "path": null, + "commit_id": "5a722779076a943e9e8ccc502566c411f6481b4a", + "created_at": "2023-09-01T12:01:16Z", + "updated_at": "2023-09-01T12:01:16Z", + "author_association": "OWNER", + "body": "@gagbo-test-app[bot] compare-tag v0.1", + "reactions": { + "url": "https://api.github.com/repos/gagbo/app-test-repo/comments/126171404/reactions", + "total_count": 0, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + "repository": { + "id": 680143540, + "node_id": "R_kgDOKIoqtA", + "name": "app-test-repo", + "full_name": "gagbo/app-test-repo", + "private": false, + "owner": { + "login": "gagbo", + "id": 10496163, + "node_id": "MDQ6VXNlcjEwNDk2MTYz", + "avatar_url": "https://avatars.githubusercontent.com/u/10496163?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gagbo", + "html_url": "https://github.com/gagbo", + "followers_url": "https://api.github.com/users/gagbo/followers", + "following_url": "https://api.github.com/users/gagbo/following{/other_user}", + "gists_url": "https://api.github.com/users/gagbo/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gagbo/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gagbo/subscriptions", + "organizations_url": "https://api.github.com/users/gagbo/orgs", + "repos_url": "https://api.github.com/users/gagbo/repos", + "events_url": "https://api.github.com/users/gagbo/events{/privacy}", + "received_events_url": "https://api.github.com/users/gagbo/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/gagbo/app-test-repo", + "description": "Nothing to see here, just testing Github App hooks", + "fork": false, + "url": "https://api.github.com/repos/gagbo/app-test-repo", + "forks_url": "https://api.github.com/repos/gagbo/app-test-repo/forks", + "keys_url": "https://api.github.com/repos/gagbo/app-test-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/gagbo/app-test-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/gagbo/app-test-repo/teams", + "hooks_url": "https://api.github.com/repos/gagbo/app-test-repo/hooks", + "issue_events_url": "https://api.github.com/repos/gagbo/app-test-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/gagbo/app-test-repo/events", + "assignees_url": "https://api.github.com/repos/gagbo/app-test-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/gagbo/app-test-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/gagbo/app-test-repo/tags", + "blobs_url": "https://api.github.com/repos/gagbo/app-test-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/gagbo/app-test-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/gagbo/app-test-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/gagbo/app-test-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/gagbo/app-test-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/gagbo/app-test-repo/languages", + "stargazers_url": "https://api.github.com/repos/gagbo/app-test-repo/stargazers", + "contributors_url": "https://api.github.com/repos/gagbo/app-test-repo/contributors", + "subscribers_url": "https://api.github.com/repos/gagbo/app-test-repo/subscribers", + "subscription_url": "https://api.github.com/repos/gagbo/app-test-repo/subscription", + "commits_url": "https://api.github.com/repos/gagbo/app-test-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/gagbo/app-test-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/gagbo/app-test-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/gagbo/app-test-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/gagbo/app-test-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/gagbo/app-test-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/gagbo/app-test-repo/merges", + "archive_url": "https://api.github.com/repos/gagbo/app-test-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/gagbo/app-test-repo/downloads", + "issues_url": "https://api.github.com/repos/gagbo/app-test-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/gagbo/app-test-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/gagbo/app-test-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/gagbo/app-test-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/gagbo/app-test-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/gagbo/app-test-repo/releases{/id}", + "deployments_url": "https://api.github.com/repos/gagbo/app-test-repo/deployments", + "created_at": "2023-08-18T12:53:34Z", + "updated_at": "2023-08-18T16:51:35Z", + "pushed_at": "2023-09-01T10:42:50Z", + "git_url": "git://github.com/gagbo/app-test-repo.git", + "ssh_url": "git@github.com:gagbo/app-test-repo.git", + "clone_url": "https://github.com/gagbo/app-test-repo.git", + "svn_url": "https://github.com/gagbo/app-test-repo", + "homepage": null, + "size": 13, + "stargazers_count": 1, + "watchers_count": 1, + "language": "Rust", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 0, + "watchers": 1, + "default_branch": "main" + }, + "sender": { + "login": "gagbo", + "id": 10496163, + "node_id": "MDQ6VXNlcjEwNDk2MTYz", + "avatar_url": "https://avatars.githubusercontent.com/u/10496163?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gagbo", + "html_url": "https://github.com/gagbo", + "followers_url": "https://api.github.com/users/gagbo/followers", + "following_url": "https://api.github.com/users/gagbo/following{/other_user}", + "gists_url": "https://api.github.com/users/gagbo/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gagbo/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gagbo/subscriptions", + "organizations_url": "https://api.github.com/users/gagbo/orgs", + "repos_url": "https://api.github.com/users/gagbo/repos", + "events_url": "https://api.github.com/users/gagbo/events{/privacy}", + "received_events_url": "https://api.github.com/users/gagbo/received_events", + "type": "User", + "site_admin": false + }, + "installation": { + "id": 88888888, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMzk1OTM1MjA=" + } +}