openzeppelin_relayer/api/routes/
plugin.rs

1//! This module defines the HTTP routes for plugin operations.
2//! It includes handlers for calling plugin methods.
3//! The routes are integrated with the Actix-web framework and interact with the plugin controller.
4use crate::{
5    api::controllers::plugin,
6    jobs::JobProducer,
7    models::{AppState, PluginCallRequest},
8};
9use actix_web::{post, web, Responder};
10
11/// Calls a plugin method.
12#[post("/plugins/{plugin_id}/call")]
13async fn plugin_call(
14    plugin_id: web::Path<String>,
15    req: web::Json<PluginCallRequest>,
16    data: web::ThinData<AppState<JobProducer>>,
17) -> impl Responder {
18    plugin::call_plugin(plugin_id.into_inner(), req.into_inner(), data).await
19}
20
21/// Initializes the routes for the plugins module.
22pub fn init(cfg: &mut web::ServiceConfig) {
23    // Register routes with literal segments before routes with path parameters
24    cfg.service(plugin_call); // /plugins/{plugin_id}/call
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30    use crate::services::plugins::PluginCallResponse;
31    use actix_web::{test, App, HttpResponse};
32
33    async fn mock_plugin_call() -> impl Responder {
34        HttpResponse::Ok().json(PluginCallResponse {
35            success: true,
36            message: "Plugin called successfully".to_string(),
37            return_value: String::from(""),
38            logs: vec![],
39            error: String::from(""),
40            traces: Vec::new(),
41        })
42    }
43
44    #[actix_web::test]
45    async fn test_plugin_call() {
46        let app = test::init_service(
47            App::new()
48                .service(
49                    web::resource("/plugins/{plugin_id}/call")
50                        .route(web::post().to(mock_plugin_call)),
51                )
52                .configure(init),
53        )
54        .await;
55
56        let req = test::TestRequest::post()
57            .uri("/plugins/test-plugin/call")
58            .insert_header(("Content-Type", "application/json"))
59            .set_json(serde_json::json!({
60                "params": serde_json::Value::Null,
61            }))
62            .to_request();
63        let resp = test::call_service(&app, req).await;
64
65        assert!(resp.status().is_success());
66
67        let body = test::read_body(resp).await;
68        let plugin_call_response: PluginCallResponse = serde_json::from_slice(&body).unwrap();
69        assert!(plugin_call_response.success);
70    }
71}