Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 1 addition & 23 deletions app/filters/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from sqlalchemy.orm import DeclarativeBase

from app.db.model import Identifiable
from app.logger import L

Aliases = dict[type[Identifiable], type[Identifiable] | dict[str, type[Identifiable]]]

Expand All @@ -25,29 +24,8 @@ class Constants(Filter.Constants):

@field_validator("*", mode="before")
@classmethod
def split_str(cls, value, field): # pyright: ignore reportIncompatibleMethodOverride
def split_str(cls, value, field): # pyright: ignore reportIncompatibleMethodOverride # noqa: ARG003
"""Prevent splitting field logic from parent class."""
# backwards compatibility by splitting only comma separated single list elements that do not
# have space directly after the comma. e.g "a,b,c" will be split but not 'a, b, c'.
if (
field.field_name is not None # noqa: PLR0916
and (
field.field_name == cls.Constants.ordering_field_name
or field.field_name.endswith("__in")
or field.field_name.endswith("__not_in")
)
and value
and len(value) == 1
and isinstance(value[0], str)
and "," in value[0]
and ", " not in value[0]
):
msg = (
"Deprecated comma separated single-string IN query used instead of native list. "
f"Filter: field.config['title'] Field name: {field.field_name} Value: {value}"
)
L.warning(msg)
return value[0].split(",")
return value

@field_validator("order_by", check_fields=False)
Expand Down
6 changes: 1 addition & 5 deletions app/filters/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@

class IdFilterMixin:
id: uuid.UUID | None = None

# id__in needs to be a str for backwards compatibility when instead of a native list a comma
# separated string is provided, e.g. 'id1,id2' . With list[UUID] backwards compatibility would
# fail because of validation of the field which would be expected to be a UUID.
id__in: list[str] | None = None
id__in: list[uuid.UUID] | None = None


class AuthorizedFilterMixin:
Expand Down
14 changes: 0 additions & 14 deletions tests/test_calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,27 +232,13 @@ def test_filtering(client, models, root_circuit, simulation_result):
assert len(data) == 2
"""

# backwards compat
data = assert_request(
client.get, url=ROUTE, params={"used__id__in": f"{root_circuit.id},{simulation_result.id}"}
).json()["data"]
assert len(data) == 5

data = assert_request(
client.get,
url=ROUTE,
params={"used__id__in": [str(root_circuit.id), str(simulation_result.id)]},
).json()["data"]
assert len(data) == 5

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"generated__id__in": f"{root_circuit.id},{simulation_result.id}"},
).json()["data"]
assert len(data) == 4

data = assert_request(
client.get,
url=ROUTE,
Expand Down
29 changes: 0 additions & 29 deletions tests/test_cell_morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,15 +649,6 @@ def test_filter_by_id__in(db, client, brain_region_id, person_id, subject_id):

# filtering by multiple IDs
selected_ids = [morphology_ids[1], morphology_ids[3]]

# backwards compat
response = client.get(ROUTE, params={"id__in": ",".join(selected_ids)})
assert response.status_code == 200
data = response.json()["data"]
assert len(data) == 2
returned_ids = [item["id"] for item in data]
assert set(returned_ids) == set(selected_ids)

response = client.get(ROUTE, params={"id__in": selected_ids})
assert response.status_code == 200
data = response.json()["data"]
Expand All @@ -666,15 +657,6 @@ def test_filter_by_id__in(db, client, brain_region_id, person_id, subject_id):
assert set(returned_ids) == set(selected_ids)

# filtering by all IDs

# backwards compat
response = client.get(ROUTE, params={"id__in": ",".join(morphology_ids)})
assert response.status_code == 200
data = response.json()["data"]
assert len(data) == 5
returned_ids = [item["id"] for item in data]
assert set(returned_ids) == set(morphology_ids)

response = client.get(ROUTE, params={"id__in": morphology_ids})
assert response.status_code == 200
data = response.json()["data"]
Expand All @@ -689,17 +671,6 @@ def test_filter_by_id__in(db, client, brain_region_id, person_id, subject_id):
assert len(data) == 0

# combining id__in with other filters

# backwards compat
response = client.get(
ROUTE,
params={"id__in": ",".join(morphology_ids), "name__ilike": "%Filter Test Morphology 2%"},
)
assert response.status_code == 200
data = response.json()["data"]
assert len(data) == 1
assert data[0]["id"] == morphology_ids[2]

response = client.get(
ROUTE,
params={"id__in": morphology_ids, "name__ilike": "%Filter Test Morphology 2%"},
Expand Down
8 changes: 0 additions & 8 deletions tests/test_electrical_cell_recording.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,6 @@ def test_filtering(client, models):
).json()["data"]
assert {d["name"] for d in data} == {"e-1", "e-2"}

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"name__in": "e-1,e-2"},
).json()["data"]
assert {d["name"] for d in data} == {"e-1", "e-2"}

data = assert_request(
client.get,
url=ROUTE,
Expand Down
8 changes: 0 additions & 8 deletions tests/test_etype.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,6 @@ def test_retrieve(db, client, person_id):
assert data[0] == with_creation_fields(items[5])

# test filter (in)

# backwards compat
response = client.get(ROUTE, params={"pref_label__in": "pref_label_5,pref_label_6"})
assert response.status_code == 200
data = response.json()["data"]
assert len(data) == 2
assert data == [with_creation_fields(items[5]), with_creation_fields(items[6])]

response = client.get(ROUTE, params={"pref_label__in": ["pref_label_5", "pref_label_6"]})
assert response.status_code == 200
data = response.json()["data"]
Expand Down
8 changes: 0 additions & 8 deletions tests/test_experimental_bouton_density.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,6 @@ def test_filtering(client, models):
).json()["data"]
assert {d["name"] for d in data} == {"d-1", "d-2"}

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"name__in": "d-1,d-2"},
).json()["data"]
assert {d["name"] for d in data} == {"d-1", "d-2"}

data = assert_request(
client.get, url=ROUTE, params="contribution__pref_label=test_person_1"
).json()["data"]
Expand Down
8 changes: 0 additions & 8 deletions tests/test_experimental_neuron_density.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,14 +353,6 @@ def test_filtering(client, models):
).json()["data"]
assert {d["name"] for d in data} == {"d-1", "d-2"}

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"name__in": "d-1,d-2"},
).json()["data"]
assert {d["name"] for d in data} == {"d-1", "d-2"}

data = assert_request(
client.get, url=ROUTE, params="contribution__pref_label=test_person_1"
).json()["data"]
Expand Down
8 changes: 0 additions & 8 deletions tests/test_ion_channel_recording.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,14 +443,6 @@ def test_filtering(client, models):
).json()["data"]
assert {d["name"] for d in data} == {"e-1", "e-2"}

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"name__in": "e-1,e-2"},
).json()["data"]
assert {d["name"] for d in data} == {"e-1", "e-2"}

data = assert_request(
client.get,
url=ROUTE,
Expand Down
7 changes: 0 additions & 7 deletions tests/test_mtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,6 @@ def test_retrieve(db, client, person_id):
assert data[0] == with_creation_fields(items[5])

# test filter (in)
# backwards compat
response = client.get(ROUTE, params={"pref_label__in": "pref_label_5,pref_label_6"})
assert response.status_code == 200
data = response.json()["data"]
assert len(data) == 2
assert data == [with_creation_fields(items[5]), with_creation_fields(items[6])]

response = client.get(ROUTE, params={"pref_label__in": ["pref_label_5", "pref_label_6"]})
assert response.status_code == 200
data = response.json()["data"]
Expand Down
10 changes: 6 additions & 4 deletions tests/test_ordering.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import pytest

from app.db.model import CellMorphology, License

from tests.utils import PROJECT_ID, add_all_db, check_sort_by_field
Expand Down Expand Up @@ -72,6 +70,10 @@ def test_cell_morphology_ordering(db, client, subject_id, license_id, brain_regi
assert response.status_code == 200
data = response.json()["data"]
assert len(data) == count / 2
with pytest.raises(AssertionError, match="Items unsorted by id"):
check_sort_by_field(data, "id")
check_sort_by_field(data, "name")

response = client.get(ROUTE_MORPHOLOGY, params={"name__ilike": "to_find", "order_by": "-name"})
assert response.status_code == 200
data = response.json()["data"]
assert len(data) == count / 2
check_sort_by_field(data, "name", how="descending")
14 changes: 0 additions & 14 deletions tests/test_simulation_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,27 +223,13 @@ def test_filtering(client, models, root_circuit, simulation_result):
).json()["data"]
assert len(data) == 2

# backwards compat
data = assert_request(
client.get, url=ROUTE, params={"used__id__in": f"{root_circuit.id},{simulation_result.id}"}
).json()["data"]
assert len(data) == 5

data = assert_request(
client.get,
url=ROUTE,
params={"used__id__in": [str(root_circuit.id), str(simulation_result.id)]},
).json()["data"]
assert len(data) == 5

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"generated__id__in": f"{root_circuit.id},{simulation_result.id}"},
).json()["data"]
assert len(data) == 4

data = assert_request(
client.get,
url=ROUTE,
Expand Down
14 changes: 0 additions & 14 deletions tests/test_simulation_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,27 +202,13 @@ def test_filtering(client, models, root_circuit, simulation_result):
).json()["data"]
assert len(data) == 2

# backwards compat
data = assert_request(
client.get, url=ROUTE, params={"used__id__in": f"{root_circuit.id},{simulation_result.id}"}
).json()["data"]
assert len(data) == 5

data = assert_request(
client.get,
url=ROUTE,
params={"used__id__in": [str(root_circuit.id), str(simulation_result.id)]},
).json()["data"]
assert len(data) == 5

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"generated__id__in": f"{root_circuit.id},{simulation_result.id}"},
).json()["data"]
assert len(data) == 4

data = assert_request(
client.get,
url=ROUTE,
Expand Down
14 changes: 0 additions & 14 deletions tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,27 +224,13 @@ def test_filtering(client, models, root_circuit, simulation_result):
assert len(data) == 2
"""

# backwards compat
data = assert_request(
client.get, url=ROUTE, params={"used__id__in": f"{root_circuit.id},{simulation_result.id}"}
).json()["data"]
assert len(data) == 5

data = assert_request(
client.get,
url=ROUTE,
params={"used__id__in": [str(root_circuit.id), str(simulation_result.id)]},
).json()["data"]
assert len(data) == 5

# backwards compat
data = assert_request(
client.get,
url=ROUTE,
params={"generated__id__in": f"{root_circuit.id},{simulation_result.id}"},
).json()["data"]
assert len(data) == 4

data = assert_request(
client.get,
url=ROUTE,
Expand Down
17 changes: 13 additions & 4 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import functools
import operator
import uuid
from collections.abc import Callable
from datetime import UTC, datetime, timedelta
Expand Down Expand Up @@ -791,10 +792,18 @@ def delete_entity_classifications(client, client_admin, entity_id):
)


def check_sort_by_field(items, field_name):
assert all(items[i][field_name] < items[i + 1][field_name] for i in range(len(items) - 1)), (
f"Items unsorted by {field_name}"
)
def check_sort_by_field(items, field_name, how="ascending"):
op = {
"ascending": operator.le,
"descending": operator.ge,
}[how]
assert all(
op(
items[i][field_name],
items[i + 1][field_name],
)
for i in range(len(items) - 1)
), f"Items not sorted {how} by {field_name}"


def create_subject_ids(db, *, created_by_id, n):
Expand Down