| 217 | await _fetch_paper_source(RawText(text="no physical pages")) |
| 218 | |
| 219 | async def test_doi_requires_an_exact_pdf_resolver(self) -> None: |
| 220 | with self.assertRaises(NotImplementedError): |
| 221 | await _fetch_paper_source(DoiIdentifier(doi="10.1000/test")) |
| 222 | |
| 223 | |
| 224 | class CitationValidationTests(unittest.TestCase): |
| 225 | def test_unknown_chunk_page_and_quote_are_rejected(self) -> None: |
| 226 | result = build_paper_result() |
| 227 | cfg = PaperSemanticCfg( |
| 228 | min_summary_citations=1, |
| 229 | min_summary_pages=1, |
| 230 | ) |
| 231 | invalid_drafts = ( |
| 232 | PaperSummaryDraft( |
| 233 | summary="x", |
| 234 | citations=( |
| 235 | PaperSummaryCitationDraft( |
| 236 | chunk_index=99, |
| 237 | page_number=1, |
| 238 | ), |
| 239 | ), |
| 240 | ), |
| 241 | PaperSummaryDraft( |
| 242 | summary="x", |
| 243 | citations=( |
| 244 | PaperSummaryCitationDraft( |
| 245 | chunk_index=0, |
| 246 | page_number=2, |
| 247 | ), |
| 248 | ), |
| 249 | ), |
| 250 | PaperSummaryDraft( |
| 251 | summary="x", |
| 252 | citations=( |
| 253 | PaperSummaryCitationDraft( |
| 254 | chunk_index=0, |
| 255 | page_number=1, |
| 256 | quote="not in source chunk", |
| 257 | ), |
| 258 | ), |
| 259 | ), |
| 260 | ) |
| 261 | |
| 262 | for draft in invalid_drafts: |
| 263 | with self.subTest(draft=draft): |
| 264 | with self.assertRaises(PaperCitationValidationError): |
| 265 | _build_summary( |
| 266 | result.chunk_set, |
| 267 | draft, |
| 268 | cfg, |
| 269 | ) |
| 270 | |
| 271 | def test_configured_citation_and_page_coverage_is_enforced(self) -> None: |
| 272 | result = build_paper_result() |
| 273 | draft = PaperSummaryDraft( |
| 274 | summary="x", |
| 275 | citations=( |
| 276 | PaperSummaryCitationDraft(chunk_index=0, page_number=1), |
nothing calls this directly
no outgoing calls
no test coverage detected