mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-18 14:59:42 +02:00
cli: add grpc/template render handlers and unsupported event errors
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
use serde_json::Value;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
@@ -8,22 +10,26 @@ use yaak::render::render_http_request;
|
|||||||
use yaak::send::{SendHttpRequestWithPluginsParams, send_http_request_with_plugins};
|
use yaak::send::{SendHttpRequestWithPluginsParams, send_http_request_with_plugins};
|
||||||
use yaak_crypto::manager::EncryptionManager;
|
use yaak_crypto::manager::EncryptionManager;
|
||||||
use yaak_models::blob_manager::BlobManager;
|
use yaak_models::blob_manager::BlobManager;
|
||||||
|
use yaak_models::models::{Environment, GrpcRequest, HttpRequestHeader};
|
||||||
use yaak_models::query_manager::QueryManager;
|
use yaak_models::query_manager::QueryManager;
|
||||||
|
use yaak_models::render::make_vars_hashmap;
|
||||||
use yaak_models::util::UpdateSource;
|
use yaak_models::util::UpdateSource;
|
||||||
use yaak_plugins::events::{
|
use yaak_plugins::events::{
|
||||||
EmptyPayload, ErrorResponse, InternalEvent, InternalEventPayload, ListOpenWorkspacesResponse,
|
EmptyPayload, ErrorResponse, InternalEvent, InternalEventPayload, ListOpenWorkspacesResponse,
|
||||||
RenderHttpRequestResponse, SendHttpRequestResponse, WorkspaceInfo,
|
RenderGrpcRequestResponse, RenderHttpRequestResponse, SendHttpRequestResponse,
|
||||||
|
TemplateRenderResponse, WorkspaceInfo,
|
||||||
};
|
};
|
||||||
use yaak_plugins::manager::PluginManager;
|
use yaak_plugins::manager::PluginManager;
|
||||||
use yaak_plugins::template_callback::PluginTemplateCallback;
|
use yaak_plugins::template_callback::PluginTemplateCallback;
|
||||||
use yaak_templates::RenderOptions;
|
use yaak_templates::{RenderOptions, TemplateCallback, parse_and_render, render_json_value_raw};
|
||||||
|
|
||||||
pub struct CliPluginEventBridge {
|
pub struct CliPluginEventBridge {
|
||||||
rx_id: String,
|
rx_id: String,
|
||||||
task: JoinHandle<()>,
|
task: JoinHandle<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CliSendHttpContext {
|
struct CliHostContext {
|
||||||
|
query_manager: QueryManager,
|
||||||
blob_manager: BlobManager,
|
blob_manager: BlobManager,
|
||||||
plugin_manager: Arc<PluginManager>,
|
plugin_manager: Arc<PluginManager>,
|
||||||
encryption_manager: Arc<EncryptionManager>,
|
encryption_manager: Arc<EncryptionManager>,
|
||||||
@@ -41,7 +47,8 @@ impl CliPluginEventBridge {
|
|||||||
let (rx_id, mut rx) = plugin_manager.subscribe("cli").await;
|
let (rx_id, mut rx) = plugin_manager.subscribe("cli").await;
|
||||||
let rx_id_for_task = rx_id.clone();
|
let rx_id_for_task = rx_id.clone();
|
||||||
let pm = plugin_manager.clone();
|
let pm = plugin_manager.clone();
|
||||||
let send_http_context = Arc::new(CliSendHttpContext {
|
let host_context = Arc::new(CliHostContext {
|
||||||
|
query_manager,
|
||||||
blob_manager,
|
blob_manager,
|
||||||
plugin_manager,
|
plugin_manager,
|
||||||
encryption_manager,
|
encryption_manager,
|
||||||
@@ -65,21 +72,15 @@ impl CliPluginEventBridge {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let pm = pm.clone();
|
let pm = pm.clone();
|
||||||
let query_manager = query_manager.clone();
|
let host_context = host_context.clone();
|
||||||
let send_http_context = send_http_context.clone();
|
|
||||||
|
|
||||||
// Avoid deadlocks for nested plugin-host requests (for example, template functions
|
// Avoid deadlocks for nested plugin-host requests (for example, template functions
|
||||||
// that trigger additional host requests during render) by handling each event in
|
// that trigger additional host requests during render) by handling each event in
|
||||||
// its own task.
|
// its own task.
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let plugin_name = plugin_handle.info().name;
|
let plugin_name = plugin_handle.info().name;
|
||||||
let Some(reply_payload) = build_plugin_reply(
|
let Some(reply_payload) =
|
||||||
&query_manager,
|
build_plugin_reply(host_context.as_ref(), &event, &plugin_name).await
|
||||||
&event,
|
|
||||||
&plugin_name,
|
|
||||||
Some(send_http_context.as_ref()),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -104,13 +105,12 @@ impl CliPluginEventBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn build_plugin_reply(
|
async fn build_plugin_reply(
|
||||||
query_manager: &QueryManager,
|
host_context: &CliHostContext,
|
||||||
event: &InternalEvent,
|
event: &InternalEvent,
|
||||||
plugin_name: &str,
|
plugin_name: &str,
|
||||||
send_http_context: Option<&CliSendHttpContext>,
|
|
||||||
) -> Option<InternalEventPayload> {
|
) -> Option<InternalEventPayload> {
|
||||||
match handle_shared_plugin_event(
|
match handle_shared_plugin_event(
|
||||||
query_manager,
|
&host_context.query_manager,
|
||||||
&event.payload,
|
&event.payload,
|
||||||
SharedPluginEventContext {
|
SharedPluginEventContext {
|
||||||
plugin_name,
|
plugin_name,
|
||||||
@@ -129,7 +129,7 @@ async fn build_plugin_reply(
|
|||||||
Some(InternalEventPayload::ShowToastResponse(EmptyPayload {}))
|
Some(InternalEventPayload::ShowToastResponse(EmptyPayload {}))
|
||||||
}
|
}
|
||||||
HostRequest::ListOpenWorkspaces(_) => {
|
HostRequest::ListOpenWorkspaces(_) => {
|
||||||
let workspaces = match query_manager.connect().list_workspaces() {
|
let workspaces = match host_context.query_manager.connect().list_workspaces() {
|
||||||
Ok(workspaces) => workspaces
|
Ok(workspaces) => workspaces
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|w| WorkspaceInfo { id: w.id.clone(), name: w.name, label: w.id })
|
.map(|w| WorkspaceInfo { id: w.id.clone(), name: w.name, label: w.id })
|
||||||
@@ -145,12 +145,6 @@ async fn build_plugin_reply(
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
HostRequest::SendHttpRequest(send_http_request_request) => {
|
HostRequest::SendHttpRequest(send_http_request_request) => {
|
||||||
let Some(send_ctx) = send_http_context else {
|
|
||||||
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
|
||||||
error: "Send HTTP request support is not initialized in CLI".to_string(),
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut http_request = send_http_request_request.http_request.clone();
|
let mut http_request = send_http_request_request.http_request.clone();
|
||||||
if http_request.workspace_id.is_empty() {
|
if http_request.workspace_id.is_empty() {
|
||||||
let Some(workspace_id) = event.context.workspace_id.clone() else {
|
let Some(workspace_id) = event.context.workspace_id.clone() else {
|
||||||
@@ -168,18 +162,18 @@ async fn build_plugin_reply(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match send_http_request_with_plugins(SendHttpRequestWithPluginsParams {
|
match send_http_request_with_plugins(SendHttpRequestWithPluginsParams {
|
||||||
query_manager,
|
query_manager: &host_context.query_manager,
|
||||||
blob_manager: &send_ctx.blob_manager,
|
blob_manager: &host_context.blob_manager,
|
||||||
request: http_request,
|
request: http_request,
|
||||||
environment_id: None,
|
environment_id: None,
|
||||||
update_source: UpdateSource::Plugin,
|
update_source: UpdateSource::Plugin,
|
||||||
cookie_jar_id: None,
|
cookie_jar_id: None,
|
||||||
response_dir: &send_ctx.response_dir,
|
response_dir: &host_context.response_dir,
|
||||||
emit_events_to: None,
|
emit_events_to: None,
|
||||||
emit_response_body_chunks_to: None,
|
emit_response_body_chunks_to: None,
|
||||||
existing_response: None,
|
existing_response: None,
|
||||||
plugin_manager: send_ctx.plugin_manager.clone(),
|
plugin_manager: host_context.plugin_manager.clone(),
|
||||||
encryption_manager: send_ctx.encryption_manager.clone(),
|
encryption_manager: host_context.encryption_manager.clone(),
|
||||||
plugin_context: &plugin_context,
|
plugin_context: &plugin_context,
|
||||||
cancelled_rx: None,
|
cancelled_rx: None,
|
||||||
connection_manager: None,
|
connection_manager: None,
|
||||||
@@ -194,17 +188,62 @@ async fn build_plugin_reply(
|
|||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HostRequest::CopyText(copy_text_request) => todo!("copy_text_request"),
|
HostRequest::RenderGrpcRequest(render_grpc_request_request) => {
|
||||||
HostRequest::PromptText(prompt_text_request) => todo!("prompt_text_request"),
|
let mut grpc_request = render_grpc_request_request.grpc_request.clone();
|
||||||
HostRequest::PromptForm(prompt_form_request) => todo!("prompt_form_request"),
|
if grpc_request.workspace_id.is_empty() {
|
||||||
HostRequest::RenderGrpcRequest(render_grpc_request_request) => todo!("render_grpc"),
|
let Some(workspace_id) = event.context.workspace_id.clone() else {
|
||||||
HostRequest::RenderHttpRequest(render_http_request_request) => {
|
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
let Some(send_ctx) = send_http_context else {
|
error: "workspace_id is required to render gRPC requests in CLI"
|
||||||
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
.to_string(),
|
||||||
error: "Render HTTP request support is not initialized in CLI".to_string(),
|
}));
|
||||||
}));
|
};
|
||||||
};
|
grpc_request.workspace_id = workspace_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut plugin_context = event.context.clone();
|
||||||
|
if plugin_context.workspace_id.is_none() {
|
||||||
|
plugin_context.workspace_id = Some(grpc_request.workspace_id.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let environment_chain =
|
||||||
|
match host_context.query_manager.connect().resolve_environments(
|
||||||
|
&grpc_request.workspace_id,
|
||||||
|
grpc_request.folder_id.as_deref(),
|
||||||
|
None,
|
||||||
|
) {
|
||||||
|
Ok(chain) => chain,
|
||||||
|
Err(err) => {
|
||||||
|
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: format!("Failed to resolve environments in CLI: {err}"),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let template_callback = PluginTemplateCallback::new(
|
||||||
|
host_context.plugin_manager.clone(),
|
||||||
|
host_context.encryption_manager.clone(),
|
||||||
|
&plugin_context,
|
||||||
|
render_grpc_request_request.purpose.clone(),
|
||||||
|
);
|
||||||
|
let render_options = RenderOptions::throw();
|
||||||
|
|
||||||
|
match render_grpc_request_for_cli(
|
||||||
|
&grpc_request,
|
||||||
|
environment_chain,
|
||||||
|
&template_callback,
|
||||||
|
&render_options,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(grpc_request) => Some(InternalEventPayload::RenderGrpcRequestResponse(
|
||||||
|
RenderGrpcRequestResponse { grpc_request },
|
||||||
|
)),
|
||||||
|
Err(err) => Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: format!("Failed to render gRPC request in CLI: {err}"),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HostRequest::RenderHttpRequest(render_http_request_request) => {
|
||||||
let mut http_request = render_http_request_request.http_request.clone();
|
let mut http_request = render_http_request_request.http_request.clone();
|
||||||
if http_request.workspace_id.is_empty() {
|
if http_request.workspace_id.is_empty() {
|
||||||
let Some(workspace_id) = event.context.workspace_id.clone() else {
|
let Some(workspace_id) = event.context.workspace_id.clone() else {
|
||||||
@@ -221,22 +260,23 @@ async fn build_plugin_reply(
|
|||||||
plugin_context.workspace_id = Some(http_request.workspace_id.clone());
|
plugin_context.workspace_id = Some(http_request.workspace_id.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let environment_chain = match query_manager.connect().resolve_environments(
|
let environment_chain =
|
||||||
&http_request.workspace_id,
|
match host_context.query_manager.connect().resolve_environments(
|
||||||
http_request.folder_id.as_deref(),
|
&http_request.workspace_id,
|
||||||
None,
|
http_request.folder_id.as_deref(),
|
||||||
) {
|
None,
|
||||||
Ok(chain) => chain,
|
) {
|
||||||
Err(err) => {
|
Ok(chain) => chain,
|
||||||
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
Err(err) => {
|
||||||
error: format!("Failed to resolve environments in CLI: {err}"),
|
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
}));
|
error: format!("Failed to resolve environments in CLI: {err}"),
|
||||||
}
|
}));
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let template_callback = PluginTemplateCallback::new(
|
let template_callback = PluginTemplateCallback::new(
|
||||||
send_ctx.plugin_manager.clone(),
|
host_context.plugin_manager.clone(),
|
||||||
send_ctx.encryption_manager.clone(),
|
host_context.encryption_manager.clone(),
|
||||||
&plugin_context,
|
&plugin_context,
|
||||||
render_http_request_request.purpose.clone(),
|
render_http_request_request.purpose.clone(),
|
||||||
);
|
);
|
||||||
@@ -258,127 +298,175 @@ async fn build_plugin_reply(
|
|||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HostRequest::TemplateRender(template_render_request) => todo!("template_render"),
|
HostRequest::TemplateRender(template_render_request) => {
|
||||||
HostRequest::OpenWindow(open_window_request) => todo!("open_window"),
|
let Some(workspace_id) = event.context.workspace_id.clone() else {
|
||||||
HostRequest::CloseWindow(close_window_request) => todo!("close_window"),
|
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
HostRequest::OpenExternalUrl(open_external_url_request) => todo!("open_url"),
|
error: "workspace_id is required to render templates in CLI".to_string(),
|
||||||
HostRequest::ListCookieNames(list_cookie_names_request) => todo!("list_cookie"),
|
}));
|
||||||
HostRequest::GetCookieValue(get_cookie_value_request) => todo!("get_cookie"),
|
};
|
||||||
HostRequest::WindowInfo(window_info_request) => todo!("window_info"),
|
|
||||||
HostRequest::OtherRequest(internal_event_payload) => todo!("other"),
|
let mut plugin_context = event.context.clone();
|
||||||
|
if plugin_context.workspace_id.is_none() {
|
||||||
|
plugin_context.workspace_id = Some(workspace_id.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let environment_chain = match host_context
|
||||||
|
.query_manager
|
||||||
|
.connect()
|
||||||
|
.resolve_environments(&workspace_id, None, None)
|
||||||
|
{
|
||||||
|
Ok(chain) => chain,
|
||||||
|
Err(err) => {
|
||||||
|
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: format!("Failed to resolve environments in CLI: {err}"),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let template_callback = PluginTemplateCallback::new(
|
||||||
|
host_context.plugin_manager.clone(),
|
||||||
|
host_context.encryption_manager.clone(),
|
||||||
|
&plugin_context,
|
||||||
|
template_render_request.purpose.clone(),
|
||||||
|
);
|
||||||
|
let render_options = RenderOptions::throw();
|
||||||
|
|
||||||
|
match render_json_value_for_cli(
|
||||||
|
template_render_request.data.clone(),
|
||||||
|
environment_chain,
|
||||||
|
&template_callback,
|
||||||
|
&render_options,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(data) => {
|
||||||
|
Some(InternalEventPayload::TemplateRenderResponse(TemplateRenderResponse {
|
||||||
|
data,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Err(err) => Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: format!("Failed to render template data in CLI: {err}"),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HostRequest::OpenExternalUrl(open_external_url_request) => {
|
||||||
|
match webbrowser::open(open_external_url_request.url.as_str()) {
|
||||||
|
Ok(_) => Some(InternalEventPayload::OpenExternalUrlResponse(EmptyPayload {})),
|
||||||
|
Err(err) => Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: format!("Failed to open external URL in CLI: {err}"),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HostRequest::CopyText(_) => Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: copy_text_request".to_string(),
|
||||||
|
})),
|
||||||
|
HostRequest::PromptText(_) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: prompt_text_request".to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
HostRequest::PromptForm(_) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: prompt_form_request".to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
HostRequest::OpenWindow(_) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: open_window_request".to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
HostRequest::CloseWindow(_) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: close_window_request".to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
HostRequest::ListCookieNames(_) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: list_cookie_names_request"
|
||||||
|
.to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
HostRequest::GetCookieValue(_) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: get_cookie_value_request"
|
||||||
|
.to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
HostRequest::WindowInfo(_) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: "Unsupported plugin request in CLI: window_info_request".to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
HostRequest::OtherRequest(payload) => {
|
||||||
|
Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
|
error: format!("Unsupported plugin request in CLI: {}", payload.type_name()),
|
||||||
|
}))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
async fn render_json_value_for_cli<T: TemplateCallback>(
|
||||||
mod tests {
|
value: Value,
|
||||||
use super::*;
|
environment_chain: Vec<Environment>,
|
||||||
use tempfile::TempDir;
|
cb: &T,
|
||||||
use yaak_models::models::HttpRequest;
|
opt: &RenderOptions,
|
||||||
use yaak_plugins::events::{GetKeyValueRequest, PluginContext, SendHttpRequestRequest};
|
) -> yaak_templates::error::Result<Value> {
|
||||||
|
let vars = &make_vars_hashmap(environment_chain);
|
||||||
fn query_manager_for_test() -> (QueryManager, TempDir) {
|
render_json_value_raw(value, vars, cb, opt).await
|
||||||
let temp_dir = TempDir::new().expect("Failed to create temp dir");
|
}
|
||||||
let db_path = temp_dir.path().join("db.sqlite");
|
|
||||||
let blob_path = temp_dir.path().join("blobs.sqlite");
|
async fn render_grpc_request_for_cli<T: TemplateCallback>(
|
||||||
let (query_manager, _blob_manager, _rx) =
|
grpc_request: &GrpcRequest,
|
||||||
yaak_models::init_standalone(&db_path, &blob_path).expect("Failed to initialize DB");
|
environment_chain: Vec<Environment>,
|
||||||
(query_manager, temp_dir)
|
cb: &T,
|
||||||
}
|
opt: &RenderOptions,
|
||||||
|
) -> yaak_templates::error::Result<GrpcRequest> {
|
||||||
fn event(payload: InternalEventPayload) -> InternalEvent {
|
let vars = &make_vars_hashmap(environment_chain);
|
||||||
InternalEvent {
|
|
||||||
id: "evt_1".to_string(),
|
let mut metadata = Vec::new();
|
||||||
plugin_ref_id: "plugin_ref_1".to_string(),
|
for p in grpc_request.metadata.clone() {
|
||||||
plugin_name: "@yaak/test-plugin".to_string(),
|
if !p.enabled {
|
||||||
reply_id: None,
|
continue;
|
||||||
context: PluginContext::new_empty(),
|
}
|
||||||
payload,
|
metadata.push(HttpRequestHeader {
|
||||||
}
|
enabled: p.enabled,
|
||||||
}
|
name: parse_and_render(p.name.as_str(), vars, cb, opt).await?,
|
||||||
|
value: parse_and_render(p.value.as_str(), vars, cb, opt).await?,
|
||||||
#[tokio::test]
|
id: p.id,
|
||||||
async fn key_value_requests_round_trip() {
|
})
|
||||||
let (query_manager, _temp_dir) = query_manager_for_test();
|
}
|
||||||
let plugin_name = "@yaak/test-plugin";
|
|
||||||
|
let authentication = {
|
||||||
let get_missing = build_plugin_reply(
|
let mut disabled = false;
|
||||||
&query_manager,
|
let mut auth = BTreeMap::new();
|
||||||
&event(InternalEventPayload::GetKeyValueRequest(GetKeyValueRequest {
|
match grpc_request.authentication.get("disabled") {
|
||||||
key: "missing".to_string(),
|
Some(Value::Bool(true)) => {
|
||||||
})),
|
disabled = true;
|
||||||
plugin_name,
|
}
|
||||||
None,
|
Some(Value::String(tmpl)) => {
|
||||||
)
|
disabled = parse_and_render(tmpl.as_str(), vars, cb, opt)
|
||||||
.await;
|
.await
|
||||||
match get_missing {
|
.unwrap_or_default()
|
||||||
Some(InternalEventPayload::GetKeyValueResponse(r)) => assert_eq!(r.value, None),
|
.is_empty();
|
||||||
other => panic!("unexpected payload for missing get: {other:?}"),
|
}
|
||||||
}
|
_ => {}
|
||||||
|
}
|
||||||
let set = build_plugin_reply(
|
if disabled {
|
||||||
&query_manager,
|
auth.insert("disabled".to_string(), Value::Bool(true));
|
||||||
&event(InternalEventPayload::SetKeyValueRequest(
|
} else {
|
||||||
yaak_plugins::events::SetKeyValueRequest {
|
for (k, v) in grpc_request.authentication.clone() {
|
||||||
key: "token".to_string(),
|
if k == "disabled" {
|
||||||
value: "{\"access_token\":\"abc\"}".to_string(),
|
auth.insert(k, Value::Bool(false));
|
||||||
},
|
} else {
|
||||||
)),
|
auth.insert(k, render_json_value_raw(v, vars, cb, opt).await?);
|
||||||
plugin_name,
|
}
|
||||||
None,
|
}
|
||||||
)
|
}
|
||||||
.await;
|
auth
|
||||||
assert!(matches!(set, Some(InternalEventPayload::SetKeyValueResponse(_))));
|
};
|
||||||
|
|
||||||
let get_present = build_plugin_reply(
|
let url = parse_and_render(grpc_request.url.as_str(), vars, cb, opt).await?;
|
||||||
&query_manager,
|
|
||||||
&event(InternalEventPayload::GetKeyValueRequest(GetKeyValueRequest {
|
Ok(GrpcRequest { url, metadata, authentication, ..grpc_request.to_owned() })
|
||||||
key: "token".to_string(),
|
|
||||||
})),
|
|
||||||
plugin_name,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
match get_present {
|
|
||||||
Some(InternalEventPayload::GetKeyValueResponse(r)) => {
|
|
||||||
assert_eq!(r.value, Some("{\"access_token\":\"abc\"}".to_string()))
|
|
||||||
}
|
|
||||||
other => panic!("unexpected payload for present get: {other:?}"),
|
|
||||||
}
|
|
||||||
|
|
||||||
let delete = build_plugin_reply(
|
|
||||||
&query_manager,
|
|
||||||
&event(InternalEventPayload::DeleteKeyValueRequest(
|
|
||||||
yaak_plugins::events::DeleteKeyValueRequest { key: "token".to_string() },
|
|
||||||
)),
|
|
||||||
plugin_name,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
match delete {
|
|
||||||
Some(InternalEventPayload::DeleteKeyValueResponse(r)) => assert!(r.deleted),
|
|
||||||
other => panic!("unexpected payload for delete: {other:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn send_http_request_without_context_gets_error_reply() {
|
|
||||||
let (query_manager, _temp_dir) = query_manager_for_test();
|
|
||||||
let payload = build_plugin_reply(
|
|
||||||
&query_manager,
|
|
||||||
&event(InternalEventPayload::SendHttpRequestRequest(SendHttpRequestRequest {
|
|
||||||
http_request: HttpRequest::default(),
|
|
||||||
})),
|
|
||||||
"@yaak/test-plugin",
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match payload {
|
|
||||||
Some(InternalEventPayload::ErrorResponse(err)) => {
|
|
||||||
assert!(err.error.contains("Send HTTP request support is not initialized in CLI"));
|
|
||||||
}
|
|
||||||
other => panic!("unexpected payload for unsupported request: {other:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user