feat: preenchimento automatico de dados do cliente a partir do CNPJ
Ao sair do campo CNPJ no formulario de cliente, busca automaticamente
na BrasilAPI (publica, gratuita, sem chave - dados abertos da Receita)
e preenche Razao/Fantasia/Endereco/Cidade/Bairro/UF/CEP/Telefone/
E-mail, so nos campos que estiverem vazios (nunca sobrescreve o que
ja foi digitado). So funciona para CNPJ - CPF e dado pessoal, sem
consulta publica, e a rota recusa (404) se detectar CPF.
- app/cnpj_lookup.py: cliente HTTP pra BrasilAPI, degrada em silencio
(retorna None) se nao encontrar/rede cair/formato nao reconhecido
(ex.: CNPJ alfanumerico novo, que a BrasilAPI pode nao cobrir ainda).
- Nova rota GET /clientes/consulta-cnpj/{documento}, chamada via
fetch() no formulario (JS vanilla, sem framework).
- Testado ponta a ponta contra a API real.
106/106 testes passando (10 novos).
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import httpx
|
||||
|
||||
from app import cnpj_lookup
|
||||
|
||||
|
||||
def test_documento_com_tamanho_errado_nao_consulta(monkeypatch):
|
||||
chamou = {}
|
||||
monkeypatch.setattr(cnpj_lookup.httpx, "get", lambda *a, **k: chamou.setdefault("ok", True))
|
||||
assert cnpj_lookup.consultar_cnpj("123") is None
|
||||
assert "ok" not in chamou
|
||||
|
||||
|
||||
def test_consulta_com_sucesso_mapeia_campos(monkeypatch):
|
||||
class _RespostaFalsa:
|
||||
status_code = 200
|
||||
|
||||
def json(self):
|
||||
return {
|
||||
"razao_social": "EMPRESA TESTE LTDA",
|
||||
"nome_fantasia": "EMPRESA TESTE",
|
||||
"logradouro": "RUA TESTE",
|
||||
"numero": "123",
|
||||
"bairro": "CENTRO",
|
||||
"municipio": "FEIRA DE SANTANA",
|
||||
"uf": "BA",
|
||||
"cep": "44000000",
|
||||
"ddd_telefone_1": "7533334444",
|
||||
"email": "contato@empresateste.com",
|
||||
}
|
||||
|
||||
monkeypatch.setattr(cnpj_lookup.httpx, "get", lambda url, timeout=None: _RespostaFalsa())
|
||||
|
||||
resultado = cnpj_lookup.consultar_cnpj("11222333000181")
|
||||
assert resultado == {
|
||||
"RAZAO": "EMPRESA TESTE LTDA",
|
||||
"FANTASIA": "EMPRESA TESTE",
|
||||
"ENDERECO": "RUA TESTE, 123",
|
||||
"CIDADE": "FEIRA DE SANTANA",
|
||||
"BAIRRO": "CENTRO",
|
||||
"UF": "BA",
|
||||
"CEP": "44000000",
|
||||
"TELEFONE": "7533334444",
|
||||
"EMAIL": "contato@empresateste.com",
|
||||
}
|
||||
|
||||
|
||||
def test_consulta_nao_encontrada_retorna_none(monkeypatch):
|
||||
class _RespostaFalsa:
|
||||
status_code = 404
|
||||
|
||||
def json(self):
|
||||
return {}
|
||||
|
||||
monkeypatch.setattr(cnpj_lookup.httpx, "get", lambda url, timeout=None: _RespostaFalsa())
|
||||
assert cnpj_lookup.consultar_cnpj("11222333000181") is None
|
||||
|
||||
|
||||
def test_falha_de_rede_retorna_none(monkeypatch):
|
||||
def _get_com_erro(url, timeout=None):
|
||||
raise httpx.ConnectError("falhou")
|
||||
|
||||
monkeypatch.setattr(cnpj_lookup.httpx, "get", _get_com_erro)
|
||||
assert cnpj_lookup.consultar_cnpj("11222333000181") is None
|
||||
|
||||
|
||||
def test_sem_nome_fantasia_usa_razao_social(monkeypatch):
|
||||
class _RespostaFalsa:
|
||||
status_code = 200
|
||||
|
||||
def json(self):
|
||||
return {"razao_social": "EMPRESA TESTE LTDA", "nome_fantasia": None}
|
||||
|
||||
monkeypatch.setattr(cnpj_lookup.httpx, "get", lambda url, timeout=None: _RespostaFalsa())
|
||||
resultado = cnpj_lookup.consultar_cnpj("11222333000181")
|
||||
assert resultado["FANTASIA"] == "EMPRESA TESTE LTDA"
|
||||
@@ -140,6 +140,48 @@ def test_listar_clientes_direcao_invalida_cai_no_padrao(monkeypatch):
|
||||
assert capturado["direcao"] == "desc"
|
||||
|
||||
|
||||
def test_consulta_cnpj_encontrado(monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
router_clientes.cnpj_lookup,
|
||||
"consultar_cnpj",
|
||||
lambda cnpj: {"RAZAO": "EMPRESA TESTE LTDA", "FANTASIA": "EMPRESA TESTE"},
|
||||
)
|
||||
resposta = client.get("/clientes/consulta-cnpj/11222333000181")
|
||||
assert resposta.status_code == 200
|
||||
corpo = resposta.json()
|
||||
assert corpo["encontrado"] is True
|
||||
assert corpo["dados"]["RAZAO"] == "EMPRESA TESTE LTDA"
|
||||
|
||||
|
||||
def test_consulta_cnpj_nao_encontrado(monkeypatch):
|
||||
monkeypatch.setattr(router_clientes.cnpj_lookup, "consultar_cnpj", lambda cnpj: None)
|
||||
resposta = client.get("/clientes/consulta-cnpj/11222333000181")
|
||||
assert resposta.status_code == 404
|
||||
assert resposta.json()["encontrado"] is False
|
||||
|
||||
|
||||
def test_consulta_cnpj_rejeita_cpf(monkeypatch):
|
||||
chamou = {}
|
||||
monkeypatch.setattr(
|
||||
router_clientes.cnpj_lookup, "consultar_cnpj", lambda cnpj: chamou.setdefault("ok", True)
|
||||
)
|
||||
# CPF válido (mesma fixture usada em test_normalize.py) — nunca deve
|
||||
# chamar a consulta de CNPJ, é dado pessoal.
|
||||
resposta = client.get("/clientes/consulta-cnpj/11144477735")
|
||||
assert resposta.status_code == 404
|
||||
assert "ok" not in chamou
|
||||
|
||||
|
||||
def test_consulta_cnpj_rejeita_formato_invalido(monkeypatch):
|
||||
chamou = {}
|
||||
monkeypatch.setattr(
|
||||
router_clientes.cnpj_lookup, "consultar_cnpj", lambda cnpj: chamou.setdefault("ok", True)
|
||||
)
|
||||
resposta = client.get("/clientes/consulta-cnpj/123")
|
||||
assert resposta.status_code == 404
|
||||
assert "ok" not in chamou
|
||||
|
||||
|
||||
def test_form_novo_preenche_codigo_sugerido(monkeypatch):
|
||||
monkeypatch.setattr(router_clientes.db_clientes, "proximo_codigo_sugerido", lambda: "000243")
|
||||
resposta = client.get("/clientes/novo")
|
||||
|
||||
Reference in New Issue
Block a user