"""Behavioral tests for the executable module 02 catalog example."""

import unittest

from catalog_core import (
    add_position,
    catalog_summary,
    find_by_article,
    missing_fields,
    normalize_article,
    search_by_name,
)


class CatalogCoreTests(unittest.TestCase):
    def setUp(self):
        self.source = {
            "article": " lo 100 ",
            "name": "Лоток перфорированный",
            "quantity": 2,
            "unit_price": 125.50,
        }

    def test_normalize_article_removes_whitespace(self):
        self.assertEqual(normalize_article(" lo\t 100 "), "LO100")
        self.assertEqual(normalize_article(" bx-10 "), "BX-10")

    def test_add_normalizes_and_rejects_equivalent_duplicate(self):
        catalog = []

        self.assertTrue(add_position(catalog, self.source))
        self.assertFalse(add_position(catalog, {**self.source, "article": "LO100"}))
        self.assertFalse(add_position(catalog, {**self.source, "article": "lo 100"}))

        self.assertEqual(len(catalog), 1)
        self.assertEqual(catalog[0]["article"], "LO100")

    def test_add_stores_a_copy(self):
        catalog = []
        self.assertTrue(add_position(catalog, self.source))

        self.source["name"] = "Изменено снаружи"
        self.source["quantity"] = 999

        self.assertEqual(catalog[0]["name"], "Лоток перфорированный")
        self.assertEqual(catalog[0]["quantity"], 2)

    def test_missing_field_is_rejected_without_mutation(self):
        catalog = []
        incomplete = self.source.copy()
        incomplete.pop("unit_price")

        self.assertEqual(missing_fields(incomplete), ["unit_price"])
        self.assertFalse(add_position(catalog, incomplete))
        self.assertEqual(catalog, [])

    def test_find_and_name_search(self):
        catalog = []
        self.assertTrue(add_position(catalog, self.source))

        self.assertIsNotNone(find_by_article(catalog, "LO100"))
        self.assertEqual(search_by_name(catalog, "ЛОТОК"), catalog)
        self.assertEqual(search_by_name(catalog, "   "), [])

    def test_summary_matches_control_values(self):
        catalog = []
        positions = [
            self.source,
            {
                "article": "CB200",
                "name": "Кабель силовой",
                "quantity": 20,
                "unit_price": 180.0,
            },
            {
                "article": "BX-10",
                "name": "Коробка монтажная",
                "quantity": 0,
                "unit_price": 95.0,
            },
        ]

        for position in positions:
            self.assertTrue(add_position(catalog, position))

        self.assertEqual(catalog_summary(catalog), (3, 22, 3851.0))


if __name__ == "__main__":
    unittest.main()
