Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build_validation_develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ jobs:
VALIDATE_TSX: true
VALIDATE_TYPESCRIPT_ES: true


- name: Docs validation
if: ${{ steps.filter.outputs.docs == 'true' }}
run: |
Expand Down
2 changes: 2 additions & 0 deletions api_app/pytest.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[pytest]
filterwarnings =
error
asyncio_mode = strict
asyncio_default_fixture_loop_scope = function
6 changes: 3 additions & 3 deletions api_app/tests_ma/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
import pytest_asyncio

from mock import AsyncMock, patch
from azure.cosmos.aio import CosmosClient, DatabaseProxy

Expand Down Expand Up @@ -575,8 +575,8 @@ def simple_pipeline_step() -> PipelineStep:
)


@pytest_asyncio.fixture(autouse=True)
async def no_database():
@pytest.fixture(autouse=True)
def no_database():
with patch('api.dependencies.database.get_credential_async', return_value=AsyncMock()), \
patch('api.dependencies.database.CosmosClient', return_value=AsyncMock(spec=CosmosClient)) as cosmos_client_mock:
cosmos_client_mock.return_value.get_database_client.return_value = AsyncMock(spec=DatabaseProxy)
Expand Down
10 changes: 7 additions & 3 deletions api_app/tests_ma/test_api/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest
import pytest_asyncio


from mock import patch

from fastapi import FastAPI
Expand Down Expand Up @@ -126,16 +128,18 @@ def inner():
return inner


@pytest_asyncio.fixture(scope='module')
@pytest.fixture(scope='module')
def app() -> FastAPI:
from main import get_application

the_app = get_application()
return the_app

return get_application()


@pytest_asyncio.fixture
async def client(app: FastAPI) -> AsyncClient:

async with AsyncClient(transport=ASGITransport(app=app), base_url="http://testserver", headers={"Content-Type": "application/json"}) as client:
yield client


50 changes: 36 additions & 14 deletions api_app/tests_ma/test_api/test_routes/test_airlock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import time
import pytest
import pytest_asyncio

pytestmark = pytest.mark.asyncio

from mock import patch
from fastapi import status
from azure.core.exceptions import HttpResponseError
Expand All @@ -17,7 +19,6 @@
from models.domain.operation import Operation
from resources import strings
from services.authentication import get_current_workspace_owner_or_researcher_user, get_current_workspace_owner_or_researcher_user_or_airlock_manager, get_current_airlock_manager_user
pytestmark = pytest.mark.asyncio


WORKSPACE_ID = "abc000d3-82da-4bfc-b6e9-9a7853ef753e"
Expand Down Expand Up @@ -127,18 +128,31 @@ def inner():


class TestAirlockRoutesThatRequireOwnerOrResearcherRights():
@pytest_asyncio.fixture(autouse=True, scope='class')
@pytest.fixture(autouse=True, scope="class")
def log_in_with_researcher_user(self, app, researcher_user):
app.dependency_overrides[get_current_workspace_owner_or_researcher_user] = researcher_user
app.dependency_overrides[get_current_workspace_owner_or_researcher_user_or_airlock_manager] = researcher_user
with patch("api.routes.airlock.AirlockRequestRepository.create_airlock_request_item", return_value=sample_airlock_request_object()), \
patch("api.routes.workspaces.OperationRepository.resource_has_deployed_operation"), \
patch("api.routes.airlock.AirlockRequestRepository.save_item"), \
patch("api.dependencies.workspaces.WorkspaceRepository.get_workspace_by_id"), \
patch("services.aad_authentication.AzureADAuthorization.get_workspace_user_emails_by_role_assignment", return_value={"WorkspaceResearcher": ["[email protected]"], "WorkspaceOwner": ["[email protected]"], "AirlockManager": ["[email protected]"]}):
with patch(
"api.routes.airlock.AirlockRequestRepository.create_airlock_request_item",
return_value=sample_airlock_request_object(),
), patch(
"api.routes.workspaces.OperationRepository.resource_has_deployed_operation"
), patch(
"api.routes.airlock.AirlockRequestRepository.save_item"
), patch(
"api.dependencies.workspaces.WorkspaceRepository.get_workspace_by_id"
), patch(
"services.aad_authentication.AzureADAuthorization.get_workspace_user_emails_by_role_assignment",
return_value={
"WorkspaceResearcher": ["[email protected]"],
"WorkspaceOwner": ["[email protected]"],
"AirlockManager": ["[email protected]"],
},
):
yield
app.dependency_overrides = {}


# [GET] /workspaces/{workspace_id}/requests}
@patch("api.routes.airlock.AirlockRequestRepository.get_airlock_requests", return_value=[])
async def test_get_all_airlock_requests_by_workspace_returns_200(self, _, app, client):
Expand Down Expand Up @@ -303,17 +317,24 @@ async def test_get_airlock_container_link_returned_as_expected(self, get_airlock


class TestAirlockRoutesThatRequireAirlockManagerRights():
@pytest_asyncio.fixture(autouse=True, scope='class')
@pytest.fixture(autouse=True, scope="class")
def log_in_with_airlock_manager_user(self, app, airlock_manager_user):
app.dependency_overrides[get_current_airlock_manager_user] = airlock_manager_user
app.dependency_overrides[get_current_workspace_owner_or_researcher_user_or_airlock_manager] = airlock_manager_user
with patch("services.airlock.AirlockRequestRepository.create_airlock_request_item", return_value=sample_airlock_request_object()), \
patch("api.routes.workspaces.OperationRepository.resource_has_deployed_operation"), \
patch("services.airlock.AirlockRequestRepository.save_item"), \
patch("api.dependencies.workspaces.WorkspaceRepository.get_workspace_by_id"):
with patch(
"services.airlock.AirlockRequestRepository.create_airlock_request_item",
return_value=sample_airlock_request_object(),
), patch(
"api.routes.workspaces.OperationRepository.resource_has_deployed_operation"
), patch(
"services.airlock.AirlockRequestRepository.save_item"
), patch(
"api.dependencies.workspaces.WorkspaceRepository.get_workspace_by_id"
):
yield
app.dependency_overrides = {}


# [POST] /workspaces/{workspace_id}/requests/{airlock_request_id}/review
@patch("services.airlock.AirlockRequestRepository.read_item_by_id", return_value=sample_airlock_request_object(status=AirlockRequestStatus.InReview))
@patch("services.airlock.AirlockRequestRepository.create_airlock_review_item", return_value=sample_airlock_review_object())
Expand Down Expand Up @@ -463,14 +484,15 @@ async def test_post_revoke_airlock_request_missing_reason_returns_422(self, _, a

class TestAirlockRoutesPermissions():

@pytest_asyncio.fixture()
@pytest.fixture()
def log_in_with_user(self, app):
def inner(user):
app.dependency_overrides[get_current_workspace_owner_or_researcher_user] = user
app.dependency_overrides[get_current_airlock_manager_user] = user
app.dependency_overrides[get_current_workspace_owner_or_researcher_user_or_airlock_manager] = user
return inner


@pytest.mark.parametrize("role", (role for role in get_required_roles(endpoint=create_draft_request)))
@patch("api.routes.workspaces.OperationRepository.resource_has_deployed_operation")
@patch("api.dependencies.workspaces.WorkspaceRepository.get_workspace_by_id", return_value=sample_workspace(WORKSPACE_ID))
Expand Down