use artisan::direction::Destination;
use artisan::plugins::{AddPayloadBodyPlugin, AddRadarPlugin, ParserPlugin, StartPlugin};
use artisan::{Artful, Plugin, Rocket, flow_ctrl::Next};
use async_trait::async_trait;
use serde_json::json;
use std::collections::HashMap;
use std::sync::Arc;
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
struct MethodUrlPlugin {
method: reqwest::Method,
url: String,
}
#[async_trait]
impl Plugin for MethodUrlPlugin {
async fn assembly(&self, rocket: &mut Rocket, next: Next<'_>) -> artisan::Result<()> {
rocket.config.method = self.method.clone();
rocket.config.url = self.url.clone();
next.call(rocket).await
}
}
#[tokio::test]
async fn test_full_pipeline() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/api/orders"))
.respond_with(
ResponseTemplate::new(200).set_body_json(json!({"code": 0, "data": "success"})),
)
.mount(&mock_server)
.await;
let plugins: Vec<Arc<dyn Plugin>> = vec![
Arc::new(StartPlugin),
Arc::new(MethodUrlPlugin {
method: reqwest::Method::POST,
url: mock_server.uri() + "/api/orders",
}),
Arc::new(AddPayloadBodyPlugin),
Arc::new(AddRadarPlugin),
Arc::new(ParserPlugin),
];
let result = Artful::artful(HashMap::new(), plugins).await.unwrap();
assert!(matches!(result, Destination::Json(_)));
}
#[tokio::test]
async fn test_pipeline_with_payload() {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/api/test"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({"status": "ok"})))
.mount(&mock_server)
.await;
let params = HashMap::from([
("order_id".to_string(), json!("123")),
("amount".to_string(), json!(100)),
]);
let plugins: Vec<Arc<dyn Plugin>> = vec![
Arc::new(StartPlugin),
Arc::new(MethodUrlPlugin {
method: reqwest::Method::POST,
url: mock_server.uri() + "/api/test",
}),
Arc::new(AddPayloadBodyPlugin),
Arc::new(AddRadarPlugin),
Arc::new(ParserPlugin),
];
let result = Artful::artful(params, plugins).await.unwrap();
assert!(matches!(result, Destination::Json(_)));
}