Browse Source

Migração para python 3 - Correção de testes

pull/65/head
Danimar Ribeiro 8 years ago
parent
commit
5c5602acf9
  1. 3
      .travis.yml
  2. 4
      pytrustnfe/Servidores.py
  3. 8
      pytrustnfe/__init__.py
  4. 4
      pytrustnfe/certificado.py
  5. 4
      pytrustnfe/client.py
  6. 14
      pytrustnfe/nfe/__init__.py
  7. 4
      pytrustnfe/nfe/assinatura.py
  8. 1
      pytrustnfe/nfe/comunicacao.py
  9. 1658
      pytrustnfe/nfe/danfe.py
  10. 90
      pytrustnfe/nfse/assinatura.py
  11. 2
      pytrustnfe/nfse/betha/__init__.py
  12. 2
      pytrustnfe/nfse/ginfes/__init__.py
  13. 9
      pytrustnfe/nfse/paulistana/__init__.py
  14. 2
      pytrustnfe/nfse/susesu/__init__.py
  15. 1
      pytrustnfe/test/XMLs/paulistana_canc_errado.xml
  16. 1
      pytrustnfe/test/XMLs/paulistana_canc_ok.xml
  17. 2
      pytrustnfe/test/XMLs/paulistana_resultado.xml
  18. 16
      pytrustnfe/test/XMLs/paulistana_signature.xml
  19. 2
      pytrustnfe/test/test_add_qr_code.py
  20. 12
      pytrustnfe/test/test_assinatura.py
  21. 8
      pytrustnfe/test/test_certificado.py
  22. 2
      pytrustnfe/test/test_consulta_cadastro.py
  23. 2
      pytrustnfe/test/test_danfe.py
  24. 2
      pytrustnfe/test/test_ginfes.py
  25. 8
      pytrustnfe/test/test_nfse_paulistana.py
  26. 16
      pytrustnfe/test/test_utils.py
  27. 4
      pytrustnfe/test/test_xml.py
  28. 6
      pytrustnfe/test/test_xml_serializacao.py
  29. 6
      pytrustnfe/test/xml_com_qrcode.xml
  30. 6
      pytrustnfe/test/xml_sem_qrcode.xml
  31. 10
      pytrustnfe/xml/__init__.py
  32. 18
      pytrustnfe/xml/filters.py
  33. 2
      requirements.txt

3
.travis.yml

@ -8,7 +8,8 @@ virtual_env:
install:
- pip install --upgrade pip
- pip install -r requirements.txt
script: coverage run --source=pytrustnfe setup.py nosetests
script:
pytest --cov=pytrustnfe
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq python-dev libffi-dev libxml2-dev libxslt1-dev libssl-dev

4
pytrustnfe/Servidores.py

@ -37,8 +37,8 @@ NFE_AMBIENTE_HOMOLOGACAO = 2
NFCE_AMBIENTE_PRODUCAO = 1
NFCE_AMBIENTE_HOMOLOGACAO = 2
NFE_MODELO = u'55'
NFCE_MODELO = u'65'
NFE_MODELO = '55'
NFCE_MODELO = '65'
SIGLA_ESTADO = {
'12': 'AC',

8
pytrustnfe/__init__.py

@ -12,10 +12,10 @@ class HttpClient(object):
def _headers(self, action):
return {
u'Content-type':
u'text/xml; charset=utf-8;',
u'Accept': u'application/soap+xml; charset=utf-8',
u'SOAPAction': action
'Content-type':
'text/xml; charset=utf-8;',
'Accept': 'application/soap+xml; charset=utf-8',
'SOAPAction': action
}
def post_soap(self, xml_soap, action):

4
pytrustnfe/certificado.py

@ -14,7 +14,7 @@ class Certificado(object):
def save_pfx(self):
pfx_temp = '/tmp/' + uuid4().hex
arq_temp = open(pfx_temp, 'w')
arq_temp = open(pfx_temp, 'wb')
arq_temp.write(self.pfx)
arq_temp.close()
return pfx_temp
@ -28,7 +28,7 @@ def extract_cert_and_key_from_pfx(pfx, password):
# PEM formatted certificate
cert = crypto.dump_certificate(crypto.FILETYPE_PEM,
pfx.get_certificate())
return cert, key
return cert.decode(), key.decode()
def save_cert_key(cert, key):

4
pytrustnfe/client.py

@ -44,8 +44,8 @@ class HttpClient(object):
def _headers(self, action):
return {
u'Content-type': u'application/soap+xml; charset=utf-8; action="http://www.portalfiscal.inf.br/nfe/wsdl/%s"' % action,
u'Accept': u'application/soap+xml; charset=utf-8',
'Content-type': 'application/soap+xml; charset=utf-8; action="http://www.portalfiscal.inf.br/nfe/wsdl/%s"' % action,
'Accept': 'application/soap+xml; charset=utf-8',
}
def post_soap(self, xml_soap, cabecalho):

14
pytrustnfe/nfe/__init__.py

@ -5,6 +5,7 @@
import os
import hashlib
import binascii
from lxml import etree
from .comunicacao import executar_consulta
from .assinatura import Assinatura
@ -80,7 +81,7 @@ def _add_qrCode(xml, **kwargs):
infnfesupl = etree.Element('infNFeSupl')
qrcode = etree.Element('qrCode')
chave_nfe = inf_nfe['Id'][3:]
dh_emissao = inf_nfe['ide']['dhEmi'].encode('hex')
dh_emissao = binascii.hexlify(inf_nfe['ide']['dhEmi'].encode()).decode()
versao = '100'
ambiente = kwargs['ambiente']
valor_total = inf_nfe['total']['vNF']
@ -98,9 +99,8 @@ def _add_qrCode(xml, **kwargs):
dest.append(cpf)
dest_parent.append(dest)
icms_total = inf_nfe['total']['vICMS']
dig_val = xml.find(
".//{http://www.w3.org/2000/09/xmldsig#}DigestValue")\
.text.encode('hex')
dig_val = binascii.hexlify(xml.find(
".//{http://www.w3.org/2000/09/xmldsig#}DigestValue").text.encode()).decode()
cid_token = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['cid_token']
csc = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['csc']
@ -108,7 +108,7 @@ def _add_qrCode(xml, **kwargs):
={5}&vICMS={6}&digVal={7}&cIdToken={8}{9}".\
format(chave_nfe, versao, ambiente, dest_cpf, dh_emissao,
valor_total, icms_total, dig_val, cid_token, csc)
c_hash_QR_code = hashlib.sha1(c_hash_QR_code).hexdigest()
c_hash_QR_code = hashlib.sha1(c_hash_QR_code.encode()).hexdigest()
QR_code_url = "?chNFe={0}&nVersao={1}&tpAmb={2}&{3}dhEmi={4}&vNF={5}&vICMS\
={6}&digVal={7}&cIdToken={8}&cHashQRCode={9}".\
@ -121,7 +121,7 @@ def _add_qrCode(xml, **kwargs):
qrcode.text = etree.CDATA(qrcode_text)
infnfesupl.append(qrcode)
nfe.insert(1, infnfesupl)
return etree.tostring(xml)
return etree.tostring(xml, encoding=str)
def _send(certificado, method, sign, **kwargs):
@ -175,7 +175,7 @@ def _send(certificado, method, sign, **kwargs):
xml_send = _add_qrCode(xml_send, **kwargs)
else:
xml_send = etree.tostring(xmlElem_send)
xml_send = etree.tostring(xmlElem_send, encoding=str)
url = localizar_url(method, kwargs['estado'], modelo,
kwargs['ambiente'])

4
pytrustnfe/nfe/assinatura.py

@ -32,7 +32,7 @@ class Assinatura(object):
ref_uri = ('#%s' % reference) if reference else None
signed_root = signer.sign(
xml_element, key=key, cert=cert,
xml_element, key=key.encode(), cert=cert.encode(),
reference_uri=ref_uri)
if reference:
element_signed = signed_root.find(".//*[@Id='%s']" % reference)
@ -42,4 +42,4 @@ class Assinatura(object):
if element_signed is not None and signature is not None:
parent = element_signed.getparent()
parent.append(signature)
return etree.tostring(signed_root)
return etree.tostring(signed_root, encoding=str)

1
pytrustnfe/nfe/comunicacao.py

@ -10,6 +10,7 @@ from ..xml import sanitize_response
def _soap_xml(body, cabecalho):
print(type(body))
xml = '<?xml version="1.0" encoding="utf-8"?>'
xml += '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header>'
xml += '<nfeCabecMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/' + cabecalho.soap_action + '">'

1658
pytrustnfe/nfe/danfe.py
File diff suppressed because it is too large
View File

90
pytrustnfe/nfse/assinatura.py

@ -2,86 +2,52 @@
# © 2016 Danimar Ribeiro, Trustcode
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from lxml import etree
import xmlsec
import libxml2
import os.path
consts = xmlsec.constants
NAMESPACE_SIG = 'http://www.w3.org/2000/09/xmldsig#'
class Assinatura(object):
def __init__(self, arquivo, senha):
self.arquivo = arquivo
self.senha = senha
def __init__(self, cert_pem, private_key, password):
self.cert_pem = cert_pem
self.private_key = private_key
self.password = password
def _checar_certificado(self):
if not os.path.isfile(self.arquivo):
if not os.path.isfile(self.private_key):
raise Exception('Caminho do certificado não existe.')
def _inicializar_cripto(self):
libxml2.initParser()
libxml2.substituteEntitiesDefault(1)
xmlsec.init()
xmlsec.cryptoAppInit(None)
xmlsec.cryptoInit()
def _finalizar_cripto(self):
xmlsec.cryptoShutdown()
xmlsec.cryptoAppShutdown()
xmlsec.shutdown()
libxml2.cleanupParser()
def assina_xml(self, xml, reference):
self._checar_certificado()
self._inicializar_cripto()
try:
doc_xml = libxml2.parseMemory(
xml, len(xml))
signNode = xmlsec.TmplSignature(doc_xml,
xmlsec.transformInclC14NId(),
xmlsec.transformRsaSha1Id(), None)
doc_xml.getRootElement().addChild(signNode)
refNode = signNode.addReference(xmlsec.transformSha1Id(),
None, reference, None)
template = etree.fromstring(xml)
refNode.addTransform(xmlsec.transformEnvelopedId())
refNode.addTransform(xmlsec.transformInclC14NId())
keyInfoNode = signNode.ensureKeyInfo()
keyInfoNode.addX509Data()
key = xmlsec.Key.from_file(
self.private_key, format=xmlsec.constants.KeyDataFormatPem,
password=self.password)
dsig_ctx = xmlsec.DSigCtx()
chave = xmlsec.cryptoAppKeyLoad(filename=str(self.arquivo),
format=xmlsec.KeyDataFormatPkcs12,
pwd=str(self.senha),
pwdCallback=None,
pwdCallbackCtx=None)
signature_node = xmlsec.template.create(
template, c14n_method=consts.TransformInclC14N,
sign_method=consts.TransformRsaSha1)
template.append(signature_node)
ref = xmlsec.template.add_reference(
signature_node, consts.TransformSha1, uri='')
dsig_ctx.signKey = chave
dsig_ctx.sign(signNode)
xmlsec.template.add_transform(ref, consts.TransformEnveloped)
xmlsec.template.add_transform(ref, consts.TransformInclC14N)
status = dsig_ctx.status
dsig_ctx.destroy()
ki = xmlsec.template.ensure_key_info(signature_node)
xmlsec.template.add_x509_data(ki)
if status != xmlsec.DSigStatusSucceeded:
raise RuntimeError(
'Erro ao realizar a assinatura do arquivo; status: "' +
str(status) +
'"')
ctx = xmlsec.SignatureContext()
ctx.key = key
xpath = doc_xml.xpathNewContext()
xpath.xpathRegisterNs('sig', NAMESPACE_SIG)
certificados = xpath.xpathEval(
'//sig:X509Data/sig:X509Certificate')
for i in range(len(certificados) - 1):
certificados[i].unlinkNode()
certificados[i].freeNode()
ctx.key.load_cert_from_file(
self.cert_pem, consts.KeyDataFormatPem)
xml = doc_xml.serialize()
return xml
finally:
doc_xml.freeDoc()
ctx.sign(signature_node)
return etree.tostring(template, encoding=str)

2
pytrustnfe/nfse/betha/__init__.py

@ -50,7 +50,7 @@ def _send(certificado, method, **kwargs):
try:
response = getattr(client.service, method)(1, xml_send)
except suds.WebFault, e:
except suds.WebFault as e:
return {
'sent_xml': xml_send,
'received_xml': e.fault.faultstring,

2
pytrustnfe/nfse/ginfes/__init__.py

@ -39,7 +39,7 @@ def _send(certificado, method, **kwargs):
xml_send = kwargs['xml']
header = '<ns2:cabecalho xmlns:ns2="http://www.ginfes.com.br/cabecalho_v03.xsd" versao="3"><versaoDados>3</versaoDados></ns2:cabecalho>' #noqa
response = getattr(client.service, method)(header, xml_send)
except suds.WebFault, e:
except suds.WebFault as e:
return {
'sent_xml': xml_send,
'received_xml': e.fault.faultstring,

9
pytrustnfe/nfse/paulistana/__init__.py

@ -18,10 +18,10 @@ def sign_tag(certificado, **kwargs):
if 'nfse' in kwargs:
for item in kwargs['nfse']['lista_rps']:
signed = crypto.sign(key, item['assinatura'], 'SHA1')
item['assinatura'] = b64encode(signed)
item['assinatura'] = b64encode(signed).decode()
if 'cancelamento' in kwargs:
signed = crypto.sign(key, kwargs['cancelamento']['assinatura'], 'SHA1')
kwargs['cancelamento']['assinatura'] = b64encode(signed)
kwargs['cancelamento']['assinatura'] = b64encode(signed).decode()
def _send(certificado, method, **kwargs):
@ -42,13 +42,12 @@ def _send(certificado, method, **kwargs):
cert, key = save_cert_key(cert, key)
client = get_authenticated_client(base_url, cert, key)
pfx_path = certificado.save_pfx()
signer = Assinatura(pfx_path, certificado.password)
signer = Assinatura(cert, key, certificado.password)
xml_send = signer.assina_xml(xml_send, '')
try:
response = getattr(client.service, method)(1, xml_send)
except suds.WebFault, e:
except suds.WebFault as e:
return {
'sent_xml': xml_send,
'received_xml': e.fault.faultstring,

2
pytrustnfe/nfse/susesu/__init__.py

@ -29,7 +29,7 @@ def _send(method, **kwargs):
'sent_xml': xml_send,
'received_xml': e.fault.faultstring,
}
result = unicode(result)
result = str(result)
result = unicodedata.normalize('NFKD', result).encode('ascii', 'ignore')
return {
'sent_xml': xml_send,

1
pytrustnfe/test/XMLs/paulistana_canc_errado.xml

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<RetornoCancelamentoNFe
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"

1
pytrustnfe/test/XMLs/paulistana_canc_ok.xml

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<RetornoCancelamentoNFe
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"

2
pytrustnfe/test/XMLs/paulistana_resultado.xml

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><RetornoEnvioLoteRPS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.prefeitura.sp.gov.br/nfe"><Cabecalho Versao="1" xmlns=""><Sucesso>true</Sucesso><InformacoesLote><NumeroLote>2654364</NumeroLote><InscricaoPrestador>51212</InscricaoPrestador><CPFCNPJRemetente><CNPJ>21332900163</CNPJ></CPFCNPJRemetente><DataEnvioLote>2016-08-29T10:52:15</DataEnvioLote><QtdNotasProcessadas>1</QtdNotasProcessadas><TempoProcessamento>0</TempoProcessamento><ValorTotalServicos>1.35</ValorTotalServicos></InformacoesLote></Cabecalho><ChaveNFeRPS xmlns=""><ChaveNFe><InscricaoPrestador>52382</InscricaoPrestador><NumeroNFe>446</NumeroNFe><CodigoVerificacao>APR9MJR</CodigoVerificacao></ChaveNFe><ChaveRPS><InscricaoPrestador>51282</InscricaoPrestador><SerieRPS>1</SerieRPS><NumeroRPS>6</NumeroRPS></ChaveRPS></ChaveNFeRPS></RetornoEnvioLoteRPS>
<RetornoEnvioLoteRPS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.prefeitura.sp.gov.br/nfe"><Cabecalho Versao="1" xmlns=""><Sucesso>true</Sucesso><InformacoesLote><NumeroLote>2654364</NumeroLote><InscricaoPrestador>51212</InscricaoPrestador><CPFCNPJRemetente><CNPJ>21332900163</CNPJ></CPFCNPJRemetente><DataEnvioLote>2016-08-29T10:52:15</DataEnvioLote><QtdNotasProcessadas>1</QtdNotasProcessadas><TempoProcessamento>0</TempoProcessamento><ValorTotalServicos>1.35</ValorTotalServicos></InformacoesLote></Cabecalho><ChaveNFeRPS xmlns=""><ChaveNFe><InscricaoPrestador>52382</InscricaoPrestador><NumeroNFe>446</NumeroNFe><CodigoVerificacao>APR9MJR</CodigoVerificacao></ChaveNFe><ChaveRPS><InscricaoPrestador>51282</InscricaoPrestador><SerieRPS>1</SerieRPS><NumeroRPS>6</NumeroRPS></ChaveRPS></ChaveNFeRPS></RetornoEnvioLoteRPS>

16
pytrustnfe/test/XMLs/paulistana_signature.xml

@ -1,8 +1,4 @@
<?xml version="1.0"?>
<PedidoEnvioLoteRPS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.prefeitura.sp.gov.br/nfe"><Cabecalho xmlns="" Versao="1"><CPFCNPJRemetente><CNPJ>12345678901234</CNPJ></CPFCNPJRemetente><transacao>false</transacao><dtInicio>2016-08-29</dtInicio><dtFim>2016-08-29</dtFim><QtdRPS>1</QtdRPS><ValorTotalServicos/><ValorTotalDeducoes/></Cabecalho><RPS xmlns=""><Assinatura>E4fpHYkQa7Naxn6IKGb7NwwZu5tPk/KXJ9hCwtZgq0xvKS450aQqqBL+7Iv46lTgqrSMu7+gLrl+LC1qs/8aT2mbHE8uaVFSbzwZ+sF/BkcT6nsFHLMswEiTAEs95Jb7hN1cC91xqQGRH4buw0TzxHKmhuLJ22WwtG/scxyKtjM=</Assinatura><ChaveRPS><InscricaoPrestador>123456</InscricaoPrestador><SerieRPS>1</SerieRPS><NumeroRPS>1</NumeroRPS></ChaveRPS><TipoRPS>RPS</TipoRPS><DataEmissao>2016-08-29</DataEmissao><StatusRPS>N</StatusRPS><TributacaoRPS>T</TributacaoRPS><ValorServicos/><ValorDeducoes/><ValorPIS>0.00</ValorPIS><ValorCOFINS>0.00</ValorCOFINS><ValorINSS>0.00</ValorINSS><ValorIR>0.00</ValorIR><ValorCSLL>0.00</ValorCSLL><CodigoServico>07498</CodigoServico><AliquotaServicos>5.00</AliquotaServicos><ISSRetido>false</ISSRetido><CPFCNPJTomador>
</CPFCNPJTomador><InscricaoMunicipalTomador>123456</InscricaoMunicipalTomador><RazaoSocialTomador>Trustcode</RazaoSocialTomador><EnderecoTomador><TipoLogradouro>1</TipoLogradouro><Logradouro>Vinicius de Moraes, 42</Logradouro><NumeroEndereco>42</NumeroEndereco><ComplementoEndereco/><Bairro>Corrego</Bairro><Cidade>Floripa</Cidade><UF>SC</UF><CEP>88037240</CEP></EnderecoTomador><Discriminacao>Venda de servico</Discriminacao></RPS><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<PedidoEnvioLoteRPS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.prefeitura.sp.gov.br/nfe"><Cabecalho xmlns="" Versao="1"><CPFCNPJRemetente><CNPJ>12345678901234</CNPJ></CPFCNPJRemetente><transacao>false</transacao><dtInicio>2016-08-29</dtInicio><dtFim>2016-08-29</dtFim><QtdRPS>1</QtdRPS><ValorTotalServicos/><ValorTotalDeducoes/></Cabecalho><RPS xmlns=""><Assinatura>E4fpHYkQa7Naxn6IKGb7NwwZu5tPk/KXJ9hCwtZgq0xvKS450aQqqBL+7Iv46lTgqrSMu7+gLrl+LC1qs/8aT2mbHE8uaVFSbzwZ+sF/BkcT6nsFHLMswEiTAEs95Jb7hN1cC91xqQGRH4buw0TzxHKmhuLJ22WwtG/scxyKtjM=</Assinatura><ChaveRPS><InscricaoPrestador>123456</InscricaoPrestador><SerieRPS>1</SerieRPS><NumeroRPS>1</NumeroRPS></ChaveRPS><TipoRPS>RPS</TipoRPS><DataEmissao>2016-08-29</DataEmissao><StatusRPS>N</StatusRPS><TributacaoRPS>T</TributacaoRPS><ValorServicos/><ValorDeducoes/><ValorPIS>0.00</ValorPIS><ValorCOFINS>0.00</ValorCOFINS><ValorINSS>0.00</ValorINSS><ValorIR>0.00</ValorIR><ValorCSLL>0.00</ValorCSLL><CodigoServico>07498</CodigoServico><AliquotaServicos>5.00</AliquotaServicos><ISSRetido>false</ISSRetido><CPFCNPJTomador/><InscricaoMunicipalTomador>123456</InscricaoMunicipalTomador><RazaoSocialTomador>Trustcode</RazaoSocialTomador><EnderecoTomador><TipoLogradouro>1</TipoLogradouro><Logradouro>Vinicius de Moraes, 42</Logradouro><NumeroEndereco>42</NumeroEndereco><ComplementoEndereco/><Bairro>Corrego</Bairro><Cidade>Floripa</Cidade><UF>SC</UF><CEP>88037240</CEP></EnderecoTomador><Discriminacao>Venda de servico</Discriminacao></RPS><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
@ -12,12 +8,12 @@
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>ivaOwkcrt0pfuMYsAdfyLaUAcIk=</DigestValue>
<DigestValue>ePJnD6hyDvlJo08PFX8h2TXk0ZM=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>FjIHdfPavSEyaWYhAT0z0shPLuTsqBKyy78PUEZ8PUhTZ+iSV0MOvAIRq9MPPVK9
jjXOw1TE903uSK8aJon52RNKPd68ORVJ3bKFSjTqQLxFRR9tiiAQFrWDETf7FF89
EhG6dy6TGcgVbOyn0Jqm8MkqrE1XrJ44orN1X+Jt+7U=</SignatureValue>
<SignatureValue>GbaQaTEtxuKdRRaadginWPFH5K65ywqEikkwChWO3xX5Kglq8RPm4+LjnpJmuTcE
9I2BVon3GJFh+c/6RKzJPose6FXog2xnCpTOgwA/rks/gKsUAaRlXCPsLcKMKaOj
3eH21RHEyrxBAbdpEUdlEgQWaWzmGq009EiQ544sD6c=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIICMTCCAZqgAwIBAgIQfYOsIEVuAJ1FwwcTrY0t1DANBgkqhkiG9w0BAQUFADBX
@ -34,4 +30,4 @@ QtgAhuZM9rxpOJuNKc+pM29EixpAiZZiRMCSWEItNyEVdUIi+YnKBcAHd88TwO86
d126MWQ2O8cu5W1VoDp7hYBYKOnLbYi11/StO+0rzK+oPYAvIw==</X509Certificate>
</X509Data>
</KeyInfo>
</Signature></PedidoEnvioLoteRPS>
</Signature></PedidoEnvioLoteRPS>

2
pytrustnfe/test/test_add_qr_code.py

@ -12,7 +12,7 @@ class TestAddQRCode(unittest.TestCase):
self.xml_sem_qrcode = open('pytrustnfe/test/xml_sem_qrcode.xml', 'r')
self.xml_com_qrcode = open('pytrustnfe/test/xml_com_qrcode.xml', 'r')
dhEmi = '2016-11-09T16:03:25-00:00'
chave_nfe = u'NFe35161121332917000163650010000000011448875034'
chave_nfe = 'NFe35161121332917000163650010000000011448875034'
ambiente = 2
valor_total = '324.00'
icms_total = '61.56'

12
pytrustnfe/test/test_assinatura.py

@ -11,16 +11,14 @@ from lxml import etree
from pytrustnfe.nfe.assinatura import Assinatura
XML_ASSINAR = '<?xml version="1.0" encoding="UTF-8"?>' \
'<Envelope xmlns="urn:envelope">' \
XML_ASSINAR = '<Envelope xmlns="urn:envelope">' \
' <Data Id="NFe43150602261542000143550010000000761792265342">'\
' Hello, World!' \
' </Data>' \
'</Envelope>'
XML_ERRADO = '<?xml version="1.0" encoding="UTF-8"?>' \
'<Envelope xmlns="urn:envelope">' \
XML_ERRADO = '<Envelope xmlns="urn:envelope">' \
' <Data Id="NFe">' \
' Hello, World!' \
' </Data>' \
@ -32,21 +30,21 @@ class test_assinatura(unittest.TestCase):
caminho = os.path.dirname(__file__)
def test_assinar_xml_senha_invalida(self):
pfx = open(os.path.join(self.caminho, 'teste.pfx')).read()
pfx = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
signer = Assinatura(pfx, '123')
self.assertRaises(Exception, signer.assina_xml, signer,
etree.fromstring(XML_ASSINAR),
'NFe43150602261542000143550010000000761792265342')
def test_assinar_xml_invalido(self):
pfx = open(os.path.join(self.caminho, 'teste.pfx')).read()
pfx = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
signer = Assinatura(pfx, '123456')
self.assertRaises(Exception, signer.assina_xml, signer,
etree.fromstring(XML_ERRADO),
'NFe43150602261542000143550010000000761792265342')
def test_assinar_xml_valido(self):
pfx = open(os.path.join(self.caminho, 'teste.pfx')).read()
pfx = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
signer = Assinatura(pfx, '123456')
xml = signer.assina_xml(
etree.fromstring(XML_ASSINAR),

8
pytrustnfe/test/test_certificado.py

@ -49,21 +49,21 @@ class test_assinatura(unittest.TestCase):
caminho = os.path.dirname(__file__)
def test_preparar_pfx(self):
dir_pfx = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
dir_pfx = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
cert, key = extract_cert_and_key_from_pfx(dir_pfx, '123456')
self.assertEqual(key, CHAVE, 'Chave gerada inválida')
self.assertEqual(cert, CERTIFICADO, 'Certificado inválido')
def test_save_pfx(self):
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
pfx = Certificado(pfx_source, '123')
path = pfx.save_pfx()
saved = open(path, 'r').read()
saved = open(path, 'rb').read()
self.assertEqual(pfx_source, saved,
'Arquivo pfx salvo não bate com arquivo lido')
def test_save_cert_and_key(self):
dir_pfx = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
dir_pfx = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
cert, key = extract_cert_and_key_from_pfx(dir_pfx, '123456')
cert_path, key_path = save_cert_key(cert, key)
cert_saved = open(cert_path, 'r').read()

2
pytrustnfe/test/test_consulta_cadastro.py

@ -12,7 +12,7 @@ class test_consulta_cadastro(unittest.TestCase):
caminho = os.path.dirname(__file__)
def test_conta_de_cadastro(self):
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
pfx = Certificado(pfx_source, '123456')
obj = {'cnpj': '12345678901234', 'estado': '42'}

2
pytrustnfe/test/test_danfe.py

@ -22,5 +22,5 @@ class test_danfe(unittest.TestCase):
# Para testar localmente o Danfe
# with open('/home/danimar/danfe.pdf', 'w') as oFile:
with tempfile.TemporaryFile(mode='w') as oFile:
with tempfile.TemporaryFile(mode='wb') as oFile:
oDanfe.writeto_pdf(oFile)

2
pytrustnfe/test/test_ginfes.py

@ -13,7 +13,7 @@ class test_nfse_ginfes(unittest.TestCase):
@unittest.skip
def test_consulta_situacao_lote(self):
pfx_source = open('/home/danimar/Downloads/machado.pfx', 'r').read()
pfx_source = open('/home/danimar/Downloads/machado.pfx', 'rb').read()
pfx = Certificado(pfx_source, '123456789')
dados = {'ambiente': 'homologacao'}

8
pytrustnfe/test/test_nfse_paulistana.py

@ -54,7 +54,7 @@ class test_nfse_paulistana(unittest.TestCase):
return nfse
def test_envio_nfse(self):
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
pfx = Certificado(pfx_source, '123456')
nfse = self._get_nfse()
@ -77,7 +77,7 @@ class test_nfse_paulistana(unittest.TestCase):
retorno['object'].ChaveNFeRPS.ChaveRPS.NumeroRPS, 6)
def test_nfse_signature(self):
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
pfx = Certificado(pfx_source, '123456')
nfse = self._get_nfse()
@ -103,7 +103,7 @@ class test_nfse_paulistana(unittest.TestCase):
}
def test_cancelamento_nfse_ok(self):
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
pfx = Certificado(pfx_source, '123456')
cancelamento = self._get_cancelamento()
@ -122,7 +122,7 @@ class test_nfse_paulistana(unittest.TestCase):
self.assertEqual(retorno['object'].Cabecalho.Sucesso, True)
def test_cancelamento_nfse_com_erro(self):
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read()
pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'rb').read()
pfx = Certificado(pfx_source, '123456')
cancelamento = self._get_cancelamento()

16
pytrustnfe/test/test_utils.py

@ -60,7 +60,7 @@ class test_utils(unittest.TestCase):
chave.validar()
chave.cnpj = '1234567891011'
self.assertEqual('CNPJ necessário para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')
with self.assertRaises(AssertionError) as cm:
@ -68,7 +68,7 @@ class test_utils(unittest.TestCase):
chave.validar()
chave.estado = '42'
self.assertEqual('Estado necessário para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')
with self.assertRaises(AssertionError) as cm:
@ -76,7 +76,7 @@ class test_utils(unittest.TestCase):
chave.validar()
chave.emissao = '0'
self.assertEqual('Emissão necessário para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')
with self.assertRaises(AssertionError) as cm:
@ -84,7 +84,7 @@ class test_utils(unittest.TestCase):
chave.validar()
chave.modelo = '55'
self.assertEqual('Modelo necessário para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')
with self.assertRaises(AssertionError) as cm:
@ -92,7 +92,7 @@ class test_utils(unittest.TestCase):
chave.validar()
chave.serie = '012'
self.assertEqual('Série necessária para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')
with self.assertRaises(AssertionError) as cm:
@ -100,7 +100,7 @@ class test_utils(unittest.TestCase):
chave.validar()
chave.numero = '000000780'
self.assertEqual('Número necessário para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')
with self.assertRaises(AssertionError) as cm:
@ -108,12 +108,12 @@ class test_utils(unittest.TestCase):
chave.validar()
chave.tipo = '42'
self.assertEqual('Tipo necessário para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')
with self.assertRaises(AssertionError) as cm:
chave.codigo = ''
chave.validar()
self.assertEqual('Código necessário para criar chave NF-e',
cm.exception.message,
str(cm.exception),
'Validação da chave nf-e incorreta')

4
pytrustnfe/test/test_xml.py

@ -26,5 +26,5 @@ class test_xmlfilters(unittest.TestCase):
self.assertEqual('2016-09-17', format_date(dt.date()))
self.assertEqual('2016-09-17T12:12:12', format_datetime(dt))
word = strip_line_feed(u"olá\ncomo vai\r senhor ")
self.assertEqual(word, u"olá como vai senhor")
word = strip_line_feed("olá\ncomo vai\r senhor ")
self.assertEqual(word, "olá como vai senhor")

6
pytrustnfe/test/test_xml_serializacao.py

@ -15,13 +15,13 @@ class test_xml_serializacao(unittest.TestCase):
tag2='ola', tag3='comovai')
result = open(os.path.join(path, 'jinja_result.xml'), 'r').read()
self.assertEqual(xml + '\n', result)
self.assertEqual(xml + "\n", result)
def test_serializacao_remove_empty(self):
path = os.path.join(os.path.dirname(__file__), 'XMLs')
xmlElem = render_xml(path, 'jinja_template.xml', True, tag1='oi',
tag2='ola', tag3='comovai')
xml = etree.tostring(xmlElem)
xml = etree.tostring(xmlElem, encoding=str)
result = open(os.path.join(path, 'jinja_remove_empty.xml'), 'r').read()
self.assertEqual(xml + '\n', result)
@ -29,7 +29,7 @@ class test_xml_serializacao(unittest.TestCase):
path = os.path.join(os.path.dirname(__file__), 'XMLs')
xml_to_clear = open(os.path.join(path, 'jinja_result.xml'), 'r').read()
xml, obj = sanitize_response(xml_to_clear)
print(type(xml))
self.assertEqual(xml, xml_to_clear)
self.assertEqual(obj.tpAmb, 'oi')
self.assertEqual(obj.CNPJ, 'ola')

6
pytrustnfe/test/xml_com_qrcode.xml

@ -30,11 +30,11 @@
<xNome>LEL AMBIENTAL LTDA - EPP</xNome>
<xFant>Zell Ambiental</xFant>
<enderEmit>
<xLgr>Rua Padre Jo&#227;o</xLgr>
<xLgr>Rua Padre João</xLgr>
<nro>444</nro>
<xBairro>Penha de Fran&#231;a</xBairro>
<xBairro>Penha de França</xBairro>
<cMun>3550308</cMun>
<xMun>S&#227;o Paulo</xMun>
<xMun>São Paulo</xMun>
<UF>SP</UF>
<CEP>03637000</CEP>
<cPais>1058</cPais>

6
pytrustnfe/test/xml_sem_qrcode.xml

@ -31,11 +31,11 @@
<xNome>LEL AMBIENTAL LTDA - EPP</xNome>
<xFant>Zell Ambiental</xFant>
<enderEmit>
<xLgr>Rua Padre Jo&#xE3;o</xLgr>
<xLgr>Rua Padre João</xLgr>
<nro>444</nro>
<xBairro>Penha de Fran&#xE7;a</xBairro>
<xBairro>Penha de França</xBairro>
<cMun>3550308</cMun>
<xMun>S&#xE3;o Paulo</xMun>
<xMun>São Paulo</xMun>
<UF>SP</UF>
<CEP>03637000</CEP>
<cPais>1058</cPais>

10
pytrustnfe/xml/__init__.py

@ -39,14 +39,14 @@ def render_xml(path, template_name, remove_empty, **nfe):
if recursively_empty(elem):
parent.remove(elem)
return root
return etree.tostring(root)
for element in root.iter("*"): # remove espaços em branco
if element.text is not None and not element.text.strip():
element.text = None
return etree.tostring(root, encoding=str)
def sanitize_response(response):
response = unicode(response)
response = unicodedata.normalize('NFKD', response).encode('ascii',
'ignore')
print(response)
tree = etree.fromstring(response)
# Remove namespaces inuteis na resposta
for elem in tree.getiterator():

18
pytrustnfe/xml/filters.py

@ -13,24 +13,24 @@ def normalize_str(string):
Remove special characters and strip spaces
"""
if string:
if not isinstance(string, unicode):
string = unicode(string, 'utf-8', 'replace')
if not isinstance(string, str):
string = str(string, 'utf-8', 'replace')
string = string.encode('utf-8')
return normalize(
'NFKD', string.decode('utf-8')).encode('ASCII', 'ignore')
'NFKD', string.decode('utf-8')).encode('ASCII', 'ignore').decode()
return ''
def strip_line_feed(string):
if string:
if not isinstance(string, unicode):
string = unicode(string, 'utf-8', 'replace')
if not isinstance(string, str):
string = str(string, 'utf-8', 'replace')
remap = {
ord(u'\t'): u' ',
ord(u'\n'): u' ',
ord(u'\f'): u' ',
ord(u'\r'): None, # Delete
ord('\t'): ' ',
ord('\n'): ' ',
ord('\f'): ' ',
ord('\r'): None, # Delete
}
return string.translate(remap).strip()
return string

2
requirements.txt

@ -2,6 +2,7 @@ lxml >= 3.5.0, < 4
coveralls
Jinja2
signxml
urllib3 >= 1.22
suds-jurko >= 0.6
suds-jurko-requests >= 1.0
defusedxml >= 0.4.1, < 0.6
@ -9,6 +10,7 @@ eight >= 0.3.0, < 0.5
cryptography >= 1.8, < 1.10
pyOpenSSL >= 16.0.0, < 17
certifi >= 2015.11.20.1
xmlsec >= 1.3.3
reportlab
pytest
pytest-cov
Loading…
Cancel
Save