Skip to content

Commit 418d134

Browse files
committed
fixes api-keys tests
1 parent 3cfc3ce commit 418d134

File tree

4 files changed

+54
-27
lines changed

4 files changed

+54
-27
lines changed

services/web/server/src/simcore_service_webserver/folders/_folders_repository.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ async def list_trashed_folders(
275275
NOTE: this is app-wide i.e. no product, user or workspace filtered
276276
TODO: check with MD about workspaces
277277
"""
278-
base_query = sql.select(_FOLDER_DB_MODEL_COLS).where(
278+
base_query = sql.select(*_FOLDER_DB_MODEL_COLS).where(
279279
folders_v2.c.trashed.is_not(None)
280280
)
281281

@@ -306,7 +306,9 @@ async def list_trashed_folders(
306306

307307

308308
def _create_base_select_query(folder_id: FolderID, product_name: ProductName) -> Select:
309-
return sql.select(*_FOLDER_DB_MODEL_COLS,).where(
309+
return sql.select(
310+
*_FOLDER_DB_MODEL_COLS,
311+
).where(
310312
(folders_v2.c.product_name == product_name)
311313
& (folders_v2.c.folder_id == folder_id)
312314
)

services/web/server/src/simcore_service_webserver/projects/_projects_db.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ async def list_trashed_projects(
6262
order_by: OrderBy = _OLDEST_TRASHED_FIRST,
6363
) -> tuple[int, list[ProjectDBGet]]:
6464

65-
base_query = sql.select(PROJECT_DB_COLS).where(projects.c.trashed.is_not(None))
65+
base_query = sql.select(*PROJECT_DB_COLS).where(projects.c.trashed.is_not(None))
6666

6767
if is_set(trashed_explicitly):
6868
assert isinstance(trashed_explicitly, bool) # nosec

services/web/server/tests/unit/conftest.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from collections.abc import Callable, Iterable
1111
from pathlib import Path
1212
from typing import Any
13-
from unittest.mock import MagicMock
1413

1514
import pytest
1615
import yaml
16+
from pytest_mock import MockFixture, MockType
1717
from pytest_simcore.helpers.webserver_projects import empty_project_data
1818
from simcore_service_webserver.application_settings_utils import AppConfigDict
1919

@@ -62,17 +62,24 @@ def activity_data(fake_data_dir: Path) -> Iterable[dict[str, Any]]:
6262

6363

6464
@pytest.fixture
65-
def mock_orphaned_services(mocker) -> MagicMock:
65+
def mock_orphaned_services(mocker: MockFixture) -> MockType:
6666
return mocker.patch(
6767
"simcore_service_webserver.garbage_collector._core.remove_orphaned_services",
6868
return_value="",
6969
)
7070

7171

7272
@pytest.fixture
73-
def disable_gc_manual_guest_users(mocker):
73+
def disable_gc_manual_guest_users(mocker: MockFixture) -> None:
7474
"""Disable to avoid an almost instant cleanup of GUEST users with their projects"""
7575
mocker.patch(
7676
"simcore_service_webserver.garbage_collector._core.remove_users_manually_marked_as_guests",
7777
return_value=None,
7878
)
79+
80+
81+
@pytest.fixture
82+
def disabled_setup_garbage_collector(mocker: MockFixture) -> MockType:
83+
return mocker.patch(
84+
"simcore_service_webserver.application.setup_garbage_collector", autospec=True
85+
)

services/web/server/tests/unit/with_dbs/01/test_api_keys.py

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,22 @@
1414
from aiohttp.test_utils import TestClient
1515
from faker import Faker
1616
from models_library.products import ProductName
17-
from pytest_mock import MockerFixture
17+
from pytest_mock import MockerFixture, MockType
1818
from pytest_simcore.helpers.assert_checks import assert_status
1919
from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict
2020
from pytest_simcore.helpers.typing_env import EnvVarsDict
2121
from pytest_simcore.helpers.webserver_login import NewUser, UserInfoDict
2222
from servicelib.aiohttp import status
23-
from servicelib.aiohttp.application_keys import APP_SETTINGS_KEY
2423
from simcore_service_webserver.api_keys import _repository, _service, api_keys_service
2524
from simcore_service_webserver.api_keys.models import ApiKey
26-
from simcore_service_webserver.application_settings import GarbageCollectorSettings
25+
from simcore_service_webserver.application_settings import (
26+
ApplicationSettings,
27+
get_application_settings,
28+
)
2729
from simcore_service_webserver.db.models import UserRole
2830
from tenacity import (
2931
retry_if_exception_type,
30-
stop_after_attempt,
32+
stop_after_delay,
3133
wait_fixed,
3234
)
3335

@@ -38,8 +40,9 @@ async def fake_user_api_keys(
3840
logged_user: UserInfoDict,
3941
osparc_product_name: ProductName,
4042
faker: Faker,
41-
) -> AsyncIterable[list[int]]:
43+
) -> AsyncIterable[list[ApiKey]]:
4244
assert client.app
45+
4346
api_keys: list[ApiKey] = [
4447
await _repository.create_api_key(
4548
client.app,
@@ -85,7 +88,7 @@ async def test_list_api_keys(
8588
logged_user: UserInfoDict,
8689
user_role: UserRole,
8790
expected: HTTPStatus,
88-
disable_gc_manual_guest_users: None,
91+
disabled_setup_garbage_collector: MockType,
8992
):
9093
resp = await client.get("/v0/auth/api-keys")
9194
data, errors = await assert_status(resp, expected)
@@ -103,7 +106,7 @@ async def test_create_api_key(
103106
logged_user: UserInfoDict,
104107
user_role: UserRole,
105108
expected: HTTPStatus,
106-
disable_gc_manual_guest_users: None,
109+
disabled_setup_garbage_collector: MockType,
107110
):
108111
display_name = "foo"
109112
resp = await client.post("/v0/auth/api-keys", json={"displayName": display_name})
@@ -130,7 +133,7 @@ async def test_delete_api_keys(
130133
logged_user: UserInfoDict,
131134
user_role: UserRole,
132135
expected: HTTPStatus,
133-
disable_gc_manual_guest_users: None,
136+
disabled_setup_garbage_collector: MockType,
134137
):
135138
resp = await client.delete("/v0/auth/api-keys/0")
136139
await assert_status(resp, expected)
@@ -140,6 +143,9 @@ async def test_delete_api_keys(
140143
await assert_status(resp, expected)
141144

142145

146+
EXPIRATION_WAIT_FACTOR = 1.2
147+
148+
143149
@pytest.mark.parametrize(
144150
"user_role,expected",
145151
_get_user_access_parametrizations(status.HTTP_200_OK),
@@ -149,7 +155,7 @@ async def test_create_api_key_with_expiration(
149155
logged_user: UserInfoDict,
150156
user_role: UserRole,
151157
expected: HTTPStatus,
152-
disable_gc_manual_guest_users: None,
158+
disabled_setup_garbage_collector: MockType,
153159
):
154160
assert client.app
155161

@@ -172,7 +178,7 @@ async def test_create_api_key_with_expiration(
172178
assert [d["displayName"] for d in data] == ["foo"]
173179

174180
# wait for api-key for it to expire and force-run scheduled task
175-
await asyncio.sleep(1.1 * expiration_interval.seconds)
181+
await asyncio.sleep(EXPIRATION_WAIT_FACTOR * expiration_interval.seconds)
176182

177183
deleted = await api_keys_service.prune_expired_api_keys(client.app)
178184
assert deleted == ["foo"]
@@ -184,6 +190,7 @@ async def test_create_api_key_with_expiration(
184190

185191
async def test_get_or_create_api_key(
186192
client: TestClient,
193+
disabled_setup_garbage_collector: MockType,
187194
):
188195
async with NewUser(
189196
app=client.app,
@@ -218,7 +225,7 @@ async def test_get_not_existing_api_key(
218225
logged_user: UserInfoDict,
219226
user_role: UserRole,
220227
expected: HTTPException,
221-
disable_gc_manual_guest_users: None,
228+
disabled_setup_garbage_collector: MockType,
222229
):
223230
resp = await client.get("/v0/auth/api-keys/42")
224231
data, errors = await assert_status(resp, expected)
@@ -241,20 +248,31 @@ async def app_environment(
241248

242249

243250
async def test_prune_expired_api_keys_task_is_triggered(
244-
app_environment: EnvVarsDict, mocker: MockerFixture, client: TestClient
251+
app_environment: EnvVarsDict,
252+
mocker: MockerFixture,
253+
client: TestClient,
245254
):
246-
mock = mocker.patch(
247-
"simcore_service_webserver.api_keys._service._repository.prune_expired"
248-
)
249-
settings = client.server.app[ # type: ignore
250-
APP_SETTINGS_KEY
251-
].WEBSERVER_GARBAGE_COLLECTOR
252-
assert isinstance(settings, GarbageCollectorSettings)
255+
assert app_environment["WEBSERVER_GARBAGE_COLLECTOR"] is not None
256+
257+
delete_expired_spy = mocker.spy(_repository, "delete_expired_api_keys")
258+
259+
assert client.app
260+
261+
settings: ApplicationSettings = get_application_settings(client.app)
262+
assert settings.WEBSERVER_GARBAGE_COLLECTOR
263+
264+
assert not delete_expired_spy.called
265+
253266
async for attempt in tenacity.AsyncRetrying(
254-
stop=stop_after_attempt(5),
267+
stop=stop_after_delay(
268+
timedelta(
269+
seconds=EXPIRATION_WAIT_FACTOR
270+
* settings.WEBSERVER_GARBAGE_COLLECTOR.GARBAGE_COLLECTOR_EXPIRED_USERS_CHECK_INTERVAL_S
271+
)
272+
),
255273
wait=wait_fixed(1),
256274
retry=retry_if_exception_type(AssertionError),
257275
reraise=True,
258276
):
259277
with attempt:
260-
mock.assert_called()
278+
delete_expired_spy.assert_called()

0 commit comments

Comments
 (0)