Skip to content

Commit

Permalink
Fix commit_comment webhook event parsing
Browse files Browse the repository at this point in the history
The list of reactions in commit_comment events was badly represented.
The correct type has directly been added in the models::commits::Comment
struct, so everything has the better typing out of the box.

This also enforces strong typing with the author_association field.
  • Loading branch information
gagbo committed Sep 1, 2023
1 parent b84edac commit f9cb3dd
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 44 deletions.
17 changes: 15 additions & 2 deletions src/models/commits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::*;
use super::{reactions::ReactionContent, *};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
Expand All @@ -20,7 +20,20 @@ pub struct Comment {
pub created_at: chrono::DateTime<chrono::Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
pub author_association: String,
pub author_association: AuthorAssociation,
#[serde(skip_serializing_if = "Option::is_none")]
pub reactions: Option<CommentReactions>,
}

/// 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<HashMap<ReactionContent, u64>>,
}

/// Commit Comparison
Expand Down
92 changes: 76 additions & 16 deletions src/models/webhook_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -1097,31 +1141,39 @@ 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);
}

#[test]
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);
}

#[test]
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);
}

#[test]
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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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);
}
}
28 changes: 2 additions & 26 deletions src/models/webhook_events/payload/commit_comment.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand All @@ -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<u64>,
pub node_id: String,
pub path: Option<String>,
pub position: Option<u64>,
pub reactions: Option<HashMap<ReactionContent, u64>>,
pub updated_at: String,
pub url: Url,
pub user: Option<Author>,
}
Loading

0 comments on commit f9cb3dd

Please sign in to comment.