Ctrl K
ComunidadGuías…

tests/test_citation_formats.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""
Tests for the citation formats (APA 7, DIN 1505-2).

Regression tests:
  - dict authors ({"family", "given"}) correctly become "Müller, A."
  - dict authors ({"name"}) likewise
  - dict authors ({"display_name"}, OpenAlex) likewise
  - a string author is not split into characters
  - et al. logic after 20 authors
  - empty fields are omitted without double full stops/commas
"""

import unittest

from src.pipeline.literature_check import (
    _build_apa_string,
    _build_din_string,
    _format_apa_authors,
)


class TestApaAuthors(unittest.TestCase):

    def test_dict_with_family_and_given(self):
        out = _format_apa_authors([
            {"family": "Müller", "given": "Anna"},
        ])
        self.assertEqual(out, "Müller, A.")

    def test_dict_with_name_field(self):
        out = _format_apa_authors([{"name": "Müller, Anna"}])
        self.assertIn("Müller", out)

    def test_dict_with_display_name(self):
        """OpenAlex-Format."""
        out = _format_apa_authors([{"display_name": "Hans Müller"}])
        self.assertEqual(out, "Müller, H.")

    def test_two_authors_uses_ampersand(self):
        out = _format_apa_authors([
            {"family": "Müller", "given": "Anna"},
            {"family": "Schmidt", "given": "Bernd"},
        ])
        self.assertEqual(out, "Müller, A. & Schmidt, B.")

    def test_three_to_twenty_authors(self):
        out = _format_apa_authors([
            {"family": f"A{i}", "given": "X"} for i in range(5)
        ])
        # APA 7: up to 20 name all, with ", &" before the last
        self.assertIn(", & A4, X.", out)

    def test_more_than_twenty_authors_uses_ellipsis(self):
        """APA 7 rule: after 19 a '... LastName' before the last."""
        out = _format_apa_authors([
            {"family": f"A{i:02d}", "given": "X"} for i in range(25)
        ])
        # first 19, then "... A24, X."
        self.assertIn("... A24, X.", out)
        # A20 not included
        self.assertNotIn("A20", out)

    def test_string_author_not_treated_as_iterable(self):
        """Regression: 'Müller, A.' must not be split into characters."""
        out = _format_apa_authors("Müller, A.")
        self.assertEqual(out, "Müller, A.")

    def test_empty_list(self):
        self.assertEqual(_format_apa_authors([]), "")

    def test_none(self):
        self.assertEqual(_format_apa_authors(None), "")

    def test_missing_given_only_family(self):
        out = _format_apa_authors([{"family": "Müller"}])
        self.assertEqual(out, "Müller")


class TestApaFullString(unittest.TestCase):

    def test_journal_article_full(self):
        out = _build_apa_string(
            authors=[{"family": "Müller", "given": "Anna"}],
            year="2023", title="Studie",
            journal="Journal X", volume="10", issue="2",
            pages="1-15", doi="10.1234/abc",
        )
        # Expected: "Müller, A. (2023) Studie. *Journal X*, *10*(2), 1-15. https://doi.org/..."
        self.assertIn("Müller, A.", out)
        self.assertIn("(2023)", out)
        self.assertIn("Studie", out)
        self.assertIn("*Journal X*", out)
        self.assertIn("*10*(2)", out)
        self.assertIn("1-15", out)
        self.assertIn("https://doi.org/10.1234/abc", out)

    def test_no_author_starts_with_year(self):
        out = _build_apa_string(
            authors=[], year="2020", title="Anon",
            journal="", volume="", issue="", pages="", doi="",
        )
        self.assertTrue(out.startswith("("))
        self.assertIn("2020", out)
        self.assertIn("Anon", out)

    def test_doi_link_format(self):
        out = _build_apa_string(
            authors=[{"family": "X", "given": "Y"}],
            year="2020", title="t",
            journal="", volume="", issue="", pages="",
            doi="10.1000/test",
        )
        self.assertIn("https://doi.org/10.1000/test", out)


class TestDin(unittest.TestCase):

    def test_din_basic(self):
        out = _build_din_string(
            authors=[{"family": "Müller", "given": "Anna"}],
            year="2023", title="Buch",
            journal="", volume="", issue="", pages="",
            doi="", publisher="Springer", isbn="",
            entry_type="book",
        )
        self.assertIn("Müller", out)
        self.assertIn("Buch", out)
        self.assertIn("2023", out)


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