openzeppelin_relayer/api/routes/
signer.rs

1//! This module defines the HTTP routes for signer operations.
2//! It includes handlers for listing, retrieving, creating, updating, and deleting signers.
3//! The routes are integrated with the Actix-web framework and interact with the signer controller.
4
5use crate::{
6    api::controllers::signer,
7    models::{DefaultAppState, PaginationQuery, SignerCreateRequest, SignerUpdateRequest},
8};
9use actix_web::{delete, get, patch, post, web, Responder};
10
11/// Lists all signers with pagination support.
12#[get("/signers")]
13async fn list_signers(
14    query: web::Query<PaginationQuery>,
15    data: web::ThinData<DefaultAppState>,
16) -> impl Responder {
17    signer::list_signers(query.into_inner(), data).await
18}
19
20/// Retrieves details of a specific signer by ID.
21#[get("/signers/{signer_id}")]
22async fn get_signer(
23    signer_id: web::Path<String>,
24    data: web::ThinData<DefaultAppState>,
25) -> impl Responder {
26    signer::get_signer(signer_id.into_inner(), data).await
27}
28
29/// Creates a new signer.
30#[post("/signers")]
31async fn create_signer(
32    request: web::Json<SignerCreateRequest>,
33    data: web::ThinData<DefaultAppState>,
34) -> impl Responder {
35    signer::create_signer(request.into_inner(), data).await
36}
37
38/// Updates an existing signer.
39#[patch("/signers/{signer_id}")]
40async fn update_signer(
41    signer_id: web::Path<String>,
42    request: web::Json<SignerUpdateRequest>,
43    data: web::ThinData<DefaultAppState>,
44) -> impl Responder {
45    signer::update_signer(signer_id.into_inner(), request.into_inner(), data).await
46}
47
48/// Deletes a signer by ID.
49#[delete("/signers/{signer_id}")]
50async fn delete_signer(
51    signer_id: web::Path<String>,
52    data: web::ThinData<DefaultAppState>,
53) -> impl Responder {
54    signer::delete_signer(signer_id.into_inner(), data).await
55}
56
57/// Configures the signer routes.
58pub fn init(cfg: &mut web::ServiceConfig) {
59    cfg.service(list_signers)
60        .service(get_signer)
61        .service(create_signer)
62        .service(update_signer)
63        .service(delete_signer);
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use crate::utils::mocks::mockutils::create_mock_app_state;
70    use actix_web::{http::StatusCode, test, web, App};
71
72    #[actix_web::test]
73    async fn test_signer_routes_are_registered() {
74        // Arrange - Create app with signer routes
75        let app_state = create_mock_app_state(None, None, None, None, None).await;
76        let app = test::init_service(
77            App::new()
78                .app_data(web::Data::new(app_state))
79                .configure(init),
80        )
81        .await;
82
83        // Test GET /signers - should not return 404 (route exists)
84        let req = test::TestRequest::get().uri("/signers").to_request();
85        let resp = test::call_service(&app, req).await;
86        assert_ne!(
87            resp.status(),
88            StatusCode::NOT_FOUND,
89            "GET /signers route not registered"
90        );
91
92        // Test GET /signers/{id} - should not return 404
93        let req = test::TestRequest::get()
94            .uri("/signers/test-id")
95            .to_request();
96        let resp = test::call_service(&app, req).await;
97        assert_ne!(
98            resp.status(),
99            StatusCode::NOT_FOUND,
100            "GET /signers/{{id}} route not registered"
101        );
102
103        // Test POST /signers - should not return 404
104        let req = test::TestRequest::post()
105            .uri("/signers")
106            .set_json(serde_json::json!({
107                "id": "test",
108                "signer_type": "test",
109                "name": "Test Signer",
110                "description": "A test signer"
111            }))
112            .to_request();
113        let resp = test::call_service(&app, req).await;
114        assert_ne!(
115            resp.status(),
116            StatusCode::NOT_FOUND,
117            "POST /signers route not registered"
118        );
119
120        // Test PATCH /signers/{id} - should not return 404
121        let req = test::TestRequest::patch()
122            .uri("/signers/test-id")
123            .set_json(serde_json::json!({"name": "Updated Name"}))
124            .to_request();
125        let resp = test::call_service(&app, req).await;
126        assert_ne!(
127            resp.status(),
128            StatusCode::NOT_FOUND,
129            "PATCH /signers/{{id}} route not registered"
130        );
131
132        // Test DELETE /signers/{id} - should not return 404
133        let req = test::TestRequest::delete()
134            .uri("/signers/test-id")
135            .to_request();
136        let resp = test::call_service(&app, req).await;
137        assert_ne!(
138            resp.status(),
139            StatusCode::NOT_FOUND,
140            "DELETE /signers/{{id}} route not registered"
141        );
142    }
143}