103 lines
4.2 KiB
Python
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 & 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()
|