Skip to content

Commit 67e3470

Browse files
committed
Add pytest support and first unit test
1 parent 81c5f2d commit 67e3470

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed

conftest.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# grequests must be imported before any module not designed for reentrancy,
2+
# because it relies on aggressive monkey patching that breaks if done after many
3+
# other common module imports, e.g. ssl.
4+
#
5+
# So we import it before everything else. For details see:
6+
# https://github.com/gevent/gevent/issues/1016#issuecomment-328530533
7+
# https://github.com/spyoungtech/grequests/issues/8
8+
import grequests
9+
################
10+
11+
import logging
12+
import os
13+
14+
import requests
15+
import pytest
16+
17+
import nucleus
18+
19+
20+
assert 'PYTEST_API_KEY' in os.environ, \
21+
"You must set the 'PYTEST_API_KEY' environment variable to a valid " \
22+
"Nucleus API key to run the test suite"
23+
24+
API_KEY = os.environ['PYTEST_API_KEY']
25+
26+
27+
@pytest.fixture(scope='session')
28+
def monkeypatch_session(request):
29+
""" This workaround is needed to allow monkeypatching in session-scoped fixtures.
30+
31+
See https://github.com/pytest-dev/pytest/issues/363
32+
"""
33+
from _pytest.monkeypatch import MonkeyPatch
34+
mpatch = MonkeyPatch()
35+
yield mpatch
36+
mpatch.undo()
37+
38+
39+
@pytest.fixture(scope='session')
40+
def CLIENT(monkeypatch_session):
41+
client = nucleus.NucleusClient(API_KEY)
42+
43+
# Change _make_request to raise AsssertionErrors when the
44+
# HTTP status code is not successful, so that tests fail if
45+
# the request was unsuccessful.
46+
def _make_request_patch(
47+
payload: dict, route: str, requests_command=requests.post
48+
) -> dict:
49+
response = client._make_request_raw(payload, route, requests_command)
50+
assert response.status_code in [200, 201], \
51+
f"HTTP response had status code: {response.status_code}. " \
52+
f"Full JSON: {response.json()}"
53+
return response.json()
54+
55+
monkeypatch_session.setattr(client, "_make_request", _make_request_patch)
56+
return client

nucleus/__init__.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,11 +878,13 @@ def _make_grequest(
878878
)
879879
return post
880880

881-
def _make_request(
881+
def _make_request_raw(
882882
self, payload: dict, route: str, requests_command=requests.post
883883
) -> dict:
884884
"""
885-
makes a request to Nucleus endpoint
885+
Makes a request to Nucleus endpoint. This method returns the raw
886+
requests.Response object which is useful for unit testing.
887+
886888
:param payload: given payload
887889
:param route: route for the request
888890
:param requests_command: requests.post, requests.get, requests.delete
@@ -899,7 +901,23 @@ def _make_request(
899901
)
900902
logger.info("API request has response code %s", response.status_code)
901903

902-
if response.status_code != 200:
904+
return response
905+
906+
def _make_request(
907+
self, payload: dict, route: str, requests_command=requests.post
908+
) -> dict:
909+
"""
910+
Makes a request to Nucleus endpoint and logs a warning if not
911+
successful.
912+
913+
:param payload: given payload
914+
:param route: route for the request
915+
:param requests_command: requests.post, requests.get, requests.delete
916+
:return: response JSON
917+
"""
918+
response = self._make_request_raw(payload, route, requests_command)
919+
920+
if response.status_code not in [200, 201]:
903921
logger.warning(response)
904922

905923
return (

tests/test_dataset.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import pytest
2+
3+
import nucleus
4+
from nucleus import Dataset
5+
6+
7+
TEST_DATASET_NAME = '[PyTest] Test Dataset'
8+
9+
def test_dataset_create_and_delete(CLIENT):
10+
# Creation
11+
ds = CLIENT.create_dataset(TEST_DATASET_NAME)
12+
assert isinstance(ds, Dataset)
13+
14+
# Deletion
15+
response = CLIENT.delete_dataset(ds.id)

0 commit comments

Comments
 (0)