Skip to content

Commit

Permalink
Try to make new tests work with a live backend
Browse files Browse the repository at this point in the history
  • Loading branch information
CasperWA committed Jan 9, 2024
1 parent 03fe631 commit acc0204
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 42 deletions.
2 changes: 1 addition & 1 deletion dlite_entities_service/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ async def get_entity(
],
) -> dict[str, Any]:
"""Get a SOFT entity."""
uri = f"{CONFIG.base_url}/{version}/{name}"
uri = f"{str(CONFIG.base_url).rstrip('/')}/{version}/{name}"
entity = get_backend().read(uri)
if entity is None:
raise HTTPException(
Expand Down
49 changes: 27 additions & 22 deletions tests/cli/test_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ def test_login(
input_method: Literal["cli_option", "stdin"],
httpx_mock: HTTPXMock,
get_backend_user: GetBackendUserFixture,
live_backend: bool,
) -> None:
"""Test the `entities-service login` CLI command."""
import re

from dlite_entities_service.cli._utils.global_settings import CONTEXT
from dlite_entities_service.cli.main import APP
from dlite_entities_service.models.auth import Token
from dlite_entities_service.service.config import CONFIG

backend_user = get_backend_user()

Expand All @@ -43,7 +43,7 @@ def test_login(

# Mock the HTTPX response
httpx_mock.add_response(
url=re.compile(r"^.*\/_auth\/token\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_auth/token",
method="POST",
match_content=f"grant_type=password&username={username}&password={password}".encode(),
json=mock_token.model_dump(),
Expand Down Expand Up @@ -73,7 +73,10 @@ def test_login(
assert "Username: " in result.stdout
assert "Password: " in result.stdout

assert CONTEXT["token"] == mock_token, CONTEXT
assert CONTEXT["token"] is not None, CONTEXT

if not live_backend:
assert CONTEXT["token"] == mock_token, CONTEXT


def test_token_persistence(
Expand All @@ -82,13 +85,13 @@ def test_token_persistence(
static_dir: Path,
random_valid_entity: dict[str, Any],
get_backend_user: GetBackendUserFixture,
live_backend: bool,
) -> None:
"""Test that the token is persisted to the config file."""
import re

from dlite_entities_service.cli._utils.global_settings import CONTEXT
from dlite_entities_service.cli.main import APP
from dlite_entities_service.models.auth import Token
from dlite_entities_service.service.config import CONFIG

backend_user = get_backend_user(auth_role="readWrite")

Expand All @@ -111,7 +114,7 @@ def test_token_persistence(

# Mock the login HTTPX response
httpx_mock.add_response(
url=re.compile(r"^.*\/_auth\/token\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_auth/token",
method="POST",
match_content=f"grant_type=password&username={username}&password={password}".encode(),
json=mock_token.model_dump(),
Expand All @@ -123,7 +126,7 @@ def test_token_persistence(
status_code=404, # not found, i.e., entity does not already exist
)
httpx_mock.add_response(
url=re.compile(r"^.*\/_admin\/create_many\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
method="POST",
match_headers={
"Authorization": f"{mock_token.token_type} {mock_token.access_token}"
Expand Down Expand Up @@ -156,7 +159,10 @@ def test_token_persistence(
stdout=result.stdout, stderr=result.stderr
)
assert "Successfully logged in." in result.stdout.replace("\n", "")
assert CONTEXT["token"] == mock_token, CONTEXT
assert CONTEXT["token"] is not None, CONTEXT

if not live_backend:
assert CONTEXT["token"] == mock_token, CONTEXT

# Run the upload command again
result = cli.invoke(
Expand All @@ -171,17 +177,19 @@ def test_token_persistence(
)
assert "Successfully uploaded 1 entity:" in result.stdout.replace("\n", "")
assert not result.stderr
assert CONTEXT["token"] == mock_token, CONTEXT
assert CONTEXT["token"] is not None, CONTEXT

if not live_backend:
assert CONTEXT["token"] == mock_token, CONTEXT


def test_login_invalid_credentials(
cli: CliRunner, httpx_mock: HTTPXMock, get_backend_user: GetBackendUserFixture
) -> None:
"""Test that the command fails with invalid credentials."""
import re

from dlite_entities_service.cli._utils.global_settings import CONTEXT
from dlite_entities_service.cli.main import APP
from dlite_entities_service.service.config import CONFIG

username = "testuser"
password = "testpassword"
Expand All @@ -197,7 +205,7 @@ def test_login_invalid_credentials(

# Mock the HTTPX response
httpx_mock.add_response(
url=re.compile(r"^.*\/_auth\/token\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_auth/token",
method="POST",
match_content=f"grant_type=password&username={username}&password={password}".encode(),
status_code=401, # unauthorized
Expand All @@ -223,12 +231,11 @@ def test_login_invalid_credentials(
@pytest.mark.skip_if_live_backend("Does not raise HTTP errors in this case.")
def test_http_errors(cli: CliRunner, httpx_mock: HTTPXMock) -> None:
"""Ensure proper error messages are given if an HTTP error occurs."""
import re

from httpx import HTTPError

from dlite_entities_service.cli._utils.global_settings import CONTEXT
from dlite_entities_service.cli.main import APP
from dlite_entities_service.service.config import CONFIG

username = "testuser"
password = "testpassword"
Expand All @@ -240,7 +247,7 @@ def test_http_errors(cli: CliRunner, httpx_mock: HTTPXMock) -> None:
# Mock the login HTTPX response
httpx_mock.add_exception(
HTTPError(error_message),
url=re.compile(r"^.*\/_auth\/token\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_auth/token",
method="POST",
match_content=f"grant_type=password&username={username}&password={password}".encode(),
)
Expand All @@ -267,10 +274,9 @@ def test_json_decode_errors(
cli: CliRunner, httpx_mock: HTTPXMock, return_status_code: Literal[200, 500]
) -> None:
"""Ensure proper error messages are given if a JSON decode error occurs."""
import re

from dlite_entities_service.cli._utils.global_settings import CONTEXT
from dlite_entities_service.cli.main import APP
from dlite_entities_service.service.config import CONFIG

username = "testuser"
password = "testpassword"
Expand All @@ -279,7 +285,7 @@ def test_json_decode_errors(

# Mock the login HTTPX response
httpx_mock.add_response(
url=re.compile(r"^.*\/_auth\/token\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_auth/token",
method="POST",
match_content=f"grant_type=password&username={username}&password={password}".encode(),
status_code=return_status_code,
Expand All @@ -305,10 +311,9 @@ def test_json_decode_errors(
def test_validation_error(cli: CliRunner, httpx_mock: HTTPXMock) -> None:
"""Ensure proper error messages are given if the response cannot be parsed as a
valid token."""
import re

from dlite_entities_service.cli._utils.global_settings import CONTEXT
from dlite_entities_service.cli.main import APP
from dlite_entities_service.service.config import CONFIG

username = "testuser"
password = "testpassword"
Expand All @@ -317,7 +322,7 @@ def test_validation_error(cli: CliRunner, httpx_mock: HTTPXMock) -> None:

# Mock the login HTTPX response
httpx_mock.add_response(
url=re.compile(r"^.*\/_auth\/token\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_auth/token",
method="POST",
match_content=f"grant_type=password&username={username}&password={password}".encode(),
status_code=200,
Expand Down
38 changes: 20 additions & 18 deletions tests/cli/test_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def test_upload_filepath(
) -> None:
"""Test upload with a filepath."""
import json
import re

from dlite_entities_service.cli import main
from dlite_entities_service.service.config import CONFIG

entity_filepath = static_dir / "valid_entities" / "Person.json"
raw_entity: dict[str, Any] = json.loads(entity_filepath.read_bytes())
Expand All @@ -54,7 +54,7 @@ def test_upload_filepath(

# Mock response for "Upload entities"
httpx_mock.add_response(
url=re.compile(r"^.*\/_admin\/create_many\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
method="POST",
match_headers={"Authorization": "Bearer mock_token"},
match_json=[raw_entity],
Expand Down Expand Up @@ -152,7 +152,7 @@ def test_upload_directory(

# Mock response for "Upload entities"
httpx_mock.add_response(
url=f"{CONFIG.base_url}/_admin/create_many",
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
method="POST",
match_headers={"Authorization": "Bearer mock_token"},
status_code=201, # created
Expand Down Expand Up @@ -377,9 +377,11 @@ def test_existing_entity_different_content(
# Mock response for "Upload entities"
new_entity_file_to_be_uploaded = deepcopy(new_entity)
new_entity_file_to_be_uploaded["version"] = "0.1.1"
new_entity_file_to_be_uploaded["uri"] = f"{CONFIG.base_url}/0.1.1/Person"
new_entity_file_to_be_uploaded[
"uri"
] = f"{str(CONFIG.base_url).rstrip('/')}/0.1.1/Person"
httpx_mock.add_response(
url=f"{CONFIG.base_url}/_admin/create_many",
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
method="POST",
match_headers={"Authorization": "Bearer mock_token"},
match_json=[new_entity_file_to_be_uploaded],
Expand Down Expand Up @@ -414,9 +416,11 @@ def test_existing_entity_different_content(
# Mock response for "Upload entities"
new_entity_file_to_be_uploaded = deepcopy(new_entity)
new_entity_file_to_be_uploaded["version"] = custom_version
new_entity_file_to_be_uploaded["uri"] = f"{CONFIG.base_url}/{custom_version}/Person"
new_entity_file_to_be_uploaded[
"uri"
] = f"{str(CONFIG.base_url).rstrip('/')}/{custom_version}/Person"
httpx_mock.add_response(
url=f"{CONFIG.base_url}/_admin/create_many",
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
method="POST",
match_headers={"Authorization": "Bearer mock_token"},
match_json=[new_entity_file_to_be_uploaded],
Expand Down Expand Up @@ -564,11 +568,10 @@ def test_http_errors(
random_valid_entity: dict[str, Any],
) -> None:
"""Ensure proper error messages are given if an HTTP error occurs."""
import re

from httpx import HTTPError

from dlite_entities_service.cli.main import APP
from dlite_entities_service.service.config import CONFIG

error_message = "Generic HTTP Error"

Expand Down Expand Up @@ -608,7 +611,8 @@ def test_http_errors(
status_code=404, # not found, i.e., entity does not already exist
)
httpx_mock.add_exception(
HTTPError(error_message), url=re.compile(r"^.*_admin/create_many/?$")
HTTPError(error_message),
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
)

result = cli.invoke(
Expand Down Expand Up @@ -636,9 +640,8 @@ def test_json_decode_errors(
random_valid_entity: dict[str, Any],
) -> None:
"""Ensure proper error messages are given if a JSONDecodeError occurs."""
import re

from dlite_entities_service.cli.main import APP
from dlite_entities_service.service.config import CONFIG

if "uri" in random_valid_entity:
entity_uri: str = random_valid_entity["uri"]
Expand Down Expand Up @@ -676,7 +679,7 @@ def test_json_decode_errors(
status_code=404, # not found, i.e., entity does not already exist
)
httpx_mock.add_response(
url=re.compile(r"^.*_admin/create_many/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
status_code=400,
content=b"not json",
)
Expand Down Expand Up @@ -707,9 +710,9 @@ def test_unable_to_upload(
) -> None:
"""Ensure a proper error message is given if an entity cannot be uploaded."""
import json
import re

from dlite_entities_service.cli.main import APP
from dlite_entities_service.service.config import CONFIG

if "uri" in random_valid_entity:
entity_uri: str = random_valid_entity["uri"]
Expand All @@ -729,7 +732,7 @@ def test_unable_to_upload(
status_code=404, # not found, i.e., entity does not already exist
)
httpx_mock.add_response(
url=re.compile(r"^.*\/_admin\/create_many\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
status_code=400,
json=error_message,
)
Expand Down Expand Up @@ -763,11 +766,10 @@ def test_global_option_token(
httpx_mock: HTTPXMock,
) -> None:
"""Test that the token is correctly used when supplied using `--token`."""
import re

from dlite_entities_service.cli._utils.global_settings import CONTEXT
from dlite_entities_service.cli.main import APP
from dlite_entities_service.models.auth import Token
from dlite_entities_service.service.config import CONFIG

if "uri" in random_valid_entity:
entity_uri: str = random_valid_entity["uri"]
Expand All @@ -791,7 +793,7 @@ def test_global_option_token(

# Mock response for "Upload entities"
httpx_mock.add_response(
url=re.compile(r".*\/_admin\/create_many\/?$"),
url=f"{str(CONFIG.base_url).rstrip('/')}/_admin/create_many",
method="POST",
match_headers={
"Authorization": f"{mock_token.token_type} {mock_token.access_token}"
Expand Down
7 changes: 6 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ def non_mocked_hosts(live_backend: bool) -> list[str]:
import os

if live_backend:
return [os.getenv("ENTITY_SERVICE_HOST", "localhost")]
host, port = os.getenv("ENTITY_SERVICE_HOST", "localhost"), os.getenv(
"ENTITY_SERVICE_PORT", "8000"
)

localhost = host + (f":{port}" if port else "")
return [localhost]

return []

0 comments on commit acc0204

Please sign in to comment.