Passed
Push — main ( 97b175...ba1019 )
by Sat CFDI
05:01
created

test_models   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 252
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 190
dl 0
loc 252
rs 9.92
c 0
b 0
f 0
wmc 31
1
import logging
2
import os
3
from datetime import date, datetime
4
from itertools import chain
5
from unittest import mock
6
7
import pytest
8
from OpenSSL import crypto
9
10
from satcfdi.models.certificate import CertificateType
11
from satcfdi.models.certificate_request import CertificateSigningRequest
12
from satcfdi.exceptions import CFDIError
13
from satcfdi.models.curp import CURP
14
from satcfdi.models.date_period import DatePeriod
15
from satcfdi.models.rfc import RFC, RFCType, RFC_Generico_Nacional, RFC_Generico_Extranjero
16
from satcfdi.models.signer import Signer
17
from satcfdi.pacs.sat import SAT
18
from satcfdi.transform import verify_certificate
19
from tests.constants import PERSONAS_FISICAS, PERSONAS_MORALES
20
from tests.utils import get_signer, SAT_Certificate_Store_Pruebas
21
22
module = 'satcfdi'
23
current_dir = os.path.dirname(__file__)
24
25
logging.basicConfig(level=logging.INFO)
26
27
sat = SAT()
28
29
30
def test_descarga_certificado_sat_pac():
31
    cert = sat.recover_certificate("00001000000504465028")
32
33
    # assert cert.issuer().startswith("1.2.840.113549.1.9.2=responsable: ADMINISTRACION CENTRAL DE SERVICIOS TRIBUTARIOS AL CONTRIBUYE")
34
    # assert cert.subject().startswith(r"OU=MEGAPACSAT970701NN301,2.5.4.5=\ / GARJ750416HDFRVR09,2.5.4.45=SAT970701NN3 / GARJ7504168N4,O=SERVIC")
35
    # assert cert.issuer().startswith("CN=AUTORIDAD CERTIFICADORA,O=SERVICIO DE ADMINISTRACION TRIBUTARIA,OU=SAT-IES Authority,emailAddress=contacto.tecnic")
36
    # assert cert.subject().startswith("CN=SERVICIO DE ADMINISTRACION TRIBUTARIA,name=SERVICIO DE ADMINISTRACION TRIBUTARIA,O=SERVICIO DE ADMINISTRACION TRIBUTARIA,x500Unique")
37
    assert cert.certificate_base64().startswith("MIIGKTCCBBGgAwIBAgIUMDAwMDEwMDAwMDA1MDQ0NjUwM")
38
    assert str(cert.serial_number) == '275106190557734483187066766829380167334928331320'
39
    assert cert.certificate_number == "00001000000504465028"
40
    assert cert.branch_name == "MEGAPACSAT970701NN301"
41
    assert cert.rfc_pac == "SAT970701NN3"
42
    assert cert.rfc_representante == "GARJ7504168N4"
43
    assert cert.curp is None
44
    assert cert.curp_representante == "GARJ750416HDFRVR09"
45
    assert str(cert.serial_number) == "275106190557734483187066766829380167334928331320"
46
    assert cert.rfc_pac == "SAT970701NN3"
47
    assert cert.rfc_representante == "GARJ7504168N4"
48
    assert cert.legal_name == 'SERVICIO DE ADMINISTRACION TRIBUTARIA'
49
    assert cert.email is None
50
51
52
def test_signer_razon_social():
53
    res = {
54
        'CACX7605101P8': 'XOCHILT CASAS CHAVEZ',
55
        'FUNK671228PH6': 'KARLA FUENTE NOLASCO',
56
        'IAÑL750210963': 'LUIS IAN ÑUZCO',
57
        'JUFA7608212V6': 'ADRIANA JUAREZ FERNANDEZ',
58
        'KAHO641101B39': 'OSCAR KALA HAAK',
59
        'KICR630120NX3': 'RODRIGO KITIA CASTRO',
60
        'MISC491214B86': 'CECILIA MIRANDA SANCHEZ',
61
        'RAQÑ7701212M3': 'ÑEVES RAMIREZ QUEZADA',
62
        'WATM640917J45': 'MARIA WATEMBER TORRES',
63
        'WERX631016S30': 'XAIME WEIR ROJO',
64
        'XAMA620210DQ5': 'ALBA XKARAJAM MENDEZ',
65
        'XIQB891116QE4': 'BERENICE XIMO QUEZADA',
66
        'XOJI740919U48': 'INGRID XODAR JIMENEZ',
67
        'EKU9003173C9': 'ESCUELA KEMPER URGATE',
68
        'EWE1709045U0': 'ESCUELA WILSON ESQUIVEL',
69
        'H&E951128469': 'HERRERIA & ELECTRICOS',
70
        'HAÑ930228SM9': 'HERMANOS ANZURES ÑARVAEZ',
71
        'IIA040805DZ4': 'INDISTRIA ILUMINADORA DE ALMACENES',
72
        'IVD920810GU2': 'INNOVACION VALOR Y DESARROLLO',
73
        'IXS7607092R5': 'INTERNACIONAL XIMBO Y SABORES',
74
        'JES900109Q90': 'JIMENEZ ESTRADA SALAS A A',
75
        'KIJ0906199R1': 'KERNEL INDUSTIA JUGUETERA',
76
        'L&O950913MSA': 'LUCES & OBRAS',
77
        'OÑO120726RX3': 'ORGANICOS ÑAVEZ OSORIO S.A DE C.V',
78
        'S&S051221SE2': 'S & SOFTWARE',
79
        'URE180429TM6': 'UNIVERSIDAD ROBOTICA ESPAÑOLA',
80
        'XIA190128J61': 'XENON INDUSTRIAL ARTICLES',
81
        'ZUÑ920208KL4': 'ZAPATERIA URTADO ÑERI'
82
    }
83
84
    for rfc in chain(PERSONAS_FISICAS, PERSONAS_MORALES):
85
        try:
86
            signer = get_signer(rfc, get_csd=True)
87
            rs = signer.legal_name
88
            assert res[rfc] == rs
89
            assert rfc == signer.rfc
90
        except FileNotFoundError as ex:
91
            pass
92
93
94
def test_curp():
95
    curp = CURP("FEPM890204HASRRN08")
96
    assert curp.is_valid()
97
    assert curp.estado == "AS"
98
99
    # for rfc in PERSONAS_FISICAS:
100
    #     signer = get_signer(rfc)
101
    #     assert not signer.curp.is_valid()
102
103
104
def test_crypto_razon_social():
105
    for rfc in chain(PERSONAS_FISICAS, PERSONAS_MORALES):
106
        try:
107
            signer = get_signer(rfc, get_csd=True)
108
109
            cer = crypto.load_certificate(crypto.FILETYPE_ASN1, signer.certificate_bytes())
110
            subj = cer.get_subject()
111
            for k, v in subj.get_components():
112
                k.decode("latin_1")
113
                v.decode("latin_1")
114
115
        except (FileNotFoundError, ValueError) as ex:
116
            pass
117
118
119
def test_verify_certificates():
120
    for rfc in chain(PERSONAS_FISICAS, PERSONAS_MORALES):
121
        with mock.patch(f'{module}.transform.SAT_Certificate_Store', SAT_Certificate_Store_Pruebas):
122
            try:
123
                signer = get_signer(rfc)
124
                verify_certificate(signer, at=datetime(2021, 6, 12))
125
                assert signer.type == CertificateType.Fiel
126
127
                signer_csd = get_signer(rfc, get_csd=True)
128
                verify_certificate(signer_csd, at=datetime(2021, 6, 12))
129
                assert signer_csd.type == CertificateType.CSD
130
131
            except FileNotFoundError as ex:
132
                pass
133
134
135
def test_requirement():
136
    for rfc in PERSONAS_FISICAS:
137
        res = CertificateSigningRequest.load(
138
            request=open(os.path.join(current_dir, "csd", "Personas Fisicas", f'{rfc.lower()}.req'), 'rb').read()
139
        )
140
    for rfc in PERSONAS_MORALES:
141
        res = CertificateSigningRequest.load(
142
            request=open(os.path.join(current_dir, "csd", "Personas Morales", f'{rfc.lower()}.req'), 'rb').read()
143
        )
144
145
146
def test_thumbprint():
147
    signer = get_signer("xiqb891116qe4")
148
149
    assert signer.fingerprint().hex() == 'cad8b0aa7940aec665d9db9755b995b8631409c4'
150
151
    signer2 = get_signer("h&e951128469")
152
153
    with pytest.raises(CFDIError) as ex:
154
        signer = Signer(
155
            key=signer.key,
156
            certificate=signer2.certificate,
157
            check=True
158
        )
159
160
    password = "IGUESSTHISISSECURE"
161
    p12 = signer.pcks12_bytes(password)
162
    with open(os.path.join(current_dir, "csd", f'xiqb891116qe4.pfx'), 'wb') as f:
163
        f.write(p12)
164
165
    pkcs12_signer = Signer.load_pkcs12(
166
        data=open(os.path.join(current_dir, "csd", f'xiqb891116qe4.pfx'), 'rb').read(),
167
        password=password
168
    )
169
170
    assert pkcs12_signer.legal_name == 'BERENICE XIMO QUEZADA'
171
172
    os.remove(os.path.join(current_dir, "csd", f'xiqb891116qe4.pfx'))
173
174
175
def test_signer_change_password():
176
    rfc = 'xiqb891116qe4'
177
    signer = get_signer(rfc)
178
179
    password = "THISISMORESCURE"
180
    key = signer.key_bytes(password)
181
    cer = signer.certificate_bytes()
182
183
    with open(os.path.join(current_dir, "csd", 'xiqb891116qe4.out.key'), 'wb') as f:
184
        f.write(key)
185
    with open(os.path.join(current_dir, "csd", 'xiqb891116qe4.out.cer'), 'wb') as f:
186
        f.write(cer)
187
    with open(os.path.join(current_dir, "csd", 'xiqb891116qe4.out.txt'), 'w') as f:
188
        f.write(password)
189
190
    signer = Signer.load(
191
        certificate=open(os.path.join(current_dir, f'csd/{rfc}.out.cer'), 'rb').read(),
192
        key=open(os.path.join(current_dir, f'csd/{rfc}.out.key'), 'rb').read(),
193
        password=open(os.path.join(current_dir, f'csd/{rfc}.out.txt'), 'rb').read()
194
    )
195
196
    os.remove(os.path.join(current_dir, "csd", 'xiqb891116qe4.out.key'))
197
    os.remove(os.path.join(current_dir, "csd", 'xiqb891116qe4.out.cer'))
198
    os.remove(os.path.join(current_dir, "csd", 'xiqb891116qe4.out.txt'))
199
200
201
def test_rfc():
202
    for rfc in PERSONAS_FISICAS:
203
        r = RFC(rfc, entity_type=RFCType.FISICA)
204
        assert r.is_valid()
205
206
    for rfc in PERSONAS_MORALES:
207
        r = RFC(rfc, entity_type=RFCType.MORAL)
208
        assert r.is_valid()
209
210
    r = RFC_Generico_Nacional
211
    assert r.is_valid()
212
    assert r.type == RFCType.FISICA
213
214
    r = RFC_Generico_Extranjero
215
    assert r.is_valid()
216
    assert r.type == RFCType.FISICA
217
218
219
def test_period():
220
    period = DatePeriod(year=2020, month=4)
221
    my_date = date(year=2021, month=3, day=20)
222
    assert my_date > period
223
    assert my_date >= period
224
    assert my_date != period
225
    assert not my_date == period
226
    assert not my_date <= period
227
    assert not my_date < period
228
229
    assert str(period) == '2020-04'
230
231
    period = DatePeriod(year=None)
232
    my_date = date(year=2021, month=3, day=20)
233
    assert my_date >= period
234
    assert my_date == period
235
    assert my_date <= period
236
    assert not my_date > period
237
    assert not my_date < period
238
    assert not my_date != period
239
240
    assert str(period) == ""
241
242
    assert not period == 1
243
    assert period != 1
244
    with pytest.raises(TypeError):
245
        assert not period < 1
246
    with pytest.raises(TypeError):
247
        assert not period > 1
248
    with pytest.raises(TypeError):
249
        assert not period >= 1
250
    with pytest.raises(TypeError):
251
        assert not period <= 1
252