Files
GTI_GERENCIADOR_FISCAL/central/tests/test_mission_07_hardening.py
T

140 lines
4.7 KiB
Python

"""Missão 7 — Endurecimento e testes de cobertura dos módulos fiscais."""
from datetime import datetime, timezone
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from fastapi.testclient import TestClient
from central.app.models import Base, Dataset
from central.app.reference_registry import (
register_draft, approve_draft, reject_draft, list_registry,
diff_against_vigente, technical_checklist, RegistryError
)
from central.app.classification import (
Classifier, classify_tipi_rate, description_tokens, normalize_description
)
from central.app.main import create_app
@pytest.fixture
def memory_db():
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
with Session(engine) as session:
yield session
def test_reference_registry_lifecycle_and_approval_workflow(memory_db):
"""Testa o ciclo de vida completo do Reference Registry: registro, diff, checklist, aprovação e rejeição."""
# 1. Registrar versão 1
d1 = register_draft(
memory_db,
kind="NCM",
provider="Siscomex",
source_url="https://siscomex.gov.br",
sha256="a" * 64,
version_label="v1",
record_count=15100,
act="Resolução Gecex 2026",
)
assert d1.status == "DRAFT"
# Idempotência de registro
d1_again = register_draft(
memory_db,
kind="NCM",
provider="Siscomex",
source_url="https://siscomex.gov.br",
sha256="a" * 64,
version_label="v1",
)
assert d1_again.id == d1.id
# Checklist técnico
chk = technical_checklist(memory_db, d1)
assert chk["ready_to_approve"] is True
assert chk["volume"]["passed"] is True
# Aprovar versão 1 -> VIGENTE
approved = approve_draft(memory_db, d1.id, admin_name="Operador Teste")
assert approved.status == "VIGENTE"
assert approved.approved_by == "Operador Teste"
# 2. Registrar versão 2
d2 = register_draft(
memory_db,
kind="NCM",
provider="Siscomex",
source_url="https://siscomex.gov.br",
sha256="b" * 64,
version_label="v2",
record_count=15200,
)
diff = diff_against_vigente(memory_db, d2)
assert diff["is_first_version"] is False
assert diff["record_count_delta"] == 100
# Aprovar versão 2 -> Torna d1 OBSOLETO
approve_draft(memory_db, d2.id, admin_name="Admin 2")
memory_db.refresh(d1)
assert d1.status == "OBSOLETO"
assert d2.status == "VIGENTE"
# Rejeitar draft com erro
d3 = register_draft(
memory_db,
kind="NCM",
provider="Siscomex",
source_url="https://siscomex.gov.br",
sha256="c" * 64,
version_label="v3",
parse_errors={"line_1": "invalid format"},
)
# Não pode aprovar draft com erros de parse
with pytest.raises(RegistryError, match="recorded parse errors"):
approve_draft(memory_db, d3.id, admin_name="Admin")
# Rejeitar draft
rejected = reject_draft(memory_db, d3.id, admin_name="Admin")
assert rejected.status == "REJECTED"
# Listar registry
items = list_registry(memory_db)
assert len(items) == 3
def test_classification_tipi_rate_classification_and_tokens():
"""Testa classificação determinística de taxas TIPI e tratamento de stopwords."""
class MockEntry:
def __init__(self, ex=None, text=None, rate=None):
self.ex = ex
self.ipi_rate_text = text
self.ipi_rate = rate
assert classify_tipi_rate(MockEntry(ex="01")) == "EX_SPECIFIC"
assert classify_tipi_rate(MockEntry(text=None)) == "SOURCE_BLANK"
assert classify_tipi_rate(MockEntry(text="NT")) == "NT_OR_NON_TAXED"
assert classify_tipi_rate(MockEntry(text="NÃO TRIBUTADO")) == "NT_OR_NON_TAXED"
assert classify_tipi_rate(MockEntry(rate=0, text="0")) == "EXPLICIT_ZERO"
assert classify_tipi_rate(MockEntry(rate=15.0, text="15%")) == "OTHER"
# Stopwords
tokens = description_tokens("CERVEJA DE MALTE COM LUPULO E CEVADA")
assert "DE" not in tokens
assert "COM" not in tokens
assert "E" not in tokens
assert "CERVEJA" in tokens
assert "MALTE" in tokens
def test_http_security_headers_middleware():
"""Testa se o middleware de cabeçalhos de segurança HTTP adiciona os headers corretos."""
app = create_app(database_probe=lambda: True, bootstrap_token="test-token")
client = TestClient(app)
response = client.get("/health")
assert response.status_code == 200
assert response.headers.get("X-Content-Type-Options") == "nosniff"
assert response.headers.get("X-Frame-Options") == "SAMEORIGIN"
assert response.headers.get("X-XSS-Protection") == "1; mode=block"
assert response.headers.get("Referrer-Policy") == "strict-origin-when-cross-origin"