dimescheduler 0.1.0

Official Rust client library for the Dime.Scheduler API.
Documentation
use serde_json::json;
use wiremock::matchers::{method, path, query_param};
use wiremock::{Mock, MockServer, ResponseTemplate};

use super::crud::client;
use crate::{entities, models, types};

async fn expect(server: &MockServer, m: &str, p: &str, body: serde_json::Value) {
    Mock::given(method(m))
        .and(path(p))
        .respond_with(ResponseTemplate::new(200).set_body_json(body))
        .expect(1)
        .mount(server)
        .await;
}

#[tokio::test]
async fn single_purpose_accessors_hit_their_routes() {
    let server = MockServer::start().await;
    expect(&server, "POST", "/connector", json!({})).await;
    expect(&server, "POST", "/geocode", json!({ "lat": 1.0 })).await;
    Mock::given(method("GET"))
        .and(path("/geocode"))
        .and(query_param("address", "Main St 1"))
        .and(query_param("country", "BE"))
        .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "lat": 1.0 })))
        .expect(1)
        .mount(&server)
        .await;
    expect(&server, "POST", "/import", json!({})).await;
    expect(&server, "POST", "/import/setup", json!({})).await;
    expect(&server, "POST", "/message", json!({})).await;
    expect(&server, "POST", "/optimization/fieldService", json!({})).await;
    expect(
        &server,
        "POST",
        "/optimization/professionalServices",
        json!({}),
    )
    .await;
    expect(&server, "POST", "/optimization/dailyRoute", json!({})).await;
    expect(&server, "POST", "/recommendation", json!({ "slots": [] })).await;
    expect(
        &server,
        "GET",
        "/recommendation/scorers",
        json!(["distance", "skills"]),
    )
    .await;
    expect(&server, "POST", "/appointmentRecurring", json!({})).await;
    expect(&server, "DELETE", "/appointmentRecurring", json!({})).await;
    expect(&server, "POST", "/user", json!({})).await;

    let c = client(&server).await;
    c.connectors
        .create(&types::NewConnectorRequest::default())
        .await
        .unwrap();
    let geo = c
        .geocoding
        .geocode(&types::Address::default())
        .await
        .unwrap();
    assert_eq!(geo["lat"], 1.0);
    c.geocoding.geocode_text("Main St 1", "BE").await.unwrap();
    c.imports
        .run(&[models::StoredProcedureData::default()])
        .await
        .unwrap();
    c.imports
        .setup(&types::SetupImportPayloadDto::default())
        .await
        .unwrap();
    c.messages
        .send(&entities::Message::default())
        .await
        .unwrap();
    c.optimization
        .field_service(&types::FieldServiceOptimizationRequest::default())
        .await
        .unwrap();
    c.optimization
        .professional_services(&types::ProfessionalServicesOptimizationRequest::default())
        .await
        .unwrap();
    c.optimization
        .daily_route(&types::OptimizeDailyRouteRequest::default())
        .await
        .unwrap();
    let rec = c
        .recommendation
        .get(&types::RecommendationRequest::default())
        .await
        .unwrap();
    assert!(rec["slots"].is_array());
    assert_eq!(c.recommendation.scorers().await.unwrap().len(), 2);
    c.recurring_appointments
        .create(&types::RecurringAppointmentRequest::default())
        .await
        .unwrap();
    c.recurring_appointments
        .delete(&types::DeleteRecurringAppointmentRequest::default())
        .await
        .unwrap();
    c.users.create(&types::ApiUser::default()).await.unwrap();
}

#[tokio::test]
async fn import_run_sends_an_array_body() {
    let server = MockServer::start().await;
    expect(&server, "POST", "/import", json!({})).await;
    client(&server)
        .await
        .imports
        .run(&[models::StoredProcedureData::default()])
        .await
        .unwrap();
    let body = server.received_requests().await.unwrap()[0].body.clone();
    assert!(body.starts_with(b"["));
}