Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(rpc_module): RpcModule::raw_json_request -> String #1287

Merged
merged 2 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
refactor async response payload test
  • Loading branch information
niklasad1 committed Feb 7, 2024
commit 4b359926c9be1f80e39b70c28a6aa34a3cad0157
57 changes: 3 additions & 54 deletions tests/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ use jsonrpsee::server::middleware::http::ProxyGetRequestLayer;
use jsonrpsee::server::{
PendingSubscriptionSink, RpcModule, Server, ServerBuilder, ServerHandle, SubscriptionMessage, TrySendError,
};
use jsonrpsee::types::{ErrorCode, ErrorObject, ErrorObjectOwned};
use jsonrpsee::{MethodResponseError, ResponsePayload, SubscriptionCloseResponse};
use serde::{Deserialize, Serialize};
use jsonrpsee::types::{ErrorObject, ErrorObjectOwned};
use jsonrpsee::SubscriptionCloseResponse;
use serde::Serialize;
use tokio::net::TcpStream;
use tokio::sync::mpsc::UnboundedSender;
use tokio::time::interval;
use tokio_stream::wrappers::IntervalStream;
use tower_http::cors::CorsLayer;
Expand Down Expand Up @@ -288,53 +287,3 @@ pub async fn connect_over_socks_stream(server_addr: SocketAddr) -> Socks5Stream<
.await
.unwrap()
}

#[derive(Copy, Clone, Deserialize, Serialize)]
pub enum Notify {
Success,
Error,
All,
}

pub type NotifyRpcModule = RpcModule<UnboundedSender<Result<(), MethodResponseError>>>;
pub type Sender = tokio::sync::mpsc::UnboundedSender<Result<(), MethodResponseError>>;
pub type Receiver = tokio::sync::mpsc::UnboundedReceiver<Result<(), MethodResponseError>>;

pub async fn run_test_notify_test(
module: &NotifyRpcModule,
server_rx: &mut Receiver,
kind: Notify,
) -> Result<(), MethodResponseError> {
use jsonrpsee_test_utils::mocks::Id;

let req = jsonrpsee_test_utils::helpers::call("hey", vec![kind], Id::Num(1));
let _ = module.raw_json_request(&req, 1).await.unwrap();
server_rx.recv().await.expect("Channel is not dropped")
}

/// Helper module that will send the results on the channel passed in.
pub fn rpc_module_notify_on_response(tx: Sender) -> NotifyRpcModule {
let mut module = RpcModule::new(tx);

module
.register_method("hey", |params, ctx| {
let kind: Notify = params.one().unwrap();
let server_sender = ctx.clone();

let (rp, rp_future) = match kind {
Notify::All => ResponsePayload::success("lo").notify_on_completion(),
Notify::Success => ResponsePayload::success("lo").notify_on_completion(),
Notify::Error => ResponsePayload::error(ErrorCode::InvalidParams).notify_on_completion(),
};

tokio::spawn(async move {
let rp = rp_future.await;
server_sender.send(rp).unwrap();
});

rp
})
.unwrap();

module
}
53 changes: 42 additions & 11 deletions tests/tests/rpc_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ use tokio::sync::mpsc;
use tokio::time::interval;
use tokio_stream::wrappers::IntervalStream;

use crate::helpers::{rpc_module_notify_on_response, run_test_notify_test, Notify};

// Helper macro to assert that a binding is of a specific type.
macro_rules! assert_type {
( $ty:ty, $expected:expr $(,)?) => {{
Expand Down Expand Up @@ -591,18 +589,51 @@ async fn subscription_close_response_works() {

#[tokio::test]
async fn method_response_notify_on_completion() {
use jsonrpsee::server::ResponsePayload;

init_logger();

// The outcome of the response future is sent out on this channel
// to test whether the call produced a valid response or not.
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();
let module = rpc_module_notify_on_response(tx);

assert!(
run_test_notify_test(&module, &mut rx, Notify::Success).await.is_ok(),
"Successful response should be notified"
);
let module = {
let mut module = RpcModule::new(tx);

assert!(matches!(
run_test_notify_test(&module, &mut rx, Notify::Error).await,
Err(MethodResponseError::JsonRpcError),
));
module
.register_method("hey", |params, ctx| {
let kind: String = params.one().unwrap();
let server_sender = ctx.clone();

let (rp, rp_future) = if kind == "success" {
ResponsePayload::success("lo").notify_on_completion()
} else {
ResponsePayload::error(ErrorCode::InvalidParams).notify_on_completion()
};

tokio::spawn(async move {
let rp = rp_future.await;
server_sender.send(rp).unwrap();
});

rp
})
.unwrap();

module
};

// Successful call should return a successful notification.
assert_eq!(module.call::<_, String>("hey", ["success"]).await.unwrap(), "lo");
assert!(matches!(rx.recv().await, Some(Ok(_))));

// Low level call should also work.
let (rp, _) =
module.raw_json_request(r#"{"jsonrpc":"2.0","method":"hey","params":["success"],"id":0}"#, 1).await.unwrap();
assert_eq!(rp, r#"{"jsonrpc":"2.0","result":"lo","id":0}"#);
assert!(matches!(rx.recv().await, Some(Ok(_))));

// Error call should return a failed notification.
assert!(module.call::<_, String>("hey", ["not success"]).await.is_err());
assert!(matches!(rx.recv().await, Some(Err(MethodResponseError::JsonRpcError))));
}
Loading