Skip to content

Commit

Permalink
feat: add event tests
Browse files Browse the repository at this point in the history
  • Loading branch information
harryle95 committed Jun 2, 2024
1 parent 8466f23 commit 3584673
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/model/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@

class Event(Base):
__tablename__ = "event_table"
title: Mapped[str]
description: Mapped[str | None]
event_date: Mapped[datetime.datetime | None]
event_type_id: Mapped[UUID | None] = mapped_column(
ForeignKey(
Expand Down Expand Up @@ -67,10 +69,12 @@ class Event(Base):

@dataclass(kw_only=True)
class EventDataclass(BaseDataclass):
title: str
description: str | None = field(default=None)
event_date: datetime.datetime | None = field(default=None)
event_type_id: UUID | None = field(default=None)
observation_unit_id: list[UUID] = field(default_factory=list[UUID])
studies: list[UUID] = field(default_factory=list[UUID])
study_id: list[UUID] = field(default_factory=list[UUID])

@classmethod
def from_orm(cls, data: Serialisable) -> "BaseDataclass":
Expand Down
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
DataFileController,
DeviceController,
EnvironmentController,
EventController,
ExperimentalFactorController,
ExperimentController,
FacilityController,
Expand Down Expand Up @@ -42,6 +43,7 @@
"tests.router.biological_material.fixture",
"tests.router.observed_variable.fixture",
"tests.router.observation_unit.fixture",
"tests.router.event.fixture",
]


Expand All @@ -67,6 +69,7 @@ async def test_client() -> AsyncGenerator[AsyncTestClient[Litestar], None]:
BiologicalMaterialController,
ObservedVariableController,
ObservationUnitController,
EventController,
],
dependencies={"transaction": provide_transaction},
plugins=[SQLAlchemyPlugin(db_config)],
Expand Down
Empty file added tests/router/event/__init__.py
Empty file.
161 changes: 161 additions & 0 deletions tests/router/event/fixture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import datetime
from collections.abc import AsyncGenerator
from dataclasses import dataclass
from uuid import UUID

import pytest
from httpx import Response
from litestar.testing import AsyncTestClient

from src.model.event import Event, EventDataclass
from src.model.vocabulary import Vocabulary
from tests.helpers import delete_fixture, post_fixture, put_fixture
from tests.router.observation_unit.fixture import AllObservationUnitFixtureResponse
from tests.router.study.fixture import AllStudyFixtureResponse


@dataclass
class EventTypeResponse:
planting: Response
fertilizing: Response
watering: Response


@dataclass
class EventResponse:
event_response: Response
event_type: Response
study_response: list[Response]
observation_unit_response: list[Response]


@dataclass
class AllEventFixtureResponse:
planting: EventResponse
fertilizing: EventResponse
watering: EventResponse
event_type: EventTypeResponse
studies: AllStudyFixtureResponse
observation_units: AllObservationUnitFixtureResponse


PATH = "event"
PLANTING_TYPE = Vocabulary(title="Planting", accession_number="CO_715:0000007")
PLANTING_EVENT = Event(
title="Planting Seed - Maize Experiment",
description="Sowing using seed drill",
event_date=datetime.datetime(2006, 9, 27),
)

FERTILIZING_TYPE = Vocabulary(title="Fertilizing", accession_number="CO_715:0000011")
FERTILIZING_EVENT = Event(
title="Fertilizing - Maize Experiment",
description="Fertilizer application: Ammonium nitrate at 3 kg/m2",
event_date=datetime.datetime(2006, 10, 27),
)

WATERING_TYPE = Vocabulary(title="Watering Exposure", accession_number="PECO:0007383")
WATERING_EVENT = Event(
title="Watering - Barley Experiment",
description="Automated pot weight based watering regime during experiment",
event_date=datetime.datetime(2017, 4, 6),
)


async def get_event_fixture(
data: Event,
event_type: Response,
studies: list[Response],
observation_units: list[Response],
test_client: AsyncTestClient,
id: UUID | None = None,
) -> EventResponse:
study_id = [item.json()["id"] for item in studies]
observation_unit_id = [item.json()["id"] for item in observation_units]
event_type_id = event_type.json()["id"]
send_data = EventDataclass(
study_id=study_id,
observation_unit_id=observation_unit_id,
event_type_id=event_type_id,
**data.to_dict(),
)
if id is None:
send_data.updated_at = None
response = await post_fixture(PATH, send_data, test_client)
else:
response = await put_fixture(PATH, send_data, test_client, id)
return EventResponse(
study_response=studies,
event_response=response,
event_type=event_type,
observation_unit_response=observation_units,
)


@pytest.fixture(scope="function")
async def setup_event_type(test_client: AsyncTestClient) -> AsyncGenerator[EventTypeResponse, None]:
planting = await post_fixture("vocabulary", PLANTING_TYPE, test_client)
fertlizing = await post_fixture("vocabulary", FERTILIZING_TYPE, test_client)
watering = await post_fixture("vocabulary", WATERING_TYPE, test_client)
yield EventTypeResponse(planting=planting, fertilizing=fertlizing, watering=watering)
await delete_fixture("vocabulary", planting.json()["id"], test_client)
await delete_fixture("vocabulary", fertlizing.json()["id"], test_client)
await delete_fixture("vocabulary", watering.json()["id"], test_client)


@pytest.fixture(scope="function")
async def setup_event(
setup_event_type: EventTypeResponse,
setup_study: AllStudyFixtureResponse,
setup_observation_units: AllObservationUnitFixtureResponse,
test_client: AsyncTestClient,
) -> AsyncGenerator[AllEventFixtureResponse, None]:
maize_study = setup_study.maize.study_response
barley_study = setup_study.barley.study_response

planting = setup_event_type.planting
fertilizing = setup_event_type.fertilizing
watering = setup_event_type.fertilizing

plot_894 = setup_observation_units.plot_894.observation_unit_response
plant_061439 = setup_observation_units.plant_061439.observation_unit_response
plant_061440 = setup_observation_units.plant_061440.observation_unit_response

planting_event = await get_event_fixture(
PLANTING_EVENT, planting, [maize_study, barley_study], [plot_894], test_client
)
fertilizing_event = await get_event_fixture(FERTILIZING_EVENT, fertilizing, [maize_study], [plot_894], test_client)
watering_event = await get_event_fixture(
WATERING_EVENT, watering, [barley_study], [plant_061439, plant_061440], test_client
)

yield AllEventFixtureResponse(
planting=planting_event,
fertilizing=fertilizing_event,
watering=watering_event,
event_type=setup_event_type,
studies=setup_study,
observation_units=setup_observation_units,
)
await delete_fixture(PATH, planting_event.event_response.json()["id"], test_client)
await delete_fixture(PATH, fertilizing_event.event_response.json()["id"], test_client)
await delete_fixture(PATH, watering_event.event_response.json()["id"], test_client)


@pytest.fixture(scope="function")
async def update_event(
setup_event: AllEventFixtureResponse, test_client: AsyncTestClient
) -> AsyncGenerator[AllEventFixtureResponse, None]:
all_responses = setup_event
maize_study = all_responses.studies.maize.study_response
planting_id = all_responses.planting.event_response.json()["id"]
planting = await get_event_fixture(
PLANTING_EVENT,
event_type=all_responses.event_type.planting,
studies=[maize_study],
observation_units=[all_responses.observation_units.plot_894.observation_unit_response],
test_client=test_client,
id=planting_id,
)
all_responses.planting = planting
yield all_responses
60 changes: 60 additions & 0 deletions tests/router/event/test_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from dataclasses import dataclass
from uuid import UUID

from httpx import Response
from litestar.testing import AsyncTestClient

from src.model.event import Event, EventDataclass
from tests.helpers import validate_post, validate_put
from tests.router.event.fixture import (
FERTILIZING_EVENT,
PATH,
PLANTING_EVENT,
WATERING_EVENT,
AllEventFixtureResponse,
EventResponse,
)


@dataclass
class EventFixture:
id: UUID
response: Response
data: EventDataclass
event_type_id: UUID
study_id: list[UUID]
observation_unit_id: list[UUID]


def get_event_fixture(response: EventResponse, data: Event) -> EventFixture:
event_response = response.event_response
study_id = [item.json()["id"] for item in response.study_response]
event_type_id = response.event_type.json()["id"]
observation_unit_id = [item.json()["id"] for item in response.observation_unit_response]
fixture = EventDataclass(
study_id=study_id, event_type_id=event_type_id, observation_unit_id=observation_unit_id, **data.to_dict()
)
return EventFixture(
id=event_response.json()["id"],
response=event_response,
data=fixture,
study_id=study_id,
event_type_id=event_type_id,
observation_unit_id=observation_unit_id,
)


async def test_all_events_created(setup_event: AllEventFixtureResponse, test_client: AsyncTestClient) -> None:
fixture = get_event_fixture(setup_event.fertilizing, FERTILIZING_EVENT)
await validate_post(PATH, fixture.data, test_client, fixture.response)

fixture = get_event_fixture(setup_event.planting, PLANTING_EVENT)
await validate_post(PATH, fixture.data, test_client, fixture.response)

fixture = get_event_fixture(setup_event.watering, WATERING_EVENT)
await validate_post(PATH, fixture.data, test_client, fixture.response)


async def test_event_file_updated(update_event: AllEventFixtureResponse, test_client: AsyncTestClient) -> None:
fixture = get_event_fixture(update_event.planting, PLANTING_EVENT)
await validate_put(PATH, fixture.data, test_client, fixture.response)

0 comments on commit 3584673

Please sign in to comment.