"""Tests for core excel parser.""" from unittest.mock import MagicMock from apps.core.excel import ( BaseExcelParser, ColumnMapping, FieldError, ParseResult, RowData, RowValidationError, validate_inn, validate_kpp, validate_ogrn, validate_okpo, ) from django.test import TestCase class ValidatorsTest(TestCase): """Tests for validators.""" def test_validate_inn_valid_10_digits(self): self.assertEqual(validate_inn("1234567890"), (True, "")) def test_validate_inn_valid_12_digits(self): self.assertEqual(validate_inn("123456789012"), (True, "")) def test_validate_inn_strips_whitespace(self): self.assertEqual(validate_inn(" 1234567890 "), (True, "")) def test_validate_inn_invalid_length(self): valid, message = validate_inn("12345") self.assertFalse(valid) self.assertIn("10 или 12", message) def test_validate_inn_none_returns_error(self): self.assertEqual(validate_inn(None), (False, "ИНН обязателен")) def test_validate_ogrn_valid_13_digits(self): self.assertEqual(validate_ogrn("1234567890123"), (True, "")) def test_validate_ogrn_valid_15_digits(self): self.assertEqual(validate_ogrn("123456789012345"), (True, "")) def test_validate_ogrn_invalid_length(self): valid, message = validate_ogrn("12345") self.assertFalse(valid) self.assertIn("13 или 15", message) def test_validate_kpp_valid(self): self.assertEqual(validate_kpp("123456789"), (True, "")) def test_validate_kpp_invalid_length(self): valid, message = validate_kpp("12345") self.assertFalse(valid) self.assertIn("9 цифр", message) def test_validate_okpo_valid_8_digits(self): self.assertEqual(validate_okpo("12345678"), (True, "")) def test_validate_okpo_valid_10_digits(self): self.assertEqual(validate_okpo("1234567890"), (True, "")) class DataclassesTest(TestCase): """Tests for dataclasses.""" def test_column_mapping_creation(self): mapping = ColumnMapping( excel_column=1, excel_header="Test Header", model_field="test_field", ) self.assertEqual(mapping.excel_column, 1) self.assertEqual(mapping.field_name, "test_field") self.assertFalse(mapping.required) def test_column_mapping_with_validator(self): mapping = ColumnMapping( excel_column=1, excel_header="ИНН", model_field="inn", required=True, validator=validate_inn, ) self.assertTrue(mapping.required) self.assertIsNotNone(mapping.validator) def test_row_data_creation(self): data = RowData( row_number=5, organization_name="Тестовая организация", inn="1234567890", ogrn="1234567890123", kpp="123456789", okpo="12345678", fields={"field1": "value1", "field2": 123}, ) self.assertEqual(data.row_number, 5) self.assertEqual(data.fields["field1"], "value1") def test_field_error_creation(self): error = FieldError( field="inn", message="Invalid INN", value="12345", ) self.assertEqual(error.field, "inn") self.assertEqual(error.message, "Invalid INN") self.assertEqual(error.value, "12345") def test_row_validation_error_creation(self): error = RowValidationError( row=10, inn="1234567890", kpp="123456789", organization_name="Тест", errors=[FieldError(field="inn", message="Invalid", value="x")], ) self.assertEqual(error.row, 10) self.assertEqual(len(error.errors), 1) def test_parse_result_creation(self): result = ParseResult( batch_id=123, loaded_count=5, skipped_count=1, errors=[], ) self.assertEqual(result.batch_id, 123) self.assertEqual(result.loaded_count, 5) self.assertEqual(result.skipped_count, 1) class BaseExcelParserTest(TestCase): """Tests for BaseExcelParser.""" def test_parser_abstract_methods(self): with self.assertRaises(TypeError): BaseExcelParser() def test_concrete_parser_implementation(self): class TestParser(BaseExcelParser): def get_column_mappings(self): return [ ColumnMapping( excel_column=1, excel_header="ИНН", model_field="inn", required=True, ), ColumnMapping( excel_column=2, excel_header="Наименование", model_field="name", ), ] def get_next_batch_id(self) -> int: return 1 def create_record(self, row_data, batch_id): return MagicMock(id=1, batch_id=batch_id, row_data=row_data) parser = TestParser() mappings = parser.get_column_mappings() self.assertEqual(len(mappings), 2) self.assertEqual(mappings[0].field_name, "inn")