Skip to content

Commit d20d48e

Browse files
committed
Adding unit tests
1 parent 4fba8eb commit d20d48e

File tree

1 file changed

+257
-29
lines changed

1 file changed

+257
-29
lines changed

tests/unit/test_db.py

+257-29
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,103 @@
11
from unittest.mock import patch, MagicMock
2-
from db import search_issues
3-
from schema import IssuesParams
2+
from db import (
3+
search_issues,
4+
duck_db_connection,
5+
search_provision_summary,
6+
search_issue_type_summary,
7+
search_dataset_resource_mapping,
8+
search_endpoint_dataset_summary,
9+
get_specification,
10+
)
11+
from schema import (
12+
IssuesParams,
13+
IssueTypeSummaryParams,
14+
CommonParams,
15+
SpecificationsParams,
16+
)
417
from pagination_model import PaginatedResult
518
import pytest
19+
import json
620

21+
# Mock data
22+
mock_results_data = [
23+
{
24+
"dataset": "conservation-area",
25+
"resource": "0b4284077da580a6daea59ee2227f9c7c55a9a45d57ef470d82418a4391ddf9a",
26+
},
27+
{
28+
"dataset": "conservation-area",
29+
"resource": "test",
30+
},
31+
]
32+
mock_count = 2
733

8-
def test_search_issues():
9-
# Prepare test params
10-
params = IssuesParams(
11-
dataset="conservation-area",
12-
resource=None,
13-
field=None,
14-
issue_type=None,
34+
35+
@pytest.fixture
36+
def sample_query_params():
37+
return ["sample_value"]
38+
39+
40+
@pytest.fixture
41+
def sample_sql_count():
42+
return "SELECT COUNT(*) FROM sample_table WHERE column = ?"
43+
44+
45+
@pytest.fixture
46+
def sample_sql_results():
47+
return "SELECT * FROM sample_table WHERE column = ? LIMIT ? OFFSET ?"
48+
49+
50+
@pytest.fixture
51+
def sample_issue_params():
52+
return IssuesParams(
53+
dataset="sample_dataset",
54+
resource="abc123",
55+
field="geometry",
56+
issue_type="sample_issue",
1557
limit=10,
1658
offset=0,
1759
)
1860

19-
# Mock data
20-
mock_results_data = [
21-
{
22-
"dataset": "conservation-area",
23-
"resource": "0b4284077da580a6daea59ee2227f9c7c55a9a45d57ef470d82418a4391ddf9a",
24-
},
25-
{
26-
"dataset": "conservation-area",
27-
"resource": "test",
28-
},
29-
]
30-
mock_count = 2
3161

62+
@pytest.fixture
63+
def sample_issue_type_params():
64+
return IssueTypeSummaryParams(
65+
dataset="sample_dataset",
66+
organisation="sample_org",
67+
issueType="sample_issue",
68+
issueField=None,
69+
severity=None,
70+
responsibility=None,
71+
limit=10,
72+
offset=0,
73+
)
74+
75+
76+
@pytest.fixture
77+
def sample_common_params():
78+
return CommonParams(
79+
dataset="sample_dataset", organisation="sample_org", limit=10, offset=0
80+
)
81+
82+
83+
@pytest.fixture
84+
def sample_specification_params():
85+
return SpecificationsParams(dataset="sample_dataset", limit=10, offset=0)
86+
87+
88+
@patch("duckdb.connect")
89+
def test_search_issues(mock_connect, sample_issue_params):
3290
# Mock `duckdb.connect`
33-
with patch("duckdb.connect") as mock_connect:
34-
mock_conn = MagicMock()
35-
mock_connect.return_value.__enter__.return_value = mock_conn
3691

37-
mock_cursor = MagicMock()
38-
mock_cursor.fetchone.return_value = (mock_count,)
39-
mock_cursor.arrow.return_value.to_pylist.return_value = mock_results_data
40-
mock_conn.execute.return_value = mock_cursor
92+
mock_conn = MagicMock()
93+
mock_connect.return_value.__enter__.return_value = mock_conn
94+
95+
mock_cursor = MagicMock()
96+
mock_cursor.fetchone.return_value = (mock_count,)
97+
mock_cursor.arrow.return_value.to_pylist.return_value = mock_results_data
98+
mock_conn.execute.return_value = mock_cursor
4199

42-
result = search_issues(params)
100+
result = search_issues(sample_issue_params)
43101

44102
# Validate the results from the search
45103
assert isinstance(result, PaginatedResult)
@@ -62,3 +120,173 @@ def test_search_issues_no_dataset():
62120
IssuesParams(
63121
dataset=None, resource=None, field=None, issue_type=None, limit=10, offset=0
64122
)
123+
124+
125+
@patch("duckdb.connect")
126+
def test_search_provision_summary(mock_connect, sample_common_params):
127+
"""Test search_issue_type_summary with mocked DuckDB connection."""
128+
mock_conn = MagicMock()
129+
mock_cursor = MagicMock()
130+
131+
# Mock query results
132+
mock_cursor.fetchone.return_value = [5] # Simulated COUNT(*) result
133+
mock_cursor.arrow.return_value.to_pylist.return_value = [
134+
{
135+
"organisation": "org1",
136+
"dataset": "data1",
137+
"active_endpoint_count": 0,
138+
"error_endpoint_count": 0,
139+
},
140+
{
141+
"organisation": "org2",
142+
"dataset": "data2",
143+
"active_endpoint_count": 4,
144+
"error_endpoint_count": 1,
145+
},
146+
{
147+
"organisation": "org3",
148+
"dataset": "data3",
149+
"active_endpoint_count": 5,
150+
"error_endpoint_count": 3,
151+
},
152+
]
153+
154+
mock_conn.execute.return_value = mock_cursor
155+
mock_connect.return_value.__enter__.return_value = mock_conn
156+
157+
result = search_provision_summary(sample_common_params)
158+
159+
assert isinstance(result, PaginatedResult)
160+
assert result.total_results_available == 5
161+
assert len(result.data) == 3
162+
assert result.data[0]["organisation"] == "org1"
163+
164+
165+
@patch("duckdb.connect")
166+
def test_search_issue_type_summary(mock_connect, sample_issue_type_params):
167+
"""Test search_issue_type_summary with mocked DuckDB connection."""
168+
mock_conn = MagicMock()
169+
mock_cursor = MagicMock()
170+
171+
# Mock query results
172+
mock_cursor.fetchone.return_value = [5] # Simulated COUNT(*) result
173+
mock_cursor.arrow.return_value.to_pylist.return_value = [
174+
{
175+
"organisation": "org1",
176+
"dataset": "data1",
177+
"issue_type": "type1",
178+
"field": "field1",
179+
},
180+
{
181+
"organisation": "org2",
182+
"dataset": "data2",
183+
"issue_type": "type2",
184+
"field": "field2",
185+
},
186+
]
187+
188+
mock_conn.execute.return_value = mock_cursor
189+
mock_connect.return_value.__enter__.return_value = mock_conn
190+
191+
result = search_issue_type_summary(sample_issue_type_params)
192+
193+
assert isinstance(result, PaginatedResult)
194+
assert result.total_results_available == 5
195+
assert len(result.data) == 2
196+
assert result.data[0]["issue_type"] == "type1"
197+
198+
199+
@patch("duckdb.connect")
200+
def test_search_dataset_resource_mapping(mock_connect, sample_common_params):
201+
"""Test search_dataset_resource_mapping with mocked DuckDB connection."""
202+
mock_conn = MagicMock()
203+
mock_cursor = MagicMock()
204+
205+
mock_cursor.fetchone.return_value = [3] # Simulated COUNT(*) result
206+
mock_cursor.arrow.return_value.to_pylist.return_value = [
207+
{"dataset": "data1", "resource": "res1"},
208+
{"dataset": "data2", "resource": "res2"},
209+
]
210+
211+
mock_conn.execute.return_value = mock_cursor
212+
mock_connect.return_value.__enter__.return_value = mock_conn
213+
214+
result = search_dataset_resource_mapping(sample_common_params)
215+
216+
assert isinstance(result, PaginatedResult)
217+
assert result.total_results_available == 3
218+
assert len(result.data) == 2
219+
assert result.data[1]["dataset"] == "data2"
220+
221+
222+
@patch("duckdb.connect")
223+
def test_search_endpoint_dataset_summary(mock_connect, sample_common_params):
224+
"""Test search_endpoint_dataset_summary with mocked DuckDB connection."""
225+
mock_conn = MagicMock()
226+
mock_cursor = MagicMock()
227+
228+
mock_cursor.fetchone.return_value = [8] # Simulated COUNT(*) result
229+
mock_cursor.arrow.return_value.to_pylist.return_value = [
230+
{"dataset": "data1", "endpoint": "endpoint1"},
231+
{"dataset": "data2", "endpoint": "endpoint2"},
232+
]
233+
234+
mock_conn.execute.return_value = mock_cursor
235+
mock_connect.return_value.__enter__.return_value = mock_conn
236+
237+
result = search_endpoint_dataset_summary(sample_common_params)
238+
239+
assert isinstance(result, PaginatedResult)
240+
assert result.total_results_available == 8
241+
assert len(result.data) == 2
242+
assert result.data[0]["endpoint"] == "endpoint1"
243+
244+
245+
@patch("duckdb.connect")
246+
def test_get_specification(mock_connect, sample_specification_params, caplog):
247+
"""Test get_specification with mocked DuckDB connection."""
248+
mock_conn = MagicMock()
249+
mock_cursor = MagicMock()
250+
251+
# Mock COUNT(*) result
252+
mock_cursor.fetchone.return_value = [3]
253+
254+
# Mock JSON data results
255+
mock_cursor.arrow.return_value.to_pylist.return_value = [
256+
{"json": json.dumps({"dataset": "test_dataset", "spec": "value1"})},
257+
{"json": json.dumps({"dataset": "test_dataset", "spec": "value2"})},
258+
]
259+
260+
mock_conn.execute.return_value = mock_cursor
261+
mock_connect.return_value.__enter__.return_value = mock_conn
262+
263+
result = get_specification(sample_specification_params)
264+
265+
# Assertions on return value
266+
assert isinstance(result, PaginatedResult)
267+
assert result.total_results_available == 3
268+
assert len(result.data) == 2
269+
assert result.data[0]["dataset"] == "test_dataset"
270+
assert result.data[1]["spec"] == "value2"
271+
272+
273+
@patch("duckdb.connect")
274+
def test_duck_db_connection_exception(
275+
mock_connect,
276+
sample_issue_params,
277+
sample_query_params,
278+
sample_sql_count,
279+
sample_sql_results,
280+
):
281+
mock_conn = MagicMock()
282+
mock_conn.execute.side_effect = Exception("Database error") # Simulate an error
283+
284+
mock_connect.return_value.__enter__.return_value = mock_conn
285+
286+
with pytest.raises(Exception, match="Database error"):
287+
duck_db_connection(
288+
sample_issue_params,
289+
sample_query_params,
290+
sample_sql_count,
291+
sample_sql_results,
292+
)

0 commit comments

Comments
 (0)