Skip to main content

wfe_core/models/
poll_config.rs

1use std::collections::HashMap;
2use std::time::Duration;
3
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
7pub enum HttpMethod {
8    #[default]
9    Get,
10    Post,
11    Put,
12    Patch,
13    Delete,
14}
15
16#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
17pub enum PollCondition {
18    /// Check a JSON path equals a value: e.g. JsonPathEquals("$.status", "complete")
19    JsonPathEquals {
20        path: String,
21        value: serde_json::Value,
22    },
23    /// Check HTTP status code
24    StatusCode(u16),
25    /// Check response body contains string
26    BodyContains(String),
27}
28
29impl Default for PollCondition {
30    fn default() -> Self {
31        Self::StatusCode(200)
32    }
33}
34
35#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
36pub struct PollEndpointConfig {
37    /// URL template. Supports `{placeholder}` interpolation from workflow data.
38    pub url: String,
39    pub method: HttpMethod,
40    #[serde(default)]
41    pub headers: HashMap<String, String>,
42    #[serde(default)]
43    pub body: Option<serde_json::Value>,
44    #[serde(with = "super::duration_millis")]
45    pub interval: Duration,
46    #[serde(with = "super::duration_millis")]
47    pub timeout: Duration,
48    pub condition: PollCondition,
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use pretty_assertions::assert_eq;
55
56    #[test]
57    fn poll_config_serde_round_trip() {
58        let config = PollEndpointConfig {
59            url: "https://api.example.com/status/{id}".into(),
60            method: HttpMethod::Get,
61            headers: HashMap::from([("Authorization".into(), "Bearer token123".into())]),
62            body: None,
63            interval: Duration::from_secs(30),
64            timeout: Duration::from_secs(3600),
65            condition: PollCondition::JsonPathEquals {
66                path: "$.status".into(),
67                value: serde_json::Value::String("complete".into()),
68            },
69        };
70        let json = serde_json::to_string(&config).unwrap();
71        let deserialized: PollEndpointConfig = serde_json::from_str(&json).unwrap();
72        assert_eq!(config, deserialized);
73    }
74
75    #[test]
76    fn poll_condition_status_code() {
77        let cond = PollCondition::StatusCode(200);
78        let json = serde_json::to_string(&cond).unwrap();
79        let deserialized: PollCondition = serde_json::from_str(&json).unwrap();
80        assert_eq!(cond, deserialized);
81    }
82
83    #[test]
84    fn poll_condition_body_contains() {
85        let cond = PollCondition::BodyContains("success".into());
86        let json = serde_json::to_string(&cond).unwrap();
87        let deserialized: PollCondition = serde_json::from_str(&json).unwrap();
88        assert_eq!(cond, deserialized);
89    }
90}