From 240ec5a71218528fd0f366067012b9ae02239ba8 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 13:20:51 -0800 Subject: [PATCH 01/28] add endpoint for 'recent' notifications --- app/dao/notifications_dao.py | 23 +++++++++++++ app/job/rest.py | 62 ++++++++++++++++++++++++++++++++++++ app/service/rest.py | 7 +++- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 806f5e957..0e1e2ac66 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -267,6 +267,29 @@ def get_notifications_for_job( return pagination +def get_recent_notifications_for_job( + service_id, job_id, filter_dict=None, page=1, page_size=None +): + if page_size is None: + page_size = current_app.config["PAGE_SIZE"] + + stmt = select(Notification).where( + Notification.service_id == service_id, + Notification.job_id == job_id, + Notification.status in [NotificationStatus.FAILED, Notification.DELIVERED], + ) + stmt = _filter_query(stmt, filter_dict) + stmt = stmt.order_by(desc(Notification.job_row_number)) + + results = db.session.execute(stmt).scalars().all() + + page_size = current_app.config["PAGE_SIZE"] + offset = (page - 1) * page_size + paginated_results = results[offset : offset + page_size] + pagination = Pagination(paginated_results, page, page_size, len(results)) + return pagination + + def dao_get_notification_count_for_job_id(*, job_id): stmt = select(func.count(Notification.id)).where(Notification.job_id == job_id) return db.session.execute(stmt).scalar() diff --git a/app/job/rest.py b/app/job/rest.py index 8b3965061..31da4e0d1 100644 --- a/app/job/rest.py +++ b/app/job/rest.py @@ -22,6 +22,7 @@ from app.dao.jobs_dao import ( from app.dao.notifications_dao import ( dao_get_notification_count_for_job_id, get_notifications_for_job, + get_recent_notifications_for_job, ) from app.dao.services_dao import dao_fetch_service_by_id from app.dao.templates_dao import dao_get_template_by_id @@ -124,6 +125,67 @@ def get_all_notifications_for_service_job(service_id, job_id): ) +@job_blueprint.route("//recent_notifications", methods=["GET"]) +def get_recent_notifications_for_service_job(service_id, job_id): + data = notifications_filter_schema.load(request.args) + page = data["page"] if "page" in data else 1 + page_size = ( + data["page_size"] + if "page_size" in data + else current_app.config.get("PAGE_SIZE") + ) + paginated_notifications = get_recent_notifications_for_job( + service_id, job_id, filter_dict=data, page=page, page_size=page_size + ) + + kwargs = request.args.to_dict() + kwargs["service_id"] = service_id + kwargs["job_id"] = job_id + + for notification in paginated_notifications.items: + if notification.job_id is not None: + recipient = get_phone_number_from_s3( + notification.service_id, + notification.job_id, + notification.job_row_number, + ) + notification.to = recipient + notification.normalised_to = recipient + + for notification in paginated_notifications.items: + if notification.job_id is not None: + notification.personalisation = get_personalisation_from_s3( + notification.service_id, + notification.job_id, + notification.job_row_number, + ) + + notifications = None + if data.get("format_for_csv"): + notifications = [ + notification.serialize_for_csv() + for notification in paginated_notifications.items + ] + else: + notifications = notification_with_template_schema.dump( + paginated_notifications.items, many=True + ) + + return ( + jsonify( + notifications=notifications, + page_size=page_size, + total=paginated_notifications.total, + links=pagination_links( + paginated_notifications, + ".get_all_notifications_for_service_job", + **kwargs, + ), + ), + 200, + ) + + @job_blueprint.route("//notification_count", methods=["GET"]) def get_notification_count_for_job_id(service_id, job_id): dao_get_job_by_service_id_and_job_id(service_id, job_id) diff --git a/app/service/rest.py b/app/service/rest.py index 657555348..98cb0e963 100644 --- a/app/service/rest.py +++ b/app/service/rest.py @@ -694,7 +694,12 @@ def get_single_month_notification_stats_by_user(service_id, user_id): service_id, start_date, end_date, user_id ) - stats = get_specific_days_stats(results, start_date, end_date=end_date, total_notifications=total_notifications,) + stats = get_specific_days_stats( + results, + start_date, + end_date=end_date, + total_notifications=total_notifications, + ) return jsonify(stats) From dd9c47e1515a4e6230eeeec9b1db4ec02f8a6548 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 13:34:44 -0800 Subject: [PATCH 02/28] add endpoint for 'recent' notifications --- .../notification_dao/test_notification_dao.py | 19 +++++++++++ tests/app/job/test_rest.py | 32 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index 1a145538a..82883466e 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -28,6 +28,7 @@ from app.dao.notifications_dao import ( get_notification_with_personalisation, get_notifications_for_job, get_notifications_for_service, + get_recent_notifications_for_job, get_service_ids_with_notifications_on_date, notifications_not_yet_sent, sanitize_successful_notification_by_id, @@ -692,6 +693,24 @@ def test_get_all_notifications_for_job(sample_job): assert len(notifications_from_db) == 5 +def test_get_recent_notifications_for_job(sample_job): + for x in range(0, 5): + try: + n = create_notification(template=sample_job.template, job=sample_job) + if x == 0: + n.status = NotificationStatus.DELIVERED + elif x in [1, 2]: + n.status = NotificationStatus.FAILED + except IntegrityError: + pass + + notifications_from_db = get_recent_notifications_for_job( + sample_job.service.id, sample_job.id + ).items + assert len(notifications_from_db) == 3 + print(notifications_from_db) + + def test_get_all_notifications_for_job_by_status(sample_job): notifications = partial( get_notifications_for_job, sample_job.service.id, sample_job.id diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 8d40a045a..644962e50 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -488,6 +488,38 @@ def test_get_all_notifications_for_job_in_order_of_job_number( assert resp["notifications"][2]["job_row_number"] == notification_3.job_row_number +def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( + admin_request, sample_template, mocker +): + mock_s3 = mocker.patch("app.job.rest.get_phone_number_from_s3") + mock_s3.return_value = "15555555555" + + mock_s3_personalisation = mocker.patch("app.job.rest.get_personalisation_from_s3") + mock_s3_personalisation.return_value = {} + + main_job = create_job(sample_template) + another_job = create_job(sample_template) + + notification_1 = create_notification(job=main_job, to_field="1", job_row_number=1) + notification_2 = create_notification(job=main_job, to_field="2", job_row_number=2) + notification_3 = create_notification(job=main_job, to_field="3", job_row_number=3) + create_notification(job=another_job) + + resp = admin_request.get( + "job.get_all_notifications_for_service_job", + service_id=main_job.service_id, + job_id=main_job.id, + ) + + assert len(resp["notifications"]) == 3 + assert resp["notifications"][0]["to"] == notification_3.to + assert resp["notifications"][0]["job_row_number"] == notification_3.job_row_number + assert resp["notifications"][1]["to"] == notification_2.to + assert resp["notifications"][1]["job_row_number"] == notification_2.job_row_number + assert resp["notifications"][2]["to"] == notification_1.to + assert resp["notifications"][2]["job_row_number"] == notification_1.job_row_number + + @pytest.mark.parametrize( "expected_notification_count, status_args", [ From 78b5f90f6717feed2c2ca6a75a9f9ed73c4047ef Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 14:21:48 -0800 Subject: [PATCH 03/28] fix test --- tests/app/job/test_rest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 644962e50..bdecc3165 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -506,12 +506,13 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( create_notification(job=another_job) resp = admin_request.get( - "job.get_all_notifications_for_service_job", + "job.get_recent_notifications_for_service_job", service_id=main_job.service_id, job_id=main_job.id, ) assert len(resp["notifications"]) == 3 + print(resp["notifications"]) assert resp["notifications"][0]["to"] == notification_3.to assert resp["notifications"][0]["job_row_number"] == notification_3.job_row_number assert resp["notifications"][1]["to"] == notification_2.to From e59e3429e4cd73822296dd7606ca29a9ed28611e Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 14:30:06 -0800 Subject: [PATCH 04/28] fix test --- app/dao/notifications_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 0e1e2ac66..418f33ff1 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -276,7 +276,7 @@ def get_recent_notifications_for_job( stmt = select(Notification).where( Notification.service_id == service_id, Notification.job_id == job_id, - Notification.status in [NotificationStatus.FAILED, Notification.DELIVERED], + Notification.status in [NotificationStatus.FAILED, NotificationStatus.DELIVERED], ) stmt = _filter_query(stmt, filter_dict) stmt = stmt.order_by(desc(Notification.job_row_number)) From 2dc07b9ceede4c7b6cf74dc085cb936dab5253c0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 14:41:14 -0800 Subject: [PATCH 05/28] fix test --- app/dao/notifications_dao.py | 3 ++- .../dao/notification_dao/test_notification_dao.py | 14 ++++---------- tests/app/job/test_rest.py | 5 +++++ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 418f33ff1..39893dfd4 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -276,7 +276,8 @@ def get_recent_notifications_for_job( stmt = select(Notification).where( Notification.service_id == service_id, Notification.job_id == job_id, - Notification.status in [NotificationStatus.FAILED, NotificationStatus.DELIVERED], + Notification.status + in [NotificationStatus.FAILED, NotificationStatus.DELIVERED], ) stmt = _filter_query(stmt, filter_dict) stmt = stmt.order_by(desc(Notification.job_row_number)) diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index 82883466e..8811ae80d 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -694,20 +694,14 @@ def test_get_all_notifications_for_job(sample_job): def test_get_recent_notifications_for_job(sample_job): - for x in range(0, 5): - try: - n = create_notification(template=sample_job.template, job=sample_job) - if x == 0: - n.status = NotificationStatus.DELIVERED - elif x in [1, 2]: - n.status = NotificationStatus.FAILED - except IntegrityError: - pass + + for status in NotificationStatus: + create_notification(template=sample_job.template, job=sample_job, status=status) notifications_from_db = get_recent_notifications_for_job( sample_job.service.id, sample_job.id ).items - assert len(notifications_from_db) == 3 + assert len(notifications_from_db) == 2 print(notifications_from_db) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index bdecc3165..e5299df6e 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -503,6 +503,11 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( notification_1 = create_notification(job=main_job, to_field="1", job_row_number=1) notification_2 = create_notification(job=main_job, to_field="2", job_row_number=2) notification_3 = create_notification(job=main_job, to_field="3", job_row_number=3) + + count = 1 + for status in NotificationStatus: + create_notification(job=main_job, to_field=str(count), status=status) + count = count + 1 create_notification(job=another_job) resp = admin_request.get( From 6d82567b0e9371f1a8c3e40254d332089b42ff20 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 14:52:48 -0800 Subject: [PATCH 06/28] fix test --- app/dao/notifications_dao.py | 6 +++++- .../notification_dao/test_notification_dao.py | 2 +- tests/app/job/test_rest.py | 16 ++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 39893dfd4..4fcd56e40 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -281,12 +281,16 @@ def get_recent_notifications_for_job( ) stmt = _filter_query(stmt, filter_dict) stmt = stmt.order_by(desc(Notification.job_row_number)) - + print(f"STMT {stmt}") results = db.session.execute(stmt).scalars().all() + print(f"RESULTS {results}") page_size = current_app.config["PAGE_SIZE"] offset = (page - 1) * page_size paginated_results = results[offset : offset + page_size] + print( + f"PAGINATED RESULTS {paginated_results} page_size {page_size} offset {offset}" + ) pagination = Pagination(paginated_results, page, page_size, len(results)) return pagination diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index 8811ae80d..d1fc1ab6e 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -701,8 +701,8 @@ def test_get_recent_notifications_for_job(sample_job): notifications_from_db = get_recent_notifications_for_job( sample_job.service.id, sample_job.id ).items - assert len(notifications_from_db) == 2 print(notifications_from_db) + assert len(notifications_from_db) == 2 def test_get_all_notifications_for_job_by_status(sample_job): diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index e5299df6e..6885b5fa2 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -500,10 +500,6 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( main_job = create_job(sample_template) another_job = create_job(sample_template) - notification_1 = create_notification(job=main_job, to_field="1", job_row_number=1) - notification_2 = create_notification(job=main_job, to_field="2", job_row_number=2) - notification_3 = create_notification(job=main_job, to_field="3", job_row_number=3) - count = 1 for status in NotificationStatus: create_notification(job=main_job, to_field=str(count), status=status) @@ -518,12 +514,12 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert len(resp["notifications"]) == 3 print(resp["notifications"]) - assert resp["notifications"][0]["to"] == notification_3.to - assert resp["notifications"][0]["job_row_number"] == notification_3.job_row_number - assert resp["notifications"][1]["to"] == notification_2.to - assert resp["notifications"][1]["job_row_number"] == notification_2.job_row_number - assert resp["notifications"][2]["to"] == notification_1.to - assert resp["notifications"][2]["job_row_number"] == notification_1.job_row_number + # assert resp["notifications"][0]["to"] == notification_3.to + # assert resp["notifications"][0]["job_row_number"] == notification_3.job_row_number + # assert resp["notifications"][1]["to"] == notification_2.to + # assert resp["notifications"][1]["job_row_number"] == notification_2.job_row_number + # assert resp["notifications"][2]["to"] == notification_1.to + # assert resp["notifications"][2]["job_row_number"] == notification_1.job_row_number @pytest.mark.parametrize( From 45308d5013519e240e30da30c2d6a2ae8e174b2a Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 15:11:16 -0800 Subject: [PATCH 07/28] fix test --- app/dao/notifications_dao.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 4fcd56e40..5b1240508 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -276,8 +276,9 @@ def get_recent_notifications_for_job( stmt = select(Notification).where( Notification.service_id == service_id, Notification.job_id == job_id, - Notification.status - in [NotificationStatus.FAILED, NotificationStatus.DELIVERED], + Notification.status.in_( + [NotificationStatus.FAILED, NotificationStatus.DELIVERED] + ), ) stmt = _filter_query(stmt, filter_dict) stmt = stmt.order_by(desc(Notification.job_row_number)) From a3fe9e24bf26ff96416c0328662bf20396ad29c5 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 15:22:01 -0800 Subject: [PATCH 08/28] fix test --- tests/app/job/test_rest.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 6885b5fa2..9dd2bc1da 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -512,14 +512,9 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( job_id=main_job.id, ) - assert len(resp["notifications"]) == 3 - print(resp["notifications"]) - # assert resp["notifications"][0]["to"] == notification_3.to - # assert resp["notifications"][0]["job_row_number"] == notification_3.job_row_number - # assert resp["notifications"][1]["to"] == notification_2.to - # assert resp["notifications"][1]["job_row_number"] == notification_2.job_row_number - # assert resp["notifications"][2]["to"] == notification_1.to - # assert resp["notifications"][2]["job_row_number"] == notification_1.job_row_number + assert len(resp["notifications"]) == 2 + assert resp["notifications"][0]["notification_status"] == "failed" + assert resp["notifications"][1]["notification_status"] == "delivered" @pytest.mark.parametrize( From 0d032cfeecf047293d369387cb52b6b8c2262e34 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 15:35:18 -0800 Subject: [PATCH 09/28] fix test --- tests/app/job/test_rest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 9dd2bc1da..9b797cf37 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -513,8 +513,8 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( ) assert len(resp["notifications"]) == 2 - assert resp["notifications"][0]["notification_status"] == "failed" - assert resp["notifications"][1]["notification_status"] == "delivered" + assert resp["notifications"][0]["status"] == "failed" + assert resp["notifications"][1]["status"] == "delivered" @pytest.mark.parametrize( From 343383e6e0177129dd95724c3f1b7ae103a88db4 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 15:44:22 -0800 Subject: [PATCH 10/28] fix test --- tests/app/job/test_rest.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 9b797cf37..54fdd3979 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -513,8 +513,10 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( ) assert len(resp["notifications"]) == 2 - assert resp["notifications"][0]["status"] == "failed" - assert resp["notifications"][1]["status"] == "delivered" + assert resp["notifications"][0]["status"] == "delivered" + assert resp["notifications"][0]["to"] == "2" + assert resp["notifications"][1]["status"] == "failed" + assert resp["notifications"][1]["to"] == "1" @pytest.mark.parametrize( From 10dee6cdd3d20a495830a92d60ccad34341d4654 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 15:52:50 -0800 Subject: [PATCH 11/28] fix test --- tests/app/job/test_rest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 54fdd3979..fd708daae 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -514,9 +514,9 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert len(resp["notifications"]) == 2 assert resp["notifications"][0]["status"] == "delivered" - assert resp["notifications"][0]["to"] == "2" + assert resp["notifications"][0]["job_row_number"] == "2" assert resp["notifications"][1]["status"] == "failed" - assert resp["notifications"][1]["to"] == "1" + assert resp["notifications"][1]["job_row_number"] == "1" @pytest.mark.parametrize( From 68f1f97a948d748379cb90193590b66e6d147612 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 16:01:55 -0800 Subject: [PATCH 12/28] fix test --- tests/app/job/test_rest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index fd708daae..ab82747a8 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -502,7 +502,7 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( count = 1 for status in NotificationStatus: - create_notification(job=main_job, to_field=str(count), status=status) + create_notification(job=main_job, job_row_number=str(count), status=status) count = count + 1 create_notification(job=another_job) @@ -513,6 +513,8 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( ) assert len(resp["notifications"]) == 2 + for n in resp["notifications"]: + print(n) assert resp["notifications"][0]["status"] == "delivered" assert resp["notifications"][0]["job_row_number"] == "2" assert resp["notifications"][1]["status"] == "failed" From 88d1b0ef0f4f0876779571826d78db8ce978630f Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 16:09:49 -0800 Subject: [PATCH 13/28] fix test --- tests/app/job/test_rest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index ab82747a8..1d32ba992 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -515,10 +515,10 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert len(resp["notifications"]) == 2 for n in resp["notifications"]: print(n) - assert resp["notifications"][0]["status"] == "delivered" - assert resp["notifications"][0]["job_row_number"] == "2" - assert resp["notifications"][1]["status"] == "failed" - assert resp["notifications"][1]["job_row_number"] == "1" + assert resp["notifications"][0]["status"] == "failed" + assert resp["notifications"][0]["job_row_number"] == "3" + assert resp["notifications"][1]["status"] == "delivered" + assert resp["notifications"][1]["job_row_number"] == "2" @pytest.mark.parametrize( From 2fbf837168b1becc3f0a1a2d64efdfdca66580eb Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 16:23:39 -0800 Subject: [PATCH 14/28] fix test --- tests/app/job/test_rest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 1d32ba992..f8c796885 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -516,9 +516,9 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( for n in resp["notifications"]: print(n) assert resp["notifications"][0]["status"] == "failed" - assert resp["notifications"][0]["job_row_number"] == "3" + assert resp["notifications"][0]["job_row_number"] == "7" assert resp["notifications"][1]["status"] == "delivered" - assert resp["notifications"][1]["job_row_number"] == "2" + assert resp["notifications"][1]["job_row_number"] == "5" @pytest.mark.parametrize( From 08211d211df043dd25e99f1757ffe956ceea2dec Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 30 Jan 2025 16:51:18 -0800 Subject: [PATCH 15/28] fix test --- tests/app/job/test_rest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index f8c796885..829cc39a3 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -516,9 +516,9 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( for n in resp["notifications"]: print(n) assert resp["notifications"][0]["status"] == "failed" - assert resp["notifications"][0]["job_row_number"] == "7" + assert resp["notifications"][0]["job_row_number"] == 7 assert resp["notifications"][1]["status"] == "delivered" - assert resp["notifications"][1]["job_row_number"] == "5" + assert resp["notifications"][1]["job_row_number"] == 5 @pytest.mark.parametrize( From 5b83c11b7bd56a3e6347a5edad29aa659f05f8f6 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 07:47:30 -0800 Subject: [PATCH 16/28] trying fixing dynamic scan --- .github/workflows/daily_checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/daily_checks.yml b/.github/workflows/daily_checks.yml index d8e19de98..23b63686a 100644 --- a/.github/workflows/daily_checks.yml +++ b/.github/workflows/daily_checks.yml @@ -84,11 +84,11 @@ jobs: env: SQLALCHEMY_DATABASE_TEST_URI: postgresql://user:password@localhost:5432/test_notification_api - name: Run OWASP API Scan - uses: zaproxy/action-api-scan@v0.5.0 + uses: zaproxy/action-api-scan@v0.6.0 with: docker_name: 'ghcr.io/zaproxy/zaproxy:weekly' target: 'http://localhost:6011/docs/openapi.yml' fail_action: true allow_issue_writing: false rules_file_name: 'zap.conf' - cmd_options: '-I' + cmd_options: '-I -d' From 6c66d66c0938605880af6b0f210f1c575c35e4c8 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 11:03:35 -0800 Subject: [PATCH 17/28] update to support status dropdown --- app/dao/notifications_dao.py | 21 +++++++++++++-------- app/job/rest.py | 8 +++++++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 5b1240508..5dc5906b3 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -268,18 +268,23 @@ def get_notifications_for_job( def get_recent_notifications_for_job( - service_id, job_id, filter_dict=None, page=1, page_size=None + service_id, job_id, filter_dict=None, page=1, page_size=None, status=None ): if page_size is None: page_size = current_app.config["PAGE_SIZE"] - stmt = select(Notification).where( - Notification.service_id == service_id, - Notification.job_id == job_id, - Notification.status.in_( - [NotificationStatus.FAILED, NotificationStatus.DELIVERED] - ), - ) + if status is None: + stmt = select(Notification).where( + Notification.service_id == service_id, + Notification.job_id == job_id, + ) + else: + stmt = select(Notification).where( + Notification.service_id == service_id, + Notification.job_id == job_id, + Notification.status == status, + ) + stmt = _filter_query(stmt, filter_dict) stmt = stmt.order_by(desc(Notification.job_row_number)) print(f"STMT {stmt}") diff --git a/app/job/rest.py b/app/job/rest.py index 31da4e0d1..d266a22bb 100644 --- a/app/job/rest.py +++ b/app/job/rest.py @@ -134,8 +134,14 @@ def get_recent_notifications_for_service_job(service_id, job_id): if "page_size" in data else current_app.config.get("PAGE_SIZE") ) + status = data["status"] if "status" in data else None paginated_notifications = get_recent_notifications_for_job( - service_id, job_id, filter_dict=data, page=page, page_size=page_size + service_id, + job_id, + filter_dict=data, + page=page, + page_size=page_size, + status=status, ) kwargs = request.args.to_dict() From 7e3bf204778d2c8f14d919eef229876f2c27430f Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 11:40:44 -0800 Subject: [PATCH 18/28] update to support status dropdown --- tests/app/dao/notification_dao/test_notification_dao.py | 3 +-- tests/app/job/test_rest.py | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index d1fc1ab6e..a6748dd33 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -701,8 +701,7 @@ def test_get_recent_notifications_for_job(sample_job): notifications_from_db = get_recent_notifications_for_job( sample_job.service.id, sample_job.id ).items - print(notifications_from_db) - assert len(notifications_from_db) == 2 + assert len(notifications_from_db) == 13 def test_get_all_notifications_for_job_by_status(sample_job): diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 829cc39a3..a12e3db36 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -512,9 +512,7 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( job_id=main_job.id, ) - assert len(resp["notifications"]) == 2 - for n in resp["notifications"]: - print(n) + assert len(resp["notifications"]) == 13 assert resp["notifications"][0]["status"] == "failed" assert resp["notifications"][0]["job_row_number"] == 7 assert resp["notifications"][1]["status"] == "delivered" From b566119c8f7e4e4fae7b27f22ad34ec5299d0190 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 11:51:24 -0800 Subject: [PATCH 19/28] update to support status dropdown --- tests/app/job/test_rest.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index a12e3db36..68f76fc03 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -513,10 +513,24 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( ) assert len(resp["notifications"]) == 13 - assert resp["notifications"][0]["status"] == "failed" - assert resp["notifications"][0]["job_row_number"] == 7 - assert resp["notifications"][1]["status"] == "delivered" - assert resp["notifications"][1]["job_row_number"] == 5 + for n in resp["notifications"]: + print(n) + assert resp["notifications"][0]["status"] == "virus-scan-failed" + assert resp["notifications"][0]["job_row_number"] == 13 + + resp = admin_request.get( + "job.get_recent_notifications_for_service_job", + service_id=main_job.service_id, + job_id=main_job.id, + status=NotificationStatus.DELIVERED + ) + + assert len(resp["notifications"]) == 1 + for n in resp["notifications"]: + print(n) + assert resp["notifications"][0]["status"] == "delivered" + assert resp["notifications"][0]["job_row_number"] == 0 + @pytest.mark.parametrize( From c266cdaefea063c46d906a29e5a5805fb7baada0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 12:01:43 -0800 Subject: [PATCH 20/28] update to support status dropdown --- tests/app/job/test_rest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 68f76fc03..75eb8660d 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -522,7 +522,7 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( "job.get_recent_notifications_for_service_job", service_id=main_job.service_id, job_id=main_job.id, - status=NotificationStatus.DELIVERED + status=NotificationStatus.DELIVERED, ) assert len(resp["notifications"]) == 1 @@ -532,7 +532,6 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert resp["notifications"][0]["job_row_number"] == 0 - @pytest.mark.parametrize( "expected_notification_count, status_args", [ From b5b7885ce4ba1eb6a7eaf7999917dc1e7a8dbd3d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 12:30:47 -0800 Subject: [PATCH 21/28] fix test --- app/dao/notifications_dao.py | 22 ++++++---------------- tests/app/job/test_rest.py | 3 ++- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 5dc5906b3..71dee7614 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -268,35 +268,25 @@ def get_notifications_for_job( def get_recent_notifications_for_job( - service_id, job_id, filter_dict=None, page=1, page_size=None, status=None + service_id, job_id, filter_dict=None, page=1, page_size=None ): if page_size is None: page_size = current_app.config["PAGE_SIZE"] - if status is None: - stmt = select(Notification).where( - Notification.service_id == service_id, - Notification.job_id == job_id, - ) - else: - stmt = select(Notification).where( - Notification.service_id == service_id, - Notification.job_id == job_id, - Notification.status == status, - ) + stmt = select(Notification).where( + Notification.service_id == service_id, + Notification.job_id == job_id, + ) stmt = _filter_query(stmt, filter_dict) stmt = stmt.order_by(desc(Notification.job_row_number)) print(f"STMT {stmt}") results = db.session.execute(stmt).scalars().all() - print(f"RESULTS {results}") page_size = current_app.config["PAGE_SIZE"] offset = (page - 1) * page_size paginated_results = results[offset : offset + page_size] - print( - f"PAGINATED RESULTS {paginated_results} page_size {page_size} offset {offset}" - ) + pagination = Pagination(paginated_results, page, page_size, len(results)) return pagination diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 75eb8660d..6abbf4cee 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -518,11 +518,12 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert resp["notifications"][0]["status"] == "virus-scan-failed" assert resp["notifications"][0]["job_row_number"] == 13 + filter_dict = {"status": NotificationStatus.DELIVERED} resp = admin_request.get( "job.get_recent_notifications_for_service_job", service_id=main_job.service_id, job_id=main_job.id, - status=NotificationStatus.DELIVERED, + filter_dict=filter_dict, ) assert len(resp["notifications"]) == 1 From 5edacd5766b2d79c1c4cf0fdbb90add4a1feccdf Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 12:39:59 -0800 Subject: [PATCH 22/28] fix test --- app/job/rest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/job/rest.py b/app/job/rest.py index d266a22bb..21ff38958 100644 --- a/app/job/rest.py +++ b/app/job/rest.py @@ -134,14 +134,12 @@ def get_recent_notifications_for_service_job(service_id, job_id): if "page_size" in data else current_app.config.get("PAGE_SIZE") ) - status = data["status"] if "status" in data else None paginated_notifications = get_recent_notifications_for_job( service_id, job_id, filter_dict=data, page=page, page_size=page_size, - status=status, ) kwargs = request.args.to_dict() From e755459041b9b82f633b6782f95513206501c3cc Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 12:49:07 -0800 Subject: [PATCH 23/28] fix test --- tests/app/job/test_rest.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 6abbf4cee..92e6bb760 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -512,9 +512,8 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( job_id=main_job.id, ) + print("RUNNING TEST 1 and checking total is 13") assert len(resp["notifications"]) == 13 - for n in resp["notifications"]: - print(n) assert resp["notifications"][0]["status"] == "virus-scan-failed" assert resp["notifications"][0]["job_row_number"] == 13 @@ -526,9 +525,9 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( filter_dict=filter_dict, ) + print("RUNNING TEST TWO WITH LENGTH == 1") assert len(resp["notifications"]) == 1 - for n in resp["notifications"]: - print(n) + assert resp["notifications"][0]["status"] == "delivered" assert resp["notifications"][0]["job_row_number"] == 0 From 68ddbf7775896f35179d6d30cde4763eb912dd8d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 13:01:10 -0800 Subject: [PATCH 24/28] fix test --- tests/app/job/test_rest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 92e6bb760..5a619e703 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -517,12 +517,12 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert resp["notifications"][0]["status"] == "virus-scan-failed" assert resp["notifications"][0]["job_row_number"] == 13 - filter_dict = {"status": NotificationStatus.DELIVERED} + data = {"status": NotificationStatus.DELIVERED} resp = admin_request.get( "job.get_recent_notifications_for_service_job", service_id=main_job.service_id, job_id=main_job.id, - filter_dict=filter_dict, + data=json.dumps(data), ) print("RUNNING TEST TWO WITH LENGTH == 1") From 88ac910d92937d2b00685e52c1a575a05adac445 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 13:13:28 -0800 Subject: [PATCH 25/28] fix test --- app/dao/notifications_dao.py | 1 + app/job/rest.py | 1 + 2 files changed, 2 insertions(+) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 71dee7614..ab34d134e 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -270,6 +270,7 @@ def get_notifications_for_job( def get_recent_notifications_for_job( service_id, job_id, filter_dict=None, page=1, page_size=None ): + print(f"FILTER_DICT AT DAO LEVEL {filter_dict}") if page_size is None: page_size = current_app.config["PAGE_SIZE"] diff --git a/app/job/rest.py b/app/job/rest.py index 21ff38958..7506b4030 100644 --- a/app/job/rest.py +++ b/app/job/rest.py @@ -128,6 +128,7 @@ def get_all_notifications_for_service_job(service_id, job_id): @job_blueprint.route("//recent_notifications", methods=["GET"]) def get_recent_notifications_for_service_job(service_id, job_id): data = notifications_filter_schema.load(request.args) + print(f"DATA COMING IN AT REST LEVEL IS {data}") page = data["page"] if "page" in data else 1 page_size = ( data["page_size"] From aefa66baea490942ebd718c38ed7082ff67204af Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 13:33:58 -0800 Subject: [PATCH 26/28] fix test --- tests/app/job/test_rest.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 5a619e703..839811310 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -517,12 +517,10 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert resp["notifications"][0]["status"] == "virus-scan-failed" assert resp["notifications"][0]["job_row_number"] == 13 - data = {"status": NotificationStatus.DELIVERED} resp = admin_request.get( - "job.get_recent_notifications_for_service_job", + "job.get_recent_notifications_for_service_job?status=delivered", service_id=main_job.service_id, job_id=main_job.id, - data=json.dumps(data), ) print("RUNNING TEST TWO WITH LENGTH == 1") From 048126caca31518bd4c6877eea44c046ea99c008 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 13:49:53 -0800 Subject: [PATCH 27/28] fix test --- tests/app/job/test_rest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 839811310..e9d3e0f7b 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -517,10 +517,12 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( assert resp["notifications"][0]["status"] == "virus-scan-failed" assert resp["notifications"][0]["job_row_number"] == 13 + query_string = {"status": "delivered"} resp = admin_request.get( - "job.get_recent_notifications_for_service_job?status=delivered", + "job.get_recent_notifications_for_service_job", service_id=main_job.service_id, job_id=main_job.id, + **query_string, ) print("RUNNING TEST TWO WITH LENGTH == 1") From dae0f9cf6df8ca5caa72c24b87be1908084ecdbb Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 31 Jan 2025 13:59:08 -0800 Subject: [PATCH 28/28] fix test --- tests/app/job/test_rest.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index e9d3e0f7b..e9091823b 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -512,7 +512,6 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( job_id=main_job.id, ) - print("RUNNING TEST 1 and checking total is 13") assert len(resp["notifications"]) == 13 assert resp["notifications"][0]["status"] == "virus-scan-failed" assert resp["notifications"][0]["job_row_number"] == 13 @@ -525,11 +524,10 @@ def test_get_recent_notifications_for_job_in_reverse_order_of_job_number( **query_string, ) - print("RUNNING TEST TWO WITH LENGTH == 1") assert len(resp["notifications"]) == 1 assert resp["notifications"][0]["status"] == "delivered" - assert resp["notifications"][0]["job_row_number"] == 0 + assert resp["notifications"][0]["job_row_number"] == 5 @pytest.mark.parametrize(