use httpmock::prelude::*;
use parcelwing::{Client, EmailSendRequest};
#[tokio::test]
async fn sends_email_request_and_returns_queued_emails() {
let server = MockServer::start();
let mock = server.mock(|when, then| {
when.method(POST)
.path("/api/emails")
.header("authorization", "Bearer pw_test_123")
.json_body_obj(&serde_json::json!({
"from": "Parcel Wing <hello@example.com>",
"to": "you@example.com",
"subject": "Hello",
"text": "It works!"
}));
then.status(202)
.header("content-type", "application/json")
.json_body_obj(&serde_json::json!({
"object": "list",
"data": [
{
"object": "email",
"id": "msg_123",
"to": "you@example.com",
"status": "queued"
}
],
"pagination": null
}));
});
let client = Client::builder("pw_test_123")
.base_url(server.base_url())
.build()
.unwrap();
let emails = client
.emails()
.send(
EmailSendRequest::new("Parcel Wing <hello@example.com>", "you@example.com")
.subject("Hello")
.text("It works!"),
)
.await
.unwrap();
mock.assert();
assert_eq!(emails.len(), 1);
assert_eq!(emails[0].id, "msg_123");
assert_eq!(emails[0].status, "queued");
}
#[tokio::test]
async fn maps_api_error_payload() {
let server = MockServer::start();
server.mock(|when, then| {
when.method(POST).path("/api/emails");
then.status(400)
.header("content-type", "application/json")
.json_body_obj(&serde_json::json!({
"error": {
"type": "validation_error",
"code": "invalid_request_body",
"message": "Invalid request body.",
"request_id": "req_123"
}
}));
});
let client = Client::builder("pw_test_123")
.base_url(server.base_url())
.build()
.unwrap();
let error = client
.emails()
.send(EmailSendRequest::new("bad", "you@example.com"))
.await
.unwrap_err();
match error {
parcelwing::Error::Api(api_error) => {
assert_eq!(api_error.status(), 400);
assert_eq!(api_error.code.as_deref(), Some("invalid_request_body"));
assert_eq!(api_error.request_id.as_deref(), Some("req_123"));
}
other => panic!("expected API error, got {other:?}"),
}
}