Skip to content

Commit 4dbcdc4

Browse files
committed
feat: update observed variable
1 parent 2353e7e commit 4dbcdc4

File tree

6 files changed

+207
-15
lines changed

6 files changed

+207
-15
lines changed

src/model/observed_variable.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@ class ObservedVariable(Variable):
2121
id: Mapped[UUID] = mapped_column(ForeignKey("variable_table.id"), primary_key=True, info=dto_field("read-only"))
2222

2323
title: Mapped[str] = mapped_column(nullable=False)
24-
variable_reference_id: Mapped[UUID | None] = mapped_column(ForeignKey("vocabulary_table.id", ondelete="SET NULL"))
25-
variable_reference: Mapped[Optional["Vocabulary"]] = relationship(
26-
"Vocabulary",
27-
lazy=None,
28-
back_populates="variable_reference",
29-
info=dto_field("read-only"),
30-
foreign_keys=[variable_reference_id],
31-
)
3224
trait_reference_id: Mapped[UUID | None] = mapped_column(ForeignKey("vocabulary_table.id", ondelete="SET NULL"))
3325
trait_reference: Mapped[Optional["Vocabulary"]] = relationship(
3426
"Vocabulary",
@@ -42,5 +34,4 @@ class ObservedVariable(Variable):
4234
@dataclass(kw_only=True)
4335
class ObservedVariableDataclass(VariableDataclass):
4436
title: str
45-
variable_reference_id: UUID | None = field(default=None)
4637
trait_reference_id: UUID | None = field(default=None)

src/model/vocabulary.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,6 @@ class Vocabulary(Base):
8282
organism: Mapped[list["BiologicalMaterial"]] = relationship(
8383
back_populates="organism", lazy=None, info=dto_field("private")
8484
)
85-
variable_reference: Mapped[list["ObservedVariable"]] = relationship(
86-
lazy=None,
87-
back_populates="variable_reference",
88-
info=dto_field("read-only"),
89-
foreign_keys="[ObservedVariable.variable_reference_id]",
90-
)
9185
trait_reference: Mapped[list["ObservedVariable"]] = relationship(
9286
lazy=None,
9387
back_populates="trait_reference",

tests/conftest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
InstitutionController,
1919
InvestigationController,
2020
MethodController,
21+
ObservedVariableController,
2122
StaffController,
2223
StudyController,
2324
UnitController,
@@ -38,6 +39,7 @@
3839
"tests.router.facility.fixture",
3940
"tests.router.experiment.fixture",
4041
"tests.router.biological_material.fixture",
42+
"tests.router.observed_variable.fixture",
4143
]
4244

4345

@@ -61,6 +63,7 @@ async def test_client() -> AsyncGenerator[AsyncTestClient[Litestar], None]:
6163
FacilityController,
6264
ExperimentController,
6365
BiologicalMaterialController,
66+
ObservedVariableController,
6467
],
6568
dependencies={"transaction": provide_transaction},
6669
plugins=[SQLAlchemyPlugin(db_config)],

tests/router/observed_variable/__init__.py

Whitespace-only changes.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
from collections.abc import AsyncGenerator
2+
from dataclasses import dataclass
3+
from uuid import UUID
4+
5+
import pytest
6+
from httpx import Response
7+
from litestar.testing import AsyncTestClient
8+
9+
from src.model.observed_variable import ObservedVariable, ObservedVariableDataclass
10+
from src.model.vocabulary import Vocabulary
11+
from tests.helpers import delete_fixture, post_fixture, put_fixture
12+
from tests.router.study.fixture import AllStudyFixtureResponse
13+
14+
15+
@dataclass
16+
class ObservedVariableResponse:
17+
observed_variable_response: Response
18+
study_response: list[Response]
19+
20+
21+
@dataclass
22+
class AllObservedVariableFixtureResponse:
23+
projected_shoot_area: ObservedVariableResponse
24+
zn_concentration: ObservedVariableResponse
25+
26+
27+
@dataclass
28+
class VariableReferenceResponse:
29+
anthesis: Response
30+
31+
32+
@dataclass
33+
class VariableTraitResponse:
34+
anthesis: Response
35+
reproductive_growth_time: Response
36+
projected_shoot_area: Response
37+
zn_concentration: Response
38+
39+
40+
PATH = "observed_variable"
41+
ANTHESIS_TRAIT = Vocabulary(title="Anthesis time", accession_number="CO_322:0000030")
42+
REPRODUCTIVE_GROWTH_TIME_TRAIT = Vocabulary(title="Reproductive growth time", accession_number="TO:0000366")
43+
PROJECTED_SHOOT_AREA_TRAIT = Vocabulary(title="Projected shoot area")
44+
ZN_CONCENTRATION_TRAIT = Vocabulary(title="Zn concentration", accession_number="CDNO_0200170")
45+
46+
ANTHESIS_VARIABLE = ObservedVariable(title="Ant_Cmp_Cday", description="Anthesis computed in growing degree days")
47+
PROJECTED_SHOOT_AREA_VARIABLE = ObservedVariable(title="PSA_img_kpixels")
48+
ZN_CONCENTRATION_VARIABLE = ObservedVariable(title="Zn_conc")
49+
50+
51+
async def get_observed_variable_fixture(
52+
data: ObservedVariable, studies: list[Response], test_client: AsyncTestClient, id: UUID | None = None
53+
) -> ObservedVariableResponse:
54+
study_id = [item.json()["id"] for item in studies]
55+
send_data = ObservedVariableDataclass(study_id=study_id, **data.to_dict())
56+
if id is None:
57+
send_data.updated_at = None
58+
response = await post_fixture(PATH, send_data, test_client)
59+
else:
60+
response = await put_fixture(PATH, send_data, test_client, id)
61+
return ObservedVariableResponse(study_response=studies, observed_variable_response=response)
62+
63+
64+
@pytest.fixture(scope="function")
65+
async def setup_observed_variable(
66+
setup_study: AllStudyFixtureResponse, test_client: AsyncTestClient
67+
) -> AsyncGenerator[AllObservedVariableFixtureResponse, None]:
68+
maize_study = setup_study.maize.study_response
69+
barley_study = setup_study.barley.study_response
70+
maize_sowing_density = await get_observed_variable_fixture(
71+
MAIZE_SOWING_DENSITY, [maize_study, barley_study], test_client
72+
)
73+
maize_rooting_medium = await get_observed_variable_fixture(MAIZE_ROOTING_MEDIUM, [maize_study], test_client)
74+
maize_ph = await get_observed_variable_fixture(MAIZE_PH, [maize_study], test_client)
75+
barley_sowing_density = await get_observed_variable_fixture(BARLEY_SOWING_DENSITY, [barley_study], test_client)
76+
barley_rooting_medium = await get_observed_variable_fixture(BARLEY_ROOTING_MEDIUM, [barley_study], test_client)
77+
barley_ferterlizer = await get_observed_variable_fixture(BARLEY_FERTILIZER, [barley_study], test_client)
78+
barley_watering_exposure = await get_observed_variable_fixture(
79+
BARLEY_WATERING_EXPOSURE, [barley_study], test_client
80+
)
81+
barley_light_intensity = await get_observed_variable_fixture(BARLEY_LIGHT_INTENSITY, [barley_study], test_client)
82+
barley_relative_humidity = await get_observed_variable_fixture(
83+
BARLEY_RELATIVE_HUMIDITY, [barley_study], test_client
84+
)
85+
barley_temperature = await get_observed_variable_fixture(BARLEY_TEMPERATURE, [barley_study], test_client)
86+
87+
yield AllObservedVariableFixtureResponse(
88+
maize_sowing_density=maize_sowing_density,
89+
maize_rooting_medium=maize_rooting_medium,
90+
maize_ph=maize_ph,
91+
barley_sowing_density=barley_sowing_density,
92+
barley_rooting_medium=barley_rooting_medium,
93+
barley_fertilizer=barley_ferterlizer,
94+
barley_watering_exposure=barley_watering_exposure,
95+
barley_light_intensity=barley_light_intensity,
96+
barley_relative_humidity=barley_relative_humidity,
97+
barley_temperature=barley_temperature,
98+
study_response=setup_study,
99+
)
100+
await delete_fixture(PATH, maize_sowing_density.observed_variable_response.json()["id"], test_client)
101+
await delete_fixture(PATH, maize_rooting_medium.observed_variable_response.json()["id"], test_client)
102+
await delete_fixture(PATH, maize_ph.observed_variable_response.json()["id"], test_client)
103+
await delete_fixture(PATH, barley_sowing_density.observed_variable_response.json()["id"], test_client)
104+
await delete_fixture(PATH, barley_rooting_medium.observed_variable_response.json()["id"], test_client)
105+
await delete_fixture(PATH, barley_ferterlizer.observed_variable_response.json()["id"], test_client)
106+
await delete_fixture(PATH, barley_watering_exposure.observed_variable_response.json()["id"], test_client)
107+
await delete_fixture(PATH, barley_light_intensity.observed_variable_response.json()["id"], test_client)
108+
await delete_fixture(PATH, barley_relative_humidity.observed_variable_response.json()["id"], test_client)
109+
await delete_fixture(PATH, barley_temperature.observed_variable_response.json()["id"], test_client)
110+
111+
112+
@pytest.fixture(scope="function")
113+
async def update_observed_variable(
114+
setup_observed_variable: AllObservedVariableFixtureResponse, test_client: AsyncTestClient
115+
) -> AsyncGenerator[AllObservedVariableFixtureResponse, None]:
116+
all_responses = setup_observed_variable
117+
maize_study = all_responses.study_response.maize.study_response
118+
maize_sowing_density = all_responses.maize_sowing_density
119+
maize_sowing_density_response = await get_observed_variable_fixture(
120+
MAIZE_SOWING_DENSITY, [maize_study], test_client, maize_sowing_density.observed_variable_response.json()["id"]
121+
)
122+
all_responses.maize_sowing_density = maize_sowing_density_response
123+
yield all_responses
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from dataclasses import dataclass
2+
from uuid import UUID
3+
4+
from httpx import Response
5+
from litestar.testing import AsyncTestClient
6+
7+
from src.model.environment import Environment, EnvironmentDataclass
8+
from tests.helpers import validate_post, validate_put
9+
from tests.router.environment.fixture import (
10+
BARLEY_FERTILIZER,
11+
BARLEY_LIGHT_INTENSITY,
12+
BARLEY_RELATIVE_HUMIDITY,
13+
BARLEY_ROOTING_MEDIUM,
14+
BARLEY_SOWING_DENSITY,
15+
BARLEY_TEMPERATURE,
16+
BARLEY_WATERING_EXPOSURE,
17+
MAIZE_PH,
18+
MAIZE_ROOTING_MEDIUM,
19+
MAIZE_SOWING_DENSITY,
20+
PATH,
21+
AllEnvironmentFixtureResponse,
22+
EnvironmentResponse,
23+
)
24+
25+
26+
@dataclass
27+
class EnvironmentFixture:
28+
id: UUID
29+
response: Response
30+
data: EnvironmentDataclass
31+
study_id: list[UUID]
32+
33+
34+
def get_environment_fixture(response: EnvironmentResponse, data: Environment) -> EnvironmentFixture:
35+
environment_response = response.environment_response
36+
study_id = [item.json()["id"] for item in response.study_response]
37+
fixture = EnvironmentDataclass(study_id=study_id, **data.to_dict())
38+
return EnvironmentFixture(
39+
id=environment_response.json()["id"], response=environment_response, data=fixture, study_id=study_id
40+
)
41+
42+
43+
async def test_all_environments_created(
44+
setup_environment: AllEnvironmentFixtureResponse, test_client: AsyncTestClient
45+
) -> None:
46+
fixture = get_environment_fixture(setup_environment.maize_sowing_density, MAIZE_SOWING_DENSITY)
47+
await validate_post(PATH, fixture.data, test_client, fixture.response)
48+
49+
fixture = get_environment_fixture(setup_environment.maize_rooting_medium, MAIZE_ROOTING_MEDIUM)
50+
await validate_post(PATH, fixture.data, test_client, fixture.response)
51+
52+
fixture = get_environment_fixture(setup_environment.maize_ph, MAIZE_PH)
53+
await validate_post(PATH, fixture.data, test_client, fixture.response)
54+
55+
fixture = get_environment_fixture(setup_environment.barley_fertilizer, BARLEY_FERTILIZER)
56+
await validate_post(PATH, fixture.data, test_client, fixture.response)
57+
58+
fixture = get_environment_fixture(setup_environment.barley_light_intensity, BARLEY_LIGHT_INTENSITY)
59+
await validate_post(PATH, fixture.data, test_client, fixture.response)
60+
61+
fixture = get_environment_fixture(setup_environment.barley_temperature, BARLEY_TEMPERATURE)
62+
await validate_post(PATH, fixture.data, test_client, fixture.response)
63+
64+
fixture = get_environment_fixture(setup_environment.barley_watering_exposure, BARLEY_WATERING_EXPOSURE)
65+
await validate_post(PATH, fixture.data, test_client, fixture.response)
66+
67+
fixture = get_environment_fixture(setup_environment.barley_sowing_density, BARLEY_SOWING_DENSITY)
68+
await validate_post(PATH, fixture.data, test_client, fixture.response)
69+
70+
fixture = get_environment_fixture(setup_environment.barley_rooting_medium, BARLEY_ROOTING_MEDIUM)
71+
await validate_post(PATH, fixture.data, test_client, fixture.response)
72+
73+
fixture = get_environment_fixture(setup_environment.barley_relative_humidity, BARLEY_RELATIVE_HUMIDITY)
74+
await validate_post(PATH, fixture.data, test_client, fixture.response)
75+
76+
77+
async def test_environment_file_updated(
78+
update_environment: AllEnvironmentFixtureResponse, test_client: AsyncTestClient
79+
) -> None:
80+
fixture = get_environment_fixture(update_environment.maize_sowing_density, MAIZE_SOWING_DENSITY)
81+
await validate_put(PATH, fixture.data, test_client, fixture.response)

0 commit comments

Comments
 (0)