Skip to content

Commit

Permalink
add: e2e tests for entities and entity lists
Browse files Browse the repository at this point in the history
- fix: entity.py `create()` should send JSON not form-encoded data
- fix: projects.py typo in comment
- chg: readme.md make description generic rather than listing everything
- add: test entity_lists.py creation of test fixture with properties
- add: e2e test cases for entities and entity_lists functionality
  • Loading branch information
lindsay-stevens committed Apr 17, 2024
1 parent 5530d12 commit 1715fdd
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ For interactive testing, debugging, or sanity checking workflows, end-to-end tes
1. Create a test project in Central.
2. Create a test user in Central. It can be a site-wide Administrator. If it is not an Administrator, assign the user to the project with "Project Manager" privileges, so that forms and submissions in the test project can be uploaded and modified.
3. Save the user's credentials and the project ID in a `.pyodk_config.toml` (or equivalent) as described in the above section titled "Configure".
4. When the tests in `test_client.py` are run, the test setup method should automatically create a few forms and submissions for testing with. At a minimum these allow the tests to pass, but can also be used to interactively test or debug.
4. When the tests in `test_client.py` are run, the test setup method should automatically create a few fixtures for testing with. At a minimum these allow the tests to pass, but can also be used to interactively test or debug.


## Release
Expand Down
2 changes: 1 addition & 1 deletion pyodk/_endpoints/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def create(
method="POST",
url=self.session.urlformat(self.urls.post, project_id=pid, el_name=eln),
logger=log,
data=req_data,
json=req_data,
)
data = response.json()
return Entity(**data)
Expand Down
2 changes: 1 addition & 1 deletion pyodk/_endpoints/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def create_app_users(
# The "App User" role_id should always be "2", so no need to look it up by name.
# Ref: "https://github.com/getodk/central-backend/blob/9db0d792cf4640ec7329722984
# cebdee3687e479/lib/model/migrations/20181212-01-add-roles.js"
# See also roles data in `tests/resorces/projects_data.py`.
# See also roles data in `tests/resources/projects_data.py`.
if forms is not None:
for user in users:
for form_id in forms:
Expand Down
35 changes: 35 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from tests.resources import RESOURCES, forms_data, submissions_data
from tests.utils import utils
from tests.utils.entity_lists import create_new_or_get_entity_list
from tests.utils.forms import (
create_new_form__md,
create_new_form__xml,
Expand Down Expand Up @@ -71,6 +72,22 @@ def create_test_submissions(client: Client | None = None) -> Client:
return client


def create_test_entity_lists(client: Client | None = None) -> Client:
"""
Create test entity lists, if they don't already exist.
:param client: Client instance to use for API calls.
:return: The original client instance, or a new one if none was provided.
"""
if client is None:
client = Client()
create_new_or_get_entity_list(
client=client,
entity_list_name="pyodk_test_eln",
entity_props=["test_label", "another_prop"],
)
return client


@skip
class TestUsage(TestCase):
"""Tests for experimenting with usage scenarios / general debugging / integration."""
Expand All @@ -82,6 +99,7 @@ def setUpClass(cls):
cls.client = Client()
create_test_forms(client=cls.client)
create_test_submissions(client=cls.client)
create_test_entity_lists(client=cls.client)

def test_direct(self):
projects = self.client.projects.list()
Expand Down Expand Up @@ -216,3 +234,20 @@ def test_submission_edit__non_ascii(self):
instance_id=iid,
comment=f"pyODK edit {now}",
)

def test_entities__create_and_query(self):
"""Should create a new entity, and query it afterwards via list() or get_table()."""
self.client.entities.default_entity_list_name = "pyodk_test_eln"
entity = self.client.entities.create(
label="test_label",
data={"test_label": "test_value", "another_prop": "another_value"},
)
entity_list = self.client.entities.list()
self.assertIn(entity, entity_list)
entity_data = self.client.entities.get_table(select="__id")
self.assertIn(entity.uuid, [d["__id"] for d in entity_data["value"]])

def test_entity_lists__list(self):
"""Should return a list of entities"""
observed = self.client.entity_lists.list()
self.assertGreater(len(observed), 0)
48 changes: 48 additions & 0 deletions tests/utils/entity_lists.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from pyodk._endpoints.entity_lists import EntityList, log
from pyodk.client import Client
from pyodk.errors import PyODKError


def create_new_or_get_entity_list(
client: Client, entity_list_name: str, entity_props: list[str]
) -> EntityList:
"""
Create a new entity list, or get the entity list metadata.
:param client: Client instance to use for API calls.
:param entity_list_name: Name of the entity list.
:param entity_props: Properties to add to the entity list.
"""
try:
entity_list = client.session.response_or_error(
method="POST",
url=client.session.urlformat(
"projects/{pid}/datasets",
pid=client.project_id,
),
logger=log,
json={"name": entity_list_name},
)
except PyODKError:
entity_list = client.session.get(
url=client.session.urlformat(
"projects/{pid}/datasets/{eln}",
pid=client.project_id,
eln=entity_list_name,
),
)
try:
for prop in entity_props:
client.session.response_or_error(
method="GET",
url=client.session.urlformat(
"projects/{pid}/datasets/{eln}/properties",
pid=client.project_id,
eln=entity_list_name,
),
logger=log,
json={"name": prop},
)
except PyODKError:
pass
return EntityList(**entity_list.json())

0 comments on commit 1715fdd

Please sign in to comment.