113 lines
6.1 KiB
Python
113 lines
6.1 KiB
Python
import pytest
|
||
|
||
from app.services import publication_vak as vak
|
||
from app.services.publication_quartiles import catalog_entries, sjr_entries, index_sjr
|
||
|
||
|
||
@pytest.fixture()
|
||
def index(monkeypatch):
|
||
k1 = {"category": "К1", "journal": "Первый журнал", "source_row": 1, "issns": ["00063835"]}
|
||
k2 = {"category": "К2", "journal": "Второй журнал", "source_row": 2, "issns": []}
|
||
monkeypatch.setattr(vak, "category_index", lambda: ({"первый журнал": [k1], "второй журнал": [k2]}, {"00063835": [k1]}))
|
||
return k1, k2
|
||
|
||
|
||
def test_vak_identifies_k1_by_issn_without_guessing_translated_names(index):
|
||
result = vak.assess_vak(["English title"], ["0006-3835"])
|
||
assert result["status"] == "found" and result["entries"][0]["category"] == "К1"
|
||
assert result["entries"][0]["identity_confirmed"] and not result["historical_category_confirmed"]
|
||
|
||
|
||
def test_k2_name_match_is_explicitly_preliminary(index):
|
||
result = vak.assess_vak([" Второй журнал. "], [])
|
||
assert result["entries"][0]["category"] == "К2"
|
||
assert not result["entries"][0]["identity_confirmed"]
|
||
assert result["entries"][0]["match_method"] == "normalized_name"
|
||
|
||
|
||
def test_vak_conflicting_identifiers_and_multiple_journals_are_not_unioned(index):
|
||
assert vak.assess_vak(["Первый журнал"], ["1111-1111"])["status"] == "journal_identity_conflict"
|
||
assert vak.assess_vak(["Первый журнал", "Второй журнал"], [])["status"] == "ambiguous_journal"
|
||
assert vak.assess_vak([], [])["status"] == "unknown_journal"
|
||
assert vak.assess_vak(["Другой журнал"], [])["status"] == "not_found_in_k1_k2"
|
||
|
||
|
||
def test_committed_category_snapshots_match_known_journal_and_record_sources():
|
||
vak.category_index.cache_clear()
|
||
result = vak.assess_vak(["Бизнес-информатика"], [])
|
||
assert result["status"] == "found" and result["entries"][0]["category"] == "К1"
|
||
assert result["entries"][0]["source_sha256"] and result["entries"][0]["categorized_on"]
|
||
|
||
|
||
def test_all_catalog_systems_keep_their_own_metric_year_and_multiple_categories(monkeypatch):
|
||
metrics = [{"year": year, "system": system, "quartile": quarter, "metric": metric,
|
||
"category": category, "source": "Snapshot", "source_url": "https://example.org/source"}
|
||
for year, system, quarter, metric, category in [(2024, "Scopus", "Q1", "CiteScore", "Analysis"),
|
||
(2024, "Scopus", "Q2", "CiteScore", "Applied Mathematics"), (2025, "Web of Science", "Q3", "JCR", "Mathematics")]]
|
||
monkeypatch.setattr("app.services.publication_quartiles.publication_catalog", lambda ids, names: ([{"name": "Journal", "metrics": metrics}], []))
|
||
metadata = {"type": "journal-article", "years": [2024], "issns": ["0006-3835"]}
|
||
result, status = catalog_entries(metadata, 2024, True)
|
||
assert status == "found_latest" and len(result) == 3
|
||
assert {(r["system"], r["quartile"], r["metric_year"]) for r in result} == {
|
||
("Scopus", "Q1", 2024), ("Scopus", "Q2", 2024), ("Web of Science", "Q3", 2025)}
|
||
|
||
|
||
def test_book_container_title_is_not_treated_as_a_vak_journal(monkeypatch, tmp_path):
|
||
from sqlalchemy import create_engine, select
|
||
from sqlalchemy.orm import Session
|
||
from app.db import Base
|
||
from app.models import Employee, EmployeePublication
|
||
from scripts.enrich_publication_quartiles import main
|
||
url = "sqlite:///" + str(tmp_path / "books.db")
|
||
engine = create_engine(url)
|
||
Base.metadata.create_all(engine)
|
||
with Session(engine) as session:
|
||
employee = Employee(profile_key="test", canonical_url="https://example.org/person")
|
||
session.add(employee)
|
||
session.flush()
|
||
session.add(EmployeePublication(employee_id=employee.id, title="Chapter", year=2024, publication_type="CHAPTER",
|
||
source_hash="hash", doi_url="10.1234/chapter", raw_data={}))
|
||
session.commit()
|
||
monkeypatch.setenv("DATABASE_URL", url)
|
||
monkeypatch.setattr("scripts.enrich_publication_quartiles.resolve_doi", lambda *args: {
|
||
"status": "resolved", "type": "book-chapter", "journals": ["Бизнес-информатика"], "issns": [], "years": [2024]})
|
||
monkeypatch.setattr("sys.argv", ["enrich", "--apply", "--lookup-doi", "--check-vak", "--all-systems",
|
||
"--cache-dir", str(tmp_path / "cache"), "--report", str(tmp_path / "report.json")])
|
||
main()
|
||
with Session(engine) as session:
|
||
publication = session.scalar(select(EmployeePublication))
|
||
assert publication.vak_categories["status"] == "unknown_journal"
|
||
assert publication.vak_categories["entries"] == [] and publication.quartiles["entries"] == []
|
||
|
||
|
||
@pytest.mark.parametrize("raw,expected", [
|
||
({"journal": "Первый журнал", "issn": "1111-1111"}, "journal_identity_conflict"),
|
||
({"issn": "0006-3835"}, "found"),
|
||
({"eissn": "0006-3835"}, "found"),
|
||
({"csv_enrichment": {"ISSN": "0006-3835"}}, "found"),
|
||
])
|
||
def test_cli_checks_original_issn_even_without_doi(index, monkeypatch, tmp_path, raw, expected):
|
||
from sqlalchemy import create_engine, select
|
||
from sqlalchemy.orm import Session
|
||
from app.db import Base
|
||
from app.models import Employee, EmployeePublication
|
||
from scripts.enrich_publication_quartiles import main
|
||
url = "sqlite:///" + str(tmp_path / "vak.db")
|
||
engine = create_engine(url)
|
||
Base.metadata.create_all(engine)
|
||
with Session(engine) as session:
|
||
person = Employee(profile_key="test", canonical_url="https://example.org/person")
|
||
session.add(person)
|
||
session.flush()
|
||
session.add(EmployeePublication(employee_id=person.id, title="Work", year=2024, source_hash="hash", raw_data=raw))
|
||
session.commit()
|
||
monkeypatch.setenv("DATABASE_URL", url)
|
||
monkeypatch.setattr("sys.argv", ["enrich", "--apply", "--check-vak", "--cache-dir", str(tmp_path / "cache"),
|
||
"--report", str(tmp_path / "report.json")])
|
||
main()
|
||
with Session(engine) as session:
|
||
publication = session.scalar(select(EmployeePublication))
|
||
assert publication.vak_categories["status"] == expected
|
||
if expected == "found":
|
||
assert publication.vak_categories["entries"][0]["identity_confirmed"]
|