paper_server/apps/resm/test_title_utils.py

103 lines
4.2 KiB
Python

import os
import tempfile
import types
import unittest
from unittest.mock import patch
from apps.resm.title_utils import (
assess_title,
extract_title_from_pdf,
extract_title_from_xml,
is_better_title,
)
class TitleAssessmentTests(unittest.TestCase):
def test_normal_title_is_not_suspect(self):
result = assess_title("Optimal Nonlinear PID Speed Control for an Electric Vehicle")
self.assertFalse(result.suspect)
def test_abstract_stored_as_title_is_suspect(self):
text = (
"In many situations, a beam opening is necessary near a plastic hinge. "
"However, few studies investigated the resulting behavior. "
"In this study, nine full-scale joints were tested with several configurations. "
"The results show that additional reinforcement improves strength and ductility. "
) * 2
result = assess_title(text)
self.assertTrue(result.suspect)
self.assertIn("abstract_like_prose", result.reasons)
def test_mathml_markup_does_not_trigger_raw_length_false_positive(self):
markup = "<mml:math>" + "<mml:mi>x</mml:mi>" * 100 + "</mml:math>"
result = assess_title(f"Behavior of {markup} under pressure")
self.assertFalse(result.suspect)
def test_short_candidate_is_better_than_abstract(self):
old = ("This study investigates reinforced concrete joints. " * 20).strip()
new = "Cyclic Behavior of Reinforced Concrete Beam-Column Joints"
self.assertTrue(is_better_title(old, new))
class XmlTitleExtractionTests(unittest.TestCase):
def _xml_file(self, body):
handle = tempfile.NamedTemporaryFile("w", suffix=".xml", delete=False, encoding="utf-8")
self.addCleanup(lambda: os.path.exists(handle.name) and os.unlink(handle.name))
handle.write(body)
handle.close()
return handle.name
def test_extracts_elsevier_title_and_verifies_doi(self):
path = self._xml_file("""<?xml version="1.0"?>
<response xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:prism="http://prismstandard.org/namespaces/basic/2.0/">
<coredata>
<prism:doi>10.1234/example.1</prism:doi>
<dc:title>Correct &amp; Verified Article Title</dc:title>
</coredata>
</response>""")
candidate = extract_title_from_xml(path, "10.1234/example.1")
self.assertIsNotNone(candidate)
self.assertEqual(candidate.title, "Correct & Verified Article Title")
self.assertEqual(candidate.confidence, "high")
def test_rejects_xml_for_another_doi(self):
path = self._xml_file("""<article>
<article-meta><article-id pub-id-type="doi">10.1234/wrong</article-id>
<title-group><article-title>A Correct Looking Title</article-title></title-group>
</article-meta></article>""")
candidate = extract_title_from_xml(path, "10.1234/expected")
self.assertIsNone(candidate)
class PdfTitleExtractionTests(unittest.TestCase):
def test_pdf_metadata_requires_identity_evidence_and_stays_medium(self):
handle = tempfile.NamedTemporaryFile("wb", suffix=".pdf", delete=False)
self.addCleanup(lambda: os.path.exists(handle.name) and os.unlink(handle.name))
handle.write(b"%PDF-placeholder")
handle.close()
page = types.SimpleNamespace(
extract_text=lambda: (
"Correct Article Title\nMohamed Shamseldin\n"
"https://doi.org/10.1234/example.1\nAbstract"
)
)
reader = types.SimpleNamespace(
pages=[page],
metadata=types.SimpleNamespace(title="Correct Article Title"),
)
module = types.SimpleNamespace(PdfReader=lambda *args, **kwargs: reader)
with patch.dict("sys.modules", {"pypdf": module}):
candidate = extract_title_from_pdf(
handle.name, "10.1234/example.1", "Mohamed Shamseldin"
)
self.assertIsNotNone(candidate)
self.assertEqual(candidate.title, "Correct Article Title")
self.assertEqual(candidate.confidence, "medium")
self.assertEqual(candidate.evidence, "pdf_metadata+doi")
if __name__ == "__main__":
unittest.main()