From f3cebd36a6afe6327f03624dc320e08ae994bde0 Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Wed, 22 Nov 2023 18:16:41 +0100 Subject: [PATCH] feat(api): usability testing - sessions list fix, return zeros if test id is not having signals --- api/chalicelib/core/sessions.py | 28 ++++++++++++ .../core/usability_testing/routes.py | 6 ++- .../core/usability_testing/service.py | 44 +++++++++++-------- 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/api/chalicelib/core/sessions.py b/api/chalicelib/core/sessions.py index 1dd66d7b3..916bd4eac 100644 --- a/api/chalicelib/core/sessions.py +++ b/api/chalicelib/core/sessions.py @@ -1260,3 +1260,31 @@ def check_recording_status(project_id: int) -> dict: "recordingStatus": row["recording_status"], "sessionsCount": row["sessions_count"] } + + +def search_sessions_by_ids(project_id: int, session_ids: list, user_id: int, sort_by: str = 'session_id', + ascending: bool = False) -> dict: + if session_ids is None or len(session_ids) == 0: + return {"total": 0, "sessions": []} + with pg_client.PostgresClient() as cur: + meta_keys = metadata.get(project_id=project_id) + params = {"project_id": project_id, "session_ids": tuple(session_ids), "userId": user_id} + order_direction = 'ASC' if ascending else 'DESC' + main_query = cur.mogrify(f"""SELECT {SESSION_PROJECTION_COLS} + {"," if len(meta_keys) > 0 else ""}{",".join([f'metadata_{m["index"]}' for m in meta_keys])} + FROM public.sessions AS s + LEFT JOIN ( SELECT user_id, session_id + FROM public.user_favorite_sessions + WHERE user_id = %(userId)s) AS favorite_sessions USING (session_id) + WHERE project_id=%(project_id)s + AND session_id IN %(session_ids)s + ORDER BY {sort_by} {order_direction};""", params) + + cur.execute(main_query) + rows = cur.fetchall() + if len(meta_keys) > 0: + for s in rows: + s["metadata"] = {} + for m in meta_keys: + s["metadata"][m["key"]] = s.pop(f'metadata_{m["index"]}') + return {"total": len(rows), "sessions": helper.list_to_camel_case(rows)} diff --git a/api/chalicelib/core/usability_testing/routes.py b/api/chalicelib/core/usability_testing/routes.py index f8c472240..87cb47c5c 100644 --- a/api/chalicelib/core/usability_testing/routes.py +++ b/api/chalicelib/core/usability_testing/routes.py @@ -78,7 +78,7 @@ async def update_ut_test(project_id: int, test_id: int, test_update: UTTestUpdat @app.get("/{project_id}/usability-tests/{test_id}/sessions", tags=tags) -async def get_sessions(project_id: int, test_id: int, page: int = 1, limit: int = 10): +async def get_sessions(project_id: int, test_id: int, page: int = 1, limit: int = 10, context: schemas.CurrentContext = Depends(OR_context)): """ Get sessions related to a specific UT test. @@ -86,7 +86,9 @@ async def get_sessions(project_id: int, test_id: int, page: int = 1, limit: int - **test_id**: The unique identifier of the UT test. """ - return service.ut_tests_sessions(project_id, test_id, page, limit) + user_id = context.user_id + + return service.ut_tests_sessions(project_id, user_id, test_id, page, limit) @app.get("/{project_id}/usability-tests/{test_id}/responses/{task_id}", tags=tags) diff --git a/api/chalicelib/core/usability_testing/service.py b/api/chalicelib/core/usability_testing/service.py index 806d21bdc..279f7750e 100644 --- a/api/chalicelib/core/usability_testing/service.py +++ b/api/chalicelib/core/usability_testing/service.py @@ -1,13 +1,15 @@ import logging -from datetime import datetime from fastapi import HTTPException, status from chalicelib.core.db_request_handler import DatabaseRequestHandler from chalicelib.core.usability_testing.schema import UTTestCreate, UTTestSearch, UTTestUpdate, UTTestStatusUpdate +from chalicelib.utils import pg_client from chalicelib.utils.TimeUTC import TimeUTC from chalicelib.utils.helper import dict_to_camel_case, list_to_camel_case +from chalicelib.core import sessions, metadata + table_name = "ut_tests" @@ -18,6 +20,7 @@ def search_ui_tests(project_id: int, search: UTTestSearch): "ut.description", "ut.created_at", "ut.updated_at", + "ut.status", "json_build_object('user_id', u.user_id, 'name', u.name) AS created_by" ] @@ -234,25 +237,20 @@ def get_test_tasks(db_handler, test_id): return db_handler.fetchall() -def ut_tests_sessions(project_id: int, test_id: int, page: int, limit: int): - db_handler = DatabaseRequestHandler("ut_tests_signals AS uts") - db_handler.set_select_columns(["s.*"]) - db_handler.add_join("JOIN sessions s ON uts.session_id = s.session_id AND s.project_id = %(project_id)s") - db_handler.add_constraint("uts.type = %(type)s", {'type': 'test'}) - db_handler.add_constraint("uts.status IN %(status_list)s", {'status_list': ('finished', 'aborted')}) - db_handler.add_constraint("project_id = %(project_id)s", {'project_id': project_id}) - db_handler.add_constraint("uts.type_id = %(test_id)s", {'test_id': test_id}) - db_handler.set_pagination(page, limit) +def ut_tests_sessions(project_id: int, user_id: int, test_id: int, page: int, limit: int): + handler = DatabaseRequestHandler("ut_tests_signals AS uts") + handler.set_select_columns(["uts.session_id"]) + handler.add_constraint("uts.test_id = %(test_id)s", {'test_id': test_id}) + handler.add_constraint("uts.status IN %(status_list)s", {'status_list': ('done', 'skipped')}) + handler.add_constraint("uts.task_id is NULL") + handler.set_pagination(page, limit) - sessions = db_handler.fetchall() + session_ids = handler.fetchall() + session_ids = [session['session_id'] for session in session_ids] + sessions_list = sessions.search_sessions_by_ids(project_id=project_id, session_ids=session_ids, user_id=user_id) + sessions_list['page'] = page - return { - "data": { - "list": list_to_camel_case(sessions), - "page": page, - "limit": limit - } - } + return sessions_list def get_responses(project_id: int, test_id: int, task_id: int, page: int = 1, limit: int = 10, query: str = None): @@ -308,7 +306,15 @@ def get_statistics(test_id: int): }) if results is None or len(results) == 0: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Test not found") + return { + "data": { + "tests_attempts": 0, + "tests_skipped": 0, + "tasks_completed": 0, + "tasks_skipped": 0, + "completed_all_tasks": 0 + } + } return { "data": results[0]