diff --git a/.gitignore b/.gitignore
index 88ba55d3..c21e08a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@ target/
.idea/
*.iml
/target/
+/.github/*.md
+show,
\ No newline at end of file
diff --git a/README.md b/README.md
index 83425b03..941c836d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Java-NFe [ ](https://github.com/Samuel-Oliveira/Java_NFe/blob/master/LICENSE) [](https://search.maven.org/artifact/br.com.swconsultoria/java-nfe/4.00.49/jar)
+# Java-NFe [ ](https://github.com/Samuel-Oliveira/Java_NFe/blob/master/LICENSE) [](https://search.maven.org/artifact/br.com.swconsultoria/java-nfe/4.00.51/jar) [](https://coveralls.io/github/Samuel-Oliveira/Java_NFe?branch=master)
Biblioteca Java para consumo do WebService de NFe/NFCe
### Powered by
@@ -22,7 +22,7 @@ Para Iniciar :
br.com.swconsultoria
java-nfe
- 4.00.49
+ 4.00.51
```
@@ -34,7 +34,7 @@ repositories {
}
}
dependencies {
- implementation "br.com.swconsultoria:java-nfe:4.00.49"
+ implementation "br.com.swconsultoria:java-nfe:4.00.51"
}
```
@@ -44,6 +44,13 @@ ________________________________________________________________________________
# Historico de Versões
+## v4.00.51 - 19/03/2026 - Schemas PL.010b (v1.30)
+- Adicionado Teste Unitarios
+- Atualizado Cacert
+
+## v4.00.50 - 16/02/2026 - Schemas PL.010b (v1.30)
+- Ajustes Impressao Danfe
+
## v4.00.49 - 18/01/2026 - Schemas PL.010b (v1.30)
- Corrigido monofasia retida Anteriormente.
- Adicionado calculos IBSCBS para Diferimento
diff --git a/pom-base.xml b/pom-base.xml
index 19f41efb..dafc6fae 100644
--- a/pom-base.xml
+++ b/pom-base.xml
@@ -3,7 +3,7 @@
br.com.swconsultoria
java-nfe
- 4.00.49-${versao}-SNAPSHOT
+ 4.00.51-${versao}-SNAPSHOT
Java_NFe
Api java para consumo do webService de nota fiscal eletronica
https://github.com/Samuel-Oliveira/Java_NFe
@@ -31,7 +31,7 @@
1.8
- 3.13
+ 3.14
4.4.6
2.3.1
2.3.1
diff --git a/pom.xml b/pom.xml
index e19b31f5..5d6db058 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
br.com.swconsultoria
java-nfe
- 4.00.49
+ 4.00.51
Java_NFe
Api java para consumo do webService de nota fiscal eletronica
https://github.com/Samuel-Oliveira/Java_NFe
@@ -31,7 +31,7 @@
1.8
- 3.13
+ 3.14
4.4.6
2.3.1
2.3.1
@@ -279,6 +279,15 @@
true
+
+
+ org.eluder.coveralls
+ coveralls-maven-plugin
+ 4.3.0
+
+ paGe4qkZvPNJtvxqY8NaJN5ImZO56RqB6
+
+
diff --git a/schemas/leiauteNFe_v4.00.xsd b/schemas/leiauteNFe_v4.00.xsd
index 7393b031..28079674 100644
--- a/schemas/leiauteNFe_v4.00.xsd
+++ b/schemas/leiauteNFe_v4.00.xsd
@@ -18,9 +18,7 @@
-
+
@@ -211,7 +209,13 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e
- Tipo de Nota de Débito
+ Tipo de Nota de Débito:
+01=Transferência de créditos para Cooperativas;
+02=Anulação de Crédito por Saídas Imunes/Isentas;
+03=Débitos de notas fiscais não processadas na apuração;
+04=Multa e juros;
+05=Transferência de crédito de sucessão.
+
@@ -503,7 +507,7 @@ Preencher com "2B", quando se tratar de Cupom Fiscal emitido por máqu
-
+
Chave de acesso da NF-e de antecipação de pagamento
@@ -2557,13 +2561,15 @@ ambiente.
- Motivo da desoneração do ICMS:3-Uso na agropecuária;9-Outros;12-Fomento agropecuário
+ Motivo da desoneração do ICMS:3-Uso na agropecuária;9-Outros; 10=Deficiente Condutor (Convênio ICMS 38/12); 11=Deficiente Não Condutor (Convênio ICMS 38/12); 12-Fomento agropecuário
+
+
@@ -3397,11 +3403,39 @@ Informar o motivo da desoneração:
Percentual de redução da BC
+
+
+ Código de Benefício Fiscal na UF aplicado ao item quando houver RBC.
+
+
+
+
+
+
+
+
Alíquota do ICMS
+
+
+
+ Valor do ICMS da Operação
+
+
+
+
+ Percentual do diferemento
+
+
+
+
+ Valor do ICMS da diferido
+
+
+
Valor do ICMS
@@ -3424,6 +3458,23 @@ Informar o motivo da desoneração:
+
+
+
+ Percentual do diferimento do ICMS relativo ao Fundo de Combate à Pobreza (FCP).
+
+
+
+
+ Valor do ICMS relativo ao Fundo de Combate à Pobreza (FCP) diferido.
+
+
+
+
+ Valor efetivo do ICMS relativo ao Fundo de Combate à Pobreza (FCP).
+
+
+
@@ -3571,12 +3622,14 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o
Tributação pelo ICMS
10 - Tributada e com cobrança do ICMS por substituição tributária;
+20 – Redução de base de cálculo
90 – Outros.
+
@@ -3695,6 +3748,43 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o
Sigla da UF para qual é devido o ICMS ST da operação.
+
+
+ Grupo desoneração
+
+
+
+ Valor do ICMS de desoneração
+
+
+
+
+ Motivo da desoneração do ICMS:9-Outros;10=Deficiente Condutor (Convênio ICMS 38/12) 11=Deficiente Não Condutor (Convênio ICMS 38/12)
+
+
+
+
+
+
+
+
+
+
+
+
+ Indica se o valor do ICMS desonerado (vICMSDeson) deduz do valor do item (vProd):
+0=Valor do ICMS desonerado (vICMSDeson) não deduz do valor do item (vProd) / total da NF-e;
+1=Valor do ICMS desonerado (vICMSDeson) deduz do valor do item (vProd) / total da NF-e.
+
+
+
+
+
+
+
+
+
+
@@ -6520,16 +6610,16 @@ tipo de ato concessório:
-
-
-
-
-
+
+
+
+
+
@@ -7578,4 +7668,4 @@ alterado para tamanho variavel 1-4. (NT2011/004)
-
\ No newline at end of file
+
diff --git a/schemas/nfe_v4.00.xsd b/schemas/nfe_v4.00.xsd
index c934ca2b..b8e3dd25 100644
--- a/schemas/nfe_v4.00.xsd
+++ b/schemas/nfe_v4.00.xsd
@@ -1,12 +1,10 @@
-
-
-
-
-
-
- Nota Fiscal Eletrônica
-
-
-
+
+
+
+
+
+
+ Nota Fiscal Eletrônica
+
+
+
diff --git a/schemas/xmldsig-core-schema_v1.01.xsd b/schemas/xmldsig-core-schema_v1.01.xsd
index 65daee9a..f7dc8dc6 100644
--- a/schemas/xmldsig-core-schema_v1.01.xsd
+++ b/schemas/xmldsig-core-schema_v1.01.xsd
@@ -1,98 +1,98 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/br/com/swconsultoria/nfe/dom/ConfiguracoesNfe.java b/src/main/java/br/com/swconsultoria/nfe/dom/ConfiguracoesNfe.java
index fec10b43..131bd422 100644
--- a/src/main/java/br/com/swconsultoria/nfe/dom/ConfiguracoesNfe.java
+++ b/src/main/java/br/com/swconsultoria/nfe/dom/ConfiguracoesNfe.java
@@ -109,8 +109,8 @@ public static ConfiguracoesNfe criarConfiguracoes(EstadosEnum estado, AmbienteEn
log.info(String.format("JAVA-NFE | Samuel Oliveira | samuel@swconsultoria.com.br " +
"| VERSAO=%s | DATA_VERSAO=%s | PASTA_SCHEMAS=%s | AMBIENTE=%s | ESTADO=%s",
- "4.00.49",
- "18/01/2026",
+ "4.00.51",
+ "19/03/2026",
pastaSchemas,
ambiente,
estado.getNome().toUpperCase()));
diff --git a/src/main/resources/jasper/nfe/danfe.jasper b/src/main/resources/jasper/nfe/danfe.jasper
index 31337840..fd78d135 100644
Binary files a/src/main/resources/jasper/nfe/danfe.jasper and b/src/main/resources/jasper/nfe/danfe.jasper differ
diff --git a/src/main/resources/jasper/nfe/danfe.jrxml b/src/main/resources/jasper/nfe/danfe.jrxml
index c50fe6e9..f472373d 100644
--- a/src/main/resources/jasper/nfe/danfe.jrxml
+++ b/src/main/resources/jasper/nfe/danfe.jrxml
@@ -1001,8 +1001,8 @@ $F{Trans_CPF}.substring(9,11) : ""]]>
-
+
diff --git a/src/test/java/br/com/swconsultoria/nfe/CancelarTest.java b/src/test/java/br/com/swconsultoria/nfe/CancelarTest.java
new file mode 100644
index 00000000..0a92613f
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/CancelarTest.java
@@ -0,0 +1,120 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.AssinaturaEnum;
+import br.com.swconsultoria.nfe.dom.enuns.DocumentoEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envEventoCancNFe.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envEventoCancNFe.TRetEnvEvento;
+import br.com.swconsultoria.nfe.util.CancelamentoUtil;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeRecepcaoEvento.NFeRecepcaoEvento4Stub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class CancelarTest {
+
+ private static final String RET_EVENTO_XML =
+ "" +
+ "12TESTE" +
+ "91128" +
+ "Lote de Evento Processado" +
+ "";
+
+ private ConfiguracoesNfe config;
+ private TEnvEvento enviEvento;
+
+ @BeforeEach
+ void setUp() throws NfeException {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+
+ config.setZoneId(java.time.ZoneId.of("America/Sao_Paulo"));
+
+ Evento evento = new Evento();
+ evento.setChave("52230309158456000159550010000731791567812345");
+ evento.setCnpj("09158456000159");
+ evento.setProtocolo("352230000123456");
+ evento.setMotivo("Cancelamento por erro na emissao do documento fiscal");
+ evento.setDataEvento(java.time.LocalDateTime.of(2024, 1, 15, 10, 0, 0));
+ enviEvento = CancelamentoUtil.montaCancelamento(evento, config);
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { }
+ };
+ }
+
+ private void mockAssinar() {
+ new MockUp() {
+ @Mock
+ public String assinaNfe(ConfiguracoesNfe cfg, String xml,
+ AssinaturaEnum tipo) throws NfeException {
+ return xml;
+ }
+ };
+ }
+
+ private void mockEventosStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { }
+
+ @Mock
+ public NFeRecepcaoEvento4Stub.NfeResultMsg nfeRecepcaoEvento(
+ NFeRecepcaoEvento4Stub.NfeDadosMsg data) throws Exception {
+ NFeRecepcaoEvento4Stub.NfeResultMsg result = new NFeRecepcaoEvento4Stub.NfeResultMsg();
+ result.setExtraElement(AXIOMUtil.stringToOM(RET_EVENTO_XML));
+ return result;
+ }
+ };
+ }
+
+ @Test
+ void eventoCancelamento_semValidacao_retornaEvento() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = Cancelar.eventoCancelamento(config, enviEvento, false, DocumentoEnum.NFE);
+
+ assertNotNull(ret);
+ assertEquals("128", ret.getCStat());
+ }
+
+ @Test
+ void eventoCancelamento_retornaLoteProcessado() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = Cancelar.eventoCancelamento(config, enviEvento, false, DocumentoEnum.NFE);
+
+ assertEquals("Lote de Evento Processado", ret.getXMotivo());
+ }
+
+ @Test
+ void eventoCancelamento_retornaAmbienteHomologacao() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = Cancelar.eventoCancelamento(config, enviEvento, false, DocumentoEnum.NFE);
+
+ assertEquals("2", ret.getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/CartaCorrecaoTest.java b/src/test/java/br/com/swconsultoria/nfe/CartaCorrecaoTest.java
new file mode 100644
index 00000000..add663a9
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/CartaCorrecaoTest.java
@@ -0,0 +1,119 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.AssinaturaEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envcce.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envcce.TRetEnvEvento;
+import br.com.swconsultoria.nfe.util.CartaCorrecaoUtil;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeRecepcaoEvento.NFeRecepcaoEvento4Stub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class CartaCorrecaoTest {
+
+ private static final String RET_EVENTO_XML =
+ "" +
+ "12TESTE" +
+ "91128" +
+ "Lote de Evento Processado" +
+ "";
+
+ private ConfiguracoesNfe config;
+ private TEnvEvento enviEvento;
+
+ @BeforeEach
+ void setUp() throws NfeException {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+
+ config.setZoneId(java.time.ZoneId.of("America/Sao_Paulo"));
+
+ Evento evento = new Evento();
+ evento.setChave("52230309158456000159550010000731791567812345");
+ evento.setCnpj("09158456000159");
+ evento.setMotivo("Correcao no campo de endereco do destinatario da nota fiscal");
+ evento.setSequencia(1);
+ evento.setDataEvento(java.time.LocalDateTime.of(2024, 3, 10, 9, 0, 0));
+ enviEvento = CartaCorrecaoUtil.montaCCe(evento, config);
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { }
+ };
+ }
+
+ private void mockAssinar() {
+ new MockUp() {
+ @Mock
+ public String assinaNfe(ConfiguracoesNfe cfg, String xml,
+ AssinaturaEnum tipo) throws NfeException {
+ return xml;
+ }
+ };
+ }
+
+ private void mockEventosStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { }
+
+ @Mock
+ public NFeRecepcaoEvento4Stub.NfeResultMsg nfeRecepcaoEvento(
+ NFeRecepcaoEvento4Stub.NfeDadosMsg data) throws Exception {
+ NFeRecepcaoEvento4Stub.NfeResultMsg result = new NFeRecepcaoEvento4Stub.NfeResultMsg();
+ result.setExtraElement(AXIOMUtil.stringToOM(RET_EVENTO_XML));
+ return result;
+ }
+ };
+ }
+
+ @Test
+ void eventoCCe_semValidacao_retornaEvento() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = CartaCorrecao.eventoCCe(config, enviEvento, false);
+
+ assertNotNull(ret);
+ assertEquals("128", ret.getCStat());
+ }
+
+ @Test
+ void eventoCCe_retornaLoteProcessado() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = CartaCorrecao.eventoCCe(config, enviEvento, false);
+
+ assertEquals("Lote de Evento Processado", ret.getXMotivo());
+ }
+
+ @Test
+ void eventoCCe_retornaAmbienteHomologacao() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = CartaCorrecao.eventoCCe(config, enviEvento, false);
+
+ assertEquals("2", ret.getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/ConsultaReciboTest.java b/src/test/java/br/com/swconsultoria/nfe/ConsultaReciboTest.java
new file mode 100644
index 00000000..edbedb5e
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/ConsultaReciboTest.java
@@ -0,0 +1,92 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.DocumentoEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema_4.consReciNFe.TRetConsReciNFe;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeRetAutorizacao.NFeRetAutorizacao4Stub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class ConsultaReciboTest {
+
+ private static final String RET_RECIBO_XML =
+ "" +
+ "2104Lote processado" +
+ "35" +
+ "";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { }
+ };
+ }
+
+ private void mockReciboStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { }
+
+ @Mock
+ public NFeRetAutorizacao4Stub.NfeResultMsg nfeRetAutorizacaoLote(
+ NFeRetAutorizacao4Stub.NfeDadosMsg data) throws Exception {
+ NFeRetAutorizacao4Stub.NfeResultMsg result = new NFeRetAutorizacao4Stub.NfeResultMsg();
+ result.setExtraElement(AXIOMUtil.stringToOM(RET_RECIBO_XML));
+ return result;
+ }
+ };
+ }
+
+ @Test
+ void reciboNfe_reciboValido_retornaLoteProcessado() throws NfeException {
+ mockStubUtil();
+ mockReciboStub();
+
+ TRetConsReciNFe ret = ConsultaRecibo.reciboNfe(config, "135240000000001", DocumentoEnum.NFE);
+
+ assertNotNull(ret);
+ assertEquals("104", ret.getCStat());
+ }
+
+ @Test
+ void reciboNfe_retornaMotivo() throws NfeException {
+ mockStubUtil();
+ mockReciboStub();
+
+ TRetConsReciNFe ret = ConsultaRecibo.reciboNfe(config, "135240000000001", DocumentoEnum.NFE);
+
+ assertEquals("Lote processado", ret.getXMotivo());
+ }
+
+ @Test
+ void reciboNfe_nfce_retornaResultado() throws NfeException {
+ mockStubUtil();
+ mockReciboStub();
+
+ TRetConsReciNFe ret = ConsultaRecibo.reciboNfe(config, "135240000000001", DocumentoEnum.NFCE);
+
+ assertNotNull(ret);
+ assertEquals("104", ret.getCStat());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/ConsultaXmlTest.java b/src/test/java/br/com/swconsultoria/nfe/ConsultaXmlTest.java
new file mode 100644
index 00000000..03a28e21
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/ConsultaXmlTest.java
@@ -0,0 +1,93 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.DocumentoEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema_4.consSitNFe.TRetConsSitNFe;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeConsultaProtocolo.NFeConsultaProtocolo4Stub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class ConsultaXmlTest {
+
+ private static final String CHAVE = "35240101234567890001550010000000011000000012";
+
+ private static final String RET_CONSULTA_XML =
+ "" +
+ "2100Autorizado o uso da NF-e" +
+ "352024-01-01T10:00:00-03:00" +
+ "";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { }
+ };
+ }
+
+ private void mockConsultaStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { }
+
+ @Mock
+ public NFeConsultaProtocolo4Stub.NfeResultMsg nfeConsultaNF(
+ NFeConsultaProtocolo4Stub.NfeDadosMsg data) throws Exception {
+ NFeConsultaProtocolo4Stub.NfeResultMsg result = new NFeConsultaProtocolo4Stub.NfeResultMsg();
+ result.setExtraElement(AXIOMUtil.stringToOM(RET_CONSULTA_XML));
+ return result;
+ }
+ };
+ }
+
+ @Test
+ void consultaXml_chaveValida_retornaResultado() throws NfeException {
+ mockStubUtil();
+ mockConsultaStub();
+
+ TRetConsSitNFe ret = ConsultaXml.consultaXml(config, CHAVE, DocumentoEnum.NFE);
+
+ assertNotNull(ret);
+ assertEquals("100", ret.getCStat());
+ }
+
+ @Test
+ void consultaXml_retornaMotivo() throws NfeException {
+ mockStubUtil();
+ mockConsultaStub();
+
+ TRetConsSitNFe ret = ConsultaXml.consultaXml(config, CHAVE, DocumentoEnum.NFE);
+
+ assertEquals("Autorizado o uso da NF-e", ret.getXMotivo());
+ }
+
+ @Test
+ void consultaXml_retornaAmbienteHomologacao() throws NfeException {
+ mockStubUtil();
+ mockConsultaStub();
+
+ TRetConsSitNFe ret = ConsultaXml.consultaXml(config, CHAVE, DocumentoEnum.NFE);
+
+ assertEquals("2", ret.getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/DistribuicaoDFeTest.java b/src/test/java/br/com/swconsultoria/nfe/DistribuicaoDFeTest.java
new file mode 100644
index 00000000..17290e95
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/DistribuicaoDFeTest.java
@@ -0,0 +1,106 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.ConsultaDFeEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.dom.enuns.PessoaEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.retdistdfeint.RetDistDFeInt;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeDistribuicaoDFe.NFeDistribuicaoDFeStub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class DistribuicaoDFeTest {
+
+ private static final String RET_DIST_XML =
+ "" +
+ "2SVRS" +
+ "137Nenhum documento localizado" +
+ "2024-01-01T10:00:00-03:00" +
+ "000000000000000000000000000000" +
+ "";
+
+ private static final String CNPJ = "09158456000159";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { }
+ };
+ }
+
+ private void mockDistStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { }
+
+ @Mock
+ public NFeDistribuicaoDFeStub.NfeDistDFeInteresseResponse nfeDistDFeInteresse(
+ NFeDistribuicaoDFeStub.NfeDistDFeInteresse data) throws Exception {
+ NFeDistribuicaoDFeStub.NfeDistDFeInteresseResult_type0 resultType0 =
+ new NFeDistribuicaoDFeStub.NfeDistDFeInteresseResult_type0();
+ resultType0.setExtraElement(AXIOMUtil.stringToOM(RET_DIST_XML));
+
+ NFeDistribuicaoDFeStub.NfeDistDFeInteresseResponse response =
+ new NFeDistribuicaoDFeStub.NfeDistDFeInteresseResponse();
+ response.setNfeDistDFeInteresseResult(resultType0);
+ return response;
+ }
+ };
+ }
+
+ @Test
+ void consultaNfe_comNsu_retornaDistribuicao() throws NfeException {
+ mockStubUtil();
+ mockDistStub();
+
+ RetDistDFeInt ret = DistribuicaoDFe.consultaNfe(config, PessoaEnum.JURIDICA, CNPJ,
+ ConsultaDFeEnum.NSU, "000000000000000");
+
+ assertNotNull(ret);
+ assertEquals("137", ret.getCStat());
+ }
+
+ @Test
+ void consultaNfe_comChave_retornaDistribuicao() throws NfeException {
+ mockStubUtil();
+ mockDistStub();
+
+ RetDistDFeInt ret = DistribuicaoDFe.consultaNfe(config, PessoaEnum.JURIDICA, CNPJ,
+ ConsultaDFeEnum.CHAVE, "35240101234567890001550010000000011000000012");
+
+ assertNotNull(ret);
+ assertEquals("Nenhum documento localizado", ret.getXMotivo());
+ }
+
+ @Test
+ void consultaNfe_comCpf_retornaDistribuicao() throws NfeException {
+ mockStubUtil();
+ mockDistStub();
+
+ RetDistDFeInt ret = DistribuicaoDFe.consultaNfe(config, PessoaEnum.FISICA, "12345678901",
+ ConsultaDFeEnum.NSU, "000000000000000");
+
+ assertNotNull(ret);
+ assertEquals("2", ret.getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/InutilizarTest.java b/src/test/java/br/com/swconsultoria/nfe/InutilizarTest.java
new file mode 100644
index 00000000..2650d3f9
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/InutilizarTest.java
@@ -0,0 +1,121 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.AssinaturaEnum;
+import br.com.swconsultoria.nfe.dom.enuns.DocumentoEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema_4.inutNFe.TInutNFe;
+import br.com.swconsultoria.nfe.schema_4.inutNFe.TRetInutNFe;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeInutilizacao.NFeInutilizacao4Stub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class InutilizarTest {
+
+ private static final String RET_INUT_XML =
+ "" +
+ "" +
+ "2102" +
+ "Inutilizacao de numero homologado" +
+ "352024-01-01T10:00:00-03:00" +
+ "";
+
+ private ConfiguracoesNfe config;
+ private TInutNFe inutNFe;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+
+ inutNFe = new TInutNFe();
+ TInutNFe.InfInut infInut = new TInutNFe.InfInut();
+ infInut.setCNPJ("09158456000159");
+ infInut.setAno("24");
+ infInut.setMod("55");
+ infInut.setSerie("001");
+ infInut.setNNFIni("1");
+ infInut.setNNFFin("1");
+ infInut.setXJust("Inutilizacao de teste com justificativa longa");
+ inutNFe.setInfInut(infInut);
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { }
+ };
+ }
+
+ private void mockAssinar() {
+ new MockUp() {
+ @Mock
+ public String assinaNfe(ConfiguracoesNfe cfg, String xml,
+ AssinaturaEnum tipo) throws NfeException {
+ return xml;
+ }
+ };
+ }
+
+ private void mockInutilizacaoStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { }
+
+ @Mock
+ public NFeInutilizacao4Stub.NfeResultMsg nfeInutilizacaoNF(
+ NFeInutilizacao4Stub.NfeDadosMsg data) throws Exception {
+ NFeInutilizacao4Stub.NfeResultMsg result = new NFeInutilizacao4Stub.NfeResultMsg();
+ result.setExtraElement(AXIOMUtil.stringToOM(RET_INUT_XML));
+ return result;
+ }
+ };
+ }
+
+ @Test
+ void inutiliza_semValidacao_retornaInutilizacao() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockInutilizacaoStub();
+
+ TRetInutNFe ret = Inutilizar.inutiliza(config, inutNFe, DocumentoEnum.NFE, false);
+
+ assertNotNull(ret);
+ assertNotNull(ret.getInfInut());
+ }
+
+ @Test
+ void inutiliza_retornaNumeroHomologado() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockInutilizacaoStub();
+
+ TRetInutNFe ret = Inutilizar.inutiliza(config, inutNFe, DocumentoEnum.NFE, false);
+
+ assertEquals("102", ret.getInfInut().getCStat());
+ assertEquals("Inutilizacao de numero homologado", ret.getInfInut().getXMotivo());
+ }
+
+ @Test
+ void inutiliza_retornaAmbienteHomologacao() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockInutilizacaoStub();
+
+ TRetInutNFe ret = Inutilizar.inutiliza(config, inutNFe, DocumentoEnum.NFE, false);
+
+ assertEquals("2", ret.getInfInut().getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/ManifestacaoDestinatarioTest.java b/src/test/java/br/com/swconsultoria/nfe/ManifestacaoDestinatarioTest.java
new file mode 100644
index 00000000..2a146fb0
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/ManifestacaoDestinatarioTest.java
@@ -0,0 +1,120 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.AssinaturaEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.dom.enuns.ManifestacaoEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envConfRecebto.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envConfRecebto.TRetEnvEvento;
+import br.com.swconsultoria.nfe.util.ManifestacaoUtil;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeRecepcaoEvento.NFeRecepcaoEvento4Stub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class ManifestacaoDestinatarioTest {
+
+ private static final String RET_EVENTO_XML =
+ "" +
+ "12TESTE" +
+ "91128" +
+ "Lote de Evento Processado" +
+ "";
+
+ private ConfiguracoesNfe config;
+ private TEnvEvento enviEvento;
+
+ @BeforeEach
+ void setUp() throws NfeException {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+
+ config.setZoneId(java.time.ZoneId.of("America/Sao_Paulo"));
+
+ Evento evento = new Evento();
+ evento.setChave("52230309158456000159550010000731791567812345");
+ evento.setCnpj("09158456000159");
+ evento.setProtocolo("352230000123456");
+ evento.setTipoManifestacao(ManifestacaoEnum.CONFIRMACAO_DA_OPERACAO);
+ evento.setDataEvento(java.time.LocalDateTime.of(2024, 1, 15, 10, 0, 0));
+ enviEvento = ManifestacaoUtil.montaManifestacao(evento, config);
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { }
+ };
+ }
+
+ private void mockAssinar() {
+ new MockUp() {
+ @Mock
+ public String assinaNfe(ConfiguracoesNfe cfg, String xml,
+ AssinaturaEnum tipo) throws NfeException {
+ return xml;
+ }
+ };
+ }
+
+ private void mockEventosStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { }
+
+ @Mock
+ public NFeRecepcaoEvento4Stub.NfeResultMsg nfeRecepcaoEvento(
+ NFeRecepcaoEvento4Stub.NfeDadosMsg data) throws Exception {
+ NFeRecepcaoEvento4Stub.NfeResultMsg result = new NFeRecepcaoEvento4Stub.NfeResultMsg();
+ result.setExtraElement(AXIOMUtil.stringToOM(RET_EVENTO_XML));
+ return result;
+ }
+ };
+ }
+
+ @Test
+ void eventoManifestacao_semValidacao_retornaEvento() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = ManifestacaoDestinatario.eventoManifestacao(config, enviEvento, false);
+
+ assertNotNull(ret);
+ assertEquals("128", ret.getCStat());
+ }
+
+ @Test
+ void eventoManifestacao_retornaLoteProcessado() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = ManifestacaoDestinatario.eventoManifestacao(config, enviEvento, false);
+
+ assertEquals("Lote de Evento Processado", ret.getXMotivo());
+ }
+
+ @Test
+ void eventoManifestacao_retornaAmbienteHomologacao() throws NfeException {
+ mockStubUtil();
+ mockAssinar();
+ mockEventosStub();
+
+ TRetEnvEvento ret = ManifestacaoDestinatario.eventoManifestacao(config, enviEvento, false);
+
+ assertEquals("2", ret.getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/NfeTest.java b/src/test/java/br/com/swconsultoria/nfe/NfeTest.java
new file mode 100644
index 00000000..4169a0eb
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/NfeTest.java
@@ -0,0 +1,98 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.DocumentoEnum;
+import br.com.swconsultoria.nfe.dom.enuns.PessoaEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Testes de Nfe — fachada principal da biblioteca.
+ * Verifica o contrato da API (construtor privado, rejeição de config nula).
+ * As chamadas de rede não são testadas aqui (requerem certificado + SEFAZ).
+ */
+class NfeTest {
+
+ // -------------------------------------------------------------------------
+ // Construtor privado
+ // -------------------------------------------------------------------------
+
+ @Test
+ void nfe_construtorEPrivado() throws Exception {
+ Constructor constructor = Nfe.class.getDeclaredConstructor();
+ assertTrue(Modifier.isPrivate(constructor.getModifiers()),
+ "Nfe deve ter construtor privado para impedir instanciação");
+ }
+
+ // -------------------------------------------------------------------------
+ // Rejeição de ConfiguracoesNfe nula (lança NfeException antes da chamada WS)
+ // -------------------------------------------------------------------------
+
+ @Test
+ void statusServico_configNula_lancaNfeException() {
+ assertThrows(NfeException.class,
+ () -> Nfe.statusServico(null, DocumentoEnum.NFE));
+ }
+
+ @Test
+ void consultaXml_configNula_lancaNfeException() {
+ assertThrows(NfeException.class,
+ () -> Nfe.consultaXml(null, "52230309158456000159550010000731791567812345", DocumentoEnum.NFE));
+ }
+
+ @Test
+ void consultaRecibo_configNula_lancaNfeException() {
+ assertThrows(NfeException.class,
+ () -> Nfe.consultaRecibo(null, "123456789012345", DocumentoEnum.NFE));
+ }
+
+ @Test
+ void distribuicaoDfe_configNula_lancaNfeException() {
+ assertThrows(NfeException.class,
+ () -> Nfe.distribuicaoDfe(null, PessoaEnum.JURIDICA, "09158456000159",
+ br.com.swconsultoria.nfe.dom.enuns.ConsultaDFeEnum.NSU, "000000000000001"));
+ }
+
+ @Test
+ void inutilizacao_configNula_lancaNfeException() {
+ br.com.swconsultoria.nfe.schema_4.inutNFe.TInutNFe inutNFe =
+ new br.com.swconsultoria.nfe.schema_4.inutNFe.TInutNFe();
+ br.com.swconsultoria.nfe.schema_4.inutNFe.TInutNFe.InfInut infInut =
+ new br.com.swconsultoria.nfe.schema_4.inutNFe.TInutNFe.InfInut();
+ infInut.setCNPJ("09158456000159");
+ inutNFe.setInfInut(infInut);
+
+ assertThrows(NfeException.class,
+ () -> Nfe.inutilizacao(null, inutNFe, DocumentoEnum.NFE, false));
+ }
+
+ // -------------------------------------------------------------------------
+ // Config sem certificado lança NfeException (getCertificado() retorna null)
+ // -------------------------------------------------------------------------
+
+ @Test
+ void statusServico_configSemCertificado_lancaNfeException() {
+ ConfiguracoesNfe config = new ConfiguracoesNfe();
+ config.setEstado(br.com.swconsultoria.nfe.dom.enuns.EstadosEnum.GO);
+ config.setAmbiente(br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum.HOMOLOGACAO);
+
+ assertThrows(Exception.class,
+ () -> Nfe.statusServico(config, DocumentoEnum.NFE));
+ }
+
+ @Test
+ void consultaXml_configSemCertificado_lancaNfeException() {
+ ConfiguracoesNfe config = new ConfiguracoesNfe();
+ config.setEstado(br.com.swconsultoria.nfe.dom.enuns.EstadosEnum.GO);
+ config.setAmbiente(br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum.HOMOLOGACAO);
+
+ assertThrows(Exception.class,
+ () -> Nfe.consultaXml(config, "52230309158456000159550010000731791567812345", DocumentoEnum.NFE));
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/StatusTest.java b/src/test/java/br/com/swconsultoria/nfe/StatusTest.java
new file mode 100644
index 00000000..ed8071fe
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/StatusTest.java
@@ -0,0 +1,93 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.DocumentoEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema_4.consStatServ.TRetConsStatServ;
+import br.com.swconsultoria.nfe.util.StubUtil;
+import br.com.swconsultoria.nfe.wsdl.NFeStatusServico4.NFeStatusServico4Stub;
+import mockit.Mock;
+import mockit.MockUp;
+import org.apache.axiom.om.util.AXIOMUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class StatusTest {
+
+ private static final String RET_STATUS_XML =
+ "" +
+ "2107Servico em Operacao" +
+ "352024-01-01T10:00:00-03:001" +
+ "";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.SP);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setEncode("UTF-8");
+ }
+
+ private void mockStubUtil() {
+ new MockUp() {
+ @Mock
+ public void configuraHttpClient(org.apache.axis2.client.Stub stub,
+ ConfiguracoesNfe cfg, String url) { /* skip cert */ }
+ };
+ }
+
+ private void mockStatusStub() {
+ new MockUp() {
+ @Mock
+ public void $init(String endpoint) { /* skip Axis2 init */ }
+
+ @Mock
+ public NFeStatusServico4Stub.NfeResultMsg nfeStatusServicoNF(
+ NFeStatusServico4Stub.NfeDadosMsg data) throws Exception {
+ NFeStatusServico4Stub.NfeResultMsg result = new NFeStatusServico4Stub.NfeResultMsg();
+ result.setExtraElement(AXIOMUtil.stringToOM(RET_STATUS_XML));
+ return result;
+ }
+ };
+ }
+
+ @Test
+ void statusServico_nfe_retornaEstadoOperacional() throws NfeException {
+ mockStubUtil();
+ mockStatusStub();
+
+ TRetConsStatServ ret = Status.statusServico(config, DocumentoEnum.NFE);
+
+ assertNotNull(ret);
+ assertEquals("107", ret.getCStat());
+ assertEquals("Servico em Operacao", ret.getXMotivo());
+ }
+
+ @Test
+ void statusServico_nfce_retornaEstadoOperacional() throws NfeException {
+ mockStubUtil();
+ mockStatusStub();
+
+ TRetConsStatServ ret = Status.statusServico(config, DocumentoEnum.NFCE);
+
+ assertNotNull(ret);
+ assertEquals("107", ret.getCStat());
+ }
+
+ @Test
+ void statusServico_retornaAmbienteHomologacao() throws NfeException {
+ mockStubUtil();
+ mockStatusStub();
+
+ TRetConsStatServ ret = Status.statusServico(config, DocumentoEnum.NFE);
+
+ assertEquals("2", ret.getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/ValidarTest.java b/src/test/java/br/com/swconsultoria/nfe/ValidarTest.java
new file mode 100644
index 00000000..f1a05da8
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/ValidarTest.java
@@ -0,0 +1,175 @@
+package br.com.swconsultoria.nfe;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.ServicosEnum;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.xml.sax.SAXParseException;
+
+import java.io.File;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Testes unitários de Validar — validação de XML contra esquemas XSD locais.
+ * Nenhuma chamada de rede é realizada.
+ */
+class ValidarTest {
+
+ /* -----------------------------------------------------------------------
+ * Constantes
+ * --------------------------------------------------------------------- */
+ private static final String SCHEMAS_PATH = "schemas";
+ private static final String STATUS_XSD =
+ SCHEMAS_PATH + File.separator + "consStatServ_v4.00.xsd";
+
+ /** XML mínimo e válido para consStatServ (homologação, Goiás). */
+ private static final String XML_STATUS_VALIDO =
+ "" +
+ "252STATUS";
+
+ /** XML inválido: campo obrigatório cUF ausente. */
+ private static final String XML_STATUS_SEM_CUF =
+ "" +
+ "2STATUS";
+
+ /** XML malformado (tag não fechada). */
+ private static final String XML_MALFORMADO = "2";
+
+ /** XML completamente vazio. */
+ private static final String XML_VAZIO = "";
+
+ private Validar validar;
+
+ @BeforeEach
+ void setUp() {
+ validar = new Validar();
+ }
+
+ // -------------------------------------------------------------------------
+ // isValidXml(String xsd, String xml)
+ // -------------------------------------------------------------------------
+
+ @Test
+ void isValidXml_xsdInexistente_retornaFalso() {
+ assertFalse(validar.isValidXml("/caminho/nao/existe.xsd", XML_STATUS_VALIDO));
+ }
+
+ @Test
+ void isValidXml_xmlValidoComXsdReal_retornaVerdadeiro() {
+ assertTrue(validar.isValidXml(STATUS_XSD, XML_STATUS_VALIDO));
+ }
+
+ @Test
+ void isValidXml_xmlInvalidoSemCampoObrigatorio_retornaFalso() {
+ assertFalse(validar.isValidXml(STATUS_XSD, XML_STATUS_SEM_CUF));
+ }
+
+ @Test
+ void isValidXml_xmlMalformado_retornaFalso() {
+ assertFalse(validar.isValidXml(STATUS_XSD, XML_MALFORMADO));
+ }
+
+ @Test
+ void isValidXml_xmlVazio_retornaFalso() {
+ assertFalse(validar.isValidXml(STATUS_XSD, XML_VAZIO));
+ }
+
+ // -------------------------------------------------------------------------
+ // isValidXml(String pastaSchemas, String xml, ServicosEnum servico)
+ // -------------------------------------------------------------------------
+
+ @Test
+ void isValidXml_comPastaEServico_xmlValido_retornaVerdadeiro() {
+ assertTrue(validar.isValidXml(SCHEMAS_PATH, XML_STATUS_VALIDO, ServicosEnum.STATUS_SERVICO));
+ }
+
+ @Test
+ void isValidXml_comPastaEServico_xmlInvalido_retornaFalso() {
+ assertFalse(validar.isValidXml(SCHEMAS_PATH, XML_STATUS_SEM_CUF, ServicosEnum.STATUS_SERVICO));
+ }
+
+ @Test
+ void isValidXml_comPastaInexistente_retornaFalso() {
+ assertFalse(validar.isValidXml("/pasta/invalida", XML_STATUS_VALIDO, ServicosEnum.STATUS_SERVICO));
+ }
+
+ // -------------------------------------------------------------------------
+ // isValidXml(ConfiguracoesNfe config, String xml, ServicosEnum servico)
+ // -------------------------------------------------------------------------
+
+ @Test
+ void isValidXml_comConfigSemPastaSchemas_retornaFalso() {
+ ConfiguracoesNfe config = new ConfiguracoesNfe(); // pastaSchemas == null
+ assertFalse(validar.isValidXml(config, XML_STATUS_VALIDO, ServicosEnum.STATUS_SERVICO));
+ }
+
+ @Test
+ void isValidXml_comConfigComPastaValida_xmlValido_retornaVerdadeiro() throws Exception {
+ ConfiguracoesNfe config = new ConfiguracoesNfe();
+ // Injetar pastaSchemas via reflexão (setter é privado)
+ java.lang.reflect.Field campo = ConfiguracoesNfe.class.getDeclaredField("pastaSchemas");
+ campo.setAccessible(true);
+ campo.set(config, SCHEMAS_PATH);
+
+ assertTrue(validar.isValidXml(config, XML_STATUS_VALIDO, ServicosEnum.STATUS_SERVICO));
+ }
+
+ @Test
+ void isValidXml_comConfigComPastaValida_xmlInvalido_retornaFalso() throws Exception {
+ ConfiguracoesNfe config = new ConfiguracoesNfe();
+ java.lang.reflect.Field campo = ConfiguracoesNfe.class.getDeclaredField("pastaSchemas");
+ campo.setAccessible(true);
+ campo.set(config, SCHEMAS_PATH);
+
+ assertFalse(validar.isValidXml(config, XML_STATUS_SEM_CUF, ServicosEnum.STATUS_SERVICO));
+ }
+
+ // -------------------------------------------------------------------------
+ // ErrorHandler — error(), fatalError(), warning()
+ // -------------------------------------------------------------------------
+
+ @Test
+ void error_comMensagemContada_naoLancaExcecao() {
+ // "cvc-type.3.1.3:" é contado como erro (não está nos filtros de isError)
+ assertDoesNotThrow(() ->
+ validar.error(new SAXParseException("cvc-type.3.1.3: campo inválido", null)));
+ }
+
+ @Test
+ void error_comMensagemIgnorada_enumeracao_naoLancaExcecao() {
+ // "cvc-enumeration-valid:" é filtrado pelo isError() e não conta como erro
+ assertDoesNotThrow(() ->
+ validar.error(new SAXParseException("cvc-enumeration-valid: valor invalido", null)));
+ }
+
+ @Test
+ void error_comMensagemIgnorada_pattern_naoLancaExcecao() {
+ assertDoesNotThrow(() ->
+ validar.error(new SAXParseException("cvc-pattern-valid: padrao invalido", null)));
+ }
+
+ @Test
+ void error_comMensagemIgnorada_maxLength_naoLancaExcecao() {
+ assertDoesNotThrow(() ->
+ validar.error(new SAXParseException("cvc-maxLength-valid: tamanho excedido", null)));
+ }
+
+ @Test
+ void error_comMensagemIgnorada_datatype_naoLancaExcecao() {
+ assertDoesNotThrow(() ->
+ validar.error(new SAXParseException("cvc-datatype-valid: tipo invalido", null)));
+ }
+
+ @Test
+ void fatalError_naoLancaExcecao() {
+ assertDoesNotThrow(() ->
+ validar.fatalError(new SAXParseException("erro fatal de parse", null)));
+ }
+
+ @Test
+ void warning_naoLancaExcecao() {
+ assertDoesNotThrow(() ->
+ validar.warning(new SAXParseException("aviso de validacao", null)));
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/exemplos/EventoGenericoTeste.java b/src/test/java/br/com/swconsultoria/nfe/exemplos/EventoGenericoTeste.java
index b269bb34..eb2877eb 100644
--- a/src/test/java/br/com/swconsultoria/nfe/exemplos/EventoGenericoTeste.java
+++ b/src/test/java/br/com/swconsultoria/nfe/exemplos/EventoGenericoTeste.java
@@ -44,7 +44,7 @@ public static void main(String[] args) {
detEvento.setDescEvento("Informação de efetivo pagamento integral para liberar crédito presumido do adquirente");
detEvento.setCOrgaoAutor(config.getEstado().getCodigoUF());
detEvento.setTpAutor("1");
- detEvento.setVerAplic("v4.00.49");
+ detEvento.setVerAplic("v4.00.51");
detEvento.setIndQuitacao("1");
generico.setDetEvento(detEvento);
diff --git a/src/test/java/br/com/swconsultoria/nfe/exemplos/IbsCbsTeste.java b/src/test/java/br/com/swconsultoria/nfe/exemplos/IbsCbsTest.java
similarity index 89%
rename from src/test/java/br/com/swconsultoria/nfe/exemplos/IbsCbsTeste.java
rename to src/test/java/br/com/swconsultoria/nfe/exemplos/IbsCbsTest.java
index aa8c021d..41db4832 100644
--- a/src/test/java/br/com/swconsultoria/nfe/exemplos/IbsCbsTeste.java
+++ b/src/test/java/br/com/swconsultoria/nfe/exemplos/IbsCbsTest.java
@@ -1,5 +1,7 @@
package br.com.swconsultoria.nfe.exemplos;
+import br.com.swconsultoria.certificado.Certificado;
+import br.com.swconsultoria.certificado.CertificadoService;
import br.com.swconsultoria.nfe.Nfe;
import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
@@ -19,13 +21,16 @@
import javax.xml.namespace.QName;
import java.io.IOException;
import java.math.BigDecimal;
+import java.net.URI;
+import java.nio.file.Paths;
+import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Samuel Oliveira
*/
-class IbsCbsTeste {
+class IbsCbsTest {
@Test
void testeIbsCbs() throws Exception {
@@ -125,7 +130,7 @@ private static TEnviNFe addTotaisIbsCbs(IbsCbsUtil ibsCbsUtil, TEnviNFe enviNFe,
TIBSCBSMonoTot totaisIbsCsb = ibsCbsUtil.preencheTotaisIbsCsb();
enviNFe.getNFe().get(0).getInfNFe().getTotal().setIBSCBSTot(totaisIbsCsb);
- return Nfe.montaNfe(config, enviNFe, true);
+ return Nfe.montaNfe(config, enviNFe, false);
}
private static String getIbsCbsJson() throws IOException {
@@ -138,7 +143,11 @@ private static TEnviNFe getEnviNFe() throws IOException {
}
private static ConfiguracoesNfe getConfiguracoesNfe() throws Exception {
- return ConfiguracaoTeste.iniciaConfiguracoes(EstadosEnum.GO, AmbienteEnum.HOMOLOGACAO);
+ URI uri = Objects.requireNonNull(IbsCbsTest.class.getClassLoader()
+ .getResource("NAO_UTILIZE.pfx"))
+ .toURI();
+ Certificado certificado = CertificadoService.certificadoPfx(Paths.get(uri).toString(), "123456");
+ return ConfiguracoesNfe.criarConfiguracoes(EstadosEnum.GO, AmbienteEnum.HOMOLOGACAO, certificado, null);
}
}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/CancelamentoSubstituicaoUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/CancelamentoSubstituicaoUtilTest.java
new file mode 100644
index 00000000..4d79699b
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/CancelamentoSubstituicaoUtilTest.java
@@ -0,0 +1,118 @@
+package br.com.swconsultoria.nfe.util;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EventosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envEventoCancSubst.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envEventoCancSubst.TEvento;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CancelamentoSubstituicaoUtilTest {
+
+ private static final String CHAVE = "52230309158456000159550010000731791567812345";
+ private static final String CHAVE_SUBST = "52230309158456000159550010000731801234567890";
+ private static final String CNPJ = "09158456000159";
+ private static final String PROTOCOLO = "352230000123456";
+ private static final String MOTIVO = "Cancelamento por substituicao de NF-e";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.GO);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setZoneId(ZoneId.of("America/Sao_Paulo"));
+ }
+
+ private Evento novoEvento() {
+ Evento e = new Evento();
+ e.setChave(CHAVE);
+ e.setCnpj(CNPJ);
+ e.setProtocolo(PROTOCOLO);
+ e.setMotivo(MOTIVO);
+ e.setChaveSusbstituta(CHAVE_SUBST);
+ e.setDataEvento(LocalDateTime.of(2024, 1, 20, 11, 0, 0));
+ return e;
+ }
+
+ @Test
+ void montaCancelamento_retornaTEnvEvento() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ assertNotNull(resultado);
+ assertEquals(1, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaCancelamento_tpEvento_ehCancelamentoSubstituicao() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ TEvento.InfEvento info = resultado.getEvento().get(0).getInfEvento();
+ assertEquals(EventosEnum.CANCELAMENTO_SUBSTITUICAO.getCodigo(), info.getTpEvento());
+ }
+
+ @Test
+ void montaCancelamento_idComecaComID() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ assertTrue(resultado.getEvento().get(0).getInfEvento().getId().startsWith("ID"));
+ }
+
+ @Test
+ void montaCancelamento_chaveNFe_preenchida() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(CHAVE, resultado.getEvento().get(0).getInfEvento().getChNFe());
+ }
+
+ @Test
+ void montaCancelamento_chaveSubstituta_preenchida() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(CHAVE_SUBST, resultado.getEvento().get(0).getInfEvento().getDetEvento().getChNFeRef());
+ }
+
+ @Test
+ void montaCancelamento_protocolo_preenchido() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(PROTOCOLO, resultado.getEvento().get(0).getInfEvento().getDetEvento().getNProt());
+ }
+
+ @Test
+ void montaCancelamento_justificativa_preenchida() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(MOTIVO, resultado.getEvento().get(0).getInfEvento().getDetEvento().getXJust());
+ }
+
+ @Test
+ void montaCancelamento_descEvento_cancelamentoPorSubstituicao() throws NfeException {
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals("Cancelamento por substituicao",
+ resultado.getEvento().get(0).getInfEvento().getDetEvento().getDescEvento());
+ }
+
+ @Test
+ void montaCancelamento_lote_retornaMultiplosEventos() throws NfeException {
+ List lista = new ArrayList<>();
+ lista.add(novoEvento());
+ lista.add(novoEvento());
+
+ TEnvEvento resultado = CancelamentoSubstituicaoUtil.montaCancelamento(lista, config);
+ assertEquals(2, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaCancelamento_loteAcimaDe20_lancaExcecao() {
+ List lista = new ArrayList<>();
+ for (int i = 0; i < 21; i++) lista.add(novoEvento());
+
+ assertThrows(NfeException.class, () -> CancelamentoSubstituicaoUtil.montaCancelamento(lista, config));
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/CancelamentoUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/CancelamentoUtilTest.java
new file mode 100644
index 00000000..fc19c635
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/CancelamentoUtilTest.java
@@ -0,0 +1,111 @@
+package br.com.swconsultoria.nfe.util;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EventosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envEventoCancNFe.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envEventoCancNFe.TEvento;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CancelamentoUtilTest {
+
+ private static final String CHAVE = "52230309158456000159550010000731791567812345";
+ private static final String CNPJ = "09158456000159";
+ private static final String PROTOCOLO = "352230000123456";
+ private static final String MOTIVO = "Cancelamento por erro na emissao";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.GO);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setZoneId(ZoneId.of("America/Sao_Paulo"));
+ }
+
+ private Evento novoEvento() {
+ Evento e = new Evento();
+ e.setChave(CHAVE);
+ e.setCnpj(CNPJ);
+ e.setProtocolo(PROTOCOLO);
+ e.setMotivo(MOTIVO);
+ e.setDataEvento(LocalDateTime.of(2024, 1, 15, 10, 0, 0));
+ return e;
+ }
+
+ @Test
+ void montaCancelamento_unico_retornaTEnvEvento() throws NfeException {
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(novoEvento(), config);
+ assertNotNull(resultado);
+ assertEquals(1, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaCancelamento_tpEvento_ehCancelamento() throws NfeException {
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(novoEvento(), config);
+ TEvento.InfEvento info = resultado.getEvento().get(0).getInfEvento();
+ assertEquals(EventosEnum.CANCELAMENTO.getCodigo(), info.getTpEvento());
+ }
+
+ @Test
+ void montaCancelamento_chaveNFe_preenchida() throws NfeException {
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(CHAVE, resultado.getEvento().get(0).getInfEvento().getChNFe());
+ }
+
+ @Test
+ void montaCancelamento_idComecaComID() throws NfeException {
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(novoEvento(), config);
+ String id = resultado.getEvento().get(0).getInfEvento().getId();
+ assertTrue(id.startsWith("ID"));
+ }
+
+ @Test
+ void montaCancelamento_protocolo_preenchido() throws NfeException {
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(PROTOCOLO, resultado.getEvento().get(0).getInfEvento().getDetEvento().getNProt());
+ }
+
+ @Test
+ void montaCancelamento_justificativa_preenchida() throws NfeException {
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(MOTIVO, resultado.getEvento().get(0).getInfEvento().getDetEvento().getXJust());
+ }
+
+ @Test
+ void montaCancelamento_lote_retornaMultiplosEventos() throws NfeException {
+ List lista = new ArrayList<>();
+ lista.add(novoEvento());
+ lista.add(novoEvento());
+
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(lista, config);
+ assertEquals(2, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaCancelamento_loteAcimaDe20_lancaExcecao() {
+ List lista = new ArrayList<>();
+ for (int i = 0; i < 21; i++) lista.add(novoEvento());
+
+ assertThrows(NfeException.class, () -> CancelamentoUtil.montaCancelamento(lista, config));
+ }
+
+ @Test
+ void montaCancelamento_ambienteHomologacao_preenchido() throws NfeException {
+ TEnvEvento resultado = CancelamentoUtil.montaCancelamento(novoEvento(), config);
+ assertEquals(AmbienteEnum.HOMOLOGACAO.getCodigo(),
+ resultado.getEvento().get(0).getInfEvento().getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/CartaCorrecaoUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/CartaCorrecaoUtilTest.java
new file mode 100644
index 00000000..6bdc32f9
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/CartaCorrecaoUtilTest.java
@@ -0,0 +1,103 @@
+package br.com.swconsultoria.nfe.util;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EventosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envcce.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envcce.TEvento;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CartaCorrecaoUtilTest {
+
+ private static final String CHAVE = "52230309158456000159550010000731791567812345";
+ private static final String CNPJ = "09158456000159";
+ private static final String CORRECAO = "Correcao no campo de endereco do destinatario";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.GO);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setZoneId(ZoneId.of("America/Sao_Paulo"));
+ }
+
+ private Evento novoCCe() {
+ Evento e = new Evento();
+ e.setChave(CHAVE);
+ e.setCnpj(CNPJ);
+ e.setMotivo(CORRECAO);
+ e.setSequencia(1);
+ e.setDataEvento(LocalDateTime.of(2024, 3, 10, 9, 0, 0));
+ return e;
+ }
+
+ @Test
+ void montaCCe_unico_retornaTEnvEvento() throws NfeException {
+ TEnvEvento resultado = CartaCorrecaoUtil.montaCCe(novoCCe(), config);
+ assertNotNull(resultado);
+ assertEquals(1, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaCCe_tpEvento_ehCCe() throws NfeException {
+ TEnvEvento resultado = CartaCorrecaoUtil.montaCCe(novoCCe(), config);
+ TEvento.InfEvento info = resultado.getEvento().get(0).getInfEvento();
+ assertEquals(EventosEnum.CCE.getCodigo(), info.getTpEvento());
+ }
+
+ @Test
+ void montaCCe_chaveNFe_preenchida() throws NfeException {
+ TEnvEvento resultado = CartaCorrecaoUtil.montaCCe(novoCCe(), config);
+ assertEquals(CHAVE, resultado.getEvento().get(0).getInfEvento().getChNFe());
+ }
+
+ @Test
+ void montaCCe_correcao_preenchida() throws NfeException {
+ TEnvEvento resultado = CartaCorrecaoUtil.montaCCe(novoCCe(), config);
+ assertEquals(CORRECAO, resultado.getEvento().get(0).getInfEvento().getDetEvento().getXCorrecao());
+ }
+
+ @Test
+ void montaCCe_descEvento_cartaDeCorrecao() throws NfeException {
+ TEnvEvento resultado = CartaCorrecaoUtil.montaCCe(novoCCe(), config);
+ assertEquals("Carta de Correcao",
+ resultado.getEvento().get(0).getInfEvento().getDetEvento().getDescEvento());
+ }
+
+ @Test
+ void montaCCe_lote_retornaMultiplosEventos() throws NfeException {
+ List lista = new ArrayList<>();
+ lista.add(novoCCe());
+ lista.add(novoCCe());
+
+ TEnvEvento resultado = CartaCorrecaoUtil.montaCCe(lista, config);
+ assertEquals(2, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaCCe_loteAcimaDe20_lancaExcecao() {
+ List lista = new ArrayList<>();
+ for (int i = 0; i < 21; i++) lista.add(novoCCe());
+
+ assertThrows(NfeException.class, () -> CartaCorrecaoUtil.montaCCe(lista, config));
+ }
+
+ @Test
+ void montaCCe_idComecaComID() throws NfeException {
+ TEnvEvento resultado = CartaCorrecaoUtil.montaCCe(novoCCe(), config);
+ assertTrue(resultado.getEvento().get(0).getInfEvento().getId().startsWith("ID"));
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/ChaveUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/ChaveUtilTest.java
new file mode 100644
index 00000000..b4149170
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/ChaveUtilTest.java
@@ -0,0 +1,100 @@
+package br.com.swconsultoria.nfe.util;
+
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ChaveUtilTest {
+
+ private static final String CNPJ = "10732644000128";
+ private static final String MODELO_NFE = "55";
+ private static final String TIPO_EMISSAO = "1";
+ private static final LocalDateTime DATA_EMISSAO = LocalDateTime.of(2024, 3, 15, 10, 30, 0);
+
+ // -------------------------------------------------------------------------
+ // completarComZerosAEsquerda
+ // -------------------------------------------------------------------------
+
+ @Test
+ void completarComZerosAEsquerda_stringMenorQueAlvo_adicionaZeros() {
+ assertEquals("00042", ChaveUtil.completarComZerosAEsquerda("42", 5));
+ }
+
+ @Test
+ void completarComZerosAEsquerda_stringExataAoTamanho_naoAltera() {
+ assertEquals("12345", ChaveUtil.completarComZerosAEsquerda("12345", 5));
+ }
+
+ @Test
+ void completarComZerosAEsquerda_stringMaiorQueAlvo_naoAltera() {
+ assertEquals("123456", ChaveUtil.completarComZerosAEsquerda("123456", 3));
+ }
+
+ @Test
+ void completarComZerosAEsquerda_stringVazia_retornaSoZeros() {
+ assertEquals("000", ChaveUtil.completarComZerosAEsquerda("", 3));
+ }
+
+ @Test
+ void completarComZerosAEsquerda_tamanhoUm_retornaUmDigito() {
+ assertEquals("5", ChaveUtil.completarComZerosAEsquerda("5", 1));
+ }
+
+ // -------------------------------------------------------------------------
+ // getChaveNF
+ // -------------------------------------------------------------------------
+
+ @Test
+ void getChaveNF_retornaChaveComPrefixoNFe() {
+ ChaveUtil chave = new ChaveUtil(EstadosEnum.GO, CNPJ, MODELO_NFE, 1, 1, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ assertTrue(chave.getChaveNF().startsWith("NFe"));
+ }
+
+ @Test
+ void getChaveNF_retornaTamanhoCorreto() {
+ // "NFe" (3) + 43 dígitos da chave + 1 dígito verificador = 47 chars
+ ChaveUtil chave = new ChaveUtil(EstadosEnum.SP, CNPJ, MODELO_NFE, 1, 92756, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ assertEquals(47, chave.getChaveNF().length());
+ }
+
+ @Test
+ void getChaveNF_conteudoNaoNulo() {
+ ChaveUtil chave = new ChaveUtil(EstadosEnum.MG, CNPJ, MODELO_NFE, 1, 1, TIPO_EMISSAO, "00000001", DATA_EMISSAO);
+ assertNotNull(chave.getChaveNF());
+ }
+
+ // -------------------------------------------------------------------------
+ // getDigitoVerificador
+ // -------------------------------------------------------------------------
+
+ @Test
+ void getDigitoVerificador_retornaUmDigito() {
+ ChaveUtil chave = new ChaveUtil(EstadosEnum.GO, CNPJ, MODELO_NFE, 1, 1, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ assertEquals(1, chave.getDigitoVerificador().length());
+ }
+
+ @Test
+ void getDigitoVerificador_consistenteComChave() {
+ ChaveUtil chave = new ChaveUtil(EstadosEnum.GO, CNPJ, MODELO_NFE, 1, 1, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ String chaveCompleta = chave.getChaveNF(); // "NFe" + 43 dígitos + dv
+ String dvDaChave = chaveCompleta.substring(chaveCompleta.length() - 1);
+ assertEquals(dvDaChave, chave.getDigitoVerificador());
+ }
+
+ @Test
+ void getDigitoVerificador_diferentes_numerosNfe_geramChavesDiferentes() {
+ ChaveUtil chave1 = new ChaveUtil(EstadosEnum.GO, CNPJ, MODELO_NFE, 1, 100, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ ChaveUtil chave2 = new ChaveUtil(EstadosEnum.GO, CNPJ, MODELO_NFE, 1, 200, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ assertNotEquals(chave1.getChaveNF(), chave2.getChaveNF());
+ }
+
+ @Test
+ void getDigitoVerificador_diferentesEstados_geramChavesDiferentes() {
+ ChaveUtil chaveGO = new ChaveUtil(EstadosEnum.GO, CNPJ, MODELO_NFE, 1, 1, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ ChaveUtil chaveSP = new ChaveUtil(EstadosEnum.SP, CNPJ, MODELO_NFE, 1, 1, TIPO_EMISSAO, "12345678", DATA_EMISSAO);
+ assertNotEquals(chaveGO.getChaveNF(), chaveSP.getChaveNF());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/EpecUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/EpecUtilTest.java
new file mode 100644
index 00000000..5fe7fe21
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/EpecUtilTest.java
@@ -0,0 +1,111 @@
+package br.com.swconsultoria.nfe.util;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.EventoEpec;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EventosEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envEpec.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envEpec.TEvento;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class EpecUtilTest {
+
+ private static final String CHAVE = "52230309158456000159550010000731791567812345";
+ private static final String CNPJ = "09158456000159";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.GO);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setZoneId(ZoneId.of("America/Sao_Paulo"));
+ }
+
+ private Evento novoEpec() {
+ EventoEpec epecDetalhe = new EventoEpec();
+ epecDetalhe.setTipoNF("1");
+ epecDetalhe.setIeEmitente("104282215");
+ epecDetalhe.setEstadoDestinatario(EstadosEnum.SP);
+ epecDetalhe.setCnpjDestinatario("08944957000360");
+ epecDetalhe.setvNF("1000.00");
+ epecDetalhe.setvICMS("0.00");
+ epecDetalhe.setvST("0.00");
+
+ Evento e = new Evento();
+ e.setChave(CHAVE);
+ e.setCnpj(CNPJ);
+ e.setDataEvento(LocalDateTime.of(2024, 2, 28, 15, 30, 0));
+ e.setEventoEpec(epecDetalhe);
+ return e;
+ }
+
+ @Test
+ void montaEpec_unico_retornaTEnvEvento() throws NfeException {
+ TEnvEvento resultado = EpecUtil.montaEpec(novoEpec(), config);
+ assertNotNull(resultado);
+ assertEquals(1, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaEpec_tpEvento_ehEpec() throws NfeException {
+ TEnvEvento resultado = EpecUtil.montaEpec(novoEpec(), config);
+ TEvento.InfEvento info = resultado.getEvento().get(0).getInfEvento();
+ assertEquals(EventosEnum.EPEC.getCodigo(), info.getTpEvento());
+ }
+
+ @Test
+ void montaEpec_chaveNFe_preenchida() throws NfeException {
+ TEnvEvento resultado = EpecUtil.montaEpec(novoEpec(), config);
+ assertEquals(CHAVE, resultado.getEvento().get(0).getInfEvento().getChNFe());
+ }
+
+ @Test
+ void montaEpec_idComecaComID() throws NfeException {
+ TEnvEvento resultado = EpecUtil.montaEpec(novoEpec(), config);
+ assertTrue(resultado.getEvento().get(0).getInfEvento().getId().startsWith("ID"));
+ }
+
+ @Test
+ void montaEpec_descEvento_epec() throws NfeException {
+ TEnvEvento resultado = EpecUtil.montaEpec(novoEpec(), config);
+ assertEquals("EPEC", resultado.getEvento().get(0).getInfEvento().getDetEvento().getDescEvento());
+ }
+
+ @Test
+ void montaEpec_lote_retornaMultiplosEventos() throws NfeException {
+ List lista = new ArrayList<>();
+ lista.add(novoEpec());
+ lista.add(novoEpec());
+
+ TEnvEvento resultado = EpecUtil.montaEpec(lista, config);
+ assertEquals(2, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaEpec_loteAcimaDe20_lancaExcecao() {
+ List lista = new ArrayList<>();
+ for (int i = 0; i < 21; i++) lista.add(novoEpec());
+
+ assertThrows(NfeException.class, () -> EpecUtil.montaEpec(lista, config));
+ }
+
+ @Test
+ void montaEpec_ambiente_preenchido() throws NfeException {
+ TEnvEvento resultado = EpecUtil.montaEpec(novoEpec(), config);
+ assertEquals(AmbienteEnum.HOMOLOGACAO.getCodigo(),
+ resultado.getEvento().get(0).getInfEvento().getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/InutilizacaoUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/InutilizacaoUtilTest.java
new file mode 100644
index 00000000..7a1ac238
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/InutilizacaoUtilTest.java
@@ -0,0 +1,100 @@
+package br.com.swconsultoria.nfe.util;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.DocumentoEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.schema_4.inutNFe.TInutNFe;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class InutilizacaoUtilTest {
+
+ private static final String CNPJ = "09158456000159";
+ private static final String JUSTIFICATIVA = "Numero de NF-e inutilizado por falha de sistema";
+
+ private ConfiguracoesNfe config;
+ private final LocalDateTime dataInut = LocalDateTime.of(2024, 5, 20, 8, 0, 0);
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.GO);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setZoneId(ZoneId.of("America/Sao_Paulo"));
+ }
+
+ @Test
+ void montaInutilizacao_retornaTInutNFe() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 1, 100, 110, JUSTIFICATIVA, dataInut, config);
+
+ assertNotNull(resultado);
+ assertNotNull(resultado.getInfInut());
+ }
+
+ @Test
+ void montaInutilizacao_id_comecaComID() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 1, 100, 110, JUSTIFICATIVA, dataInut, config);
+
+ assertTrue(resultado.getInfInut().getId().startsWith("ID"));
+ }
+
+ @Test
+ void montaInutilizacao_serieFormatada3digitos() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 5, 1, 1, JUSTIFICATIVA, dataInut, config);
+
+ // ID contains zero-padded serie
+ String id = resultado.getInfInut().getId();
+ assertTrue(id.contains("005"), "ID deve conter serie com 3 digitos: " + id);
+ }
+
+ @Test
+ void montaInutilizacao_numeroFormatado9digitos() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 1, 42, 50, JUSTIFICATIVA, dataInut, config);
+
+ String id = resultado.getInfInut().getId();
+ assertTrue(id.contains("000000042"), "ID deve conter nNFIni com 9 digitos: " + id);
+ assertTrue(id.contains("000000050"), "ID deve conter nNFFin com 9 digitos: " + id);
+ }
+
+ @Test
+ void montaInutilizacao_justificativa_preenchida() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 1, 1, 1, JUSTIFICATIVA, dataInut, config);
+
+ assertEquals(JUSTIFICATIVA, resultado.getInfInut().getXJust());
+ }
+
+ @Test
+ void montaInutilizacao_cnpj_preenchido() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 1, 1, 1, JUSTIFICATIVA, dataInut, config);
+
+ assertEquals(CNPJ, resultado.getInfInut().getCNPJ());
+ }
+
+ @Test
+ void montaInutilizacao_xServ_inutilizar() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 1, 1, 1, JUSTIFICATIVA, dataInut, config);
+
+ assertEquals("INUTILIZAR", resultado.getInfInut().getXServ());
+ }
+
+ @Test
+ void montaInutilizacao_ambiente_homologacao() {
+ TInutNFe resultado = InutilizacaoUtil.montaInutilizacao(
+ DocumentoEnum.NFE, CNPJ, 1, 1, 1, JUSTIFICATIVA, dataInut, config);
+
+ assertEquals(AmbienteEnum.HOMOLOGACAO.getCodigo(), resultado.getInfInut().getTpAmb());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/ManifestacaoUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/ManifestacaoUtilTest.java
new file mode 100644
index 00000000..5a3a539a
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/ManifestacaoUtilTest.java
@@ -0,0 +1,122 @@
+package br.com.swconsultoria.nfe.util;
+
+import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
+import br.com.swconsultoria.nfe.dom.Evento;
+import br.com.swconsultoria.nfe.dom.enuns.AmbienteEnum;
+import br.com.swconsultoria.nfe.dom.enuns.EstadosEnum;
+import br.com.swconsultoria.nfe.dom.enuns.ManifestacaoEnum;
+import br.com.swconsultoria.nfe.exception.NfeException;
+import br.com.swconsultoria.nfe.schema.envConfRecebto.TEnvEvento;
+import br.com.swconsultoria.nfe.schema.envConfRecebto.TEvento;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ManifestacaoUtilTest {
+
+ private static final String CHAVE = "52230309158456000159550010000731791567812345";
+ private static final String CNPJ = "09158456000159";
+
+ private ConfiguracoesNfe config;
+
+ @BeforeEach
+ void setUp() {
+ config = new ConfiguracoesNfe();
+ config.setEstado(EstadosEnum.GO);
+ config.setAmbiente(AmbienteEnum.HOMOLOGACAO);
+ config.setZoneId(ZoneId.of("America/Sao_Paulo"));
+ }
+
+ private Evento novoEvento(ManifestacaoEnum tipo) {
+ Evento e = new Evento();
+ e.setChave(CHAVE);
+ e.setCnpj(CNPJ);
+ e.setTipoManifestacao(tipo);
+ e.setSequencia(1);
+ e.setDataEvento(LocalDateTime.of(2024, 4, 1, 12, 0, 0));
+ return e;
+ }
+
+ @Test
+ void montaManifestacao_confirmacao_retornaTEnvEvento() throws NfeException {
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(
+ novoEvento(ManifestacaoEnum.CONFIRMACAO_DA_OPERACAO), config);
+ assertNotNull(resultado);
+ assertEquals(1, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaManifestacao_tpEvento_confirmacao() throws NfeException {
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(
+ novoEvento(ManifestacaoEnum.CONFIRMACAO_DA_OPERACAO), config);
+ TEvento.InfEvento info = resultado.getEvento().get(0).getInfEvento();
+ assertEquals(ManifestacaoEnum.CONFIRMACAO_DA_OPERACAO.getCodigo(), info.getTpEvento());
+ }
+
+ @Test
+ void montaManifestacao_ciencia_tpEvento() throws NfeException {
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(
+ novoEvento(ManifestacaoEnum.CIENCIA_DA_OPERACAO), config);
+ assertEquals(ManifestacaoEnum.CIENCIA_DA_OPERACAO.getCodigo(),
+ resultado.getEvento().get(0).getInfEvento().getTpEvento());
+ }
+
+ @Test
+ void montaManifestacao_desconhecimento_tpEvento() throws NfeException {
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(
+ novoEvento(ManifestacaoEnum.DESCONHECIMENTO_DA_OPERACAO), config);
+ assertEquals(ManifestacaoEnum.DESCONHECIMENTO_DA_OPERACAO.getCodigo(),
+ resultado.getEvento().get(0).getInfEvento().getTpEvento());
+ }
+
+ @Test
+ void montaManifestacao_operacaoNaoRealizada_comJustificativa() throws NfeException {
+ Evento e = novoEvento(ManifestacaoEnum.OPERACAO_NAO_REALIZADA);
+ e.setMotivo("Mercadoria nao recebida");
+
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(e, config);
+ TEvento.InfEvento.DetEvento det = resultado.getEvento().get(0).getInfEvento().getDetEvento();
+ assertEquals("Mercadoria nao recebida", det.getXJust());
+ }
+
+ @Test
+ void montaManifestacao_sequenciaZero_usaUm() throws NfeException {
+ Evento e = novoEvento(ManifestacaoEnum.CONFIRMACAO_DA_OPERACAO);
+ e.setSequencia(0); // deve ser corrigido para 1
+
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(e, config);
+ assertEquals("1", resultado.getEvento().get(0).getInfEvento().getNSeqEvento());
+ }
+
+ @Test
+ void montaManifestacao_lote_retornaMultiplosEventos() throws NfeException {
+ List lista = new ArrayList<>();
+ lista.add(novoEvento(ManifestacaoEnum.CONFIRMACAO_DA_OPERACAO));
+ lista.add(novoEvento(ManifestacaoEnum.CIENCIA_DA_OPERACAO));
+
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(lista, config);
+ assertEquals(2, resultado.getEvento().size());
+ }
+
+ @Test
+ void montaManifestacao_loteAcimaDe20_lancaExcecao() {
+ List lista = new ArrayList<>();
+ for (int i = 0; i < 21; i++)
+ lista.add(novoEvento(ManifestacaoEnum.CIENCIA_DA_OPERACAO));
+
+ assertThrows(NfeException.class, () -> ManifestacaoUtil.montaManifestacao(lista, config));
+ }
+
+ @Test
+ void montaManifestacao_chaveNFe_preenchida() throws NfeException {
+ TEnvEvento resultado = ManifestacaoUtil.montaManifestacao(
+ novoEvento(ManifestacaoEnum.CONFIRMACAO_DA_OPERACAO), config);
+ assertEquals(CHAVE, resultado.getEvento().get(0).getInfEvento().getChNFe());
+ }
+}
diff --git a/src/test/java/br/com/swconsultoria/nfe/util/ObjetoUtilTest.java b/src/test/java/br/com/swconsultoria/nfe/util/ObjetoUtilTest.java
new file mode 100644
index 00000000..9d007faa
--- /dev/null
+++ b/src/test/java/br/com/swconsultoria/nfe/util/ObjetoUtilTest.java
@@ -0,0 +1,157 @@
+package br.com.swconsultoria.nfe.util;
+
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ObjetoUtilTest {
+
+ // -------------------------------------------------------------------------
+ // verifica(T)
+ // -------------------------------------------------------------------------
+
+ @Test
+ void verifica_null_retornaVazio() {
+ Optional