File size: 4,791 Bytes
5e952bb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | import os
import json
import uuid
import tempfile
import pytest
import networkx as nx
from src.models.claim import Claim, ClaimType, Polarity, StudyDesign, Entity, EntityType
from src.models.paper import Paper
from src.models.contradiction import ContradictionPair, ContradictionType
from src.graph.claim_graph import build_claim_graph
from src.graph.graph_export import export_graph_to_cytoscape_json, export_graph_to_gexf
@pytest.fixture
def sample_data():
paper_1 = Paper(
pmid="11111",
title="Study 1 on Metformin",
authors=["Author One", "Co-Author One"],
year=2020,
journal="Journal of Diabetes",
abstract_text="Metformin reduces cancer risk."
)
paper_2 = Paper(
pmid="22222",
title="Study 2 on Metformin",
authors=["Author Two"],
year=2023,
journal="Cancer Letters",
abstract_text="Metformin increases cancer risk."
)
entity_metformin = Entity(text="Metformin", canonical_id="MeSH:D001241", entity_type=EntityType.DRUG)
entity_cancer = Entity(text="Cancer", canonical_id="MeSH:D009369", entity_type=EntityType.DISEASE)
claim_1 = Claim(
id=uuid.uuid4(),
text="Metformin reduces breast cancer risk.",
paper_id="11111",
authors=["Author One", "Co-Author One"],
year=2020,
confidence_score=1.0,
claim_type=ClaimType.CAUSAL,
polarity=Polarity.NEGATIVE,
entities=[entity_metformin, entity_cancer],
population="humans",
context="general",
quote_anchor="reduces risk",
study_design=StudyDesign.RCT
)
claim_2 = Claim(
id=uuid.uuid4(),
text="Metformin increases breast cancer risk.",
paper_id="22222",
authors=["Author Two"],
year=2023,
confidence_score=1.0,
claim_type=ClaimType.CAUSAL,
polarity=Polarity.POSITIVE,
entities=[entity_metformin, entity_cancer],
population="humans",
context="general",
quote_anchor="increases risk",
study_design=StudyDesign.RCT
)
contradiction = ContradictionPair(
claim_a=claim_1,
claim_b=claim_2,
contradiction_score=0.95,
contradiction_type=ContradictionType.DIRECTION_REVERSAL,
explanation="Claim 1 reduces risk, Claim 2 increases risk.",
scope_note="",
is_genuine=True
)
return [claim_1, claim_2], [contradiction], [paper_1, paper_2]
def test_export_graph_to_cytoscape_json(sample_data):
claims, contradictions, papers = sample_data
G = build_claim_graph(claims, contradictions, papers)
with tempfile.TemporaryDirectory() as tmpdir:
json_path = os.path.join(tmpdir, "graph.json")
export_graph_to_cytoscape_json(G, json_path)
assert os.path.exists(json_path)
with open(json_path, "r", encoding="utf-8") as f:
data = json.load(f)
# Cytoscape format should contain 'elements'
assert "elements" in data
elements = data["elements"]
assert "nodes" in elements
assert "edges" in elements
# Verify node counts (2 papers + 2 claims + 2 entities = 6 nodes)
nodes = elements["nodes"]
assert len(nodes) == 6
# Verify node properties
node_ids = {n["data"]["id"] for n in nodes}
assert "11111" in node_ids
paper_node = next(n for n in nodes if n["data"]["id"] == "11111")
assert paper_node["data"]["type"] == "paper"
assert paper_node["data"]["title"] == "Study 1 on Metformin"
assert paper_node["data"]["authors"] == ["Author One", "Co-Author One"]
claim_node = next(n for n in nodes if n["data"]["id"] == str(claims[0].id))
assert claim_node["data"]["type"] == "claim"
assert claim_node["data"]["polarity"] == Polarity.NEGATIVE.value
def test_export_graph_to_gexf(sample_data):
claims, contradictions, papers = sample_data
G = build_claim_graph(claims, contradictions, papers)
with tempfile.TemporaryDirectory() as tmpdir:
gexf_path = os.path.join(tmpdir, "graph.gexf")
export_graph_to_gexf(G, gexf_path)
assert os.path.exists(gexf_path)
# Check that the file parses correctly back using networkx GEXF reader
G_imported = nx.read_gexf(gexf_path)
assert G_imported.number_of_nodes() == 6
# Check that the paper's authors (originally a list) have been converted to a comma-separated string
paper_data = G_imported.nodes["11111"]
assert paper_data["type"] == "paper"
assert paper_data["authors"] == "Author One, Co-Author One"
|