use crate::distribuicao::{
CienciaOperacao, ConfirmacaoOperacao, Consulta, ConsultaChaveAcesso, ConsultaNSU,
DesconhecimentoOperacao, DistribuicaoResposta, OperacaoNaoRealizada,
};
use std::{collections::HashMap, fs, path::Path};
#[tokio::test]
async fn test_consulta() {
let config = load_test_config();
let result = Consulta::new()
.cert_path(&config.cert_path) .cert_pass(&config.cert_pass) .cnpj(&config.cnpj) .uf(35) .ambiente(1) .send()
.await;
assert!(
result.is_ok(),
"Falha ao consultar distribuição: {:?}",
result
);
let distribuicao = result.unwrap();
println!("Distribuição Resposta:\n{:#?}", distribuicao);
}
#[tokio::test]
async fn teste_consulta_nsu() {
let config = load_test_config();
let result = ConsultaNSU::new()
.cert_path(&config.cert_path)
.cert_pass(&config.cert_pass)
.cnpj(&config.cnpj)
.uf(35)
.ambiente(1)
.nsu("000000000000083")
.check_flag()
.send()
.await;
assert!(
result.is_ok(),
"Falha ao consultar distribuição por NSU: {:?}",
result
);
let distribuicao = result.unwrap();
println!("Distribuição Resposta por NSU:\n{:#?}", distribuicao);
}
#[tokio::test]
async fn teste_consulta_chave_acesso() {
let config = load_test_config();
let result: Result<DistribuicaoResposta, String> = ConsultaChaveAcesso::new()
.cert_path(&config.cert_path)
.cert_pass(&config.cert_pass)
.cnpj(&config.cnpj)
.uf(35)
.ambiente(1)
.chave_acesso("35260402084385000148550010008921991199917393")
.send()
.await;
assert!(
result.is_ok(),
"Falha ao consultar distribuição por chave de acesso: {:?}",
result
);
let distribuicao = result.unwrap();
println!(
"Distribuição Resposta por Chave de Acesso:\n{:#?}",
distribuicao
);
}
#[tokio::test]
async fn teste_ciencia_operacao() {
let config = load_manifestacao_test_config();
let result = CienciaOperacao::new()
.cert_path(&config.cert_path)
.cert_pass(&config.cert_pass)
.cnpj(&config.cnpj)
.ambiente(2)
.chave_acesso("35260402084385000148550010008921991199917393") .send()
.await;
assert!(
result.is_ok(),
"Falha ao enviar ciência da operação: {:?}",
result
);
let response = result.unwrap();
println!("Resposta ciência da operação:\n{:#?}", response);
}
#[tokio::test]
async fn teste_confirmacao_operacao() {
let config = load_manifestacao_test_config();
let result = ConfirmacaoOperacao::new()
.cert_path(&config.cert_path)
.cert_pass(&config.cert_pass)
.cnpj(&config.cnpj)
.ambiente(1)
.chave_acesso("35260402084385000148550010008921991199917393") .send()
.await;
assert!(
result.is_ok(),
"Falha ao enviar confirmação da operação: {:?}",
result
);
let response = result.unwrap();
println!("Resposta confirmação da operação:\n{:#?}", response);
}
#[tokio::test]
async fn teste_desconhecimento_operacao() {
let config = load_manifestacao_test_config();
let result = DesconhecimentoOperacao::new()
.cert_path(&config.cert_path)
.cert_pass(&config.cert_pass)
.cnpj(&config.cnpj)
.ambiente(1)
.chave_acesso("35260402084385000148550010008921991199917393") .send()
.await;
assert!(
result.is_ok(),
"Falha ao enviar desconhecimento da operação: {:?}",
result
);
let response = result.unwrap();
println!("Resposta desconhecimento da operação:\n{:#?}", response);
}
#[tokio::test]
async fn teste_operacao_nao_realizada() {
let config = load_manifestacao_test_config();
let result = OperacaoNaoRealizada::new()
.cert_path(&config.cert_path)
.cert_pass(&config.cert_pass)
.cnpj(&config.cnpj)
.ambiente(1)
.chave_acesso("35260402084385000148550010008921991199917393") .justificativa("Operacao nao realizada para teste")
.send()
.await;
assert!(
result.is_ok(),
"Falha ao enviar operação não realizada: {:?}",
result
);
let response = result.unwrap();
println!("Resposta operação não realizada:\n{:#?}", response);
}
struct TestConfig {
cert_path: String,
cert_pass: String,
cnpj: String,
}
fn load_test_config() -> TestConfig {
let config_path = Path::new("distribuicao.conf.ini");
if !config_path.exists() {
create_default_config(config_path);
panic!(
"Arquivo de configuração criado em '{}'. Preencha CERT_PATH, CERT_PASS e CNPJ antes de executar o teste.",
config_path.display()
);
}
let contents = fs::read_to_string(config_path).unwrap_or_else(|error| {
panic!(
"Falha ao ler o arquivo de configuração '{}': {}",
config_path.display(),
error
)
});
let values = parse_config(&contents);
TestConfig {
cert_path: require_config_value(&values, "CERT_PATH", config_path),
cert_pass: require_config_value(&values, "CERT_PASS", config_path),
cnpj: require_config_value(&values, "CNPJ", config_path),
}
}
fn create_default_config(config_path: &Path) {
let default_contents = [
"# Configuração local para o teste de distribuição.",
"# Preencha os valores abaixo com os dados do seu ambiente antes de executar o teste.",
"# CERT_PATH: caminho completo para o arquivo .pfx do certificado digital.",
"# CERT_PASS: senha do certificado digital.",
"# CNPJ: CNPJ do destinatário, somente números.",
"",
"CERT_PATH=",
"CERT_PASS=",
"CNPJ=",
"",
]
.join("\n");
fs::write(config_path, default_contents).unwrap_or_else(|error| {
panic!(
"Falha ao criar o arquivo de configuração '{}': {}",
config_path.display(),
error
)
});
}
fn load_manifestacao_test_config() -> TestConfig {
load_test_config()
}
fn parse_config(contents: &str) -> HashMap<String, String> {
contents
.lines()
.filter_map(|line| {
let trimmed = line.trim();
if trimmed.is_empty() || trimmed.starts_with('#') || trimmed.starts_with(';') {
return None;
}
let (key, value) = trimmed.split_once('=')?;
Some((key.trim().to_string(), value.trim().to_string()))
})
.collect()
}
fn require_config_value(values: &HashMap<String, String>, key: &str, config_path: &Path) -> String {
let value = values
.get(key)
.map(|value| value.trim())
.filter(|value| !value.is_empty())
.unwrap_or_else(|| {
panic!(
"A chave '{}' não foi preenchida em '{}'.",
key,
config_path.display()
)
});
value.to_string()
}