mod client;
use serde::{Deserialize, Serialize};
pub use client::{Client, ClientBuilder, Error};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum ReplayPreset {
Latest,
Earliest,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum SubscriptionState {
Run,
Stop,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ManagedEventSubscriptionMetadata {
pub label: String,
pub topic_name: String,
pub default_replay: ReplayPreset,
pub state: SubscriptionState,
pub error_recovery_replay: ReplayPreset,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct CreateManagedEventSubscriptionRequest {
pub full_name: String,
pub metadata: ManagedEventSubscriptionMetadata,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CreateManagedEventSubscriptionResponse {
pub id: String,
pub success: bool,
#[serde(default)]
pub errors: Vec<ToolingApiError>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ToolingApiError {
pub status_code: String,
pub message: String,
#[serde(default)]
pub fields: Vec<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_replay_preset_serialization() {
let latest = ReplayPreset::Latest;
let earliest = ReplayPreset::Earliest;
assert_eq!(serde_json::to_string(&latest).unwrap(), r#""LATEST""#);
assert_eq!(serde_json::to_string(&earliest).unwrap(), r#""EARLIEST""#);
}
#[test]
fn test_replay_preset_deserialization() {
let latest: ReplayPreset = serde_json::from_str(r#""LATEST""#).unwrap();
let earliest: ReplayPreset = serde_json::from_str(r#""EARLIEST""#).unwrap();
assert_eq!(latest, ReplayPreset::Latest);
assert_eq!(earliest, ReplayPreset::Earliest);
}
#[test]
fn test_subscription_state_serialization() {
let run = SubscriptionState::Run;
let stop = SubscriptionState::Stop;
assert_eq!(serde_json::to_string(&run).unwrap(), r#""RUN""#);
assert_eq!(serde_json::to_string(&stop).unwrap(), r#""STOP""#);
}
#[test]
fn test_subscription_state_deserialization() {
let run: SubscriptionState = serde_json::from_str(r#""RUN""#).unwrap();
let stop: SubscriptionState = serde_json::from_str(r#""STOP""#).unwrap();
assert_eq!(run, SubscriptionState::Run);
assert_eq!(stop, SubscriptionState::Stop);
}
#[test]
fn test_managed_event_subscription_metadata_serialization() {
let metadata = ManagedEventSubscriptionMetadata {
label: "Test Subscription".to_string(),
topic_name: "/data/OpportunityChangeEvent".to_string(),
default_replay: ReplayPreset::Latest,
state: SubscriptionState::Run,
error_recovery_replay: ReplayPreset::Earliest,
};
let json = serde_json::to_value(&metadata).unwrap();
assert_eq!(json["label"], "Test Subscription");
assert_eq!(json["topicName"], "/data/OpportunityChangeEvent");
assert_eq!(json["defaultReplay"], "LATEST");
assert_eq!(json["state"], "RUN");
assert_eq!(json["errorRecoveryReplay"], "EARLIEST");
}
#[test]
fn test_create_managed_event_subscription_request_serialization() {
let request = CreateManagedEventSubscriptionRequest {
full_name: "Managed_Sub_Test".to_string(),
metadata: ManagedEventSubscriptionMetadata {
label: "Test".to_string(),
topic_name: "/data/Test".to_string(),
default_replay: ReplayPreset::Latest,
state: SubscriptionState::Run,
error_recovery_replay: ReplayPreset::Latest,
},
};
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["FullName"], "Managed_Sub_Test");
assert!(json["Metadata"].is_object());
assert_eq!(json["Metadata"]["label"], "Test");
}
#[test]
fn test_create_managed_event_subscription_response_success() {
let json = r#"{
"id": "0Xaxx000000001AAA",
"success": true,
"errors": []
}"#;
let response: CreateManagedEventSubscriptionResponse = serde_json::from_str(json).unwrap();
assert_eq!(response.id, "0Xaxx000000001AAA");
assert!(response.success);
assert!(response.errors.is_empty());
}
#[test]
fn test_create_managed_event_subscription_response_error() {
let json = r#"{
"id": "",
"success": false,
"errors": [
{
"statusCode": "INVALID_FIELD",
"message": "Invalid topic name",
"fields": ["topicName"]
}
]
}"#;
let response: CreateManagedEventSubscriptionResponse = serde_json::from_str(json).unwrap();
assert!(!response.success);
assert_eq!(response.errors.len(), 1);
assert_eq!(response.errors[0].status_code, "INVALID_FIELD");
assert_eq!(response.errors[0].message, "Invalid topic name");
assert_eq!(response.errors[0].fields, vec!["topicName"]);
}
#[test]
fn test_tooling_api_error_camel_case_fields() {
let json = r#"{
"statusCode": "DUPLICATE_VALUE",
"message": "Duplicate subscription name",
"fields": ["fullName"]
}"#;
let error: ToolingApiError = serde_json::from_str(json).unwrap();
assert_eq!(error.status_code, "DUPLICATE_VALUE");
assert_eq!(error.message, "Duplicate subscription name");
assert_eq!(error.fields, vec!["fullName"]);
}
#[test]
fn test_tooling_api_error_default_fields() {
let json = r#"{
"statusCode": "UNKNOWN_ERROR",
"message": "Something went wrong"
}"#;
let error: ToolingApiError = serde_json::from_str(json).unwrap();
assert_eq!(error.status_code, "UNKNOWN_ERROR");
assert_eq!(error.message, "Something went wrong");
assert!(error.fields.is_empty());
}
}