Skip to main content

busbar_sf_rest/client/
scheduler.rs

1use tracing::instrument;
2
3use crate::error::Result;
4use crate::scheduler::{AppointmentCandidatesRequest, AppointmentCandidatesResponse};
5
6impl super::SalesforceRestClient {
7    /// Get appointment candidates based on scheduling parameters.
8    #[instrument(skip(self, request))]
9    pub async fn appointment_candidates(
10        &self,
11        request: &AppointmentCandidatesRequest,
12    ) -> Result<AppointmentCandidatesResponse> {
13        self.client
14            .rest_post("scheduling/getAppointmentCandidates", request)
15            .await
16            .map_err(Into::into)
17    }
18
19    /// Get appointment slots based on scheduling parameters.
20    #[instrument(skip(self, request))]
21    pub async fn appointment_slots(
22        &self,
23        request: &serde_json::Value,
24    ) -> Result<serde_json::Value> {
25        self.client
26            .rest_post("scheduling/getAppointmentSlots", request)
27            .await
28            .map_err(Into::into)
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::super::SalesforceRestClient;
35
36    #[tokio::test]
37    async fn test_appointment_candidates_wiremock() {
38        use wiremock::matchers::{method, path_regex};
39        use wiremock::{Mock, MockServer, ResponseTemplate};
40
41        let mock_server = MockServer::start().await;
42
43        let body = serde_json::json!({
44            "candidates": [{
45                "startTime": "2024-01-01T09:00:00.000Z",
46                "endTime": "2024-01-01T10:00:00.000Z",
47                "territoryId": "0Hhxx0000000001"
48            }]
49        });
50
51        Mock::given(method("POST"))
52            .and(path_regex(".*/scheduling/getAppointmentCandidates$"))
53            .respond_with(ResponseTemplate::new(200).set_body_json(&body))
54            .mount(&mock_server)
55            .await;
56
57        let client = SalesforceRestClient::new(mock_server.uri(), "test-token").unwrap();
58        let request = crate::scheduler::AppointmentCandidatesRequest {
59            start_time: "2024-01-01T09:00:00.000Z".to_string(),
60            end_time: "2024-01-01T17:00:00.000Z".to_string(),
61            work_type_group_id: None,
62            work_type_id: None,
63            account_id: None,
64            territory_ids: None,
65        };
66        let result = client
67            .appointment_candidates(&request)
68            .await
69            .expect("appointment_candidates should succeed");
70        assert_eq!(result.candidates.len(), 1);
71    }
72
73    #[tokio::test]
74    async fn test_appointment_slots_wiremock() {
75        use wiremock::matchers::{method, path_regex};
76        use wiremock::{Mock, MockServer, ResponseTemplate};
77
78        let mock_server = MockServer::start().await;
79
80        let body = serde_json::json!({
81            "timeSlots": [
82                {"startTime": "2024-01-01T09:00:00.000Z", "endTime": "2024-01-01T10:00:00.000Z"}
83            ]
84        });
85
86        Mock::given(method("POST"))
87            .and(path_regex(".*/scheduling/getAppointmentSlots$"))
88            .respond_with(ResponseTemplate::new(200).set_body_json(&body))
89            .mount(&mock_server)
90            .await;
91
92        let client = SalesforceRestClient::new(mock_server.uri(), "test-token").unwrap();
93        let request = serde_json::json!({
94            "startTime": "2024-01-01T09:00:00.000Z",
95            "endTime": "2024-01-01T17:00:00.000Z"
96        });
97        let result = client
98            .appointment_slots(&request)
99            .await
100            .expect("appointment_slots should succeed");
101        assert!(result["timeSlots"].is_array());
102    }
103}