first commit - MVE Incrementables Parser microservice with FastAPI, JWT, Celery, Redis
This commit is contained in:
201
tests/test_parser.py
Normal file
201
tests/test_parser.py
Normal file
@@ -0,0 +1,201 @@
|
||||
"""Tests for the incrementables parser service."""
|
||||
import pytest
|
||||
from app.services.parser import IncrementablesParser, ParsingError, parse_incrementables
|
||||
|
||||
|
||||
# Sample text fixtures
|
||||
SAMPLE_TEXT_COMPLETE = """
|
||||
CARTA INSTRUCTIVO DE EMBARQUE No. 228718
|
||||
|
||||
AJUSTE DE INCREMENTABLES EN:
|
||||
|
||||
Fletes: $1,591.20 USD
|
||||
Seguros: $250.50 USD
|
||||
Almacenaje/Consolidación: $100.00 USD
|
||||
Regalías: $75.00 USD
|
||||
|
||||
Total: $2,016.70 USD
|
||||
"""
|
||||
|
||||
SAMPLE_TEXT_EMPTY_FIELDS = """
|
||||
AJUSTE DE INCREMENTABLES EN:
|
||||
|
||||
Fletes: $1,591.20 USD
|
||||
Seguros: USD
|
||||
Almacenaje/Consolidación: $0.00 USD
|
||||
Regalías: USD
|
||||
|
||||
Observaciones: Los seguros y regalías están vacíos
|
||||
"""
|
||||
|
||||
SAMPLE_TEXT_NO_ANCHOR = """
|
||||
Este es un documento sin la sección de incrementables.
|
||||
Solo tiene texto normal sin el ancla esperada.
|
||||
"""
|
||||
|
||||
SAMPLE_TEXT_VARIATIONS = """
|
||||
INCREMENTABLES EN:
|
||||
|
||||
Fletes: $2,500.00 USD
|
||||
Seguros: USD
|
||||
Almacenaje Consolidacion: $150.75 USD
|
||||
Regalias: $300.00 USD
|
||||
"""
|
||||
|
||||
|
||||
class TestIncrementablesParser:
|
||||
"""Test cases for IncrementablesParser class."""
|
||||
|
||||
def test_parse_complete_data(self):
|
||||
"""Test parsing with all fields present."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_COMPLETE)
|
||||
result = parser.parse()
|
||||
|
||||
assert result["currency"] == "USD"
|
||||
assert result["fletes"] == 1591.20
|
||||
assert result["seguros"] == 250.50
|
||||
assert result["almacenaje_consolidacion"] == 100.00
|
||||
assert result["regalias"] == 75.00
|
||||
assert len(result["anchors_found"]) > 0
|
||||
|
||||
def test_parse_empty_fields(self):
|
||||
"""Test parsing with empty seguros and regalias."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_EMPTY_FIELDS)
|
||||
result = parser.parse()
|
||||
|
||||
assert result["currency"] == "USD"
|
||||
assert result["fletes"] == 1591.20
|
||||
assert result["seguros"] is None
|
||||
assert result["almacenaje_consolidacion"] == 0.00
|
||||
assert result["regalias"] is None
|
||||
|
||||
def test_parse_no_anchor(self):
|
||||
"""Test parsing fails when anchor not found."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_NO_ANCHOR)
|
||||
|
||||
with pytest.raises(ParsingError) as exc_info:
|
||||
parser.parse()
|
||||
|
||||
assert "not found" in str(exc_info.value).lower()
|
||||
|
||||
def test_parse_variations(self):
|
||||
"""Test parsing with text variations."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_VARIATIONS)
|
||||
result = parser.parse()
|
||||
|
||||
assert result["currency"] == "USD"
|
||||
assert result["fletes"] == 2500.00
|
||||
assert result["seguros"] is None
|
||||
assert result["almacenaje_consolidacion"] == 150.75
|
||||
assert result["regalias"] == 300.00
|
||||
|
||||
def test_parse_amount_with_commas(self):
|
||||
"""Test amount parsing with comma separators."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_COMPLETE)
|
||||
amount = parser._parse_amount("1,591.20")
|
||||
assert amount == 1591.20
|
||||
|
||||
def test_parse_amount_with_dollar(self):
|
||||
"""Test amount parsing with dollar sign."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_COMPLETE)
|
||||
amount = parser._parse_amount("$1,591.20")
|
||||
assert amount == 1591.20
|
||||
|
||||
def test_parse_amount_empty(self):
|
||||
"""Test amount parsing with empty string."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_COMPLETE)
|
||||
amount = parser._parse_amount("")
|
||||
assert amount is None
|
||||
|
||||
def test_parse_amount_none(self):
|
||||
"""Test amount parsing with None."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_COMPLETE)
|
||||
amount = parser._parse_amount(None)
|
||||
assert amount is None
|
||||
|
||||
def test_extract_currency_default(self):
|
||||
"""Test currency extraction defaults to USD."""
|
||||
parser = IncrementablesParser("Text without currency")
|
||||
currency = parser._extract_currency("No currency here")
|
||||
|
||||
assert currency == "USD"
|
||||
assert len(parser.warnings) > 0
|
||||
assert "currency" in parser.warnings[0].lower()
|
||||
|
||||
def test_find_incrementables_section(self):
|
||||
"""Test finding incrementables section."""
|
||||
parser = IncrementablesParser(SAMPLE_TEXT_COMPLETE)
|
||||
section = parser._find_incrementables_section()
|
||||
|
||||
assert section is not None
|
||||
assert "Fletes" in section
|
||||
assert len(parser.anchors_found) > 0
|
||||
|
||||
|
||||
def test_parse_incrementables_function():
|
||||
"""Test the main parse_incrementables function."""
|
||||
result = parse_incrementables(SAMPLE_TEXT_COMPLETE)
|
||||
|
||||
assert result["currency"] == "USD"
|
||||
assert result["fletes"] == 1591.20
|
||||
assert "anchors_found" in result
|
||||
assert "warnings" in result
|
||||
|
||||
|
||||
def test_parse_incrementables_raises_error():
|
||||
"""Test parse_incrementables raises error on invalid input."""
|
||||
with pytest.raises(ParsingError):
|
||||
parse_incrementables(SAMPLE_TEXT_NO_ANCHOR)
|
||||
|
||||
|
||||
class TestParserEdgeCases:
|
||||
"""Test edge cases and error conditions."""
|
||||
|
||||
def test_missing_fletes(self):
|
||||
"""Test that missing fletes raises error."""
|
||||
text = """
|
||||
AJUSTE DE INCREMENTABLES EN:
|
||||
Seguros: $100.00 USD
|
||||
Almacenaje: $50.00 USD
|
||||
"""
|
||||
parser = IncrementablesParser(text)
|
||||
|
||||
with pytest.raises(ParsingError) as exc_info:
|
||||
parser.parse()
|
||||
|
||||
assert "fletes" in str(exc_info.value).lower()
|
||||
|
||||
def test_missing_almacenaje(self):
|
||||
"""Test that missing almacenaje raises error."""
|
||||
text = """
|
||||
AJUSTE DE INCREMENTABLES EN:
|
||||
Fletes: $1000.00 USD
|
||||
Seguros: $100.00 USD
|
||||
"""
|
||||
parser = IncrementablesParser(text)
|
||||
|
||||
with pytest.raises(ParsingError) as exc_info:
|
||||
parser.parse()
|
||||
|
||||
assert "almacenaje" in str(exc_info.value).lower()
|
||||
|
||||
def test_case_insensitive_anchor(self):
|
||||
"""Test anchor detection is case insensitive."""
|
||||
text_lower = "ajuste de incrementables en:\nFletes: $100.00 USD\nAlmacenaje: $50.00 USD"
|
||||
parser = IncrementablesParser(text_lower)
|
||||
section = parser._find_incrementables_section()
|
||||
|
||||
assert section is not None
|
||||
|
||||
def test_accent_variations_regalias(self):
|
||||
"""Test that both 'regalías' and 'regalias' work."""
|
||||
text_with_accent = """
|
||||
AJUSTE DE INCREMENTABLES EN:
|
||||
Fletes: $100.00 USD
|
||||
Almacenaje: $50.00 USD
|
||||
Regalías: $25.00 USD
|
||||
"""
|
||||
parser = IncrementablesParser(text_with_accent)
|
||||
result = parser.parse()
|
||||
|
||||
assert result["regalias"] == 25.00
|
||||
Reference in New Issue
Block a user