138 lines
3.4 KiB
Rust
138 lines
3.4 KiB
Rust
use serde::Deserialize;
|
|
use serde_json::Value;
|
|
|
|
use crate::errors::AppError;
|
|
|
|
#[derive(Debug)]
|
|
pub enum WebhookType {
|
|
Review(ReviewPayload),
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct ReviewPayload {
|
|
pub action: String,
|
|
pub pull_request: PullRequest,
|
|
pub comment: Comment,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct PullRequest {
|
|
pub id: u64,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct Comment {
|
|
pub id: u64,
|
|
pub body: String,
|
|
pub user: User,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct User {
|
|
pub id: u64,
|
|
}
|
|
|
|
impl WebhookType {
|
|
pub fn from_event(event: &str, json: Value) -> Result<Self, AppError> {
|
|
match event {
|
|
"pull_request_comment" => Ok(WebhookType::Review(serde_json::from_value(json)?)),
|
|
_ => Err(AppError::UnknownEventErr),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use serde_json::json;
|
|
|
|
#[test]
|
|
fn test_from_event_valid_pull_request_comment() {
|
|
let json = json!({
|
|
"action": "created",
|
|
"pull_request": {
|
|
"id": 42
|
|
},
|
|
"comment": {
|
|
"id": 7,
|
|
"body": "LGTM",
|
|
"user": {
|
|
"id": 100
|
|
}
|
|
}
|
|
});
|
|
|
|
let result = WebhookType::from_event("pull_request_comment", json);
|
|
assert!(result.is_ok());
|
|
|
|
match result.unwrap() {
|
|
WebhookType::Review(payload) => {
|
|
assert_eq!(payload.action, "created");
|
|
assert_eq!(payload.pull_request.id, 42);
|
|
assert_eq!(payload.comment.id, 7);
|
|
assert_eq!(payload.comment.body, "LGTM");
|
|
assert_eq!(payload.comment.user.id, 100);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_from_event_unknown_event() {
|
|
let json = json!({});
|
|
let result = WebhookType::from_event("push", json);
|
|
assert!(result.is_err());
|
|
|
|
match result.unwrap_err() {
|
|
AppError::UnknownEventErr => {}
|
|
_ => panic!("expected UnknownEventErr"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_from_event_malformed_json() {
|
|
let json = json!({
|
|
"action": "created"
|
|
// pull_request and comment are missing
|
|
});
|
|
|
|
let result = WebhookType::from_event("pull_request_comment", json);
|
|
assert!(result.is_err());
|
|
|
|
match result.unwrap_err() {
|
|
AppError::BadJsonStructErr(_) => {}
|
|
_ => panic!("expected BadJsonStructErr"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_deserialize_review_payload() {
|
|
let json = json!({
|
|
"action": "edited",
|
|
"pull_request": {
|
|
"id": 99
|
|
},
|
|
"comment": {
|
|
"id": 12,
|
|
"body": "Needs work",
|
|
"user": {
|
|
"id": 200
|
|
}
|
|
}
|
|
});
|
|
|
|
let payload: ReviewPayload = serde_json::from_value(json).unwrap();
|
|
assert_eq!(payload.action, "edited");
|
|
assert_eq!(payload.pull_request.id, 99);
|
|
assert_eq!(payload.comment.id, 12);
|
|
assert_eq!(payload.comment.body, "Needs work");
|
|
assert_eq!(payload.comment.user.id, 200);
|
|
}
|
|
|
|
#[test]
|
|
fn test_from_event_empty_json() {
|
|
let result = WebhookType::from_event("pull_request_comment", json!({}));
|
|
assert!(result.is_err());
|
|
assert!(matches!(result.unwrap_err(), AppError::BadJsonStructErr(_)));
|
|
}
|
|
}
|