use serde_json::json;
use snippe::models::session::{AllowedMethod, CreateSessionRequest, SessionStatus};
use snippe::Client;
use wiremock::matchers::{body_json, method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
fn client_for(server: &MockServer) -> Client {
Client::builder()
.api_key("snp_test_key")
.base_url(server.uri())
.build()
.unwrap()
}
#[tokio::test]
async fn create_fixed_amount_session() {
let server = MockServer::start().await;
let response = json!({
"code": 201,
"data": {
"reference": "sess_abc123",
"status": "pending",
"amount": 50000,
"currency": "TZS",
"checkout_url": "https://snippe.me/checkout/xyz",
"short_code": "Ax7kM2",
"payment_link_url": "https://snippe.me/p/Ax7kM2",
"expires_at": "2026-02-26T11:00:00Z"
}
});
let expected = json!({
"amount": 50000,
"currency": "TZS",
"allowed_methods": ["mobile_money", "qr"],
"description": "Order #1"
});
Mock::given(method("POST"))
.and(path("/api/v1/sessions"))
.and(body_json(expected))
.respond_with(ResponseTemplate::new(201).set_body_json(response))
.mount(&server)
.await;
let client = client_for(&server);
let req = CreateSessionRequest::fixed_amount(50_000)
.with_allowed_methods([AllowedMethod::MobileMoney, AllowedMethod::Qr])
.with_description("Order #1");
let session = client.sessions().create(&req, None).await.unwrap();
assert_eq!(session.reference, "sess_abc123");
assert_eq!(session.status, SessionStatus::Pending);
assert_eq!(session.amount, Some(50_000));
assert!(session.payment_link_url.is_some());
}
#[tokio::test]
async fn cancel_session() {
let server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/api/v1/sessions/sess_1/cancel"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"data": {
"reference": "sess_1",
"status": "cancelled",
"amount": 50000,
"currency": "TZS",
"checkout_url": "https://snippe.me/checkout/xyz",
"expires_at": "2026-02-26T11:00:00Z"
}
})))
.mount(&server)
.await;
let client = client_for(&server);
let session = client.sessions().cancel("sess_1").await.unwrap();
assert_eq!(session.status, SessionStatus::Cancelled);
assert!(session.status.is_terminal());
}