use super::*;
pub struct NewWebhook<'a> {
pub url: &'a str,
pub name: Option<&'a str>,
pub format: Option<&'a str>,
pub events: &'a [String],
}
pub struct WebhookChange<'a> {
pub name: Option<&'a str>,
pub events: Option<&'a [String]>,
pub enabled: Option<bool>,
}
impl ApiClient {
pub async fn webhooks(&self, project_id: &str) -> Result<Answer<WebhooksPage>> {
self.get_answer(&format!("/api/infra/projects/{project_id}/webhooks"))
.await
}
pub async fn create_webhook(
&self,
project_id: &str,
draft: &NewWebhook<'_>,
) -> Result<Answer<CreatedWebhook>> {
self.post_answer(
&format!("/api/infra/projects/{project_id}/webhooks"),
&webhook_body(draft),
)
.await
}
pub async fn update_webhook(
&self,
project_id: &str,
webhook: &str,
change: &WebhookChange<'_>,
) -> Result<Answer<WebhookPage>> {
self.answer(
Method::PATCH,
&format!(
"/api/infra/projects/{project_id}/webhooks/{}",
utf8_percent_encode(webhook, NON_ALPHANUMERIC)
),
Some(&change_body(change)),
)
.await
}
pub async fn delete_webhook(&self, project_id: &str, webhook: &str) -> Result<()> {
self.delete(&format!(
"/api/infra/projects/{project_id}/webhooks/{}",
utf8_percent_encode(webhook, NON_ALPHANUMERIC)
))
.await
}
pub async fn test_webhook(
&self,
project_id: &str,
webhook: &str,
) -> Result<Answer<WebhookTestPage>> {
self.post_answer(
&format!(
"/api/infra/projects/{project_id}/webhooks/{}/test",
utf8_percent_encode(webhook, NON_ALPHANUMERIC)
),
&serde_json::json!({}),
)
.await
}
}
fn webhook_body(draft: &NewWebhook<'_>) -> serde_json::Value {
let mut body = serde_json::Map::new();
body.insert("url".into(), draft.url.into());
if let Some(name) = draft.name {
body.insert("name".into(), name.into());
}
if let Some(format) = draft.format {
body.insert("format".into(), format.into());
}
if !draft.events.is_empty() {
body.insert("events".into(), draft.events.into());
}
serde_json::Value::Object(body)
}
fn change_body(change: &WebhookChange<'_>) -> serde_json::Value {
let mut body = serde_json::Map::new();
if let Some(name) = change.name {
body.insert("name".into(), name.into());
}
if let Some(events) = change.events {
body.insert("events".into(), events.into());
}
if let Some(enabled) = change.enabled {
body.insert("enabled".into(), enabled.into());
}
serde_json::Value::Object(body)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_should_leave_the_format_and_events_to_the_server_when_none_is_given() {
let draft = NewWebhook {
url: "https://hooks.slack.com/services/x",
name: None,
format: None,
events: &[],
};
assert_eq!(
webhook_body(&draft),
serde_json::json!({ "url": "https://hooks.slack.com/services/x" })
);
}
#[test]
fn it_should_send_only_what_changes() {
let change = WebhookChange {
name: None,
events: None,
enabled: Some(false),
};
assert_eq!(
change_body(&change),
serde_json::json!({ "enabled": false })
);
}
}