diff --git a/oarepo_model_builder_tests/datatypes/components.py b/oarepo_model_builder_tests/datatypes/components.py index 42d23f8..d6173f4 100644 --- a/oarepo_model_builder_tests/datatypes/components.py +++ b/oarepo_model_builder_tests/datatypes/components.py @@ -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): @@ -20,6 +32,10 @@ class Meta: module = ma.fields.String(load_default="tests") + disabled = ma.fields.List(ma.fields.String()) + + + class ModelTestComponent(DataTypeComponent): eligible_datatypes = [ModelDataType] @@ -27,5 +43,32 @@ class ModelTestComponent(DataTypeComponent): 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] diff --git a/oarepo_model_builder_tests/templates/conftest.py.jinja2 b/oarepo_model_builder_tests/templates/conftest.py.jinja2 index 495a5bd..4b3c144 100644 --- a/oarepo_model_builder_tests/templates/conftest.py.jinja2 +++ b/oarepo_model_builder_tests/templates/conftest.py.jinja2 @@ -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(): diff --git a/oarepo_model_builder_tests/templates/test_resource.py.jinja2 b/oarepo_model_builder_tests/templates/test_resource.py.jinja2 index 21212d8..50a1833 100644 --- a/oarepo_model_builder_tests/templates/test_resource.py.jinja2 +++ b/oarepo_model_builder_tests/templates/test_resource.py.jinja2 @@ -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 @@ -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 ): @@ -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"] @@ -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"]) @@ -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 \ No newline at end of file + assert len(res_facets.json["hits"]["hits"]) == 1 +{% endif %} \ No newline at end of file diff --git a/oarepo_model_builder_tests/templates/test_service.py.jinja2 b/oarepo_model_builder_tests/templates/test_service.py.jinja2 index 5fbf7c1..3c7acdd 100644 --- a/oarepo_model_builder_tests/templates/test_service.py.jinja2 +++ b/oarepo_model_builder_tests/templates/test_service.py.jinja2 @@ -24,24 +24,23 @@ 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 ( @@ -49,18 +48,18 @@ def test_create({{ vars.tests.extra_fixtures|generate_list(end=true) }} app, db, ) -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"] @@ -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: @@ -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) @@ -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": { @@ -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 %} diff --git a/oarepo_model_builder_tests/test_resource_builder.py b/oarepo_model_builder_tests/test_resource_builder.py index 98ae871..9e2a671 100644 --- a/oarepo_model_builder_tests/test_resource_builder.py +++ b/oarepo_model_builder_tests/test_resource_builder.py @@ -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' diff --git a/oarepo_model_builder_tests/test_service_builder.py b/oarepo_model_builder_tests/test_service_builder.py index 8657988..28933e3 100644 --- a/oarepo_model_builder_tests/test_service_builder.py +++ b/oarepo_model_builder_tests/test_service_builder.py @@ -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' diff --git a/setup.cfg b/setup.cfg index 73b697b..e260e35 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 =