mod common;
use apibrasil::{Config, Method, RequestOptions};
use common::{
assert_request, build_api, build_api_anonymous, build_api_with, ok, raw_bytes, BASE_URL,
};
use serde_json::json;
#[tokio::test]
async fn auth_guarda_o_token_do_login() {
let (api, transport) = build_api_anonymous();
transport.respond_with(ok(json!({ "authorization": { "token": "novo-jwt" } })));
api.auth()
.login(json!({ "email": "a@b.c", "password": "x" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/auth/login", None);
assert_eq!(api.http().bearer_token().as_deref(), Some("novo-jwt"));
}
#[tokio::test]
async fn auth_guarda_o_token_no_formato_plano() {
let (api, transport) = build_api();
transport.respond_with(ok(json!({ "token": "jwt-2fa" })));
api.auth()
.verify_2fa(json!({ "challenge": "x", "code": "000000" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/auth/login/verify-2fa", None);
assert_eq!(api.http().bearer_token().as_deref(), Some("jwt-2fa"));
}
#[tokio::test]
async fn auth_login_sinaliza_2fa() {
let (api, transport) = build_api();
transport.respond_with(ok(json!({ "requires_2fa": true, "challenge": "abc" })));
let sessao = api.auth().login(json!({ "email": "a@b.c" })).await.unwrap();
assert!(apibrasil::requires_2fa(&sessao));
assert_eq!(apibrasil::extract_token(&sessao), None);
}
#[tokio::test]
async fn auth_logout_limpa_o_token() {
let (api, _transport) = build_api();
api.auth().logout().await.unwrap();
assert_eq!(api.http().bearer_token(), None);
}
#[tokio::test]
async fn auth_cobre_perfil_e_senha() {
let (api, transport) = build_api();
api.auth().profile().await.unwrap();
assert_request(&transport, Method::Post, "/profile", None);
api.auth().me().await.unwrap();
assert_request(&transport, Method::Get, "/profile/me", None);
api.auth().update_me(json!({ "name": "x" })).await.unwrap();
assert_request(&transport, Method::Put, "/profile/me", None);
api.auth()
.change_password(json!({ "password": "x" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/password/change", None);
api.auth().two_factor_methods().await.unwrap();
assert_request(&transport, Method::Get, "/auth/2fa/methods", None);
}
#[tokio::test]
async fn devices_store_envia_a_secret_key_no_header() {
let (api, transport) = build_api_with(Config {
secret_key: Some("segredo".to_string()),
..Default::default()
});
api.devices()
.store(json!({ "device_name": "bot", "type": "server" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/devices/store", None);
assert_eq!(
transport.last_header("SecretKey").as_deref(),
Some("segredo")
);
}
#[tokio::test]
async fn devices_store_aceita_secret_key_por_requisicao() {
let (api, transport) = build_api();
api.with_options(RequestOptions::new().secret_key("da-chamada"))
.devices()
.store(json!({ "device_name": "bot" }))
.await
.unwrap();
assert_eq!(
transport.last_header("SecretKey").as_deref(),
Some("da-chamada")
);
}
#[tokio::test]
async fn devices_show_e_destroy_usam_o_device_do_cliente() {
let (api, transport) = build_api();
api.devices().show(None).await.unwrap();
assert_eq!(transport.last().method, Method::Get);
assert_eq!(
transport.last().url,
format!("{BASE_URL}/devices/show?search=dev")
);
api.devices().show(Some("outro")).await.unwrap();
assert_eq!(
transport.last().url,
format!("{BASE_URL}/devices/show?search=outro")
);
api.devices().destroy(None).await.unwrap();
assert_request(
&transport,
Method::Delete,
"/devices/destroy",
Some(json!({ "search": "dev" })),
);
}
#[tokio::test]
async fn devices_list_monta_a_query() {
let (api, transport) = build_api();
api.devices()
.list(json!({ "page": 2, "search": "bot" }))
.await
.unwrap();
assert_eq!(
transport.last().url,
format!("{BASE_URL}/devices?page=2&search=bot")
);
}
#[tokio::test]
async fn catalog_cobre_apis_planos_e_documentacoes() {
let (api, transport) = build_api();
api.catalog().apis(None).await.unwrap();
assert_request(&transport, Method::Get, "/apis", None);
api.catalog().apis(Some("whats app")).await.unwrap();
assert_eq!(
transport.last().url,
format!("{BASE_URL}/apis?search=whats+app")
);
api.catalog().api("123").await.unwrap();
assert_request(&transport, Method::Get, "/apis/123", None);
api.catalog().api_by_name("API de CNPJ").await.unwrap();
assert_request(&transport, Method::Get, "/apis/name/API%20de%20CNPJ", None);
api.catalog().plans().await.unwrap();
assert_request(&transport, Method::Get, "/plans", None);
api.catalog().documentations_by_server("srv").await.unwrap();
assert_request(&transport, Method::Get, "/documentations/server/srv", None);
api.catalog()
.endpoint_url(json!({ "action": "sendText" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/endpoint/url", None);
}
#[tokio::test]
async fn account_cobre_saldo_faturas_e_tickets() {
let (api, transport) = build_api();
api.account().balance().await.unwrap();
assert_request(&transport, Method::Get, "/balance", None);
api.account().pay_invoice(json!({ "id": 1 })).await.unwrap();
assert_request(&transport, Method::Post, "/invoices/pay", None);
api.account().mark_notification_read(7).await.unwrap();
assert_request(&transport, Method::Patch, "/notifications/7/read", None);
api.account().mark_all_notifications_read().await.unwrap();
assert_request(
&transport,
Method::Post,
"/notifications/mark-all-read",
None,
);
api.account()
.update_ticket(9, json!({ "status": "closed" }))
.await
.unwrap();
assert_request(&transport, Method::Put, "/ticket/9", None);
api.account().ticket_messages(9).await.unwrap();
assert_request(&transport, Method::Get, "/ticket/9/messages", None);
api.account()
.add_ticket_message(9, json!({ "message": "oi" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/ticket/9/messages", None);
}
#[tokio::test]
async fn payments_cobre_pix_boleto_e_cartao() {
let (api, transport) = build_api();
api.payments()
.recharge(json!({ "amount": 50, "type": "pix" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/recharge", None);
api.payments().recharge_show("REC1").await.unwrap();
assert_request(&transport, Method::Get, "/recharge/REC1", None);
api.payments()
.pix_generate("santander", json!({ "amount": 50 }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/santander/pix/generate", None);
api.payments().pix_status("santander", "TX1").await.unwrap();
assert_request(&transport, Method::Get, "/santander/pix/TX1", None);
api.payments()
.boleto_generate("inter", json!({ "amount": 50 }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/inter/boleto/generate", None);
api.payments()
.card_process(json!({ "token": "x" }))
.await
.unwrap();
assert_request(&transport, Method::Post, "/mercadopago/card/process", None);
api.payments().card_status("PAY1").await.unwrap();
assert_request(&transport, Method::Get, "/mercadopago/card/PAY1", None);
}
#[tokio::test]
async fn boleto_pdf_devolve_os_bytes_crus() {
let (api, transport) = build_api();
transport.respond_with(raw_bytes(200, b"%PDF-1.4 conteudo"));
let pdf = api.payments().boleto_pdf("inter", "ID").await.unwrap();
assert_eq!(pdf, b"%PDF-1.4 conteudo");
assert_request(&transport, Method::Get, "/inter/boleto/ID/pdf", None);
assert_eq!(
transport.last().response_type,
apibrasil::ResponseType::Bytes
);
}
#[tokio::test]
async fn seguranca_cobre_ip_whitelist_e_rate_limit() {
let (api, transport) = build_api();
api.ip_whitelist().get().await.unwrap();
assert_request(&transport, Method::Get, "/ip-whitelist", None);
api.ip_whitelist()
.set(["1.1.1.1", "2.2.2.2"])
.await
.unwrap();
assert_request(
&transport,
Method::Put,
"/ip-whitelist",
Some(json!({ "ip_whitelist": ["1.1.1.1", "2.2.2.2"] })),
);
api.ip_whitelist().add("3.3.3.3").await.unwrap();
assert_request(
&transport,
Method::Post,
"/ip-whitelist/add",
Some(json!({ "entry": "3.3.3.3" })),
);
api.ip_whitelist().remove("3.3.3.3").await.unwrap();
assert_request(&transport, Method::Delete, "/ip-whitelist/remove", None);
api.ip_whitelist().add_current().await.unwrap();
assert_request(&transport, Method::Post, "/ip-whitelist/add-current", None);
api.bearer_rate_limit().get().await.unwrap();
assert_request(&transport, Method::Get, "/bearer-rate-limit", None);
api.bearer_rate_limit()
.set(json!({ "limit": 60 }))
.await
.unwrap();
assert_request(&transport, Method::Put, "/bearer-rate-limit", None);
}
#[tokio::test]
async fn reports_cobre_o_dashboard_de_consumo() {
let (api, transport) = build_api();
api.reports().dashboard_stats().await.unwrap();
assert_request(&transport, Method::Get, "/dashboard/stats", None);
api.reports().quick_stats().await.unwrap();
assert_request(&transport, Method::Get, "/reports/quick-stats", None);
api.reports()
.generate_consumption_report(json!({ "month": "2026-07" }))
.await
.unwrap();
assert_request(
&transport,
Method::Post,
"/reports/generate-consumption-report",
None,
);
}