sota 0.9.1

API crate for Summits on the Air
Documentation
use super::Client;

use std::{fmt::Debug, str::FromStr};

use httpmock::prelude::*;
use serde::{de::DeserializeOwned, Serialize};

use crate::{callsign::Callsign, summit::SummitCode, Mode};

fn round_trip<T: DeserializeOwned + Serialize + Eq + Debug>(value: &T) {
    let string = serde_json::to_string(&value).unwrap();
    let deserialized: T = serde_json::from_str(&string).unwrap();
    assert_eq!(value, &deserialized);
}

#[tokio::test]
async fn alerts() {
    // TODO: Ow, the boilerplate.
    let server = MockServer::start();

    let m = server.mock(|when, then| {
        when.path("/alerts/12/all/all");
        then.status(200)
            .header("content-type", "application/json")
            .body(include_str!("test/alerts.json"));
    });
    let c = Client::new_with_base(&server.base_url(), "".into());

    let response = c.all_alerts().await.unwrap();

    m.assert();
    assert_eq!(response.len(), 1);
    assert_eq!(response[0].activating_callsign, Callsign::from("N6TNO"));

    round_trip(&response[0]);
}

#[tokio::test]
async fn spot() {
    let server = MockServer::start();

    let m = server.mock(|when, then| {
        when.path("/spots/-1/all/all");
        then.status(200)
            .header("content-type", "application/json")
            .body(include_str!("test/spot_variants.json"));
    });
    let c = Client::new_with_base(&server.base_url(), "".into());

    let response = c.all_spots(1).await.unwrap();

    m.assert();
    assert_eq!(response.len(), 4);
    assert_eq!(response[3].mode, Mode::CW);

    round_trip(&response[0]);
}

#[tokio::test]
async fn summit() {
    let server = MockServer::start();

    let m = server.mock(|when, then| {
        when.path("/summits/W6/CC-063");
        then.status(200)
            .header("content-type", "application/json")
            .body(include_str!("test/summit.json"));
    });
    let c = Client::new_with_base(&server.base_url(), "".into());

    let code = SummitCode::from_str("W6/CC-063").unwrap();
    let response = c.summit(&code).await.unwrap();

    m.assert();
    assert_eq!(response.name, "Mount Tamalpais");
}

#[tokio::test]
async fn assoc() {
    let server = MockServer::start();

    let m = server.mock(|when, then| {
        when.path("/associations/W6");
        then.status(200)
            .header("content-type", "application/json")
            .body(include_str!("test/assoc.json"));
    });
    let c = Client::new_with_base(&server.base_url(), "".into());

    let response = c.association("W6").await.unwrap();

    m.assert();
    assert_eq!(response.association_name, "USA");
}

#[tokio::test]
async fn region() {
    let server = MockServer::start();

    let m = server.mock(|when, then| {
        when.path("/regions/W6/CC");
        then.status(200)
            .header("content-type", "application/json")
            .body(include_str!("test/region.json"));
    });
    let c = Client::new_with_base(&server.base_url(), "".into());

    let response = c.region("W6", "CC").await.unwrap();

    m.assert();
    assert_eq!(response.region_name, "Coastal Ranges");
}