Skip to content

refactor: Replace wiremock for mockito#436

Merged
zeljkoX merged 3 commits into
mainfrom
replace-wiremock
Aug 28, 2025
Merged

refactor: Replace wiremock for mockito#436
zeljkoX merged 3 commits into
mainfrom
replace-wiremock

Conversation

@LuisUrrutia

@LuisUrrutia LuisUrrutia commented Aug 27, 2025

Copy link
Copy Markdown
Contributor

Summary

Since wiremock MSRV is 1.88.0 LukeMathWalker/wiremock-rs#173, I've replaced it with mockito that is already in our deps.

Summary by CodeRabbit

  • Tests

    • Migrated HTTP test mocks from WireMock to Mockito across services; updated async test server setup, request matching, JSON responses, and mock lifetimes.
    • Adjusted test helpers and added/updated scenarios for error cases and edge conditions.
    • No production behavior or public APIs changed.
  • Chores

    • Updated dependencies: bumped mockito and removed wiremock from project config.

@LuisUrrutia LuisUrrutia requested review from a team as code owners August 27, 2025 14:07
@coderabbitai

coderabbitai Bot commented Aug 27, 2025

Copy link
Copy Markdown

Walkthrough

Migrated test suites from WireMock to Mockito across multiple modules, updated async mock server creation and mock lifetimes, adapted request/response/header/json matching, and replaced usages of uri() with url(); removed wiremock from dev-dependencies. No production/public API changes.

Changes

Cohort / File(s) Summary of changes
Dev-deps cleanup
Cargo.toml
Removed wiremock from [dev-dependencies] and bumped mockito version.
Bootstrap config processor tests (Vault AppRole)
src/bootstrap/config_processor.rs
Migrated tests from WireMock to Mockito: use mockito::Server::new_async(), helpers accept &mut mockito::ServerGuard and return mockito::Mock, replaced mount semantics with create_async(), switched uri() to url(), adapted JSON/body/header matching.
Google Cloud KMS service tests
src/services/google_cloud_kms/mod.rs
Replaced println! with debug! logs; migrated tests to Mockito with async Server, match_header/Regex matchers, with_body JSON responses, explicit headers, url() usage, and expanded test scenarios for errors and parsing.
Jupiter service tests
src/services/jupiter/mod.rs
Switched tests to Mockito: Server::new_async(), .mock(...).create_async(), query matching via Matcher::AllOf/Regex, JSON bodies via with_body, and url() usage.
Notification service tests
src/services/notification/mod.rs
Migrated tests to Mockito: async server, header matching with Matcher::Any, JSON bodies via serde_json::to_string, explicit status/content-type headers, and url() for base URL.
Provider service tests
src/services/provider/mod.rs
Converted tests to Mockito: Server::new_async(), generic GET mocks returning 429/502 via with_status, stored mocks to keep alive, and replaced uri() with url().
EVM Google Cloud KMS signer tests
src/services/signer/evm/google_cloud_kms_signer.rs
Switched mocks to Mockito: Regex path matching, match_header(..., Matcher::Any), with_body JSON responses, async mock creation, and use of server.url() in test config.
Turnkey service tests
src/services/turnkey/mod.rs
Migrated to Mockito: helpers accept &mut ServerGuard and return Mock, async create_async() mocks, response payload field casing adjusted (camelCase), and url() usage.
Vault service tests
src/services/vault/mod.rs
Replaced WireMock with Mockito: AppRole login helper returns mockito::Mock, mocks use with_status/with_header/with_body, header and regex path matching, async server startup, and url() adoption.

Sequence Diagram(s)

(omitted — changes are test harness/mocking migrations and do not alter runtime control flow)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I twitch my nose at mocks anew,
From wire to mito, tests now flew.
Async burrows hum with cheer,
JSON carrots drawing near.
Headers matched — the logs say true. 🥕🐇


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 303c2a0 and 217988b.

📒 Files selected for processing (1)
  • Cargo.toml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Cargo.toml
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch replace-wiremock

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/services/jupiter/mod.rs (1)

274-286: Bug: wrong slippage basis points calculation (loss of precision).

(request.slippage as u32) * 100 truncates before multiplying (e.g., 0.5 → 0). Convert first, then cast.

-        let slippage_bps: u32 = request.slippage as u32 * 100;
+        // Convert percent (e.g., 0.5%) to bps (50) without truncation
+        let slippage_bps: u32 = (request.slippage * 100.0).round() as u32;
src/services/turnkey/mod.rs (1)

481-505: Critical: infinite recursion and potential ambiguity in trait impl methods.

  • sign_evm_transaction calls itself, causing infinite recursion.
  • address_solana/address_evm may resolve ambiguously; use fully-qualified calls to the inherent methods.

Fix by explicitly calling inherent methods.

 impl TurnkeyServiceTrait for TurnkeyService {
     fn address_solana(&self) -> Result<Address, TurnkeyError> {
-        self.address_solana()
+        TurnkeyService::address_solana(self)
     }
 
     fn address_evm(&self) -> Result<Address, TurnkeyError> {
-        self.address_evm()
+        TurnkeyService::address_evm(self)
     }
@@
     async fn sign_evm_transaction(&self, message: &[u8]) -> Result<Vec<u8>, TurnkeyError> {
-        let signature_bytes = self.sign_evm_transaction(message).await?;
-        Ok(signature_bytes)
+        TurnkeyService::sign_evm_transaction(self, message).await
     }
src/services/notification/mod.rs (1)

36-52: Fix infinite recursion in trait impl by calling inherent methods explicitly

Both trait methods call themselves recursively, leading to stack overflow at runtime.

 impl WebhookNotificationServiceTrait for WebhookNotificationService {
   async fn send_notification(
       &self,
       notification: WebhookNotification,
   ) -> Result<WebhookResponse, WebhookNotificationError> {
-      self.send_notification(notification).await
+      WebhookNotificationService::send_notification(self, notification).await
   }

   fn sign_payload(
       &self,
       payload: &str,
       secret_key: &SecretString,
   ) -> Result<String, WebhookNotificationError> {
-      self.sign_payload(payload, secret_key)
+      WebhookNotificationService::sign_payload(self, payload, secret_key)
   }
 }
🧹 Nitpick comments (25)
src/services/provider/mod.rs (4)

278-279: Remove unused use mockito; or import specific items.

You already refer to items as mockito::...; this use is redundant and may trigger an unused import warning. Prefer importing the symbols you use (e.g., Matcher) or drop this line.

-    use mockito;
+    // use mockito::{Matcher}; // If you want shorter paths

382-389: Mockito migration for 429 case is correct; consider asserting call count.

The matcher and status mapping are aligned with categorize_reqwest_error. Add .expect(1) to ensure the mock was hit exactly once.

-        let _mock = mock_server
-            .mock("GET", mockito::Matcher::Any)
+        let _mock = mock_server
+            .mock("GET", mockito::Matcher::Any)
+            .expect(1)
             .with_status(429)

Also applies to: 392-396


410-417: Mockito migration for 502 case is correct; add .expect(1) for robustness.

Same rationale as the 429 test to avoid false positives.

-        let _mock = mock_server
-            .mock("GET", mockito::Matcher::Any)
+        let _mock = mock_server
+            .mock("GET", mockito::Matcher::Any)
+            .expect(1)
             .with_status(502)

Also applies to: 420-424


364-379: Unify async test runtime to Tokio for consistency.

These tests don’t use Actix runtime features. Consider switching #[actix_rt::test] to #[tokio::test] (as in other modules) to keep a single runtime in tests.

-    #[actix_rt::test]
+    #[tokio::test]
src/services/signer/evm/google_cloud_kms_signer.rs (3)

171-175: Base URL wiring is good; ensure OAuth token endpoint isn’t hit in tests.

If GoogleCloudKmsService fetches OAuth tokens via token_uri, your tests may perform external network calls. Recommend stubbing the token endpoint and pointing token_uri at the mock server.

-    use mockito::{Mock, ServerGuard};
+    use mockito::{Mock, ServerGuard};
@@
-    async fn setup_mock_gcp_signer(mock_server: &ServerGuard) -> GoogleCloudKmsSigner {
-        let base_url = mock_server.url();
+    async fn setup_mock_gcp_signer(mock_server: &mut ServerGuard) -> GoogleCloudKmsSigner {
+        let base_url = mock_server.url();
+        // Stub OAuth token exchange if the service requests it
+        let _token_mock = mock_server
+            .mock("POST", "/token")
+            .expect(1)
+            .with_status(200)
+            .with_header("content-type", "application/json")
+            .with_body(r#"{"access_token":"test","expires_in":3600,"token_type":"Bearer"}"#)
+            .create_async()
+            .await;
@@
-                token_uri: "https://oauth2.googleapis.com/token".to_string(),
+                token_uri: format!("{}/token", base_url),

Update callers:

-        let signer = setup_mock_gcp_signer(&mock_server).await;
+        let signer = setup_mock_gcp_signer(&mut mock_server).await;

206-226: Good WireMock → Mockito migration; add call count assertion.

Add .expect(1) to catch accidental extra requests.

-        let _mock = mock_server
+        let _mock = mock_server
             .mock(
                 "GET",
                 mockito::Matcher::Regex(
                     r"/v1/projects/.*/locations/.*/keyRings/.*/cryptoKeys/.*/cryptoKeyVersions/.*"
                         .to_string(),
                 ),
             )
             .match_header("authorization", mockito::Matcher::Any)
+            .expect(1)
             .with_status(200)

258-277: Mocks look correct; add .expect(1) to each for stronger guarantees.

Ensures exactly one call to public-key and sign endpoints.

-        let _mock_pubkey = mock_server
+        let _mock_pubkey = mock_server
             .mock(
                 "GET",
                 mockito::Matcher::Regex(
                     r"/v1/projects/.*/locations/.*/keyRings/.*/cryptoKeys/.*/cryptoKeyVersions/.*"
                         .to_string(),
                 ),
             )
             .match_header("authorization", mockito::Matcher::Any)
+            .expect(1)
             .with_status(200)
@@
-        let _mock_sign = mock_server
+        let _mock_sign = mock_server
             .mock(
                 "POST",
                 mockito::Matcher::Regex(
                     r"/v1/projects/.*/locations/.*/keyRings/.*/cryptoKeys/.*:asymmetricSign"
                         .to_string(),
                 ),
             )
             .match_header("authorization", mockito::Matcher::Any)
+            .expect(1)
             .with_status(200)

Also applies to: 293-311

src/services/jupiter/mod.rs (4)

732-783: Query matchers migrated correctly; consider asserting call counts.

Optional: add .expect(1) to ensure single invocation.

-        let _mock = mock_server
+        let _mock = mock_server
             .mock("GET", "/ultra/v1/order")
             .match_query(mockito::Matcher::AllOf(vec![
                 /* ... */
             ]))
+            .expect(1)
             .with_status(200)

824-835: Execute endpoint mock OK; add .expect(1) for determinism.

-        let _mock = mock_server
+        let _mock = mock_server
             .mock("POST", "/ultra/v1/execute")
+            .expect(1)
             .with_status(200)

851-866: Minor: fix test failure message to match expectation.

The test expects HttpRequestError but the panic says "Expected ApiError...".

-            _ => panic!("Expected ApiError but got different error type"),
+            _ => panic!("Expected HttpRequestError but got different error type"),

Also applies to: 879-885


586-631: Optional: avoid external calls in quote tests.

These tests hit real endpoints. Consider switching to Mockito like other tests or mark them #[ignore] to avoid flakiness.

src/services/turnkey/mod.rs (3)

635-657: Raw payload mock migration looks good; assert call count.

-        mock_server
+        mock_server
             .mock("POST", "/public/v1/submit/sign_raw_payload")
+            .expect(1)
             .match_header("Content-Type", "application/json")

660-685: EVM transaction mock migration looks good; add .expect(1).

-        mock_server
+        mock_server
             .mock("POST", "/public/v1/submit/sign_transaction")
+            .expect(1)
             .match_header("Content-Type", "application/json")

688-706: Error response mock is correct; add .expect(1) for strictness.

-        mock_server
+        mock_server
             .mock("POST", "/public/v1/submit/sign_raw_payload")
+            .expect(1)
             .match_header("Content-Type", "application/json")
src/services/notification/mod.rs (4)

165-179: Strengthen the assertion: verify exact HMAC, not just header presence

Use an exact match for X-Signature to validate signing logic end-to-end. Compute the expected signature from the same payload used in the request.

-            .match_header("X-Signature", mockito::Matcher::Any)
+            .match_header("X-Signature", expected_signature.as_str())

Add before creating the mock (outside this hunk):

let secret_key = SecretString::new("test_secret");
let notification = WebhookNotification { /* ...same as below... */ };
let payload = serde_json::to_string(&notification).unwrap();
let expected_signature = WebhookNotificationService::new("".into(), None)
    .sign_payload(&payload, &secret_key)
    .unwrap();

182-182: Avoid unnecessary clone of SecretString

-        let service = WebhookNotificationService::new(mock_server.url(), Some(secret_key.clone()));
+        let service = WebhookNotificationService::new(mock_server.url(), Some(secret_key));

197-213: Test name is misleading; it succeeds without signature

Rename to reflect expected outcome.

-    async fn test_failed_notification_without_signature() {
+    async fn test_successful_notification_without_signature() {

227-241: Assert error message content to tighten failure check

Since send_notification returns WebhookError(response_text), assert it contains "Internal Server Error".

-    assert!(result.is_err());
+    assert!(result.is_err());
+    let err = format!("{}", result.err().unwrap());
+    assert!(err.contains("Internal Server Error"));
src/services/google_cloud_kms/mod.rs (3)

328-337: Replace println!/print! with log macros

Use debug! for non-essential output to keep production logs clean.

-        println!("PEM solana: {}", pem_str);
+        debug!("PEM solana: {}", pem_str);

336-337: Replace remaining println!/print! with debug!

-        println!("PEM evm: {}", pem_str);
+        debug!("PEM evm: {}", pem_str);
...
-        print!("KMS asymmetricSign body: {}", body);
+        debug!("KMS asymmetricSign body: {}", body);
...
-        println!("KMS asymmetricSign response: {}", resp);
+        debug!("KMS asymmetricSign response: {}", resp);
...
-        print!("KMS asymmetricSign body: {}", body);
+        debug!("KMS asymmetricSign body: {}", body);
...
-        println!("KMS asymmetricSign response: {}", resp);
+        debug!("KMS asymmetricSign response: {}", resp);
-        print!("Signature b64 decoded: {:?}", signature_b64);
+        debug!("Signature b64 decoded: {:?}", signature_b64);

Also applies to: 355-356, 363-364, 395-399


586-596: Optional: assert mocks were hit to prevent false positives

Call _mock.assert() at the end of each test to ensure the expected request occurred.

Also applies to: 662-673, 740-751, 753-767, 769-781, 783-798, 858-869, 883-896

src/bootstrap/config_processor.rs (1)

528-571: Good helper; consider deduplicating across test modules

This AppRole login mock appears in multiple modules (also in src/services/vault/mod.rs). Move to a shared test util to reduce duplication.

src/services/vault/mod.rs (3)

368-411: Consolidate duplicated AppRole mock helper

Same helper exists here and in config_processor tests. Centralize in a test utils module to avoid divergence.


415-455: Remove unused secret mock in auth-failure test

Login is expected to fail; the secret GET mock is unnecessary and adds noise.

-        let _secret_mock = mock_server
-            .mock("GET", "/v1/test-mount/data/my-secret")
-            .match_header("X-Vault-Token", "test-token")
-            .with_status(200)
-            .with_header("content-type", "application/json")
-            .with_body(serde_json::to_string(&json!({ /* ... */ })).unwrap(),)
-            .create_async()
-            .await;

479-537: Optionally assert mock expectations to tighten tests

Call .assert() on created mocks to ensure requests were actually issued.

Also applies to: 541-595, 597-645, 648-696

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 632b93c and ff3d847.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • Cargo.toml (1 hunks)
  • src/bootstrap/config_processor.rs (3 hunks)
  • src/services/google_cloud_kms/mod.rs (16 hunks)
  • src/services/jupiter/mod.rs (8 hunks)
  • src/services/notification/mod.rs (4 hunks)
  • src/services/provider/mod.rs (3 hunks)
  • src/services/signer/evm/google_cloud_kms_signer.rs (5 hunks)
  • src/services/turnkey/mod.rs (11 hunks)
  • src/services/vault/mod.rs (6 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/bootstrap/config_processor.rs (1)
src/services/vault/mod.rs (1)
  • setup_mock_approle_login (369-411)
src/services/vault/mod.rs (2)
src/bootstrap/config_processor.rs (1)
  • setup_mock_approle_login (529-571)
src/utils/base64.rs (1)
  • base64_encode (5-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: test
  • GitHub Check: clippy
  • GitHub Check: msrv
  • GitHub Check: boostsecurity - boostsecurityio/semgrep-pro
  • GitHub Check: Redirect rules - openzeppelin-relayer
  • GitHub Check: Header rules - openzeppelin-relayer
  • GitHub Check: Pages changed - openzeppelin-relayer
  • GitHub Check: Analyze (rust)
🔇 Additional comments (5)
Cargo.toml (1)

91-99: No remaining WireMock references — code changes are safe to merge

  • Ran rg -nP '\bwiremock\b' across the repository (excluding target/) and within all Cargo.* files; no occurrences were found.
src/services/jupiter/mod.rs (1)

662-705: Mockito migration for swap endpoint looks solid.

Stubbing, headers, and base_url injection are correct.

Also applies to: 706-710

src/services/turnkey/mod.rs (1)

718-732: End-to-end tests: base_url injection and client setup look good.

Nice isolation via Mockito and custom client (no redirects). No issues spotted.

Also applies to: 741-753, 763-775, 787-801

src/services/google_cloud_kms/mod.rs (1)

494-507: Regex path matcher usage is supported in mockito v1.7.0

We’ve confirmed that the project is on mockito 1.7.0 (Cargo.lock shows version “1.7.0”) (lambdatest.com), and the Server::mock<P: Into<Matcher>> API explicitly accepts Matcher::Regex for the path parameter (see the docs.rs example using mockito::Matcher::Regex in s.mock("GET", mockito::Matcher::Regex(...))) (docs.rs). No changes are required here.

src/bootstrap/config_processor.rs (1)

575-612: Mockito migration looks correct; nice use of mock_server.url()

Mocks are kept alive via bindings; address uses server.url(); headers and bodies match expected vaultrs calls.

Also applies to: 613-627

@codecov

codecov Bot commented Aug 27, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.0%. Comparing base (7e7fb4f) to head (217988b).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##            main    #436     +/-   ##
=======================================
+ Coverage   92.7%   93.0%   +0.2%     
=======================================
  Files        217     217             
  Lines      73295   74164    +869     
=======================================
+ Hits       67992   68994   +1002     
+ Misses      5303    5170    -133     
Flag Coverage Δ
integration 0.5% <0.0%> (-0.1%) ⬇️
properties <0.1% <0.0%> (-0.1%) ⬇️
unittests 93.0% <100.0%> (+0.2%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
src/services/provider/mod.rs (1)

381-387: Tighten matchers and assert mocks were hit

Using Matcher::Any for the path is broad; prefer a precise path to avoid accidental matches. Also assert the mock was exercised to catch false positives.

Apply:

-        let _mock = mock_server
-            .mock("GET", mockito::Matcher::Any)
+        let mock = mock_server
+            .mock("GET", "/")
             .with_status(429)
             .create_async()
             .await;
...
-        let _mock = mock_server
-            .mock("GET", mockito::Matcher::Any)
+        let mock = mock_server
+            .mock("GET", "/")
             .with_status(502)
             .create_async()
             .await;

And after exercising the request in each test:

         assert!(matches!(provider_error, ProviderError::RateLimited));
+        mock.assert();
         assert!(matches!(provider_error, ProviderError::BadGateway));
+        mock.assert();

Also applies to: 409-415

src/services/google_cloud_kms/mod.rs (5)

329-329: Avoid logging full PEM material; log a fingerprint

Reduce log verbosity and risk by logging a stable fingerprint instead of the entire PEM.

-        debug!("PEM solana: {}", pem_str);
+        debug!("PEM solana fingerprint (sha256): {}", hex::encode(Sha256::digest(pem_str.as_bytes())));
-        debug!("PEM evm: {}", pem_str);
+        debug!("PEM evm fingerprint (sha256): {}", hex::encode(Sha256::digest(pem_str.as_bytes())));

Also applies to: 336-336


364-364: Unify logging; avoid print! in library code

You switched several println! to debug!, but print! calls remain for request bodies. Use debug!/trace! consistently.

Within the same methods (change outside this hunk):

-        print!("KMS asymmetricSign body: {}", body);
+        debug!("KMS asymmetricSign body: {}", body);
-        print!("KMS asymmetricSign body: {}", body);
+        debug!("KMS asymmetricSign body: {}", body);

Also applies to: 395-399


495-507: Strengthen header matching in mocks

Match the Authorization header format, not Any, to catch regressions in test-only auth header wiring.

-            .match_header("Authorization", mockito::Matcher::Any)
+            .match_header("Authorization", mockito::Matcher::Regex(r"^Bearer .+$".to_string()))

Apply to all helper setups that currently use Matcher::Any for Authorization.

Also applies to: 509-521, 553-568, 570-582


523-534: Validate request body shape in sign mocks

Ensure tests fail if the client sends an unexpected payload.

For sign success:

         mock_server
             .mock("POST", mockito::Matcher::Regex(r"/v1/projects/.*/locations/global/keyRings/.*/cryptoKeys/.*/cryptoKeyVersions/.*:asymmetricSign".to_string()))
             .match_header("Authorization", mockito::Matcher::Any)
+            .match_body(mockito::Matcher::Regex(r#""(digest|data)":"#.to_string()))
             .with_status(200)

For sign error:

         mock_server
             .mock("POST", mockito::Matcher::Regex(r"/v1/projects/.*/locations/global/keyRings/.*/cryptoKeys/.*/cryptoKeyVersions/.*:asymmetricSign".to_string()))
             .match_header("Authorization", mockito::Matcher::Any)
+            .match_body(mockito::Matcher::Regex(r#""(digest|data)":"#.to_string()))
             .with_status(400)

Also applies to: 536-551


587-591: Assert mocks were exercised

Rename _mock to mock and assert after the call. Prevents tests from passing when no HTTP call is made.

Example (replicate across tests):

-        let _mock = setup_mock_solana_public_key(&mut mock_server).await;
+        let mock = setup_mock_solana_public_key(&mut mock_server).await;
...
         assert_eq!(
             result.unwrap(),
             "6s7RsvzcdXFJi1tXeDoGfSKZWjCDNJLiu74rd72zLy6J"
         );
+        mock.assert();

Also applies to: 603-607, 619-623, 635-639, 649-653, 665-669, 695-699, 712-716, 742-746, 755-759, 771-775, 786-790, 859-871, 883-897

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ff3d847 and 303c2a0.

📒 Files selected for processing (6)
  • src/services/google_cloud_kms/mod.rs (19 hunks)
  • src/services/jupiter/mod.rs (9 hunks)
  • src/services/notification/mod.rs (4 hunks)
  • src/services/provider/mod.rs (2 hunks)
  • src/services/signer/evm/google_cloud_kms_signer.rs (5 hunks)
  • src/services/turnkey/mod.rs (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/services/turnkey/mod.rs
  • src/services/jupiter/mod.rs
  • src/services/signer/evm/google_cloud_kms_signer.rs
  • src/services/notification/mod.rs
🧰 Additional context used
🧬 Code graph analysis (1)
src/services/google_cloud_kms/mod.rs (2)
src/utils/address_derivation.rs (1)
  • derive_solana_address_from_pem (40-60)
src/utils/base64.rs (1)
  • base64_decode (8-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: boostsecurity - boostsecurityio/semgrep-pro
  • GitHub Check: test
  • GitHub Check: msrv
  • GitHub Check: clippy
  • GitHub Check: Redirect rules - openzeppelin-relayer
  • GitHub Check: Header rules - openzeppelin-relayer
  • GitHub Check: Pages changed - openzeppelin-relayer
  • GitHub Check: semgrep/ci
  • GitHub Check: Analyze (rust)
🔇 Additional comments (1)
src/services/provider/mod.rs (1)

391-395: LGTM: mockito base URL usage

get(mock_server.url()) is correct with ServerGuard. No issues.

Also applies to: 419-423

@zeljkoX zeljkoX left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Thanks!

@zeljkoX zeljkoX merged commit efede36 into main Aug 28, 2025
25 of 26 checks passed
@zeljkoX zeljkoX deleted the replace-wiremock branch August 28, 2025 07:34
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants