use super::*;
use std::sync::mpsc::channel;
use tokio_util::sync::CancellationToken;
use crate::autocomplete::json_navigator::DEFAULT_ARRAY_SAMPLE_SIZE;
#[test]
fn test_worker_spawns_successfully() {
let json_input = r#"{"test": "data"}"#.to_string();
let (request_tx, request_rx) = channel();
let (response_tx, response_rx) = channel();
spawn_worker(
json_input,
request_rx,
response_tx,
DEFAULT_ARRAY_SAMPLE_SIZE,
);
let cancel_token = CancellationToken::new();
request_tx
.send(QueryRequest {
query: ".".to_string(),
request_id: 1,
cancel_token,
})
.unwrap();
match response_rx.recv_timeout(std::time::Duration::from_secs(2)) {
Ok(QueryResponse::ProcessedSuccess { processed, .. }) => {
assert_eq!(processed.query, ".");
}
Ok(other) => panic!("Expected ProcessedSuccess, got {:?}", other),
Err(e) => panic!("Timeout waiting for response: {}", e),
}
}
#[test]
fn test_worker_handles_invalid_query() {
let json_input = r#"{"test": "data"}"#.to_string();
let (request_tx, request_rx) = channel();
let (response_tx, response_rx) = channel();
spawn_worker(
json_input,
request_rx,
response_tx,
DEFAULT_ARRAY_SAMPLE_SIZE,
);
let cancel_token = CancellationToken::new();
request_tx
.send(QueryRequest {
query: ".invalid syntax [".to_string(),
request_id: 1,
cancel_token,
})
.unwrap();
match response_rx.recv_timeout(std::time::Duration::from_secs(2)) {
Ok(QueryResponse::Error { .. }) => {
}
Ok(other) => panic!("Expected Error, got {:?}", other),
Err(e) => panic!("Timeout waiting for response: {}", e),
}
}
#[test]
fn test_worker_handles_pre_cancelled_request() {
let json_input = r#"{"test": "data"}"#.to_string();
let (request_tx, request_rx) = channel();
let (response_tx, response_rx) = channel();
spawn_worker(
json_input,
request_rx,
response_tx,
DEFAULT_ARRAY_SAMPLE_SIZE,
);
let cancel_token = CancellationToken::new();
cancel_token.cancel();
request_tx
.send(QueryRequest {
query: ".".to_string(),
request_id: 1,
cancel_token,
})
.unwrap();
match response_rx.recv_timeout(std::time::Duration::from_secs(2)) {
Ok(QueryResponse::Cancelled { .. }) => {
}
Ok(other) => panic!("Expected Cancelled, got {:?}", other),
Err(e) => panic!("Timeout waiting for response: {}", e),
}
}
#[test]
fn test_worker_sends_error_response_for_jq_failure() {
let json_input = r#"{"test": "data"}"#.to_string();
let (request_tx, request_rx) = channel();
let (response_tx, response_rx) = channel();
spawn_worker(
json_input,
request_rx,
response_tx,
DEFAULT_ARRAY_SAMPLE_SIZE,
);
let cancel_token = CancellationToken::new();
request_tx
.send(QueryRequest {
query: ".invalid syntax [".to_string(),
request_id: 1,
cancel_token,
})
.unwrap();
match response_rx.recv_timeout(std::time::Duration::from_secs(2)) {
Ok(QueryResponse::Error {
message,
query,
request_id,
}) => {
assert_eq!(request_id, 1);
assert_eq!(query, ".invalid syntax [");
assert!(message.contains("parse error") || message.contains("syntax"));
}
Ok(other) => panic!("Expected Error, got {:?}", other),
Err(e) => panic!("Timeout waiting for error response: {}", e),
}
}
#[test]
fn test_worker_handles_multiple_rapid_queries() {
let json_input = r#"{"a": 1, "b": 2, "c": 3}"#.to_string();
let (request_tx, request_rx) = channel();
let (response_tx, response_rx) = channel();
spawn_worker(
json_input,
request_rx,
response_tx,
DEFAULT_ARRAY_SAMPLE_SIZE,
);
for i in 1..=5 {
let cancel_token = CancellationToken::new();
request_tx
.send(QueryRequest {
query: format!(".{}", if i % 2 == 0 { "a" } else { "b" }),
request_id: i,
cancel_token,
})
.unwrap();
}
let mut received_count = 0;
for _ in 0..5 {
match response_rx.recv_timeout(std::time::Duration::from_secs(3)) {
Ok(QueryResponse::ProcessedSuccess { .. }) | Ok(QueryResponse::Error { .. }) => {
received_count += 1;
}
Ok(QueryResponse::Cancelled { .. }) => {
received_count += 1;
}
Err(e) => panic!("Timeout after {} responses: {}", received_count, e),
}
}
assert_eq!(received_count, 5, "Should receive all 5 responses");
}
#[test]
fn test_worker_response_includes_original_query() {
let json_input = r#"{"test": "value"}"#.to_string();
let (request_tx, request_rx) = channel();
let (response_tx, response_rx) = channel();
spawn_worker(
json_input,
request_rx,
response_tx,
DEFAULT_ARRAY_SAMPLE_SIZE,
);
let original_query = ".test";
let cancel_token = CancellationToken::new();
request_tx
.send(QueryRequest {
query: original_query.to_string(),
request_id: 42,
cancel_token,
})
.unwrap();
match response_rx.recv_timeout(std::time::Duration::from_secs(2)) {
Ok(QueryResponse::ProcessedSuccess {
processed,
request_id,
}) => {
assert_eq!(
processed.query, original_query,
"Response should include original query"
);
assert_eq!(request_id, 42);
}
Ok(other) => panic!("Expected ProcessedSuccess, got {:?}", other),
Err(e) => panic!("Timeout: {}", e),
}
}
#[test]
fn test_worker_error_response_includes_original_query() {
let json_input = r#"{"test": "value"}"#.to_string();
let (request_tx, request_rx) = channel();
let (response_tx, response_rx) = channel();
spawn_worker(
json_input,
request_rx,
response_tx,
DEFAULT_ARRAY_SAMPLE_SIZE,
);
let original_query = ".invalid syntax [";
let cancel_token = CancellationToken::new();
request_tx
.send(QueryRequest {
query: original_query.to_string(),
request_id: 99,
cancel_token,
})
.unwrap();
match response_rx.recv_timeout(std::time::Duration::from_secs(2)) {
Ok(QueryResponse::Error {
query, request_id, ..
}) => {
assert_eq!(
query, original_query,
"Error response should include original query"
);
assert_eq!(request_id, 99);
}
Ok(other) => panic!("Expected Error, got {:?}", other),
Err(e) => panic!("Timeout: {}", e),
}
}