bridge: Expose FakeChatRemote gRPC testing endpoints to apps

This commit is contained in:
Jordan Rose 2026-05-06 18:02:00 -07:00
parent 875f93019b
commit af55da7bbd
4 changed files with 79 additions and 0 deletions

View File

@ -138,12 +138,16 @@ public object NativeTesting {
@JvmStatic
public external fun TESTING_FakeChatRemoteEnd_NextGrpcMessage(input: ByteArray, offset: Int): Pair<Int, Int>
@JvmStatic
public external fun TESTING_FakeChatRemoteEnd_ReceiveIncomingGrpcRequest(asyncRuntime: ObjectHandle, chat: ObjectHandle): CompletableFuture<Pair<ObjectHandle, Long>?>
@JvmStatic
public external fun TESTING_FakeChatRemoteEnd_ReceiveIncomingRequest(asyncRuntime: ObjectHandle, chat: ObjectHandle): CompletableFuture<Pair<ObjectHandle, Long>?>
@JvmStatic
public external fun TESTING_FakeChatRemoteEnd_SendRawServerRequest(chat: ObjectHandle, bytes: ByteArray): Unit
@JvmStatic
public external fun TESTING_FakeChatRemoteEnd_SendRawServerResponse(chat: ObjectHandle, bytes: ByteArray): Unit
@JvmStatic
public external fun TESTING_FakeChatRemoteEnd_SendServerGrpcResponse(asyncRuntime: ObjectHandle, chat: ObjectHandle, response: ObjectHandle): CompletableFuture<Void?>
@JvmStatic
public external fun TESTING_FakeChatRemoteEnd_SendServerResponse(chat: ObjectHandle, response: ObjectHandle): Unit
@JvmStatic
public external fun TESTING_FakeChatResponse_Create(id: Long, status: Int, message: String, headers: Array<Object>, body: ByteArray?): ObjectHandle

View File

@ -663,8 +663,10 @@ type NativeFunctions = {
TESTING_FakeChatRemoteEnd_SendRawServerRequest: (chat: Wrapper<FakeChatRemoteEnd>, bytes: Uint8Array<ArrayBuffer>) => void;
TESTING_FakeChatRemoteEnd_SendRawServerResponse: (chat: Wrapper<FakeChatRemoteEnd>, bytes: Uint8Array<ArrayBuffer>) => void;
TESTING_FakeChatRemoteEnd_SendServerResponse: (chat: Wrapper<FakeChatRemoteEnd>, response: Wrapper<FakeChatResponse>) => void;
TESTING_FakeChatRemoteEnd_SendServerGrpcResponse: (asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<FakeChatRemoteEnd>, response: Wrapper<FakeChatResponse>) => CancellablePromise<void>;
TESTING_FakeChatRemoteEnd_InjectConnectionInterrupted: (chat: Wrapper<FakeChatRemoteEnd>) => void;
TESTING_FakeChatRemoteEnd_ReceiveIncomingRequest: (asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<FakeChatRemoteEnd>) => CancellablePromise<[HttpRequest, bigint] | null>;
TESTING_FakeChatRemoteEnd_ReceiveIncomingGrpcRequest: (asyncRuntime: Wrapper<TokioAsyncContext>, chat: Wrapper<FakeChatRemoteEnd>) => CancellablePromise<[HttpRequest, bigint] | null>;
TESTING_ChatResponseConvert: (bodyPresent: boolean) => ChatResponse;
TESTING_ChatRequestGetMethod: (request: Wrapper<HttpRequest>) => string;
TESTING_ChatRequestGetPath: (request: Wrapper<HttpRequest>) => string;
@ -1236,8 +1238,10 @@ const { registerErrors,
TESTING_FakeChatRemoteEnd_SendRawServerRequest,
TESTING_FakeChatRemoteEnd_SendRawServerResponse,
TESTING_FakeChatRemoteEnd_SendServerResponse,
TESTING_FakeChatRemoteEnd_SendServerGrpcResponse,
TESTING_FakeChatRemoteEnd_InjectConnectionInterrupted,
TESTING_FakeChatRemoteEnd_ReceiveIncomingRequest,
TESTING_FakeChatRemoteEnd_ReceiveIncomingGrpcRequest,
TESTING_ChatResponseConvert,
TESTING_ChatRequestGetMethod,
TESTING_ChatRequestGetPath,
@ -1811,8 +1815,10 @@ export { registerErrors,
TESTING_FakeChatRemoteEnd_SendRawServerRequest,
TESTING_FakeChatRemoteEnd_SendRawServerResponse,
TESTING_FakeChatRemoteEnd_SendServerResponse,
TESTING_FakeChatRemoteEnd_SendServerGrpcResponse,
TESTING_FakeChatRemoteEnd_InjectConnectionInterrupted,
TESTING_FakeChatRemoteEnd_ReceiveIncomingRequest,
TESTING_FakeChatRemoteEnd_ReceiveIncomingGrpcRequest,
TESTING_ChatResponseConvert,
TESTING_ChatRequestGetMethod,
TESTING_ChatRequestGetPath,

View File

@ -165,6 +165,37 @@ fn TESTING_FakeChatRemoteEnd_SendServerResponse(
.expect("chat task finished")
}
#[bridge_io(TokioAsyncContext)]
async fn TESTING_FakeChatRemoteEnd_SendServerGrpcResponse(
chat: &FakeChatRemoteEnd,
response: &FakeChatResponse,
) {
let FakeChatResponse(ResponseProto {
id,
status,
message,
headers,
body,
}) = response;
assert!(
message.as_deref().unwrap_or_default().is_empty(),
"messages not supported for gRPC"
);
assert!(headers.is_empty(), "headers not yet implemented for gRPC");
let http_response = http::Response::builder()
.status(u16::try_from(status.unwrap_or_default()).unwrap_or(u16::MAX))
.body(body.as_ref().cloned().unwrap_or_default())
.expect("valid");
chat.0
.grpc()
.await
.send_response(id.unwrap_or_default(), http_response)
.expect("chat task finished");
}
#[bridge_fn]
fn TESTING_FakeChatRemoteEnd_InjectConnectionInterrupted(chat: &FakeChatRemoteEnd) {
chat.0
@ -209,6 +240,40 @@ async fn TESTING_FakeChatRemoteEnd_ReceiveIncomingRequest(
Some((http_request, id.unwrap()))
}
#[bridge_io(TokioAsyncContext)]
async fn TESTING_FakeChatRemoteEnd_ReceiveIncomingGrpcRequest(
chat: &FakeChatRemoteEnd,
) -> Option<(HttpRequest, u64)> {
let (id, request) = chat
.0
.grpc()
.await
.receive_request()
.await
.expect("message was invalid")?;
let (
http::request::Parts {
method,
uri,
headers,
..
},
body,
) = request.into_parts();
let http_request = HttpRequest {
method,
path: uri
.into_parts()
.path_and_query
.unwrap_or(http::uri::PathAndQuery::from_static("")),
body: Some(body),
headers: headers.into(),
};
Some((http_request, id))
}
#[bridge_fn]
fn TESTING_ChatResponseConvert(body_present: bool) -> ChatResponse {
let body = match body_present {

View File

@ -354,12 +354,16 @@ SignalFfiError *signal_testing_fake_chat_remote_end_json_to_binproto(SignalOwned
SignalFfiError *signal_testing_fake_chat_remote_end_next_grpc_message(SignalPairOfu32u32 *out, SignalBorrowedBuffer input, uint32_t offset);
SignalFfiError *signal_testing_fake_chat_remote_end_receive_incoming_grpc_request(SignalCPromiseOptionalPairOfMutPointerHttpRequestu64 *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerFakeChatRemoteEnd chat);
SignalFfiError *signal_testing_fake_chat_remote_end_receive_incoming_request(SignalCPromiseOptionalPairOfMutPointerHttpRequestu64 *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerFakeChatRemoteEnd chat);
SignalFfiError *signal_testing_fake_chat_remote_end_send_raw_server_request(SignalConstPointerFakeChatRemoteEnd chat, SignalBorrowedBuffer bytes);
SignalFfiError *signal_testing_fake_chat_remote_end_send_raw_server_response(SignalConstPointerFakeChatRemoteEnd chat, SignalBorrowedBuffer bytes);
SignalFfiError *signal_testing_fake_chat_remote_end_send_server_grpc_response(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerFakeChatRemoteEnd chat, SignalConstPointerFakeChatResponse response);
SignalFfiError *signal_testing_fake_chat_remote_end_send_server_response(SignalConstPointerFakeChatRemoteEnd chat, SignalConstPointerFakeChatResponse response);
SignalFfiError *signal_testing_fake_chat_response_create(SignalMutPointerFakeChatResponse *out, uint64_t id, uint16_t status, const char *message, SignalBorrowedBytestringArray headers, SignalOptionalBorrowedSliceOfc_uchar body);