115 lines
6.7 KiB
Python
115 lines
6.7 KiB
Python
"""Pinned T78 evidence, edition-local aliases and an explicitly identified material."""
|
|
import copy
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import sqlite3
|
|
import tempfile
|
|
import unittest
|
|
import xml.etree.ElementTree as ET
|
|
|
|
from paper_atlas.collectors.acl import collect_xml, volume_scope
|
|
from paper_atlas.collectors.acl_historical import event_scope, material_reason
|
|
from paper_atlas.db.store import Store
|
|
from paper_atlas.ingestion.records import ingest_file
|
|
|
|
FIXTURE = Path(__file__).parent/'fixtures/acl-t78.xml'
|
|
COMMIT = 'a7be623d01c48c61405dec31c871121cdbed5a01'
|
|
|
|
|
|
class AclHistoricalTests(unittest.TestCase):
|
|
def setUp(self):
|
|
self.root = ET.parse(FIXTURE).getroot()
|
|
self.volume = self.root.find('volume')
|
|
self.meta = self.volume.find('meta')
|
|
|
|
def test_frozen_volume_matches_official_snapshot(self):
|
|
self.assertEqual(hashlib.sha256(FIXTURE.read_bytes()).hexdigest(), 'f712f94cff0cba05f786b7ac31dad2ea9408fde2a17a04531130df623f57dd84')
|
|
self.assertEqual(len(self.volume.findall('paper')), 36)
|
|
self.assertEqual(volume_scope(self.meta, '1', 'T78'), ('ACL+TINLAP', ['ACL', 'TINLAP'], 'proceedings_unspecified'))
|
|
|
|
def test_unknown_year_collection_or_volume_is_not_globally_aliased(self):
|
|
for collection, volume in [('T75', '1'), ('T87', '1'), ('T78', '2'), ('C65', '1')]:
|
|
with self.subTest(collection=collection, volume=volume):
|
|
self.assertIsNone(event_scope(self.meta, volume, collection))
|
|
self.assertIsNone(volume_scope(self.meta, volume, collection))
|
|
self.assertIsNone(volume_scope(self.meta, '1'))
|
|
|
|
def test_known_volume_scope_rejects_critical_metadata_drift(self):
|
|
for field, replacement in [('venue', 'acl'), ('year', '1979'), ('booktitle', 'Another TINLAP'), ('editor/first', 'Another')]:
|
|
changed = copy.deepcopy(self.meta)
|
|
changed.find(field).text = replacement
|
|
with self.subTest(field=field), self.assertRaises(ValueError):
|
|
event_scope(changed, '1', 'T78')
|
|
changed = copy.deepcopy(self.meta)
|
|
ET.SubElement(changed, 'year').text = '1978'
|
|
with self.assertRaises(ValueError):
|
|
event_scope(changed, '1', 'T78')
|
|
|
|
def test_evidence_retains_original_series_dates_and_role_boundary(self):
|
|
scope = event_scope(self.meta, '1', 'T78')
|
|
self.assertEqual(scope['original_venue'], 'TINLAP')
|
|
self.assertEqual(scope['event_dates'], ['1978-07-25', '1978-07-27'])
|
|
self.assertEqual([e['pdf_pages'] for e in scope['evidence']], [[9, 10], [3]])
|
|
self.assertIn('not identified', scope['track_scope_note'])
|
|
self.assertIn('pending', scope['evidence'][0]['scope'])
|
|
|
|
def test_only_exact_session_questions_material_is_excluded(self):
|
|
paper = copy.deepcopy(self.volume.findall('paper')[-1])
|
|
self.assertIn('Session question list', material_reason('T78', '1', paper))
|
|
self.assertIsNone(material_reason('C65', '1', paper))
|
|
self.assertIsNone(material_reason('T78', '2', paper))
|
|
paper.set('id', '37')
|
|
self.assertIsNone(material_reason('T78', '1', paper))
|
|
paper.set('id', '36')
|
|
ET.SubElement(paper, 'author')
|
|
with self.assertRaises(ValueError):
|
|
material_reason('T78', '1', paper)
|
|
|
|
def test_all_authored_source_fields_and_material_receipt_survive_collection(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
manifest, = collect_xml(FIXTURE, temporary, COMMIT)
|
|
rows = [json.loads(raw) for raw in Path(manifest['file']).read_text().splitlines()]
|
|
self.assertEqual(manifest['count'], 35)
|
|
self.assertEqual(manifest['xml_paper_elements'], 36)
|
|
self.assertEqual(manifest['missing_abstract_count'], 35)
|
|
self.assertEqual(manifest['excluded_materials'][0]['external_id'], 'T78-1036')
|
|
for number, row in enumerate(rows, 1):
|
|
paper = self.volume.findall('paper')[number-1]
|
|
self.assertEqual(row['external_id'], f'T78-1{number:03d}')
|
|
self.assertEqual(row['title'], ' '.join(''.join(paper.find('title').itertext()).split()))
|
|
self.assertEqual(row['metadata']['venue_codes'], ['tinlap'])
|
|
self.assertEqual(row['metadata']['historical_event_scope']['original_venue'], 'TINLAP')
|
|
self.assertEqual(row['metadata']['metadata_commit'], COMMIT)
|
|
self.assertEqual((row['status'], row['track'], row['abstract']), ('accepted', 'proceedings_unspecified', None))
|
|
|
|
def test_old_coling_scope_is_unchanged_by_calendar_replacement_evidence(self):
|
|
meta = ET.fromstring('<meta><venue>coling</venue><year>1965</year><booktitle>COLING 1965</booktitle></meta>')
|
|
self.assertEqual(volume_scope(meta, '1', 'C65'), ('COLING', ['COLING'], 'main'))
|
|
self.assertIsNone(event_scope(meta, '1', 'C65'))
|
|
|
|
def test_native_ingestion_does_not_alias_other_tinlap_years_or_infer_negative_status(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root = Path(temporary)
|
|
manifest, = collect_xml(FIXTURE, root/'source', COMMIT)
|
|
db = root/'sample.sqlite'
|
|
store = Store(db)
|
|
pid, rid = store.record('test_control', 'tinlap1975', 'https://example.org/tinlap1975',
|
|
'An earlier TINLAP contribution', None, ['Jane Doe'])
|
|
store.decision(pid, rid, 'TINLAP', 1975, 'main', 'tinlap1975', 'https://example.org/tinlap1975', 'accepted', 'test control')
|
|
store.conn.commit()
|
|
store.conn.close()
|
|
ingest_file(db, manifest['file'])
|
|
ingest_file(db, manifest['file'])
|
|
with sqlite3.connect(db) as c:
|
|
self.assertEqual(c.execute('SELECT count(*) FROM papers').fetchone()[0], 36)
|
|
self.assertEqual(c.execute('SELECT count(*) FROM submissions').fetchone()[0], 36)
|
|
self.assertEqual(c.execute('SELECT count(*) FROM decisions').fetchone()[0], 36)
|
|
self.assertEqual(c.execute("SELECT count(*) FROM decisions WHERE status!='accepted'").fetchone()[0], 0)
|
|
self.assertIsNone(c.execute("SELECT 1 FROM source_records WHERE external_id='T78-1036'").fetchone())
|
|
aliases = c.execute('SELECT v.acronym,a.alias FROM venue_aliases a JOIN venues v ON v.id=a.venue_id ORDER BY a.alias').fetchall()
|
|
self.assertEqual(aliases, [('ACL+TINLAP', 'ACL'), ('ACL+TINLAP', 'TINLAP')])
|
|
metadata = json.loads(c.execute("SELECT metadata_json FROM source_records WHERE external_id='T78-1001'").fetchone()[0])
|
|
self.assertEqual(metadata['historical_event_scope']['event_year'], 1978)
|
|
self.assertEqual(c.execute('PRAGMA foreign_key_check').fetchall(), [])
|