Skip to content

Commit a066b1c

Browse files
committed
test fix/refactor
1 parent 090dc6e commit a066b1c

6 files changed

Lines changed: 189 additions & 180 deletions

File tree

src/dataverse_sdk/client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@ def get_table_info(self, logical_name: str) -> Optional[Dict[str, Any]]:
387387
Example:
388388
Retrieve table metadata::
389389
390-
info = client.get_table_info("new_sampleitem") if info:
390+
info = client.get_table_info("new_sampleitem")
391+
if info:
391392
print(f"Logical name: {info['entity_logical_name']}")
392393
print(f"Entity set: {info['entity_set_name']}")
393394
"""
@@ -407,6 +408,8 @@ def create_table(
407408
:type logical_name: str
408409
:param schema: Dictionary mapping column logical names (with prefix) to their types.
409410
411+
Supported types:
412+
410413
- Primitive types: ``"string"``, ``"int"``, ``"decimal"``, ``"float"``, ``"datetime"``, ``"bool"``
411414
- Enum subclass (IntEnum preferred): Creates a local option set. Optional multilingual
412415
labels can be provided via ``__labels__`` class attribute, defined inside the Enum subclass::

tests/unit/core/test_http_errors.py

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,13 @@
55
from dataverse_sdk.core.errors import HttpError
66
from dataverse_sdk.core import error_codes as ec
77
from dataverse_sdk.data.odata import ODataClient
8-
9-
class DummyAuth:
10-
def acquire_token(self, scope):
11-
class T: access_token = "x"
12-
return T()
13-
14-
class DummyHTTP:
15-
def __init__(self, responses):
16-
self._responses = responses
17-
def request(self, method, url, **kwargs):
18-
if not self._responses:
19-
raise AssertionError("No more responses")
20-
status, headers, body = self._responses.pop(0)
21-
class R:
22-
pass
23-
r = R()
24-
r.status_code = status
25-
r.headers = headers
26-
if isinstance(body, dict):
27-
import json
28-
r.text = json.dumps(body)
29-
def json_func(): return body
30-
r.json = json_func
31-
else:
32-
r.text = body or ""
33-
def json_fail(): raise ValueError("non-json")
34-
r.json = json_fail
35-
return r
8+
from tests.unit.test_helpers import DummyAuth, DummyHTTPClient
369

3710
class TestClient(ODataClient):
11+
"""Test client for HTTP error testing."""
3812
def __init__(self, responses):
3913
super().__init__(DummyAuth(), "https://org.example", None)
40-
self._http = DummyHTTP(responses)
14+
self._http = DummyHTTPClient(responses)
4115

4216
# --- Tests ---
4317

tests/unit/data/test_enum_optionset_payload.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,7 @@
55
from enum import Enum, IntEnum
66

77
from dataverse_sdk.data.odata import ODataClient
8-
9-
class DummyAuth:
10-
def acquire_token(self, scope): # pragma: no cover - simple stub
11-
class T:
12-
access_token = "token"
13-
return T()
14-
15-
class DummyConfig:
16-
"""Minimal config stub providing attributes ODataClient.__init__ expects."""
17-
18-
def __init__(self, language_code=1033):
19-
self.language_code = language_code
20-
# HTTP settings referenced during ODataClient construction
21-
self.http_retries = 0
22-
self.http_backoff = 0
23-
self.http_timeout = 5
8+
from tests.unit.test_helpers import DummyAuth, DummyConfig
249

2510
def _make_client(lang=1033):
2611
return ODataClient(DummyAuth(), "https://org.example", DummyConfig(language_code=lang))

tests/unit/data/test_logical_crud.py

Lines changed: 8 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,17 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT license.
33

4-
import types
54
import pytest
6-
from dataverse_sdk.data.odata import ODataClient
75
from dataverse_sdk.core.errors import MetadataError
6+
from tests.unit.test_helpers import (
7+
TestableClient,
8+
MD_ACCOUNT,
9+
make_entity_create_headers,
10+
make_entity_metadata
11+
)
812

9-
class DummyAuth:
10-
def acquire_token(self, scope):
11-
class T: access_token = "x"
12-
return T()
13-
14-
class DummyHTTPClient:
15-
def __init__(self, responses):
16-
self._responses = responses
17-
self.calls = []
18-
def request(self, method, url, **kwargs):
19-
self.calls.append((method, url, kwargs))
20-
if not self._responses:
21-
raise AssertionError("No more dummy responses configured")
22-
status, headers, body = self._responses.pop(0)
23-
resp = types.SimpleNamespace()
24-
resp.status_code = status
25-
resp.headers = headers
26-
resp.text = "" if body is None else ("{}" if isinstance(body, dict) else str(body))
27-
def raise_for_status():
28-
if status >= 400:
29-
raise RuntimeError(f"HTTP {status}")
30-
return None
31-
def json_func():
32-
return body if isinstance(body, dict) else {}
33-
resp.raise_for_status = raise_for_status
34-
resp.json = json_func
35-
return resp
36-
37-
class TestableClient(ODataClient):
38-
def __init__(self, responses):
39-
super().__init__(DummyAuth(), "https://org.example", None)
40-
self._http = DummyHTTPClient(responses)
41-
def _convert_labels_to_ints(self, logical_name, record): # pragma: no cover - test shim
42-
return record
43-
44-
# Helper metadata response for logical name resolution
45-
MD_ACCOUNT = {
46-
"value": [
47-
{
48-
"LogicalName": "account",
49-
"EntitySetName": "accounts",
50-
"PrimaryIdAttribute": "accountid"
51-
}
52-
]
53-
}
54-
55-
MD_SAMPLE = {
56-
"value": [
57-
{
58-
"LogicalName": "new_sampleitem",
59-
"EntitySetName": "new_sampleitems",
60-
"PrimaryIdAttribute": "new_sampleitemid"
61-
}
62-
]
63-
}
64-
65-
def make_entity_create_headers(entity_set, guid):
66-
return {"OData-EntityId": f"https://org.example/api/data/v9.2/{entity_set}({guid})"}
13+
# Additional metadata for this test file
14+
MD_SAMPLE = make_entity_metadata("new_sampleitem", "new_sampleitems", "new_Sampleitem", "new_sampleitemid")
6715

6816

6917
def test_single_create_update_delete_get():

tests/unit/data/test_naming_normalization.py

Lines changed: 7 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -8,86 +8,19 @@
88
and unified metadata cache introduced for explicit naming enforcement.
99
"""
1010

11-
import types
1211
import pytest
13-
from dataverse_sdk.data.odata import ODataClient
1412
from dataverse_sdk.core.errors import MetadataError
15-
16-
17-
class DummyAuth:
18-
"""Mock authentication for testing."""
19-
def acquire_token(self, scope):
20-
class T:
21-
access_token = "test_token"
22-
return T()
23-
24-
25-
class DummyHTTPClient:
26-
"""Mock HTTP client that returns pre-configured responses."""
27-
def __init__(self, responses):
28-
self._responses = responses
29-
self.calls = []
30-
31-
def request(self, method, url, **kwargs):
32-
self.calls.append((method, url, kwargs))
33-
if not self._responses:
34-
raise AssertionError("No more dummy responses configured")
35-
status, headers, body = self._responses.pop(0)
36-
resp = types.SimpleNamespace()
37-
resp.status_code = status
38-
resp.headers = headers
39-
resp.text = "" if body is None else ("{}" if isinstance(body, dict) else str(body))
40-
41-
def raise_for_status():
42-
if status >= 400:
43-
raise RuntimeError(f"HTTP {status}")
44-
return None
45-
46-
def json_func():
47-
return body if isinstance(body, dict) else {}
48-
49-
resp.raise_for_status = raise_for_status
50-
resp.json = json_func
51-
return resp
52-
53-
54-
class TestableClient(ODataClient):
55-
"""ODataClient with mocked HTTP for testing."""
56-
def __init__(self, responses):
57-
super().__init__(DummyAuth(), "https://org.example", None)
58-
self._http = DummyHTTPClient(responses)
59-
60-
def _convert_labels_to_ints(self, logical_name, record):
61-
"""Test shim - no-op conversion."""
62-
return record
63-
13+
from tests.unit.test_helpers import (
14+
TestableClient,
15+
MD_ACCOUNT,
16+
MD_SAMPLE_ITEM,
17+
make_entity_create_headers
18+
)
6419

6520
# ============================================================================
66-
# Test Data - Metadata Responses
21+
# Test Data - Additional Metadata Responses for this test file
6722
# ============================================================================
6823

69-
MD_SAMPLE_ITEM = {
70-
"value": [
71-
{
72-
"LogicalName": "new_sampleitem",
73-
"EntitySetName": "new_sampleitems",
74-
"SchemaName": "new_Sampleitem",
75-
"PrimaryIdAttribute": "new_sampleitemid"
76-
}
77-
]
78-
}
79-
80-
MD_ACCOUNT = {
81-
"value": [
82-
{
83-
"LogicalName": "account",
84-
"EntitySetName": "accounts",
85-
"SchemaName": "Account",
86-
"PrimaryIdAttribute": "accountid"
87-
}
88-
]
89-
}
90-
9124
MD_ENTITY_BY_LOGICAL = {
9225
"LogicalName": "new_sampleitem",
9326
"EntitySetName": "new_sampleitems",

0 commit comments

Comments
 (0)