diff --git a/store/neurostore/schemas/data.py b/store/neurostore/schemas/data.py index dea575cd..be991f84 100644 --- a/store/neurostore/schemas/data.py +++ b/store/neurostore/schemas/data.py @@ -5,10 +5,15 @@ post_dump, pre_dump, pre_load, + post_load, EXCLUDE, ) + +from sqlalchemy import func import orjson -from marshmallow.decorators import post_load + +from neurostore.core import db +from neurostore.models import Analysis, Point # context parameters # clone: create a new object with new ids (true or false) @@ -229,6 +234,17 @@ def process_values(self, data, **kwargs): if data.get("coordinates"): coords = [float(c) for c in data.pop("coordinates")] data["x"], data["y"], data["z"] = coords + + if data.get("order") is None: + if data.get("analysis_id") is not None: + max_order = ( + db.session.query(func.max(Point.order)) + .filter_by(analysis_id=data["analysis_id"]) + .scalar() + ) + data["order"] = 1 if max_order is None else max_order + 1 + else: + data["order"] = 1 return data @pre_dump @@ -285,6 +301,17 @@ def load_values(self, data, **kwargs): data.pop("conditions", None) data.pop("weights", None) + + if data.get("order") is None: + if data.get("study_id") is not None: + max_order = ( + db.session.query(func.max(Analysis.order)) + .filter_by(study_id=data["study_id"]) + .scalar() + ) + data["order"] = 1 if max_order is None else max_order + 1 + else: + data["order"] = 1 return data @post_dump diff --git a/store/neurostore/tests/api/test_analyses.py b/store/neurostore/tests/api/test_analyses.py index 9283cf98..bfad2c87 100644 --- a/store/neurostore/tests/api/test_analyses.py +++ b/store/neurostore/tests/api/test_analyses.py @@ -130,3 +130,24 @@ def test_update_points_analyses(auth_client, ingest_neurovault, session): == set(p for p in get.json()["points"]) == set(p for p in payload["points"]) ) + + +def test_post_analysis_without_order(auth_client, ingest_neurosynth, session): + # Get an existing analysis from the database + analysis_db = Analysis.query.first() + analysis = AnalysisSchema().dump(analysis_db) + + # Remove the 'order' field from the analysis + analysis.pop("order", None) + + # Submit a POST request without the 'order' field + resp = auth_client.post("/api/analyses/", data=analysis) + + # Check if the response status code is 200 (OK) + assert resp.status_code == 200 + + # Check if the 'order' field is in the response + assert "order" in resp.json() + + # Check if the 'order' field is not None + assert resp.json()["order"] is not None diff --git a/store/neurostore/tests/api/test_points.py b/store/neurostore/tests/api/test_points.py index 25c556ac..853e46db 100644 --- a/store/neurostore/tests/api/test_points.py +++ b/store/neurostore/tests/api/test_points.py @@ -102,3 +102,24 @@ def test_delete_points(auth_client, session): auth_client.delete(f"/api/points/{point_id}") assert Point.query.filter_by(id=point_id).first() is None + + +def test_post_point_without_order(auth_client, ingest_neurosynth, session): + # Get an existing analysis from the database + point_db = Point.query.first() + point = PointSchema().dump(point_db) + + # Remove the 'order' field from the analysis + point.pop("order", None) + + # Submit a POST request without the 'order' field + resp = auth_client.post("/api/points/", data=point) + + # Check if the response status code is 200 (OK) + assert resp.status_code == 200 + + # Check if the 'order' field is in the response + assert "order" in resp.json() + + # Check if the 'order' field is not None + assert resp.json()["order"] is not None