Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Granular #16

Merged
merged 2 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions oarepo_model_builder_tests/datatypes/components.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import marshmallow as ma
from oarepo_model_builder.datatypes import DataTypeComponent, ModelDataType
from oarepo_model_builder.datatypes.components.model.utils import set_default

# todo
"""
tests running in separate profile *after* generation
ask about links
hardcoding profile names for identifying services?
ui and entrypoints for draft files
"""





class TestSchema(ma.Schema):
Expand All @@ -20,12 +32,43 @@ class Meta:

module = ma.fields.String(load_default="tests")

disabled = ma.fields.List(ma.fields.String())




class ModelTestComponent(DataTypeComponent):
eligible_datatypes = [ModelDataType]

class ModelSchema(ma.Schema):
tests = ma.fields.Nested(TestSchema, load_default=lambda: TestSchema().load({}))

def before_model_prepare(self, datatype, *, context, **kwargs):
tests = set_default(datatype, "tests", {})
tests.setdefault(
"module",
"tests",
)

def process_tests(self, datatype, section, **extra_kwargs):
section.fixtures = {
"record_service": "record_service",
"sample_record": "sample_record",
}

section.constants = {
"read_url": "",
"update_url": "",
"delete_url": "",
"deleted_http_code": 410,
"skip_search_test": False,
"service_read_method": "read",
"service_create_method": "create",
"service_delete_method": "delete",
"service_update_method": "update",
"deleted_record_pid_error" : "PIDDeletedError"
}



components = [ModelTestComponent]
3 changes: 3 additions & 0 deletions oarepo_model_builder_tests/templates/conftest.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import os
from {{ vars.proxy.module }} import {{ vars.service.proxy }}
{{ vars.record.class|generate_import }}

@pytest.fixture
def record_service():
return current_service

@pytest.fixture(scope="function")
def sample_metadata_list():
Expand Down
75 changes: 55 additions & 20 deletions oarepo_model_builder_tests/templates/test_resource.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def _get_paths(cur_path, cur_val):
def get_paths(prefix, data):
return _get_paths(prefix, data)

BASE_URL = f"http://localhost{{ "{" }} {{ vars.resource_config.class|base_name }}.url_prefix{{ "}" }}"
BASE_URL = {{ vars.resource_config.class|base_name }}.url_prefix
"""
def check_allowed(action_name):
permission_cls = {{ vars.service.proxy }}.config.permission_policy_cls
Expand Down Expand Up @@ -59,16 +59,49 @@ def response_code_ok(action_name, user_is_auth, response, authorized_response_co
return False


def test_get_item({{ vars.tests.extra_fixtures|generate_list(end=true) }} client_with_credentials, sample_record, search_clear):
def test_read(client_with_credentials, {{ fixtures.sample_record }}, search_clear):
non_existing = client_with_credentials.get(f"{BASE_URL}yjuykyukyuk")
assert non_existing.status_code == 404

get_response = client_with_credentials.get(f"{BASE_URL}{sample_record['id']}")
get_response = client_with_credentials.get(f"{BASE_URL}{{ "{" }}{{ fixtures.sample_record }}['id']{{ "}" }}{{ test_constants.read_url }}")
assert response_code_ok("read", True, get_response, 200)
if is_action_allowed("read", True):
assert get_response.json["metadata"] == sample_record["metadata"]
assert get_response.json["metadata"] == {{ fixtures.sample_record }}["metadata"]

def test_create(
client_with_credentials, client, sample_metadata_list, app, search_clear
):
created_responses = []
for sample_metadata_point in sample_metadata_list:
created_responses.append(
client_with_credentials.post(f"{BASE_URL}", json=sample_metadata_point)
)
with app.test_client() as unauth_client:
unauth_response = unauth_client.post(
f"{BASE_URL}", json=sample_metadata_point
)
assert response_code_ok("create", False, unauth_response, 201)
assert all(
[
response_code_ok("create", True, new_response, 201)
for new_response in created_responses
]
)

if is_action_allowed("create", True):
for sample_metadata_point, created_response in zip(
sample_metadata_list, created_responses
):
created_response_reread = client_with_credentials.get(
f"{BASE_URL}{created_response.json['id']}{{ test_constants.read_url }}"
)
assert response_code_ok("read", True, created_response_reread, 200)
assert (
created_response_reread.json["metadata"]
== sample_metadata_point["metadata"]
)

"""
def test_create(
{{ vars.tests.extra_fixtures|generate_list(end=true) }}client_with_credentials, client, sample_metadata_list, app, search_clear
):
Expand Down Expand Up @@ -96,38 +129,40 @@ def test_create(
created_response_reread.json["metadata"]
== sample_metadata_point["metadata"]
)
"""


"""
def test_listing({{ vars.tests.extra_fixtures|generate_list(end=true) }} client_with_credentials, sample_records, search_clear):
listing_response = client_with_credentials.get(BASE_URL)
hits = listing_response.json["hits"]["hits"]
assert len(hits) == 10
"""


def test_update(
{{ vars.tests.extra_fixtures|generate_list(end=true) }} client_with_credentials, sample_record, sample_metadata_list, search_clear
client_with_credentials, {{ fixtures.sample_record }}, sample_metadata_list, search_clear
):
non_existing = client_with_credentials.put(
f"{BASE_URL}yjuykyukyuk", json=sample_metadata_list[5]
f"{BASE_URL}yjuykyukyuk{{ test_constants.read_url }}", json=sample_metadata_list[5]
)

old_record_read_response_json = client_with_credentials.get(
f"{BASE_URL}{sample_record['id']}"
f"{BASE_URL}{{ "{" }} {{ fixtures.sample_record }}['id']{{ "}" }}{{ test_constants.read_url }}"
).json

update_response = client_with_credentials.put(
f"{BASE_URL}{sample_record['id']}", json=sample_metadata_list[2]
f"{BASE_URL}{{ "{" }} {{ fixtures.sample_record }}['id']{{ "}" }}{{ test_constants.update_url }}", json=sample_metadata_list[2]
)

updated_record_read_response = client_with_credentials.get(
f"{BASE_URL}{sample_record['id']}"
f"{BASE_URL}{{ "{" }} {{ fixtures.sample_record }}['id']{{ "}" }}{{ test_constants.read_url }}"
)

assert response_code_ok("read", True, updated_record_read_response, 200)
assert response_code_ok("update", True, non_existing, 404)
assert response_code_ok("update", True, update_response, 200)
if is_action_allowed("update", True):
assert old_record_read_response_json["metadata"] == sample_record.metadata
assert old_record_read_response_json["metadata"] == {{ fixtures.sample_record }}.metadata
assert (
update_response.json["metadata"]
== sample_metadata_list[2]["metadata"]
Expand All @@ -150,30 +185,29 @@ def test_update(
# "value": "UPDATED!"})


def test_delete({{ vars.tests.extra_fixtures|generate_list(end=true) }} client_with_credentials, sample_record, app, search_clear):
def test_delete(client_with_credentials, {{ fixtures.sample_record }}, app, search_clear):
non_existing = client_with_credentials.delete(f"{BASE_URL}yjuykyukyuk")
assert response_code_ok("delete", True, non_existing, 404)

read_response = client_with_credentials.get(f"{BASE_URL}{sample_record['id']}")
assert response_code_ok("read", True, read_response, 200)

delete_response = client_with_credentials.delete(f"{BASE_URL}{sample_record['id']}")
delete_response = client_with_credentials.delete(f"{BASE_URL}{{ "{" }} {{ fixtures.sample_record }}['id']{{ "}" }}{{ test_constants.delete_url }}")
assert response_code_ok("delete", True, delete_response, 204)

if is_action_allowed("delete", True):
deleted_get_response = client_with_credentials.delete(
f"{BASE_URL}{sample_record['id']}"
f"{BASE_URL}{{ "{" }} {{ fixtures.sample_record }}['id']{{ "}" }}{{ test_constants.delete_url }}"
)
assert deleted_get_response.status_code == 410
assert deleted_get_response.status_code == {{ test_constants.deleted_http_code }}

"""
def test_delete_unauth(sample_record, search_clear, app):
with app.test_client() as unauth_client:
unauth_delete_response = unauth_client.delete(
f"{BASE_URL}{sample_record['id']}"
)
assert response_code_ok("delete", False, unauth_delete_response, 204)
"""


{% if not test_constants.skip_search_test %}
def test_search({{ vars.tests.extra_fixtures|generate_list(end=true) }} client_with_credentials, sample_records, sample_metadata_list, search_clear):
if is_action_allowed("search", True):
paths = get_paths("metadata", sample_metadata_list[0]["metadata"])
Expand Down Expand Up @@ -216,4 +250,5 @@ def test_search({{ vars.tests.extra_fixtures|generate_list(end=true) }} client_w
assert len(res_fail.json["hits"]["hits"]) == 0
assert len(res_created.json["hits"]["hits"]) == 10
assert len(res_created_fail.json["hits"]["hits"]) == 0
assert len(res_facets.json["hits"]["hits"]) == 1
assert len(res_facets.json["hits"]["hits"]) == 1
{% endif %}
58 changes: 29 additions & 29 deletions oarepo_model_builder_tests/templates/test_service.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,42 @@ def _get_paths(cur_path, cur_val):
def get_paths(prefix, data):
return _get_paths(prefix, data)


def test_read({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, sample_record, sample_metadata_list, search_clear):
def test_read({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, {{ fixtures.sample_record }}, {{ fixtures.record_service }}, sample_metadata_list, search_clear):
with pytest.raises(PIDDoesNotExistError):
current_service.read(system_identity, "fwegthi8op")
read_record = current_service.read(system_identity, sample_record["id"])
assert read_record.data["metadata"] == sample_record.metadata
{{ fixtures.record_service }}.{{ test_constants.service_read_method }}(system_identity, "fwegthi8op")
read_record = {{ fixtures.record_service }}.{{ test_constants.service_read_method }}(system_identity, {{ fixtures.sample_record }}["id"])
assert read_record.data["metadata"] == {{ fixtures.sample_record }}.metadata


def test_create({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, sample_metadata_list, search_clear):
def test_create({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, {{ fixtures.record_service }}, sample_metadata_list, search_clear):
created_records = []
for sample_metadata_point in sample_metadata_list:
created_records.append(
current_service.create(system_identity, sample_metadata_point)
{{ fixtures.record_service }}.{{ test_constants.service_create_method }}(system_identity, sample_metadata_point)
)
for sample_metadata_point, created_record in zip(
sample_metadata_list, created_records
):
created_record_reread = current_service.read(
created_record_reread = {{ fixtures.record_service }}.{{ test_constants.service_read_method }}(
system_identity, created_record["id"]
)
assert (
created_record_reread.data["metadata"] == sample_metadata_point["metadata"]
)


def test_update({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, sample_record, sample_metadata_list, search_clear):
def test_update(app, db, {{ fixtures.sample_record }}, {{ fixtures.record_service}}, sample_metadata_list, search_clear):
with pytest.raises(PIDDoesNotExistError):
current_service.update(
{{ fixtures.record_service }}.{{ test_constants.service_update_method }}(
system_identity, "fwsegerhjtyuk754dh", sample_metadata_list[2]
)

old_record_data = current_service.read(system_identity, sample_record["id"]).data
updated_record = current_service.update(
system_identity, sample_record["id"], sample_metadata_list[2]
old_record_data = {{ fixtures.record_service }}.{{ test_constants.service_read_method }}(system_identity, {{ fixtures.sample_record }}["id"]).data
updated_record = {{ fixtures.record_service }}.{{ test_constants.service_update_method }}(
system_identity, {{ fixtures.sample_record }}["id"], sample_metadata_list[2]
)
updated_record_read = current_service.read(system_identity, sample_record["id"])
assert old_record_data["metadata"] == sample_record["metadata"]
updated_record_read = {{ fixtures.record_service }}.{{ test_constants.service_read_method }}(system_identity, {{ fixtures.sample_record }}["id"])
assert old_record_data["metadata"] == {{ fixtures.sample_record }}["metadata"]
assert (
updated_record.data["metadata"]
== sample_metadata_list[2]["metadata"]
Expand All @@ -74,26 +73,26 @@ def test_update({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db,
)


def test_delete({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, sample_record, search_clear):
def test_delete(app, db, {{ fixtures.sample_record }}, {{ fixtures.record_service }}, search_clear):
with pytest.raises(PIDDoesNotExistError):
current_service.delete(system_identity, "fwsegerhjtyuk754dh")
{{ fixtures.record_service }}.{{ test_constants.service_delete_method }}(system_identity, "fwsegerhjtyuk754dh")

to_delete_record = current_service.read(system_identity, sample_record["id"])
to_delete_record = {{ fixtures.record_service }}.{{ test_constants.service_read_method }}(system_identity, {{ fixtures.sample_record }}["id"])
assert to_delete_record
current_service.delete(system_identity, sample_record["id"])
with pytest.raises(PIDDeletedError):
current_service.read(system_identity, sample_record["id"])

{{ fixtures.record_service }}.{{ test_constants.service_delete_method }}(system_identity, {{ fixtures.sample_record }}["id"])
with pytest.raises({{ test_constants.deleted_record_pid_error }}):
{{ fixtures.record_service }}.{{ test_constants.service_read_method }}(system_identity, {{ fixtures.sample_record }}["id"])

{% if not test_constants.skip_search_test %}
def test_search(
{{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, sample_records, sample_metadata_list, search_clear
app, db, {{ fixtures.record_service }}, sample_records, sample_metadata_list, search_clear
):
paths = get_paths("metadata", sample_metadata_list[0]["metadata"])

for record in sample_records:
for path in paths:
field_value = dict_lookup(record, path)
path_search_results = current_service.search(system_identity, params={"q": f"{path}:\"{field_value}\""})
path_search_results = {{ fixtures.record_service }}.search(system_identity, params={"q": f"{path}:\"{field_value}\""})
assert len(path_search_results) > 0
for field_result in [dict_lookup(res, path) for res in list(path_search_results)]:
if field_result == field_value:
Expand All @@ -102,7 +101,7 @@ def test_search(
raise AssertionError("Queried field value not found in search results.")


res_fail = list(current_service.search(system_identity, params={"q": "wefrtghthy"}))
res_fail = list( {{ fixtures.record_service }}.search(system_identity, params={"q": "wefrtghthy"}))

start_datetime = (
datetime.datetime.utcnow() - datetime.timedelta(minutes=5)
Expand All @@ -112,17 +111,17 @@ def test_search(
).isoformat() + "Z"

res_created = list(
current_service.search(
{{ fixtures.record_service }}.search(
system_identity,
params={"q": f'created:["{start_datetime}" TO "{end_datetime}"]'},
)
)

res_created_fail = list(
current_service.search(system_identity, params={"q": "2022-10-16"})
{{ fixtures.record_service }}.search(system_identity, params={"q": "2022-10-16"})
)
res_facets = list(
current_service.scan(
{{ fixtures.record_service }}.scan(
system_identity,
params={
"facets": {
Expand All @@ -134,10 +133,11 @@ def test_search(
).hits
)

res_listing = list(current_service.search(system_identity))
res_listing = list( {{ fixtures.record_service }}.search(system_identity))

assert len(res_fail) == 0
assert len(res_listing) == 10
assert len(res_created) == 10
assert len(res_created_fail) == 0
assert len(res_facets) == 1
{% endif %}
4 changes: 4 additions & 0 deletions oarepo_model_builder_tests/test_resource_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ class TestResourceBuilder(InvenioBaseClassPythonBuilder):
TYPE = "invenio_tests_resource"
template = "test_resource"

def finish(self, **extra_kwargs):
tests = getattr(self.current_model, "section_tests")
super().finish(fixtures=tests.fixtures, test_constants=tests.constants, **extra_kwargs)

def _get_output_module(self):
return f'{self.current_model.definition["tests"]["module"]}.test_resource'
4 changes: 4 additions & 0 deletions oarepo_model_builder_tests/test_service_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
class TestServiceBuilder(InvenioBaseClassPythonBuilder):
TYPE = "invenio_tests_service"
template = "test_service"

def finish(self, **extra_kwargs):
tests = getattr(self.current_model, "section_tests")
super().finish(fixtures=tests.fixtures, test_constants=tests.constants, **extra_kwargs)

def _get_output_module(self):
return f'{self.current_model.definition["tests"]["module"]}.test_service'
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ oarepo_model_builder.datatypes.components =
oarepo_model_builder.builders.record =
2010-oarepo_model_builder_setup_cfg = oarepo_model_builder_tests.oarepo_model_builder_setup_cfg:OarepoModelBuilderSetupCfgBuilder
5020-conftest = oarepo_model_builder_tests.conftest_builder:ConftestBuilder
5020-test_utils = oarepo_model_builder_tests.utils_builder:TestUtilsBuilder
#5020-test_utils = oarepo_model_builder_tests.utils_builder:TestUtilsBuilder
5021-test_resource = oarepo_model_builder_tests.test_resource_builder:TestResourceBuilder
5022-test_service = oarepo_model_builder_tests.test_service_builder:TestServiceBuilder
oarepo_model_builder.templates =
Expand Down