#![cfg(feature = "bulk")]
#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used)]
use async_trait::async_trait;
use force::api::bulk::JobOperation;
use force::api::bulk::{process_csv_batches, serialize_to_csv};
use force::auth::{AccessToken, Authenticator, TokenResponse};
use force::client::builder;
use force::error::Result;
use serde::{Deserialize, Serialize};
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
#[derive(Debug)]
struct TestAuthenticator {
instance_url: String,
}
#[async_trait]
impl Authenticator for TestAuthenticator {
async fn authenticate(&self) -> Result<AccessToken> {
Ok(AccessToken::from_response(TokenResponse {
access_token: "test_token".to_string(),
instance_url: self.instance_url.clone(),
token_type: "Bearer".to_string(),
issued_at: "1000".to_string(),
signature: "sig".to_string(),
expires_in: None,
refresh_token: None,
}))
}
async fn refresh(&self) -> Result<AccessToken> {
self.authenticate().await
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Record {
id: String,
}
#[test]
fn test_process_csv_batches_errors_on_zero_batch_size() {
let records = vec![Record {
id: "1".to_string(),
}];
let mut csv_data = Vec::new();
serialize_to_csv(&records, &mut csv_data).unwrap();
let reader = &csv_data[..];
let result = process_csv_batches::<Record, _, _>(reader, 0, |_| Ok(()));
assert!(
result.is_err(),
"Expected error for batch_size 0, but got Ok"
);
}
#[tokio::test]
async fn test_smart_ingest_errors_on_zero_batch_size() {
let mock_server = MockServer::start().await;
let auth = TestAuthenticator {
instance_url: mock_server.uri(),
};
let client = builder().authenticate(auth).build().await.unwrap();
let handler = client.bulk();
let records = vec![Record {
id: "1".to_string(),
}];
let stream = futures::stream::iter(records);
Mock::given(method("POST"))
.and(path("/services/data/v60.0/jobs/ingest"))
.respond_with(ResponseTemplate::new(500))
.mount(&mock_server)
.await;
let result = handler
.smart_ingest("Account", JobOperation::Insert)
.batch_size(0)
.execute_stream(stream)
.await;
match result {
Err(force::error::ForceError::InvalidInput(msg)) => {
assert!(
msg.contains("Batch size must be greater than 0"),
"Unexpected error message: {msg}"
);
}
Err(e) => panic!("Expected InvalidInput error (batch size 0), got {e:?}"),
Ok(_) => panic!("Expected error, got Ok"),
}
}