|
7 | 7 | import random |
8 | 8 | from collections.abc import Iterator |
9 | 9 | from threading import Thread |
10 | | -from typing import Any |
11 | | -from urllib.parse import quote |
12 | 10 |
|
13 | 11 | import pytest |
14 | 12 | import uvicorn |
15 | | -from aiohttp.test_utils import TestClient |
16 | 13 | from faker import Faker |
17 | | -from fastapi import APIRouter, FastAPI, Request |
| 14 | +from fastapi import APIRouter, FastAPI, Request, status |
18 | 15 | from models_library.generics import Envelope |
19 | 16 | from models_library.projects import ProjectID |
20 | 17 | from models_library.projects_nodes_io import LocationID, StorageFileID |
|
30 | 27 | ) |
31 | 28 | from models_library.users import UserID |
32 | 29 | from pydantic import AnyUrl, TypeAdapter |
33 | | -from pytest_simcore.helpers.assert_checks import assert_status |
34 | 30 | from pytest_simcore.helpers.logging_tools import log_context |
35 | | -from servicelib.aiohttp import status |
| 31 | +from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict |
36 | 32 | from servicelib.utils import unused_port |
37 | | -from simcore_postgres_database.models.users import UserRole |
38 | 33 | from yarl import URL |
39 | 34 |
|
40 | | -API_VERSION = "v0" |
41 | | - |
42 | 35 |
|
43 | 36 | @pytest.fixture(scope="session") |
44 | 37 | def storage_vtag() -> str: |
@@ -296,238 +289,18 @@ def app_environment( |
296 | 289 | monkeypatch: pytest.MonkeyPatch, |
297 | 290 | ) -> dict[str, str]: |
298 | 291 | # NOTE: overrides app_environment |
299 | | - monkeypatch.setenv("STORAGE_PORT", f"{fake_storage_server.port}") |
300 | | - monkeypatch.setenv("STORAGE_VTAG", storage_vtag) |
301 | | - monkeypatch.setenv("WEBSERVER_GARBAGE_COLLECTOR", "null") |
302 | | - return app_environment | {"WEBSERVER_GARBAGE_COLLECTOR": "null"} |
303 | | - |
304 | | - |
305 | | -# -------------------------------------------------------------------------- |
306 | | -PREFIX = "/" + API_VERSION + "/storage" |
307 | | - |
308 | | - |
309 | | -@pytest.mark.parametrize( |
310 | | - "user_role,expected", |
311 | | - [ |
312 | | - (UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED), |
313 | | - (UserRole.GUEST, status.HTTP_200_OK), |
314 | | - (UserRole.USER, status.HTTP_200_OK), |
315 | | - (UserRole.TESTER, status.HTTP_200_OK), |
316 | | - ], |
317 | | -) |
318 | | -async def test_list_storage_locations( |
319 | | - client: TestClient, |
320 | | - logged_user: dict[str, Any], |
321 | | - expected: int, |
322 | | -): |
323 | | - url = "/v0/storage/locations" |
324 | | - assert url.startswith(PREFIX) |
325 | | - |
326 | | - resp = await client.get(url, params={"user_id": logged_user["id"]}) |
327 | | - data, error = await assert_status(resp, expected) |
328 | | - |
329 | | - if not error: |
330 | | - assert "json_schema_extra" in FileLocation.model_config |
331 | | - assert isinstance(FileLocation.model_config["json_schema_extra"], dict) |
332 | | - assert isinstance( |
333 | | - FileLocation.model_config["json_schema_extra"]["examples"], list |
334 | | - ) |
335 | | - assert len(data) == len( |
336 | | - FileLocation.model_config["json_schema_extra"]["examples"] |
337 | | - ) |
338 | | - assert data == FileLocation.model_config["json_schema_extra"]["examples"] |
339 | | - |
340 | | - |
341 | | -@pytest.mark.parametrize( |
342 | | - "user_role,expected", |
343 | | - [ |
344 | | - (UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED), |
345 | | - (UserRole.GUEST, status.HTTP_200_OK), |
346 | | - (UserRole.USER, status.HTTP_200_OK), |
347 | | - (UserRole.TESTER, status.HTTP_200_OK), |
348 | | - ], |
349 | | -) |
350 | | -async def test_list_datasets_metadata( |
351 | | - client: TestClient, |
352 | | - logged_user: dict[str, Any], |
353 | | - expected: int, |
354 | | -): |
355 | | - url = "/v0/storage/locations/0/datasets" |
356 | | - assert url.startswith(PREFIX) |
357 | | - assert client.app |
358 | | - _url = client.app.router["list_datasets_metadata"].url_for(location_id="0") |
359 | | - |
360 | | - assert url == str(_url) |
361 | | - |
362 | | - resp = await client.get(url, params={"user_id": logged_user["id"]}) |
363 | | - data, error = await assert_status(resp, expected) |
364 | | - |
365 | | - if not error: |
366 | | - assert "json_schema_extra" in DatasetMetaDataGet.model_config |
367 | | - assert isinstance(DatasetMetaDataGet.model_config["json_schema_extra"], dict) |
368 | | - assert isinstance( |
369 | | - DatasetMetaDataGet.model_config["json_schema_extra"]["examples"], list |
370 | | - ) |
371 | | - |
372 | | - assert len(data) == len( |
373 | | - DatasetMetaDataGet.model_config["json_schema_extra"]["examples"] |
374 | | - ) |
375 | | - assert data == DatasetMetaDataGet.model_config["json_schema_extra"]["examples"] |
376 | | - |
377 | | - |
378 | | -@pytest.mark.parametrize( |
379 | | - "user_role,expected", |
380 | | - [ |
381 | | - (UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED), |
382 | | - (UserRole.GUEST, status.HTTP_200_OK), |
383 | | - (UserRole.USER, status.HTTP_200_OK), |
384 | | - (UserRole.TESTER, status.HTTP_200_OK), |
385 | | - ], |
386 | | -) |
387 | | -async def test_list_dataset_files_metadata( |
388 | | - client: TestClient, |
389 | | - logged_user: dict[str, Any], |
390 | | - expected: int, |
391 | | -): |
392 | | - url = "/v0/storage/locations/0/datasets/N:asdfsdf/metadata" |
393 | | - assert url.startswith(PREFIX) |
394 | | - assert client.app |
395 | | - _url = client.app.router["list_dataset_files_metadata"].url_for( |
396 | | - location_id="0", dataset_id="N:asdfsdf" |
397 | | - ) |
398 | | - |
399 | | - assert url == str(_url) |
400 | | - |
401 | | - resp = await client.get(url, params={"user_id": logged_user["id"]}) |
402 | | - data, error = await assert_status(resp, expected) |
403 | | - |
404 | | - if not error: |
405 | | - assert "json_schema_extra" in FileMetaDataGet.model_config |
406 | | - assert isinstance(FileMetaDataGet.model_config["json_schema_extra"], dict) |
407 | | - assert isinstance( |
408 | | - FileMetaDataGet.model_config["json_schema_extra"]["examples"], list |
409 | | - ) |
410 | | - assert len(data) == len( |
411 | | - FileMetaDataGet.model_config["json_schema_extra"]["examples"] |
412 | | - ) |
413 | | - assert data == [ |
414 | | - FileMetaDataGet.model_validate(e).model_dump(mode="json") |
415 | | - for e in FileMetaDataGet.model_config["json_schema_extra"]["examples"] |
416 | | - ] |
417 | | - |
418 | | - |
419 | | -@pytest.mark.parametrize( |
420 | | - "user_role,expected", |
421 | | - [ |
422 | | - (UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED), |
423 | | - (UserRole.GUEST, status.HTTP_200_OK), |
424 | | - (UserRole.USER, status.HTTP_200_OK), |
425 | | - (UserRole.TESTER, status.HTTP_200_OK), |
426 | | - ], |
427 | | -) |
428 | | -async def test_storage_file_meta( |
429 | | - client: TestClient, |
430 | | - logged_user: dict[str, Any], |
431 | | - expected: int, |
432 | | - faker: Faker, |
433 | | -): |
434 | | - # tests redirect of path with quotes in path |
435 | | - file_id = f"{faker.uuid4()}/{faker.uuid4()}/a/b/c/d/e/dat" |
436 | | - quoted_file_id = quote(file_id, safe="") |
437 | | - url = f"/v0/storage/locations/0/files/{quoted_file_id}/metadata" |
438 | | - |
439 | | - assert url.startswith(PREFIX) |
440 | | - |
441 | | - resp = await client.get(url, params={"user_id": logged_user["id"]}) |
442 | | - data, error = await assert_status(resp, expected) |
443 | | - |
444 | | - if not error: |
445 | | - assert "json_schema_extra" in FileMetaDataGet.model_config |
446 | | - assert isinstance(FileMetaDataGet.model_config["json_schema_extra"], dict) |
447 | | - assert isinstance( |
448 | | - FileMetaDataGet.model_config["json_schema_extra"]["examples"], list |
449 | | - ) |
450 | 292 |
|
451 | | - assert data |
452 | | - model = FileMetaDataGet.model_validate(data) |
453 | | - assert model |
454 | | - |
455 | | - |
456 | | -@pytest.mark.parametrize( |
457 | | - "user_role,expected", |
458 | | - [ |
459 | | - (UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED), |
460 | | - (UserRole.GUEST, status.HTTP_200_OK), |
461 | | - (UserRole.USER, status.HTTP_200_OK), |
462 | | - (UserRole.TESTER, status.HTTP_200_OK), |
463 | | - ], |
464 | | -) |
465 | | -async def test_storage_list_filter( |
466 | | - client: TestClient, |
467 | | - logged_user: dict[str, Any], |
468 | | - expected: int, |
469 | | -): |
470 | | - # tests composition of 2 queries |
471 | | - file_id = "a/b/c/d/e/dat" |
472 | | - url = "/v0/storage/locations/0/files/metadata?uuid_filter={}".format( |
473 | | - quote(file_id, safe="") |
| 293 | + return app_environment | setenvs_from_dict( |
| 294 | + monkeypatch, |
| 295 | + { |
| 296 | + "STORAGE_PORT": f"{fake_storage_server.port}", |
| 297 | + "STORAGE_VTAG": storage_vtag, |
| 298 | + "WEBSERVER_DB_LISTENER": "0", |
| 299 | + "WEBSERVER_GARBAGE_COLLECTOR": "null", |
| 300 | + }, |
474 | 301 | ) |
475 | 302 |
|
476 | | - assert url.startswith(PREFIX) |
477 | | - |
478 | | - resp = await client.get(url, params={"user_id": logged_user["id"]}) |
479 | | - data, error = await assert_status(resp, expected) |
480 | | - |
481 | | - if not error: |
482 | | - assert "json_schema_extra" in FileMetaDataGet.model_config |
483 | | - assert isinstance(FileMetaDataGet.model_config["json_schema_extra"], dict) |
484 | | - assert isinstance( |
485 | | - FileMetaDataGet.model_config["json_schema_extra"]["examples"], list |
486 | | - ) |
487 | | - |
488 | | - assert len(data) == 2 |
489 | | - for item in data: |
490 | | - model = FileMetaDataGet.model_validate(item) |
491 | | - assert model |
492 | | - |
493 | 303 |
|
494 | 304 | @pytest.fixture |
495 | | -def file_id(faker: Faker) -> StorageFileID: |
496 | | - return TypeAdapter(StorageFileID).validate_python( |
497 | | - f"{faker.uuid4()}/{faker.uuid4()}/{faker.file_name()} with spaces.dat" |
498 | | - ) |
499 | | - |
500 | | - |
501 | | -@pytest.mark.parametrize( |
502 | | - "user_role,expected", |
503 | | - [ |
504 | | - # (UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED), |
505 | | - # (UserRole.GUEST, status.HTTP_200_OK), |
506 | | - (UserRole.USER, status.HTTP_200_OK), |
507 | | - # (UserRole.TESTER, status.HTTP_200_OK), |
508 | | - ], |
509 | | -) |
510 | | -async def test_upload_file( |
511 | | - client: TestClient, |
512 | | - logged_user: dict[str, Any], |
513 | | - expected: int, |
514 | | - file_id: StorageFileID, |
515 | | -): |
516 | | - url = f"/v0/storage/locations/0/files/{quote(file_id, safe='')}" |
517 | | - |
518 | | - assert url.startswith(PREFIX) |
519 | | - |
520 | | - resp = await client.put(url, params={"user_id": logged_user["id"]}) |
521 | | - data, error = await assert_status(resp, expected) |
522 | | - assert not error |
523 | | - assert data |
524 | | - file_upload_schema = FileUploadSchema.model_validate(data) |
525 | | - |
526 | | - # let's abort |
527 | | - resp = await client.post( |
528 | | - f"{file_upload_schema.links.abort_upload.path}", |
529 | | - params={"user_id": logged_user["id"]}, |
530 | | - ) |
531 | | - data, error = await assert_status(resp, status.HTTP_204_NO_CONTENT) |
532 | | - assert not error |
533 | | - assert not data |
| 305 | +def location_id(faker: Faker) -> LocationID: |
| 306 | + return TypeAdapter(LocationID).validate_python(faker.pyint(min_value=0)) |
0 commit comments