202 lines
6.4 KiB
Python
202 lines
6.4 KiB
Python
"""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
|