Skip to content

Commit 87ac0f9

Browse files
authored
Merge pull request DIMO-Network#21 from ardevd/unit-testing
test: added unit test for SDK root code. Added github actions
2 parents 40aef81 + 4103d4c commit 87ac0f9

5 files changed

Lines changed: 145 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Python application
2+
3+
on:
4+
push:
5+
branches: [ "master" ]
6+
pull_request:
7+
branches: [ "master" ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
max-parallel: 4
17+
matrix:
18+
python-version: ["3.13"]
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
- name: Set up Python ${{ matrix.python-version }}
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: ${{ matrix.python-version }}
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install flake8 pytest coverage
30+
pip install -r requirements.txt
31+
- name: Lint with flake8
32+
run: |
33+
# stop the build if there are Python syntax errors or undefined names
34+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
35+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
36+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
37+
- name: DIMO Api test
38+
run: |
39+
PYTHONPATH=$(pwd) coverage run -m pytest -v && coverage xml -o coverage.xml

tests/__init__.py

Whitespace-only changes.

tests/test_dimo.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from unittest.mock import MagicMock
2+
3+
from dimo.dimo import DIMO
4+
5+
6+
def test_get_full_path_no_params():
7+
client = DIMO(env="Dev")
8+
result = client._get_full_path("Valuations", "/v2/vehicles/1234/valuations")
9+
assert result == "https://valuations-api.dev.dimo.zone/v2/vehicles/1234/valuations"
10+
11+
12+
def test_get_full_path_with_params():
13+
client = DIMO(env="Dev")
14+
result = client._get_full_path(
15+
"Telemetry",
16+
"/items/:item_id",
17+
{"item_id": 123, "detail_id": "abc"},
18+
)
19+
assert result == "https://telemetry-api.dev.dimo.zone/query/items/123"
20+
21+
22+
def test_get_auth_headers():
23+
client = DIMO(env="Dev")
24+
headers = client._get_auth_headers("token123")
25+
assert headers == {
26+
"Authorization": "Bearer token123",
27+
"Content-Type": "application/json",
28+
}
29+
30+
31+
def test_query_calls_request_with_correct_payload(monkeypatch):
32+
client = DIMO(env="Dev")
33+
# Create a fake request method on the client
34+
fake_request = MagicMock(return_value={"data": {"result": True}})
35+
monkeypatch.setattr(client, "request", fake_request)
36+
37+
query_str = "query { test }"
38+
variables = {"key": "value"}
39+
result = client.query("Trips", query_str, variables=variables, token="mocked_token")
40+
41+
# Verify the fake request was invoked once
42+
fake_request.assert_called_once()
43+
# Inspect call arguments
44+
args, kwargs = fake_request.call_args
45+
assert args[0] == "POST"
46+
assert args[1] == "Trips"
47+
assert args[2] == ""
48+
49+
# Assert correct headers
50+
headers = kwargs["headers"]
51+
assert headers["Authorization"] == "Bearer mocked_token"
52+
assert headers["Content-Type"] == "application/json"
53+
assert headers["User-Agent"] == "dimo-python-sdk"
54+
55+
# Check payload data
56+
data = kwargs["data"]
57+
assert data["query"] == query_str
58+
assert data["variables"] == variables
59+
60+
assert result == {"data": {"result": True}}

tests/test_errors.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import pytest
2+
from dimo.errors import DimoTypeError, check_type, check_optional_type
3+
4+
5+
def test_check_type_passes_for_correct_type():
6+
# call check_type with valid args which should not raise anything
7+
check_type("count", 5, int)
8+
9+
10+
def test_check_type_raises_for_incorrect_type():
11+
with pytest.raises(DimoTypeError) as exc:
12+
check_type("name", 123, str)
13+
err = exc.value
14+
assert err.param_name == "name"
15+
assert err.expected_type is str
16+
assert isinstance(err.actual_value, int)
17+
18+
assert "name must be a str" in str(err)
19+
assert "but was entered as type int" in str(err)
20+
21+
22+
def test_check_optional_type_allows_none():
23+
# None is allowed
24+
check_optional_type("maybe", None, dict)
25+
26+
27+
def test_check_optional_type_raises_for_wrong_non_none():
28+
with pytest.raises(DimoTypeError) as exc:
29+
check_optional_type("maybe", 3.14, str)
30+
err = exc.value
31+
assert err.param_name == "maybe"
32+
assert err.expected_type is str
33+
assert isinstance(err.actual_value, float)

tests/test_permission_decoder.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from dimo.permission_decoder import PermissionDecoder
2+
3+
4+
def test_dimo_client_hex_to_permissions():
5+
permissions_hex = "0x3ffc"
6+
permissions_list = PermissionDecoder.decode_permission_bits(permissions_hex)
7+
assert permissions_list == [1, 2, 3, 4, 5, 6]
8+
9+
one_to_five_hex = "0xffc"
10+
assert PermissionDecoder.decode_permission_bits(one_to_five_hex) == [1, 2, 3, 4, 5]
11+
12+
another_hex = "0x3fcc"
13+
assert PermissionDecoder.decode_permission_bits(another_hex) == [1, 3, 4, 5, 6]

0 commit comments

Comments
 (0)