Spaces:
Build error
Build error
more tests
Browse files- .coverage +0 -0
- pyproject.toml +1 -0
- tests/test_functionality.py +80 -0
.coverage
ADDED
|
Binary file (53.2 kB). View file
|
|
|
pyproject.toml
CHANGED
|
@@ -12,6 +12,7 @@ streamlit = "^1.35.0"
|
|
| 12 |
streamlit-agraph = "^0.0.45"
|
| 13 |
pyvis = "^0.3.2"
|
| 14 |
websockets = "^12.0"
|
|
|
|
| 15 |
|
| 16 |
[tool.poetry.group.dev.dependencies]
|
| 17 |
pytest = "^8.2.0"
|
|
|
|
| 12 |
streamlit-agraph = "^0.0.45"
|
| 13 |
pyvis = "^0.3.2"
|
| 14 |
websockets = "^12.0"
|
| 15 |
+
pytest-cov = "^6.1.1"
|
| 16 |
|
| 17 |
[tool.poetry.group.dev.dependencies]
|
| 18 |
pytest = "^8.2.0"
|
tests/test_functionality.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pytest
|
| 2 |
+
from unittest.mock import patch, AsyncMock, MagicMock
|
| 3 |
+
from src.graph import build_tree_structure, tree_to_dot, create_hierarchical_view
|
| 4 |
+
from src.network import make_payload, get_graph
|
| 5 |
+
from src.viz import create_pyvis_network
|
| 6 |
+
from app import get_id_from_input
|
| 7 |
+
import asyncio
|
| 8 |
+
|
| 9 |
+
# sample graph for testing
|
| 10 |
+
SAMPLE_GRAPH = {
|
| 11 |
+
"nodes": {
|
| 12 |
+
1: {"name": "Root", "year": 2000, "advisors": [], "institution": "A"},
|
| 13 |
+
2: {"name": "Child", "year": 2020, "advisors": [1], "institution": "B"},
|
| 14 |
+
3: {"name": "Grandchild", "year": 2040, "advisors": [2], "institution": "C"},
|
| 15 |
+
4: {"name": "Unrelated", "year": 1990, "advisors": [], "institution": "D"},
|
| 16 |
+
}
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
def test_build_tree_structure_basic():
|
| 20 |
+
tree = build_tree_structure(SAMPLE_GRAPH, 1)
|
| 21 |
+
# only the root node is included when root_id=1
|
| 22 |
+
assert list(tree.keys()) == [1]
|
| 23 |
+
assert tree[1]["depth"] == 0
|
| 24 |
+
assert tree[1]["advisors"] == []
|
| 25 |
+
assert tree[1]["children"] == []
|
| 26 |
+
|
| 27 |
+
def test_tree_to_dot_output():
|
| 28 |
+
dot = tree_to_dot(SAMPLE_GRAPH)
|
| 29 |
+
assert "digraph G" in dot
|
| 30 |
+
assert '"1" [label="Root (2000)"' in dot
|
| 31 |
+
assert '"2" [label="Child (2020)"' in dot
|
| 32 |
+
assert '"1" -> "2";' in dot
|
| 33 |
+
|
| 34 |
+
def test_create_hierarchical_view_nodes_edges():
|
| 35 |
+
nodes, edges = create_hierarchical_view(SAMPLE_GRAPH, 1)
|
| 36 |
+
node_ids = {n.id for n in nodes}
|
| 37 |
+
# only the root node is present
|
| 38 |
+
assert node_ids == {"1"}
|
| 39 |
+
assert edges == []
|
| 40 |
+
|
| 41 |
+
def test_make_payload_structure():
|
| 42 |
+
payload = make_payload(123)
|
| 43 |
+
assert payload["kind"] == "build-graph"
|
| 44 |
+
assert payload["options"]["reportingCallback"] is True
|
| 45 |
+
assert payload["startNodes"][0]["recordId"] == 123
|
| 46 |
+
|
| 47 |
+
@pytest.mark.asyncio
|
| 48 |
+
async def test_get_graph_mocks_websocket():
|
| 49 |
+
payload = make_payload(1)
|
| 50 |
+
fake_graph = {"kind": "graph", "payload": {"nodes": {1: {"name": "Root", "advisors": []}}}}
|
| 51 |
+
# patch websockets.connect to yield a mock websocket
|
| 52 |
+
with patch("src.network.websockets.connect", new_callable=AsyncMock) as mock_connect:
|
| 53 |
+
mock_ws = AsyncMock()
|
| 54 |
+
mock_connect.return_value.__aenter__.return_value = mock_ws
|
| 55 |
+
# simulate .recv() returning a graph message
|
| 56 |
+
mock_ws.recv = AsyncMock(side_effect=[
|
| 57 |
+
# first message: progress
|
| 58 |
+
'{"kind": "progress", "payload": {"queued": 1, "fetching": 0, "done": 0}}',
|
| 59 |
+
# second message: graph
|
| 60 |
+
'{"kind": "graph", "payload": {"nodes": {"1": {"name": "Root", "advisors": []}}}}'
|
| 61 |
+
])
|
| 62 |
+
result = await get_graph(payload)
|
| 63 |
+
assert "nodes" in result
|
| 64 |
+
assert 1 in result["nodes"] or "1" in result["nodes"]
|
| 65 |
+
|
| 66 |
+
def test_create_pyvis_network_html():
|
| 67 |
+
html = create_pyvis_network(SAMPLE_GRAPH, 1)
|
| 68 |
+
assert "<html" in html.lower()
|
| 69 |
+
assert "Root" in html
|
| 70 |
+
assert "Child" in html
|
| 71 |
+
|
| 72 |
+
@pytest.mark.parametrize("val,expected", [
|
| 73 |
+
("123", 123),
|
| 74 |
+
("0", 0),
|
| 75 |
+
("notanint", None),
|
| 76 |
+
("", None),
|
| 77 |
+
(" 42 ", 42),
|
| 78 |
+
])
|
| 79 |
+
def test_get_id_from_input(val, expected):
|
| 80 |
+
assert get_id_from_input(val) == expected
|