Skip to main content

devboy_clickup/
liveness.rs

1//! ClickUp [`LivenessProbe`] stub per [ADR-021] §6.
2//!
3//! ClickUp's introspection endpoint is `GET /api/v2/user`, but
4//! routing the response through the typed liveness shape (active /
5//! revoked / expired) requires more sniffing than this commit's
6//! scope allows. The stub uses the trait's default `test` impl
7//! (which returns [`LivenessStatus::NotImplemented`]) and wires
8//! the provider name so `doctor` shows
9//! "clickup liveness probe is not implemented; format-only
10//! validation only" instead of "no probe configured".
11//!
12//! Replacing the stub: drop a real `test` override against
13//! `<base>/api/v2/user`, mirroring `crates/plugins/api/github`.
14//!
15//! [ADR-021]: https://github.com/meteora-pro/devboy-tools/blob/main/docs/architecture/adr/ADR-021-external-secret-sources.md
16//! [`LivenessStatus::NotImplemented`]: devboy_core::liveness::LivenessStatus
17
18use async_trait::async_trait;
19use devboy_core::LivenessProbe;
20
21use crate::client::ClickUpClient;
22
23#[async_trait]
24impl LivenessProbe for ClickUpClient {
25    fn provider_name(&self) -> &str {
26        "clickup"
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33    use devboy_core::liveness::LivenessStatus;
34    use secrecy::SecretString;
35
36    #[tokio::test]
37    async fn provider_name_is_clickup_and_default_returns_not_implemented() {
38        let client = ClickUpClient::new("list-id", SecretString::from("any".to_owned()));
39        assert_eq!(client.provider_name(), "clickup");
40        let r = client
41            .test(&SecretString::from("any".to_owned()))
42            .await
43            .unwrap();
44        assert_eq!(r.status, LivenessStatus::NotImplemented);
45        assert!(r.detail.unwrap().contains("clickup"));
46    }
47}