#![cfg(test)]
use microformats::types::{Class, KnownClass};

use super::Action;
use crate::standards::micropub::action::{ActionResponse, CreationProperties};

async fn mock_micropub_request(
    client: impl crate::http::Client,
    endpoint: &url::Url,
    token: &oauth2::AccessToken,
    action: &Action,
    response: &ActionResponse,
    message: impl ToString,
) {
    assert_eq!(
        action.send(&client, endpoint, token).await,
        Ok(response.to_owned()),
        "crafts expected response for {}",
        message.to_string()
    );
}

#[tracing_test::traced_test]
#[tokio::test]
async fn action_send_request() {
    let mut client = crate::test::Client::new().await;
    let token = oauth2::AccessToken::new("a-bad-token".into());

    client
        .mock_server
        .mock("POST", "/action-create-sync")
        .with_header(http::header::CONTENT_TYPE.to_string(), "application/json")
        .with_header(http::header::LOCATION.to_string(), "http://example.com/new")
        .with_status(http::StatusCode::CREATED.as_u16().into())
        .expect(1)
        .create_async()
        .await;

    let u = format!("{}/action-create-sync", client.mock_server.url())
        .parse()
        .unwrap();

    mock_micropub_request(
        client,
        &u,
        &token,
        &Action::Create {
            properties: CreationProperties {
                r#type: Class::Known(KnownClass::Entry),
                parameters: Default::default(),
                extra_fields: Default::default(),
            },
            files: Default::default(),
        },
        &ActionResponse::Created {
            sync: true,
            location: "http://example.com/new".parse().unwrap(),
            rel: Default::default(),
        },
        "create sync",
    )
    .await;
}
