diff --git a/src/apps/answers/api.py b/src/apps/answers/api.py index ce6fe3fff34..e1e88aada45 100644 --- a/src/apps/answers/api.py +++ b/src/apps/answers/api.py @@ -87,13 +87,16 @@ async def create_answer( raise InvalidVersionError() if device_id: - device = await UserDeviceService(session, user.id).get_by_device_id(device_id) + device = await UserDeviceService(session, user.id).get_by_device_id_and_user_id(device_id) if device is None: raise NotFoundError("Invalid device_id provided") if schema.event_history_id: - event = await ScheduleHistoryService(session).get_by_id(schema.event_history_id) - if not event: + event = await ScheduleHistoryService(session).get_by_id_version_and_activity_or_flow( + id_version=schema.event_history_id, + activity_or_flow_id=schema.activity_id or schema.flow_id, + ) + if event is None: raise NotFoundError("Invalid event_history_id provided") service = AnswerService(session, user.id, answer_session) diff --git a/src/apps/answers/tests/test_answers.py b/src/apps/answers/tests/test_answers.py index eb80c79e40c..f487bcf89a4 100644 --- a/src/apps/answers/tests/test_answers.py +++ b/src/apps/answers/tests/test_answers.py @@ -685,7 +685,7 @@ async def applet_default_events(session: AsyncSession, applet: AppletFull) -> li @pytest.fixture def device_create_data() -> UserDeviceCreate: - return UserDeviceCreate(os=AppInfoOS(name="os1", version="1.0.0"), app_version="1.1.1", device_id="device#id") + return UserDeviceCreate(os=AppInfoOS(name="os1", version="1.0.0"), app_version="51.0.0", device_id="device_id") @pytest.mark.usefixtures("mock_kiq_report") @@ -843,7 +843,8 @@ async def test_create_answer__with_device_id_and_event_history_id( assert response.status_code == http.HTTPStatus.OK data = answer_create.copy(deep=True) - event = applet_default_events[0] + event = next((event for event in applet_default_events if event.activity_id == answer_create.activity_id), None) + assert event data.event_history_id = f"{event.id}_{event.version}" response = await client.post(self.answer_url, data=data, headers={"Device-Id": device_create_data.device_id}) diff --git a/src/apps/schedule/crud/schedule_history.py b/src/apps/schedule/crud/schedule_history.py index e61d9ad647f..36a960eb4be 100644 --- a/src/apps/schedule/crud/schedule_history.py +++ b/src/apps/schedule/crud/schedule_history.py @@ -3,7 +3,7 @@ import asyncio import uuid -from sqlalchemy import update +from sqlalchemy import case, select, update from apps.schedule.db.schemas import ( AppletEventsSchema, @@ -36,6 +36,24 @@ async def mark_as_deleted(self, events: list[tuple[uuid.UUID, str]]): ReminderHistoryCRUD(self.session).mark_as_deleted(events), ) + async def get_by_id_version_and_activity_or_flow( + self, id_version: str, activity_or_flow_id: uuid.UUID + ) -> EventHistorySchema: + query = select(EventHistorySchema).where( + EventHistorySchema.id_version == id_version, + case( + ( + EventHistorySchema.activity_flow_id.isnot(None), + EventHistorySchema.activity_flow_id == activity_or_flow_id, + ), + else_=EventHistorySchema.activity_id == activity_or_flow_id, + ), + ) + + result = await self._execute(query) + + return result.scalars().first() + class AppletEventsCRUD(BaseCRUD[AppletEventsSchema]): async def add(self, applet_event: AppletEventsSchema) -> AppletEventsSchema: diff --git a/src/apps/schedule/service/schedule_history.py b/src/apps/schedule/service/schedule_history.py index 3f76dae36a0..66fee95ef35 100644 --- a/src/apps/schedule/service/schedule_history.py +++ b/src/apps/schedule/service/schedule_history.py @@ -27,6 +27,16 @@ def __init__(self, session): async def get_by_id(self, id_version: str) -> EventHistorySchema | None: return await ScheduleHistoryCRUD(self.session).get_by_id(id_version) + async def get_by_id_version_and_activity_or_flow( + self, id_version: str, activity_or_flow_id: uuid.UUID | None + ) -> EventHistorySchema | None: + if activity_or_flow_id is None: + return None + + return await ScheduleHistoryCRUD(self.session).get_by_id_version_and_activity_or_flow( + id_version, activity_or_flow_id + ) + async def add_history(self, applet_id: uuid.UUID, event: ScheduleEvent): applet = await AppletsCRUD(self.session).get_by_id(applet_id) diff --git a/src/apps/users/cruds/user_device.py b/src/apps/users/cruds/user_device.py index 2edd861d154..30d93b05c32 100644 --- a/src/apps/users/cruds/user_device.py +++ b/src/apps/users/cruds/user_device.py @@ -1,6 +1,7 @@ import datetime import uuid +from sqlalchemy import select from sqlalchemy.dialects.postgresql import insert from apps.users.db.schemas import UserDeviceSchema @@ -10,8 +11,14 @@ class UserDevicesCRUD(BaseCRUD[UserDeviceSchema]): schema_class = UserDeviceSchema - async def get_by_device_id(self, device_id: str) -> UserDeviceSchema | None: - return await self._get(key="device_id", value=device_id) + async def get_by_device_id_and_user_id(self, device_id: str, user_id: uuid.UUID) -> UserDeviceSchema | None: + query = select(UserDeviceSchema).where( + UserDeviceSchema.device_id == device_id, + UserDeviceSchema.user_id == user_id, + ) + result = await self._execute(query) + + return result.scalars().first() async def add_device(self, user_id: uuid.UUID, device_id: str) -> None: await self._delete(user_id=user_id, device_id=device_id) diff --git a/src/apps/users/services/user_device.py b/src/apps/users/services/user_device.py index 6f7e11a87b6..77a72518c59 100644 --- a/src/apps/users/services/user_device.py +++ b/src/apps/users/services/user_device.py @@ -9,10 +9,10 @@ def __init__(self, session, user_id: uuid.UUID) -> None: self.session = session self.user_id = user_id - async def get_by_device_id(self, device_id: str) -> UserDevice: - schema = await UserDevicesCRUD(self.session).get_by_device_id(device_id) - if schema: - return UserDevice.from_schema(schema) + async def get_by_device_id_and_user_id(self, device_id: str) -> UserDevice | None: + schema = await UserDevicesCRUD(self.session).get_by_device_id_and_user_id(device_id, self.user_id) + + return UserDevice.from_schema(schema) if schema else None async def add_device(self, data: UserDeviceCreate) -> UserDevice: app_data = dict(