bestool 1.6.2

BES Deployment tooling
Documentation
use std::path::PathBuf;

use chrono::{Duration, Utc};

use super::{
	definition::{AlertDefinition, TicketSource},
	targets::SendTarget,
	templates::build_context,
};

fn interval_context(dur: Duration) -> Option<String> {
	let alert = AlertDefinition {
		file: PathBuf::from("test.yaml"),
		enabled: true,
		interval: dur.to_std().unwrap(),
		source: TicketSource::Sql { sql: "".into() },
		send: vec![],
	};
	build_context(&alert, Utc::now())
		.get("interval")
		.and_then(|v| v.as_str())
		.map(|s| s.to_owned())
}

#[test]
fn test_interval_format_minutes() {
	assert_eq!(
		interval_context(Duration::minutes(15)).as_deref(),
		Some("15m"),
	);
}

#[test]
fn test_interval_format_hour() {
	assert_eq!(interval_context(Duration::hours(1)).as_deref(), Some("1h"),);
}

#[test]
fn test_interval_format_day() {
	assert_eq!(interval_context(Duration::days(1)).as_deref(), Some("1d"),);
}

#[test]
fn test_alert_parse_email() {
	let alert = r#"
sql: SELECT $1::timestamptz;
send:
- target: email
  addresses: [test@example.com]
  subject: "[Tamanu Alert] Example ({{ hostname }})"
  template: |
    <p>Server: {{ hostname }}</p>
    <p>There are {{ rows | length }} rows.</p>
"#;
	let alert: AlertDefinition = serde_yaml::from_str(alert).unwrap();
	let alert = alert.normalise(&Default::default());
	assert_eq!(alert.interval, std::time::Duration::default());
	assert!(matches!(alert.source, TicketSource::Sql { sql } if sql == "SELECT $1::timestamptz;"));
	assert!(matches!(alert.send[0], SendTarget::Email { .. }));
}

#[test]
fn test_alert_parse_shell() {
	let alert = r#"
shell: bash
run: echo foobar
"#;
	let alert: AlertDefinition = serde_yaml::from_str(alert).unwrap();
	let alert = alert.normalise(&Default::default());
	assert_eq!(alert.interval, std::time::Duration::default());
	assert!(
		matches!(alert.source, TicketSource::Shell { shell, run } if shell == "bash" && run == "echo foobar")
	);
}

#[test]
fn test_alert_parse_invalid_source() {
	let alert = r#"
shell: bash
"#;
	assert!(serde_yaml::from_str::<AlertDefinition>(alert).is_err());
	let alert = r#"
run: echo foo
"#;
	assert!(serde_yaml::from_str::<AlertDefinition>(alert).is_err());
	let alert = r#"
sql: SELECT $1::timestamptz;
run: echo foo
"#;
	assert!(serde_yaml::from_str::<AlertDefinition>(alert).is_err());
	let alert = r#"
sql: SELECT $1::timestamptz;
shell: bash
"#;
	assert!(serde_yaml::from_str::<AlertDefinition>(alert).is_err());
	let alert = r#"
sql: SELECT $1::timestamptz;
shell: bash
run: echo foo
"#;
	assert!(serde_yaml::from_str::<AlertDefinition>(alert).is_err());
}

#[test]
fn test_alert_parse_zendesk_authorized() {
	let alert = r#"
sql: SELECT $1::timestamptz;
send:
- target: zendesk
  endpoint: https://example.zendesk.com/api/v2/requests
  credentials:
    email: foo@example.com
    password: pass
  subject: "[Tamanu Alert] Example ({{ hostname }})"
  template: "Output: {{ output }}""#;
	let alert: AlertDefinition = serde_yaml::from_str(alert).unwrap();
	assert!(matches!(alert.send[0], SendTarget::Zendesk { .. }));
}

#[test]
fn test_alert_parse_zendesk_anon() {
	let alert = r#"
sql: SELECT $1::timestamptz;
send:
- target: zendesk
  endpoint: https://example.zendesk.com/api/v2/requests
  requester: "{{ hostname }}"
  subject: "[Tamanu Alert] Example ({{ hostname }})"
  template: "Output: {{ output }}""#;
	let alert: AlertDefinition = serde_yaml::from_str(alert).unwrap();
	assert!(matches!(alert.send[0], SendTarget::Zendesk { .. }));
}

#[test]
fn test_alert_parse_zendesk_form_fields() {
	let alert = r#"
sql: SELECT $1::timestamptz;
send:
- target: zendesk
  endpoint: https://example.zendesk.com/api/v2/requests
  requester: "{{ hostname }}"
  subject: "[Tamanu Alert] Example ({{ hostname }})"
  template: "Output: {{ output }}"
  ticket_form_id: 500
  custom_fields:
  - id: 100
    value: tamanu_
  - id: 200
    value: Test
"#;
	let alert: AlertDefinition = serde_yaml::from_str(alert).unwrap();
	assert!(matches!(alert.send[0], SendTarget::Zendesk { .. }));
}

#[test]
fn test_alert_parse_slack() {
	let alert = r#"
sql: SELECT $1::timestamptz;
send:
- target: slack
  webhook: https://hooks.slack.com/triggers/
  template: Something happened
"#;
	let alert: AlertDefinition = serde_yaml::from_str(alert).unwrap();
	assert!(matches!(alert.send[0], SendTarget::Slack { .. }));
}

#[test]
fn test_alert_parse_slack_fields() {
	let alert = r#"
sql: SELECT $1::timestamptz;
send:
- target: slack
  webhook: https://hooks.slack.com/triggers/
  template: Something happened
  fields:
  - name: alertname
    field: filename
  - name: deployment
    value: production
"#;
	let alert: AlertDefinition = serde_yaml::from_str(alert).unwrap();
	assert!(matches!(alert.send[0], SendTarget::Slack { .. }));
}