diff --git a/tests/app/conftest.py b/tests/app/conftest.py index d4a45ae063c6b185382acd230f6f99120f2ad5b6..15ea03221b5ce175b0010cd319970fc063677f8c 100644 --- a/tests/app/conftest.py +++ b/tests/app/conftest.py @@ -20,35 +20,30 @@ import pytest from fastapi.testclient import TestClient from nomad.app.main import app +from nomad.app.v1.routers.auth import generate_simple_token, generate_upload_token from nomad.datamodel import User -from nomad.app.v1.routers.auth import generate_upload_token, generate_simple_token def create_auth_headers(token: str): return {'Authorization': f'Bearer {token}'} -@pytest.fixture(scope='module') +@pytest.fixture(scope='session') def user0_auth(user0: User): return create_auth_headers(user0.user_id) -@pytest.fixture(scope='module') +@pytest.fixture(scope='session') def user1_auth(user1: User): return create_auth_headers(user1.user_id) -@pytest.fixture(scope='module') +@pytest.fixture(scope='session') def user2_auth(user2: User): return create_auth_headers(user2.user_id) -@pytest.fixture(scope='module') -def user3_auth(user3: User): - return create_auth_headers(user3.user_id) - - -@pytest.fixture(scope='module') +@pytest.fixture(scope='session') def invalid_user_auth(): return create_auth_headers('invalid.bearer.token') @@ -59,30 +54,19 @@ def app_token_auth(user1: User): return create_auth_headers(app_token) -@pytest.fixture(scope='module') -def auth_dict( - user0, - user1, - user2, - user3, - user0_auth, - user1_auth, - user2_auth, - user3_auth, - invalid_user_auth, -): +@pytest.fixture(scope='session') +def auth_dict(users_dict, invalid_user_auth): """ - Returns a dictionary of the form {user_name: (auth_headers, token)}. The key 'invalid' + Returns a dictionary of the form {user_label: (auth_headers, token)}. The key 'invalid' contains an example of invalid credentials, and the key None contains (None, None). """ - return { - 'user0': (user0_auth, generate_upload_token(user0)), - 'user1': (user1_auth, generate_upload_token(user1)), - 'user2': (user2_auth, generate_upload_token(user2)), - 'user3': (user3_auth, generate_upload_token(user3)), - 'invalid': (invalid_user_auth, 'invalid.upload.token'), - None: (None, None), + auths = { + label: (create_auth_headers(user.user_id), generate_upload_token(user)) + for label, user in users_dict.items() } + auths['invalid'] = (invalid_user_auth, 'invalid.upload.token') + auths[None] = (None, None) + return auths @pytest.fixture(scope='session') diff --git a/tests/app/v1/routers/uploads/common.py b/tests/app/v1/routers/uploads/common.py index a3432721be44576bc738c3855ff0b581aea8040c..259eb4c80d4f05b28b29b2d45dec97bea8a4373f 100644 --- a/tests/app/v1/routers/uploads/common.py +++ b/tests/app/v1/routers/uploads/common.py @@ -19,3 +19,15 @@ def assert_upload(response_json, **kwargs): for key, value in kwargs.items(): assert data.get(key, None) == value return data + + +def assert_entry(entry, has_metadata=True, **kwargs): + """Checks the content of a returned entry dictionary.""" + assert 'upload_id' in entry + assert 'entry_id' in entry + assert 'entry_create_time' in entry + assert not entry['process_running'] + for key, value in kwargs.items(): + assert entry.get(key, None) == value + if has_metadata: + assert 'entry_metadata' in entry diff --git a/tests/app/v1/routers/uploads/test_basic_uploads.py b/tests/app/v1/routers/uploads/test_basic_uploads.py index 4528f4a69ba470b0601daa0f1cc380dc6e4328e0..d3559e5d7dd82c07bc61375fab3891b9fc9734f4 100644 --- a/tests/app/v1/routers/uploads/test_basic_uploads.py +++ b/tests/app/v1/routers/uploads/test_basic_uploads.py @@ -16,46 +16,47 @@ # limitations under the License. # -import pytest import io import os -import requests import time import zipfile from datetime import datetime -from typing import List, Dict, Any, Iterable -from tests.app.v1.routers.uploads.common import assert_upload +from typing import Any, Dict, Iterable, List -from tests.utils import build_url, set_upload_entry_metadata -from tests.test_files import ( - example_file_mainfile_different_atoms, - example_file_vasp_with_binary, - example_file_aux, - example_file_unparsable, - example_file_corrupt_zip, - empty_file, - assert_upload_files, +import pytest +import requests + +from nomad import files, infrastructure +from nomad.bundles import BundleExporter +from nomad.config import config +from nomad.config.models.config import BundleImportSettings +from nomad.datamodel import EntryMetadata +from nomad.files import PublicUploadFiles, StagingUploadFiles, UploadFiles +from nomad.processing import Entry, ProcessStatus, Upload +from tests.app.v1.routers.common import ( + assert_browser_download_headers, + assert_response, + perform_get, ) -from tests.test_search import assert_search_upload from tests.processing.test_edit_metadata import ( - assert_metadata_edited, - all_coauthor_metadata, all_admin_metadata, + all_coauthor_metadata, + assert_metadata_edited, ) -from tests.app.v1.routers.common import ( - assert_response, - assert_browser_download_headers, - perform_get, +from tests.test_files import ( + assert_upload_files, + empty_file, + example_file_aux, + example_file_corrupt_zip, + example_file_mainfile_different_atoms, + example_file_unparsable, + example_file_vasp_with_binary, ) -from nomad import files, infrastructure -from nomad.config import config -from nomad.config.models.config import BundleImportSettings -from nomad.processing import Upload, Entry, ProcessStatus -from nomad.files import UploadFiles, StagingUploadFiles, PublicUploadFiles -from nomad.bundles import BundleExporter -from nomad.datamodel import EntryMetadata +from tests.test_search import assert_search_upload +from tests.utils import build_url, set_upload_entry_metadata from ..test_entries import assert_archive_response +from .common import assert_entry, assert_upload """ These are the tests for all API operations below ``uploads``. The tests are organized @@ -357,17 +358,6 @@ def assert_gets_published( assert_upload_files(upload_id, entries, files.PublicUploadFiles, published=True) -def assert_entry(entry, **kwargs): - """Checks the content of a returned entry dictionary.""" - assert 'upload_id' in entry - assert 'entry_id' in entry - assert 'entry_create_time' in entry - assert not entry['process_running'] - for key, value in kwargs.items(): - assert entry.get(key, None) == value - assert 'entry_metadata' in entry - - def assert_pagination(pagination, expected_pagination): """Checks that the contents of `paginaion` matches what is expected.""" for key, value in expected_pagination.items(): diff --git a/tests/fixtures/users.py b/tests/fixtures/users.py index 6c97444f2877b54ab647da0d6b3331bb624e53e9..3d3742fd7e4723e7092322be9864990a0995da8f 100644 --- a/tests/fixtures/users.py +++ b/tests/fixtures/users.py @@ -2,7 +2,7 @@ User fixtures: - user0: admin user - user1: default user to use -- user2, user3: additional users for access or interaction tests +- user2, user3, ...: additional users for access or interaction tests """ import pytest @@ -10,41 +10,50 @@ import pytest from nomad import infrastructure from nomad.config import config from nomad.datamodel import User -from tests.utils import fake_user_uuid +from tests.utils import fake_user_uuid, generate_convert_label admin_user_id = fake_user_uuid(0) + +def fake_user(num, first_name, last_name, *, email=None, **kwargs): + if email is None: + email = f'{first_name}.{last_name}@nomad-fairdi.tests.de'.lower() + + username = f'{first_name[0]}{last_name}'.lower() + + return dict( + user_id=fake_user_uuid(num), + username=username, + email=email, + first_name=first_name, + last_name=last_name, + **kwargs, + ) + + users = { fake_user_uuid(0): dict(username='admin', email='admin', user_id=fake_user_uuid(0)), - fake_user_uuid(1): dict( - username='scooper', - email='sheldon.cooper@nomad-coe.eu', - first_name='Sheldon', - last_name='Cooper', - user_id=fake_user_uuid(1), + fake_user_uuid(1): fake_user( + 1, + 'Sheldon', + 'Cooper', + email='sheldon.cooper@nomad-coe.eu', # domain differs from default is_oasis_admin=True, ), - fake_user_uuid(2): dict( - username='lhofstadter', - email='leonard.hofstadter@nomad-fairdi.tests.de', - first_name='Leonard', - last_name='Hofstadter', - user_id=fake_user_uuid(2), - ), - fake_user_uuid(3): dict( - username='hwolowitz', - email='howard.wolowitz@nomad-fairdi.tests.de', - first_name='Howard', - last_name='Wolowitz', - user_id=fake_user_uuid(3), - ), + fake_user_uuid(2): fake_user(2, 'Leonard', 'Hofstadter'), + fake_user_uuid(3): fake_user(3, 'Howard', 'Wolowitz'), + fake_user_uuid(4): fake_user(4, 'Rajesh', 'Koothrappali'), + fake_user_uuid(5): fake_user(5, 'Penny', 'Hofstadter'), + fake_user_uuid(6): fake_user(6, 'Bernadette', 'Rostenkowski-Wolowitz'), + fake_user_uuid(7): fake_user(7, 'Amy', 'Fowler'), + fake_user_uuid(8): fake_user(8, 'Stuart', 'Bloom'), + fake_user_uuid(9): fake_user(9, 'Emily', 'Sweeney'), } @pytest.fixture(scope='session') def user_molds(): - label_num = {f'user{i}': i for i in range(4)} - return {label: users[fake_user_uuid(num)] for label, num in label_num.items()} + return {f'user{i}': user for i, user in enumerate(users.values())} @pytest.fixture(scope='session') @@ -63,18 +72,19 @@ def user2(): @pytest.fixture(scope='session') -def user3(): - return User(**users[fake_user_uuid(3)]) +def users_dict(user_molds): + return {k: User(**v) for k, v in user_molds.items()} + + +@pytest.fixture(scope='session') +def user_label_id_mapping(user_molds): + return {label: value.get('user_id') for label, value in user_molds.items()} @pytest.fixture(scope='session') -def users_dict(user0, user1, user2, user3): - return { - 'user0': user0, - 'user1': user1, - 'user2': user2, - 'user3': user3, - } +def convert_user_labels_to_ids(user_label_id_mapping): + """Returned function converts user labels to ids, also in lists and dicts.""" + return generate_convert_label(user_label_id_mapping) @pytest.fixture(scope='session', autouse=True) @@ -84,7 +94,7 @@ def configure_admin_user_id(monkeysession): class KeycloakMock: def __init__(self): - self.id_counter = 3 + self.id_counter = len(users) self.users = dict(**users) def tokenauth(self, access_token: str): diff --git a/tests/utils.py b/tests/utils.py index d9f452963760ee31e67593429061cc04019e3548..6a95a2154853794a8d0ba1c0ecf117ad73f7fdeb 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -18,12 +18,14 @@ """Methods to help with testing of nomad@FAIRDI.""" -from typing import List, Union, Dict, Any -import urllib.parse import json -from logging import LogRecord -import zipfile import os.path +import urllib.parse +import zipfile +from logging import LogRecord +from typing import Any, Dict, List, Union + +import pytest def assert_log(caplog, level: str, event_part: str) -> LogRecord: @@ -160,9 +162,36 @@ def create_template_upload_file( def fake_user_uuid(handle): - return '00000000-0000-0000-0000-00000000000%d' % handle + uuid = '00000000-0000-0000-0000-' + str(handle).rjust(12, '0') + assert len(uuid) == 36 + return uuid def fake_group_uuid(handle: Any): """Returns a test user group uuid based on the handle.""" - return str(handle).rjust(22, 'G') + uuid = str(handle).rjust(22, 'G') + assert len(uuid) == 22 + return uuid + + +def generate_convert_label(mapping): + """Returned function converts labels to values according to mapping, + also in lists and dicts, returns copies. Missing labels persist.""" + + def convert(raw): + if isinstance(raw, str): + return mapping.get(raw, raw) + + if isinstance(raw, list): + return [convert(v) for v in raw] + + if isinstance(raw, dict): + return {k: convert(v) for k, v in raw.items()} + + return raw + + return convert + + +def dict_to_params(d): + return [pytest.param(*item, id=id) for id, item in d.items()]