From 16bb89d62a4982f061f9a044e40456956846e4ca Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 11:46:57 -0700 Subject: [PATCH 001/109] initial --- app/dao/services_dao.py | 20 ++++++++++++++------ app/service_invite/rest.py | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 19755edfe..9ac63327f 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -51,14 +51,22 @@ from app.utils import ( def dao_fetch_all_services(only_active=False): - query = Service.query.order_by(asc(Service.created_at)).options( - joinedload(Service.users) + + stmt = ( + select(Service) + .order_by(asc(Service.created_at)) + .options(joinedload(Service.users)) ) - if only_active: - query = query.filter(Service.active) - - return query.all() + stmt = ( + select(Service) + .where(Service.active is True) + .order_by(asc(Service.created_at)) + .options(joinedload(Service.users)) + ) + if only_active: + stmt = stmt.filter(Service.active) + return db.session.execute(stmt).scalars().all() def get_services_by_partial_name(service_name): diff --git a/app/service_invite/rest.py b/app/service_invite/rest.py index f6d9627da..5728b3ed5 100644 --- a/app/service_invite/rest.py +++ b/app/service_invite/rest.py @@ -86,7 +86,7 @@ def _create_service_invite(invited_user, invite_link_host): redis_store.set( f"email-personalisation-{saved_notification.id}", json.dumps(personalisation), - ex=2*24*60*60, + ex=2 * 24 * 60 * 60, ) send_notification_to_queue(saved_notification, queue=QueueNames.NOTIFY) From bf271bfa222e55ec5a6314e528601202ec65c5d0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 11:59:06 -0700 Subject: [PATCH 002/109] initial --- app/dao/services_dao.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 9ac63327f..39c9dcbef 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -64,9 +64,8 @@ def dao_fetch_all_services(only_active=False): .order_by(asc(Service.created_at)) .options(joinedload(Service.users)) ) - if only_active: - stmt = stmt.filter(Service.active) - return db.session.execute(stmt).scalars().all() + result = db.session.execute(stmt) + return result.scalars().all() def get_services_by_partial_name(service_name): From bd334ffb42b803135d1ea6f1a87b511fd46c3393 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 12:11:02 -0700 Subject: [PATCH 003/109] initial --- app/dao/services_dao.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 39c9dcbef..5099ef439 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -3,7 +3,7 @@ from datetime import timedelta from flask import current_app from sqlalchemy import Float, cast, select -from sqlalchemy.orm import joinedload +from sqlalchemy.orm import joinedload, Session from sqlalchemy.sql.expression import and_, asc, case, func from app import db @@ -51,21 +51,21 @@ from app.utils import ( def dao_fetch_all_services(only_active=False): - - stmt = ( - select(Service) - .order_by(asc(Service.created_at)) - .options(joinedload(Service.users)) - ) - if only_active: + with Session() as session: stmt = ( select(Service) - .where(Service.active is True) .order_by(asc(Service.created_at)) .options(joinedload(Service.users)) ) - result = db.session.execute(stmt) - return result.scalars().all() + if only_active: + stmt = ( + select(Service) + .where(Service.active is True) + .order_by(asc(Service.created_at)) + .options(joinedload(Service.users)) + ) + result = db.session.execute(stmt) + return result.scalars().all() def get_services_by_partial_name(service_name): From 115233dec72a61c1a3d73fd6d53372cc263f4c3a Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 12:15:51 -0700 Subject: [PATCH 004/109] initial --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 5099ef439..66c8ca58e 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -64,7 +64,7 @@ def dao_fetch_all_services(only_active=False): .order_by(asc(Service.created_at)) .options(joinedload(Service.users)) ) - result = db.session.execute(stmt) + result = session.execute(stmt) return result.scalars().all() From 149ee70547c3ec77ed3b7036010205acb796b77d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 12:19:29 -0700 Subject: [PATCH 005/109] initial --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 66c8ca58e..0f87c1410 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -3,7 +3,7 @@ from datetime import timedelta from flask import current_app from sqlalchemy import Float, cast, select -from sqlalchemy.orm import joinedload, Session +from sqlalchemy.orm import Session, joinedload from sqlalchemy.sql.expression import and_, asc, case, func from app import db From 38194873285d79ab6e79f6fbbded29c1a90b6cb6 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 12:53:12 -0700 Subject: [PATCH 006/109] initial --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 0f87c1410..38ced647f 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -51,7 +51,7 @@ from app.utils import ( def dao_fetch_all_services(only_active=False): - with Session() as session: + with Session(db.engine) as session: stmt = ( select(Service) .order_by(asc(Service.created_at)) From c1a179976426a6d5ff9d9947ff272f1bb49b9149 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 13:04:29 -0700 Subject: [PATCH 007/109] initial --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 38ced647f..281529d7c 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -64,7 +64,7 @@ def dao_fetch_all_services(only_active=False): .order_by(asc(Service.created_at)) .options(joinedload(Service.users)) ) - result = session.execute(stmt) + result = session.execute(stmt).unique() return result.scalars().all() From 49fd034b34fa916112e100f4ad37eb57db06408d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 13:15:10 -0700 Subject: [PATCH 008/109] try by not closing session --- app/dao/services_dao.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 281529d7c..ff4d372de 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -3,7 +3,7 @@ from datetime import timedelta from flask import current_app from sqlalchemy import Float, cast, select -from sqlalchemy.orm import Session, joinedload +from sqlalchemy.orm import joinedload from sqlalchemy.sql.expression import and_, asc, case, func from app import db @@ -51,21 +51,21 @@ from app.utils import ( def dao_fetch_all_services(only_active=False): - with Session(db.engine) as session: + + stmt = ( + select(Service) + .order_by(asc(Service.created_at)) + .options(joinedload(Service.users)) + ) + if only_active: stmt = ( select(Service) + .where(Service.active is True) .order_by(asc(Service.created_at)) .options(joinedload(Service.users)) ) - if only_active: - stmt = ( - select(Service) - .where(Service.active is True) - .order_by(asc(Service.created_at)) - .options(joinedload(Service.users)) - ) - result = session.execute(stmt).unique() - return result.scalars().all() + result = db.session.execute(stmt).unique() + return result.scalars().all() def get_services_by_partial_name(service_name): From b94b2b7b84a1cd671ea462c55ba533783bbc03b7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 13:29:42 -0700 Subject: [PATCH 009/109] try by not closing session --- app/dao/services_dao.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index ff4d372de..2e05af00f 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -52,20 +52,15 @@ from app.utils import ( def dao_fetch_all_services(only_active=False): - stmt = ( - select(Service) - .order_by(asc(Service.created_at)) - .options(joinedload(Service.users)) - ) + stmt = select(Service) + if only_active: - stmt = ( - select(Service) - .where(Service.active is True) - .order_by(asc(Service.created_at)) - .options(joinedload(Service.users)) - ) - result = db.session.execute(stmt).unique() - return result.scalars().all() + stmt = stmt.where(Service.active) + + stmt = stmt.order_by(asc(Service.created_at)).options(joinedload(Service.users)) + + result = db.session.execute(stmt) + return result.unique().scalars().one() def get_services_by_partial_name(service_name): From cc3a6235410914bcc4d8d95d0a080ba694619164 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 13:37:20 -0700 Subject: [PATCH 010/109] try by not closing session --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 2e05af00f..d442e8305 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -60,7 +60,7 @@ def dao_fetch_all_services(only_active=False): stmt = stmt.order_by(asc(Service.created_at)).options(joinedload(Service.users)) result = db.session.execute(stmt) - return result.unique().scalars().one() + return result.unique().scalars().all() def get_services_by_partial_name(service_name): From 8f434d00042fc047b9fe0d610b7aabc09f4690b0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 13:50:12 -0700 Subject: [PATCH 011/109] try by not closing session --- app/dao/services_dao.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index d442e8305..28bf48881 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -65,7 +65,9 @@ def dao_fetch_all_services(only_active=False): def get_services_by_partial_name(service_name): service_name = escape_special_characters(service_name) - return Service.query.filter(Service.name.ilike("%{}%".format(service_name))).all() + stmt = select(Service).where(Service.name.ilike("%{}%".format(service_name))) + result = db.session.execute(stmt) + return result.scalars.all() def dao_count_live_services(): From 964464ed3fad2a6ce86954fdee6f4ac39a55e862 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 14:22:00 -0700 Subject: [PATCH 012/109] fix another --- app/dao/services_dao.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 28bf48881..1d558be1f 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -67,7 +67,7 @@ def get_services_by_partial_name(service_name): service_name = escape_special_characters(service_name) stmt = select(Service).where(Service.name.ilike("%{}%".format(service_name))) result = db.session.execute(stmt) - return result.scalars.all() + return result.scalars().all() def dao_count_live_services(): @@ -191,14 +191,18 @@ def dao_fetch_service_by_id(service_id, only_active=False): def dao_fetch_service_by_inbound_number(number): - inbound_number = InboundNumber.query.filter( + stmt = select(InboundNumber).where( InboundNumber.number == number, InboundNumber.active - ).first() + ) + result = db.session.execute(stmt) + inbound_number = result.scalars().first() if not inbound_number: return None - return Service.query.filter(Service.id == inbound_number.service_id).first() + stmt = select(Service).where(Service.id == inbound_number.service_id) + result = db.session.execute(stmt) + return result.scalars().first() def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): From 213b36e4de3bae2d53d2e9566f10e1aacde1c4fa Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 14:34:12 -0700 Subject: [PATCH 013/109] fix another --- app/dao/services_dao.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 1d558be1f..22c0e8395 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -71,11 +71,11 @@ def get_services_by_partial_name(service_name): def dao_count_live_services(): - return Service.query.filter_by( - active=True, - restricted=False, - count_as_live=True, - ).count() + stmt = select(Service).where( + Service.active, Service.count_as_live, Service.restricted is False + ) + result = db.session.execute(stmt) + return result.scalars().count() def dao_fetch_live_services_data(): @@ -228,11 +228,11 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): def dao_fetch_all_services_created_by_user(user_id): - query = Service.query.filter_by(created_by_id=user_id).order_by( - asc(Service.created_at) + stmt = ( + select(Service).where(created_by_id=user_id).order_by(asc(Service.created_at)) ) - - return query.all() + result = db.session.execute(stmt) + return result.scalars.all() @autocommit From 60148a2848c4aa2b3ea54e2938063176225dbb31 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 14:43:56 -0700 Subject: [PATCH 014/109] fix another --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 22c0e8395..b66cafa59 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -75,7 +75,7 @@ def dao_count_live_services(): Service.active, Service.count_as_live, Service.restricted is False ) result = db.session.execute(stmt) - return result.scalars().count() + return result.count() def dao_fetch_live_services_data(): From a41fa318a8442d151e89512ffcfa462f3944d803 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 14:52:05 -0700 Subject: [PATCH 015/109] fix another --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index b66cafa59..96efe5041 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -75,7 +75,7 @@ def dao_count_live_services(): Service.active, Service.count_as_live, Service.restricted is False ) result = db.session.execute(stmt) - return result.count() + return result.scalar() def dao_fetch_live_services_data(): From df93bbb45b5446736c122b697a997b5b060ecd53 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 15:01:46 -0700 Subject: [PATCH 016/109] fix another --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 96efe5041..93a8692df 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -75,7 +75,7 @@ def dao_count_live_services(): Service.active, Service.count_as_live, Service.restricted is False ) result = db.session.execute(stmt) - return result.scalar() + return result.scalars() def dao_fetch_live_services_data(): From aab06dc5ab2256fc23b95893727adf5ef6487d60 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 15:12:01 -0700 Subject: [PATCH 017/109] fix another --- app/dao/services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 93a8692df..0dfd1c36b 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -72,10 +72,10 @@ def get_services_by_partial_name(service_name): def dao_count_live_services(): stmt = select(Service).where( - Service.active, Service.count_as_live, Service.restricted is False + Service.active, Service.count_as_live, Service.restricted == False ) result = db.session.execute(stmt) - return result.scalars() + return result.scalar() # Retrieves the count def dao_fetch_live_services_data(): From 6fc889db04fe5acbf8f2eb47df30efe7628436cd Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 15:16:04 -0700 Subject: [PATCH 018/109] fix another --- app/dao/services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 0dfd1c36b..9fdae8636 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -72,10 +72,10 @@ def get_services_by_partial_name(service_name): def dao_count_live_services(): stmt = select(Service).where( - Service.active, Service.count_as_live, Service.restricted == False + Service.active, Service.count_as_live, Service.restricted == False # noqa ) result = db.session.execute(stmt) - return result.scalar() # Retrieves the count + return result.scalar() # Retrieves the count def dao_fetch_live_services_data(): From 40ff981b7935d80eb3565314baaf6b236b12e8ce Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 8 Oct 2024 15:27:20 -0700 Subject: [PATCH 019/109] fix another --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 9fdae8636..139e7c9a4 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -71,7 +71,7 @@ def get_services_by_partial_name(service_name): def dao_count_live_services(): - stmt = select(Service).where( + stmt = select(func.count()).select_from(Service).where( Service.active, Service.count_as_live, Service.restricted == False # noqa ) result = db.session.execute(stmt) From d5979286863c951335e2c5d0478d3de87217415f Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 07:08:01 -0700 Subject: [PATCH 020/109] convert more queries --- app/dao/services_dao.py | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 139e7c9a4..c853f0596 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -71,8 +71,12 @@ def get_services_by_partial_name(service_name): def dao_count_live_services(): - stmt = select(func.count()).select_from(Service).where( - Service.active, Service.count_as_live, Service.restricted == False # noqa + stmt = ( + select(func.count()) + .select_from(Service) + .where( + Service.active, Service.count_as_live, Service.restricted == False # noqa + ) ) result = db.session.execute(stmt) return result.scalar() # Retrieves the count @@ -267,11 +271,19 @@ def dao_archive_service(service_id): def dao_fetch_service_by_id_and_user(service_id, user_id): - return ( - Service.query.filter(Service.users.any(id=user_id), Service.id == service_id) + # return ( + # Service.query.filter(Service.users.any(id=user_id), Service.id == service_id) + # .options(joinedload(Service.users)) + # .one() + # ) + + stmt = ( + select(Service.users.any(id=user_id), Service.id == service_id) + .select_from(Service) .options(joinedload(Service.users)) - .one() ) + result = db.session.execute(stmt) + return result.scalars().one() @autocommit @@ -565,14 +577,22 @@ def dao_suspend_service(service_id): @autocommit @version_class(Service) def dao_resume_service(service_id): - service = Service.query.get(service_id) + # service = Service.query.get(service_id) + stmt = select(Service).where(id == service_id) + result = db.session.execute(stmt) + service = result.scalars().one() + service.active = True def dao_fetch_active_users_for_service(service_id): - query = User.query.filter(User.services.any(id=service_id), User.state == "active") + # query = User.query.filter(User.services.any(id=service_id), User.state == "active") - return query.all() + # return query.all() + + stmt = select(User).where(User.services.any(id=service_id), User.state == "active") + result = db.session.execute(stmt) + return result.scalars().all() def dao_find_services_sending_to_tv_numbers(start_date, end_date, threshold=500): From c8a8290053679ad5142411ade71f515c1b588219 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 07:35:13 -0700 Subject: [PATCH 021/109] convert more queries --- app/dao/services_dao.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index c853f0596..d78d108f4 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -278,12 +278,11 @@ def dao_fetch_service_by_id_and_user(service_id, user_id): # ) stmt = ( - select(Service.users.any(id=user_id), Service.id == service_id) - .select_from(Service) + select(Service).filter(Service.users.any(id=user_id), Service.id == service_id) .options(joinedload(Service.users)) ) - result = db.session.execute(stmt) - return result.scalars().one() + result = db.session.execute(stmt).scalar_one() + return result @autocommit From bf822bf74f286ccbb3a4b8335cbc87811a653ca0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 08:00:17 -0700 Subject: [PATCH 022/109] convert more queries --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index d78d108f4..658eac96d 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -579,7 +579,7 @@ def dao_resume_service(service_id): # service = Service.query.get(service_id) stmt = select(Service).where(id == service_id) result = db.session.execute(stmt) - service = result.scalars().one() + service = result.scalar_one() service.active = True From d1fb503f37ee8dc5e240d0a697ec201b82df3766 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 08:10:10 -0700 Subject: [PATCH 023/109] convert more queries --- app/dao/services_dao.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 658eac96d..42cfa7227 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -577,9 +577,7 @@ def dao_suspend_service(service_id): @version_class(Service) def dao_resume_service(service_id): # service = Service.query.get(service_id) - stmt = select(Service).where(id == service_id) - result = db.session.execute(stmt) - service = result.scalar_one() + service = db.session.get(Service, service_id) service.active = True From dc4902835eb3e9b9004b80726f28326cbe7d5ec5 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 08:34:40 -0700 Subject: [PATCH 024/109] convert more queries --- app/dao/services_dao.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 42cfa7227..e86fab52a 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -232,8 +232,15 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): def dao_fetch_all_services_created_by_user(user_id): + + # query = Service.query.filter_by(created_by_id=user_id).order_by(asc(Service.created_at) + + # return query.all() + stmt = ( - select(Service).where(created_by_id=user_id).order_by(asc(Service.created_at)) + select(Service) + .filter_by(created_by_id=user_id) + .order_by(asc(Service.created_at)) ) result = db.session.execute(stmt) return result.scalars.all() @@ -278,7 +285,8 @@ def dao_fetch_service_by_id_and_user(service_id, user_id): # ) stmt = ( - select(Service).filter(Service.users.any(id=user_id), Service.id == service_id) + select(Service) + .filter(Service.users.any(id=user_id), Service.id == service_id) .options(joinedload(Service.users)) ) result = db.session.execute(stmt).scalar_one() From c9b5bf5d0bae2bb5620af641ba51f66827e5ada9 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 09:05:14 -0700 Subject: [PATCH 025/109] convert more queries --- app/dao/services_dao.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index e86fab52a..c688caecd 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -233,17 +233,19 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): def dao_fetch_all_services_created_by_user(user_id): - # query = Service.query.filter_by(created_by_id=user_id).order_by(asc(Service.created_at) - - # return query.all() - - stmt = ( - select(Service) - .filter_by(created_by_id=user_id) - .order_by(asc(Service.created_at)) + query = Service.query.filter_by(created_by_id=user_id).order_by( + asc(Service.created_at) ) - result = db.session.execute(stmt) - return result.scalars.all() + + return query.all() + + # stmt = ( + # select(Service) + # .filter_by(created_by_id=user_id) + # .order_by(asc(Service.created_at)) + # ) + # result = db.session.execute(stmt) + # return result.scalars.all() @autocommit From 6af03ff8aa0c950a5e737284c0ca9bf1d50ca25b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 11:56:02 -0700 Subject: [PATCH 026/109] convert more queries --- app/dao/services_dao.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index c688caecd..e3124c8ad 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -233,19 +233,19 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): def dao_fetch_all_services_created_by_user(user_id): - query = Service.query.filter_by(created_by_id=user_id).order_by( - asc(Service.created_at) + # query = Service.query.filter_by(created_by_id=user_id).order_by( + # asc(Service.created_at) + # ) + + # return query.all() + + stmt = ( + select(Service) + .filter_by(created_by_id=user_id) + .order_by(asc(Service.created_at)) ) - return query.all() - - # stmt = ( - # select(Service) - # .filter_by(created_by_id=user_id) - # .order_by(asc(Service.created_at)) - # ) - # result = db.session.execute(stmt) - # return result.scalars.all() + return db.session.scalars(stmt).all() @autocommit From 29eb9627e9ebabb5d0c8d721ca178b24a4cc5e0d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 12:15:01 -0700 Subject: [PATCH 027/109] convert more queries --- app/dao/services_dao.py | 53 +++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index e3124c8ad..60eed6b70 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -210,25 +210,41 @@ def dao_fetch_service_by_inbound_number(number): def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): - query = Service.query.filter_by(id=service_id).options(joinedload(Service.api_keys)) + # query = Service.query.filter_by(id=service_id).options(joinedload(Service.api_keys)) + # if only_active: + # query = query.filter(Service.active) + + # return query.one() + stmt = ( + select(Service).filter_by(id=service_id).options(joinedload(Service.api_keys)) + ) if only_active: - query = query.filter(Service.active) - - return query.one() + stmt = stmt.filter(Service.working) + return db.session.scalar(stmt.one()) def dao_fetch_all_services_by_user(user_id, only_active=False): - query = ( - Service.query.filter(Service.users.any(id=user_id)) + # query = ( + # Service.query.filter(Service.users.any(id=user_id)) + # .order_by(asc(Service.created_at)) + # .options(joinedload(Service.users)) + # ) + + # if only_active: + # query = query.filter(Service.active) + + # return query.all() + + stmt = ( + select(Service) + .filter(Service.users.any(id=user_id)) .order_by(asc(Service.created_at)) .options(joinedload(Service.users)) ) - if only_active: - query = query.filter(Service.active) - - return query.all() + stmt = stmt.filter(Service.active) + return db.session.scalar(stmt.one()) def dao_fetch_all_services_created_by_user(user_id): @@ -257,14 +273,21 @@ def dao_fetch_all_services_created_by_user(user_id): def dao_archive_service(service_id): # have to eager load templates and api keys so that we don't flush when we loop through them # to ensure that db.session still contains the models when it comes to creating history objects - service = ( - Service.query.options( + # service = ( + # Service.query.options( + # joinedload(Service.templates).subqueryload(Template.template_redacted), + # joinedload(Service.api_keys), + # ) + # .filter(Service.id == service_id) + # .one() + # ) + stmt = select( + Service.options( joinedload(Service.templates).subqueryload(Template.template_redacted), joinedload(Service.api_keys), ) - .filter(Service.id == service_id) - .one() - ) + ).filter(Service.id == service_id) + service = db.session.scalars(stmt.one()) service.active = False service.name = get_archived_db_column_value(service.name) From ba787b0febd850015057e38e9b5575ab683513c0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 12:40:42 -0700 Subject: [PATCH 028/109] convert more queries --- app/dao/services_dao.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 60eed6b70..5277e09ef 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -282,11 +282,10 @@ def dao_archive_service(service_id): # .one() # ) stmt = select( - Service.options( + Service).options( joinedload(Service.templates).subqueryload(Template.template_redacted), joinedload(Service.api_keys), - ) - ).filter(Service.id == service_id) + ).filter(Service.id == service_id) service = db.session.scalars(stmt.one()) service.active = False From 18053205ece6c81c3235138629820d175725f459 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 12:51:21 -0700 Subject: [PATCH 029/109] convert more queries --- app/dao/services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 5277e09ef..82c6874d4 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -261,7 +261,7 @@ def dao_fetch_all_services_created_by_user(user_id): .order_by(asc(Service.created_at)) ) - return db.session.scalars(stmt).all() + return db.session.execute(stmt).scalars().all() @autocommit @@ -286,7 +286,7 @@ def dao_archive_service(service_id): joinedload(Service.templates).subqueryload(Template.template_redacted), joinedload(Service.api_keys), ).filter(Service.id == service_id) - service = db.session.scalars(stmt.one()) + service = db.session.execute(stmt).scalars().one() service.active = False service.name = get_archived_db_column_value(service.name) From 0f5453165c7aa99ef8a30797526bdc80a215a24d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 13:08:47 -0700 Subject: [PATCH 030/109] convert more queries --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 82c6874d4..ebf12469a 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -286,7 +286,7 @@ def dao_archive_service(service_id): joinedload(Service.templates).subqueryload(Template.template_redacted), joinedload(Service.api_keys), ).filter(Service.id == service_id) - service = db.session.execute(stmt).scalars().one() + service = db.session.execute(stmt).scalars().unique().one() service.active = False service.name = get_archived_db_column_value(service.name) From f02a0b247929da3c0a9d08eaff7be3cdf8c35730 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 13:18:41 -0700 Subject: [PATCH 031/109] convert more queries --- app/dao/services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index ebf12469a..05a75685a 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -221,7 +221,7 @@ def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.working) - return db.session.scalar(stmt.one()) + return db.session.execute(stmt).scalar().one() def dao_fetch_all_services_by_user(user_id, only_active=False): @@ -244,7 +244,7 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.active) - return db.session.scalar(stmt.one()) + return db.session.execute(stmt).scalar().one() def dao_fetch_all_services_created_by_user(user_id): From 298f589833ece93509fe67aa90c51bfa624b72f1 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 13:28:31 -0700 Subject: [PATCH 032/109] convert more queries --- app/dao/services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 05a75685a..2c8c36dad 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -221,7 +221,7 @@ def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.working) - return db.session.execute(stmt).scalar().one() + return db.session.execute(stmt).scalars().one() def dao_fetch_all_services_by_user(user_id, only_active=False): @@ -244,7 +244,7 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.active) - return db.session.execute(stmt).scalar().one() + return db.session.execute(stmt).scalars().one() def dao_fetch_all_services_created_by_user(user_id): From 3cc398023401d21a3c5a7297851b6db921fecdfc Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 13:38:14 -0700 Subject: [PATCH 033/109] convert more queries --- app/dao/services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 2c8c36dad..fe19ee7e1 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -191,7 +191,7 @@ def dao_fetch_service_by_id(service_id, only_active=False): stmt = stmt.where(Service.active) result = db.session.execute(stmt) - return result.unique().scalars().one() + return result.unique().scalars().unique().one() def dao_fetch_service_by_inbound_number(number): @@ -244,7 +244,7 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.active) - return db.session.execute(stmt).scalars().one() + return db.session.execute(stmt).scalars().unique().one() def dao_fetch_all_services_created_by_user(user_id): From bba76a3dfce2ef9db8f9d30f0dfda8ebfe9c3213 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 13:48:06 -0700 Subject: [PATCH 034/109] convert more queries --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index fe19ee7e1..5a3771867 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -244,7 +244,7 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.active) - return db.session.execute(stmt).scalars().unique().one() + return db.session.execute(stmt).scalars().all() def dao_fetch_all_services_created_by_user(user_id): From 61114e86dd32fb54383ef7b7428c79b5714b13f0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 13:56:26 -0700 Subject: [PATCH 035/109] convert more queries --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 5a3771867..e2594f337 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -244,7 +244,7 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.active) - return db.session.execute(stmt).scalars().all() + return db.session.execute(stmt).scalars().unique().all() def dao_fetch_all_services_created_by_user(user_id): From 2c870d20f46a1b3bf7f42bc6d9176cc33a888258 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 14:05:11 -0700 Subject: [PATCH 036/109] convert more queries --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index e2594f337..687145fe2 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -221,7 +221,7 @@ def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): ) if only_active: stmt = stmt.filter(Service.working) - return db.session.execute(stmt).scalars().one() + return db.session.execute(stmt).scalars().unique().one() def dao_fetch_all_services_by_user(user_id, only_active=False): From f771c30430e3ee0650e659c0144ee9c9f1ed4c59 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 14:12:51 -0700 Subject: [PATCH 037/109] convert more queries --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 687145fe2..3fcdbf3ef 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -220,7 +220,7 @@ def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): select(Service).filter_by(id=service_id).options(joinedload(Service.api_keys)) ) if only_active: - stmt = stmt.filter(Service.working) + stmt = stmt.filter(Service.active) return db.session.execute(stmt).scalars().unique().one() From ae60cbe5641a79c482c64fb4be222abc9616999e Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 14:23:43 -0700 Subject: [PATCH 038/109] convert more queries --- app/dao/services_dao.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 3fcdbf3ef..e5725aedf 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -704,23 +704,34 @@ def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10 def get_live_services_with_organization(): - query = ( - db.session.query( - Service.id.label("service_id"), + # query = ( + # db.session.query( + # Service.id.label("service_id"), + # Service.name.label("service_name"), + # Organization.id.label("organization_id"), + # Organization.name.label("organization_name"), + # ) + # .outerjoin(Service.organization) + # .filter( + # Service.count_as_live.is_(True), + # Service.active.is_(True), + # Service.restricted.is_(False), + # ) + # .order_by(Organization.name, Service.name) + # ) + + # return query.all() + + stmt = select(Service.id.label("service_id"), Service.name.label("service_name"), Organization.id.label("organization_id"), - Organization.name.label("organization_name"), - ) - .outerjoin(Service.organization) - .filter( + Organization.name.label("organization_name")).select_from(Service).outerjoin(Service.organization).filter( Service.count_as_live.is_(True), Service.active.is_(True), Service.restricted.is_(False), - ) - .order_by(Organization.name, Service.name) - ) + ).order_by(Organization.name, Service.name) - return query.all() + return db.session.execute(stmt).all() def fetch_notification_stats_for_service_by_month_by_user( From 85b88c046ed9c976f329e6257ac0ffb0fd54ff00 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 14:34:11 -0700 Subject: [PATCH 039/109] convert more queries --- app/dao/services_dao.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index e5725aedf..581a950d9 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -281,11 +281,14 @@ def dao_archive_service(service_id): # .filter(Service.id == service_id) # .one() # ) - stmt = select( - Service).options( + stmt = ( + select(Service) + .options( joinedload(Service.templates).subqueryload(Template.template_redacted), joinedload(Service.api_keys), - ).filter(Service.id == service_id) + ) + .filter(Service.id == service_id) + ) service = db.session.execute(stmt).scalars().unique().one() service.active = False @@ -722,14 +725,22 @@ def get_live_services_with_organization(): # return query.all() - stmt = select(Service.id.label("service_id"), + stmt = ( + select( + Service.id.label("service_id"), Service.name.label("service_name"), Organization.id.label("organization_id"), - Organization.name.label("organization_name")).select_from(Service).outerjoin(Service.organization).filter( + Organization.name.label("organization_name"), + ) + .select_from(Service) + .outerjoin(Service.organization) + .filter( Service.count_as_live.is_(True), Service.active.is_(True), Service.restricted.is_(False), - ).order_by(Organization.name, Service.name) + ) + .order_by(Organization.name, Service.name) + ) return db.session.execute(stmt).all() From c1a4c7e508c2ca73169cf4a5997917d1080a2914 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 9 Oct 2024 14:48:07 -0700 Subject: [PATCH 040/109] convert more queries --- app/dao/services_dao.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 581a950d9..9bbaa5c75 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -514,13 +514,35 @@ def dao_fetch_stats_for_service_from_days_for_user( start_date = get_midnight_in_utc(start_date) end_date = get_midnight_in_utc(end_date + timedelta(days=1)) - return ( - db.session.query( + # return ( + # db.session.query( + # NotificationAllTimeView.notification_type, + # NotificationAllTimeView.status, + # func.date_trunc("day", NotificationAllTimeView.created_at).label("day"), + # func.count(NotificationAllTimeView.id).label("count"), + # ) + # .filter( + # NotificationAllTimeView.service_id == service_id, + # NotificationAllTimeView.key_type != KeyType.TEST, + # NotificationAllTimeView.created_at >= start_date, + # NotificationAllTimeView.created_at < end_date, + # NotificationAllTimeView.created_by_id == user_id, + # ) + # .group_by( + # NotificationAllTimeView.notification_type, + # NotificationAllTimeView.status, + # func.date_trunc("day", NotificationAllTimeView.created_at), + # ) + # .all() + # ) + stmt = ( + select( NotificationAllTimeView.notification_type, NotificationAllTimeView.status, func.date_trunc("day", NotificationAllTimeView.created_at).label("day"), func.count(NotificationAllTimeView.id).label("count"), ) + .select_from(NotificationAllTimeView) .filter( NotificationAllTimeView.service_id == service_id, NotificationAllTimeView.key_type != KeyType.TEST, @@ -533,8 +555,8 @@ def dao_fetch_stats_for_service_from_days_for_user( NotificationAllTimeView.status, func.date_trunc("day", NotificationAllTimeView.created_at), ) - .all() ) + return db.session.execute(stmt).scalars().all() def dao_fetch_todays_stats_for_all_services( From cbd2cd132fd105d16c710968d218e02cfed1d4be Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 07:22:15 -0700 Subject: [PATCH 041/109] convert service_permissions_dao --- app/dao/service_permissions_dao.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/app/dao/service_permissions_dao.py b/app/dao/service_permissions_dao.py index e459b6e56..95a40c903 100644 --- a/app/dao/service_permissions_dao.py +++ b/app/dao/service_permissions_dao.py @@ -1,12 +1,17 @@ +from sqlalchemy import delete, select + from app import db from app.dao.dao_utils import autocommit from app.models import ServicePermission def dao_fetch_service_permissions(service_id): - return ServicePermission.query.filter( - ServicePermission.service_id == service_id - ).all() + # return ServicePermission.query.filter( + # ServicePermission.service_id == service_id + # ).all() + + stmt = select(ServicePermission).filter(ServicePermission.service_id == service_id) + return db.session.execute(stmt).scalars().all() @autocommit @@ -16,9 +21,17 @@ def dao_add_service_permission(service_id, permission): def dao_remove_service_permission(service_id, permission): - deleted = ServicePermission.query.filter( + # deleted = ServicePermission.query.filter( + # ServicePermission.service_id == service_id, + # ServicePermission.permission == permission, + # ).delete() + # db.session.commit() + # return deleted + + stmt = delete(ServicePermission).where( ServicePermission.service_id == service_id, ServicePermission.permission == permission, - ).delete() + ) + result = db.session.execute(stmt) db.session.commit() - return deleted + return result.rowcount From 2db45c8b508b6312f3a946340613589302c8a592 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 07:49:26 -0700 Subject: [PATCH 042/109] convert other daos --- app/dao/service_sms_sender_dao.py | 22 ++++++++++++++++------ app/dao/service_user_dao.py | 25 ++++++++++++++++++------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/app/dao/service_sms_sender_dao.py b/app/dao/service_sms_sender_dao.py index 9224cf09d..c23bd5a2e 100644 --- a/app/dao/service_sms_sender_dao.py +++ b/app/dao/service_sms_sender_dao.py @@ -1,4 +1,4 @@ -from sqlalchemy import desc +from sqlalchemy import desc, select from app import db from app.dao.dao_utils import autocommit @@ -17,17 +17,27 @@ def insert_service_sms_sender(service, sms_sender): def dao_get_service_sms_senders_by_id(service_id, service_sms_sender_id): - return ServiceSmsSender.query.filter_by( + # return ServiceSmsSender.query.filter_by( + # id=service_sms_sender_id, service_id=service_id, archived=False + # ).one() + stmt = select(ServiceSmsSender).filter_by( id=service_sms_sender_id, service_id=service_id, archived=False - ).one() + ) + return db.session.execute(stmt).scalars().one() def dao_get_sms_senders_by_service_id(service_id): - return ( - ServiceSmsSender.query.filter_by(service_id=service_id, archived=False) + # return ( + # ServiceSmsSender.query.filter_by(service_id=service_id, archived=False) + # .order_by(desc(ServiceSmsSender.is_default)) + # .all() + # ) + stmt = ( + select(ServiceSmsSender) + .filter_by(ervice_id=service_id, archived=False) .order_by(desc(ServiceSmsSender.is_default)) - .all() ) + return db.session.execute(stmt).scalars().all() @autocommit diff --git a/app/dao/service_user_dao.py b/app/dao/service_user_dao.py index 0b991a4fc..b02005a3f 100644 --- a/app/dao/service_user_dao.py +++ b/app/dao/service_user_dao.py @@ -1,3 +1,5 @@ +from sqlalchemy import select + from app import db from app.dao.dao_utils import autocommit from app.models import ServiceUser, User @@ -7,19 +9,28 @@ def dao_get_service_user(user_id, service_id): # TODO: This has been changed to account for the test case failure # that used this method but have any service user to return. Somehow, this # started to throw an error with one() method in sqlalchemy 2.0 unlike 1.4 - return ServiceUser.query.filter_by( - user_id=user_id, service_id=service_id - ).one_or_none() + # return ServiceUser.query.filter_by( + # user_id=user_id, service_id=service_id + # ).one_or_none() + stmt = select(ServiceUser).filter_by(user_id=user_id, service_id=service_id) + return db.session.execute(stmt).scalars().one_or_none() def dao_get_active_service_users(service_id): - query = ( - db.session.query(ServiceUser) + # query = ( + # db.session.query(ServiceUser) + # .join(User, User.id == ServiceUser.user_id) + # .filter(User.state == "active", ServiceUser.service_id == service_id) + # ) + + # return query.all() + + stmt = ( + select(ServiceUser) .join(User, User.id == ServiceUser.user_id) .filter(User.state == "active", ServiceUser.service_id == service_id) ) - - return query.all() + return db.session.execute(stmt).scalars().all() def dao_get_service_users_by_user_id(user_id): From 2cd7cc4665d4298cf884765eacf89cb1894f52e4 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 08:10:19 -0700 Subject: [PATCH 043/109] convert other daos --- app/dao/service_sms_sender_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/service_sms_sender_dao.py b/app/dao/service_sms_sender_dao.py index c23bd5a2e..df0f2a3e9 100644 --- a/app/dao/service_sms_sender_dao.py +++ b/app/dao/service_sms_sender_dao.py @@ -34,7 +34,7 @@ def dao_get_sms_senders_by_service_id(service_id): # ) stmt = ( select(ServiceSmsSender) - .filter_by(ervice_id=service_id, archived=False) + .filter_by(service_id=service_id, archived=False) .order_by(desc(ServiceSmsSender.is_default)) ) return db.session.execute(stmt).scalars().all() From 36a834697269030f452c8e119f566ecd98a5460c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 08:25:34 -0700 Subject: [PATCH 044/109] convert other daos --- app/dao/services_dao.py | 96 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 9bbaa5c75..d65d57ddc 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -85,8 +85,90 @@ def dao_count_live_services(): def dao_fetch_live_services_data(): year_start_date, year_end_date = get_current_calendar_year() + # most_recent_annual_billing = ( + # db.session.query( + # AnnualBilling.service_id, + # func.max(AnnualBilling.financial_year_start).label("year"), + # ) + # .group_by(AnnualBilling.service_id) + # .subquery() + # ) + + # this_year_ft_billing = FactBilling.query.filter( + # FactBilling.local_date >= year_start_date, + # FactBilling.local_date <= year_end_date, + # ).subquery() + + # data = ( + # db.session.query( + # Service.id.label("service_id"), + # Service.name.label("service_name"), + # Organization.name.label("organization_name"), + # Organization.organization_type.label("organization_type"), + # Service.consent_to_research.label("consent_to_research"), + # User.name.label("contact_name"), + # User.email_address.label("contact_email"), + # User.mobile_number.label("contact_mobile"), + # Service.go_live_at.label("live_date"), + # Service.volume_sms.label("sms_volume_intent"), + # Service.volume_email.label("email_volume_intent"), + # case( + # ( + # this_year_ft_billing.c.notification_type == NotificationType.EMAIL, + # func.sum(this_year_ft_billing.c.notifications_sent), + # ), + # else_=0, + # ).label("email_totals"), + # case( + # ( + # this_year_ft_billing.c.notification_type == NotificationType.SMS, + # func.sum(this_year_ft_billing.c.notifications_sent), + # ), + # else_=0, + # ).label("sms_totals"), + # AnnualBilling.free_sms_fragment_limit, + # ) + # .join(Service.annual_billing) + # .join( + # most_recent_annual_billing, + # and_( + # Service.id == most_recent_annual_billing.c.service_id, + # AnnualBilling.financial_year_start == most_recent_annual_billing.c.year, + # ), + # ) + # .outerjoin(Service.organization) + # .outerjoin( + # this_year_ft_billing, Service.id == this_year_ft_billing.c.service_id + # ) + # .outerjoin(User, Service.go_live_user_id == User.id) + # .filter( + # Service.count_as_live.is_(True), + # Service.active.is_(True), + # Service.restricted.is_(False), + # ) + # .group_by( + # Service.id, + # Organization.name, + # Organization.organization_type, + # Service.name, + # Service.consent_to_research, + # Service.count_as_live, + # Service.go_live_user_id, + # User.name, + # User.email_address, + # User.mobile_number, + # Service.go_live_at, + # Service.volume_sms, + # Service.volume_email, + # this_year_ft_billing.c.notification_type, + # AnnualBilling.free_sms_fragment_limit, + # ) + # .order_by(asc(Service.go_live_at)) + # .all() + # ) + most_recent_annual_billing = ( - db.session.query( + select( AnnualBilling.service_id, func.max(AnnualBilling.financial_year_start).label("year"), ) @@ -94,13 +176,13 @@ def dao_fetch_live_services_data(): .subquery() ) - this_year_ft_billing = FactBilling.query.filter( + this_year_ft_billing = select(FactBilling).filter( FactBilling.local_date >= year_start_date, FactBilling.local_date <= year_end_date, ).subquery() - data = ( - db.session.query( + stmt = ( + select( Service.id.label("service_id"), Service.name.label("service_name"), Organization.name.label("organization_name"), @@ -164,8 +246,12 @@ def dao_fetch_live_services_data(): AnnualBilling.free_sms_fragment_limit, ) .order_by(asc(Service.go_live_at)) - .all() ) + + data = db.session.execute(stmt).scalars().all() + + + results = [] for row in data: existing_service = next( From 556158012d2b8eda1b93798fc99ef01a42f33d84 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 08:33:14 -0700 Subject: [PATCH 045/109] convert other daos --- app/dao/services_dao.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index d65d57ddc..da237fcb2 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -176,10 +176,14 @@ def dao_fetch_live_services_data(): .subquery() ) - this_year_ft_billing = select(FactBilling).filter( - FactBilling.local_date >= year_start_date, - FactBilling.local_date <= year_end_date, - ).subquery() + this_year_ft_billing = ( + select(FactBilling) + .filter( + FactBilling.local_date >= year_start_date, + FactBilling.local_date <= year_end_date, + ) + .subquery() + ) stmt = ( select( @@ -250,8 +254,6 @@ def dao_fetch_live_services_data(): data = db.session.execute(stmt).scalars().all() - - results = [] for row in data: existing_service = next( From 20585ce29ca729003f40a8e9cdcbb5f49ff17127 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 08:43:13 -0700 Subject: [PATCH 046/109] convert other daos --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index da237fcb2..b745985f3 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -253,7 +253,7 @@ def dao_fetch_live_services_data(): ) data = db.session.execute(stmt).scalars().all() - + print(f"DATA IS {data}") results = [] for row in data: existing_service = next( From d845e0602b8534b2b418742b9d6857acb964dacd Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 08:55:17 -0700 Subject: [PATCH 047/109] convert other daos --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index b745985f3..7e7f99481 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -252,7 +252,7 @@ def dao_fetch_live_services_data(): .order_by(asc(Service.go_live_at)) ) - data = db.session.execute(stmt).scalars().all() + data = db.session.execute(stmt).all() print(f"DATA IS {data}") results = [] for row in data: From 299926df1eb5d4a7b56e6bc59c07367ccc04f7a9 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 10:09:24 -0700 Subject: [PATCH 048/109] convert other daos --- app/dao/services_dao.py | 121 ++++++++++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 18 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 7e7f99481..7bb6e9c2f 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -253,7 +253,6 @@ def dao_fetch_live_services_data(): ) data = db.session.execute(stmt).all() - print(f"DATA IS {data}") results = [] for row in data: existing_service = next( @@ -551,8 +550,25 @@ def delete_service_and_all_associated_db_objects(service): def dao_fetch_todays_stats_for_service(service_id): today = utc_now().date() start_date = get_midnight_in_utc(today) - return ( - db.session.query( + # return ( + # db.session.query( + # Notification.notification_type, + # Notification.status, + # func.count(Notification.id).label("count"), + # ) + # .filter( + # Notification.service_id == service_id, + # Notification.key_type != KeyType.TEST, + # Notification.created_at >= start_date, + # ) + # .group_by( + # Notification.notification_type, + # Notification.status, + # ) + # .all() + # ) + stmt = ( + select( Notification.notification_type, Notification.status, func.count(Notification.id).label("count"), @@ -566,16 +582,37 @@ def dao_fetch_todays_stats_for_service(service_id): Notification.notification_type, Notification.status, ) - .all() ) + return db.session.execute(stmt).all() def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): start_date = get_midnight_in_utc(start_date) end_date = get_midnight_in_utc(end_date + timedelta(days=1)) - return ( - db.session.query( + # return ( + # db.session.query( + # NotificationAllTimeView.notification_type, + # NotificationAllTimeView.status, + # func.date_trunc("day", NotificationAllTimeView.created_at).label("day"), + # func.count(NotificationAllTimeView.id).label("count"), + # ) + # .filter( + # NotificationAllTimeView.service_id == service_id, + # NotificationAllTimeView.key_type != KeyType.TEST, + # NotificationAllTimeView.created_at >= start_date, + # NotificationAllTimeView.created_at < end_date, + # ) + # .group_by( + # NotificationAllTimeView.notification_type, + # NotificationAllTimeView.status, + # func.date_trunc("day", NotificationAllTimeView.created_at), + # ) + # .all() + # ) + + stmt = ( + select( NotificationAllTimeView.notification_type, NotificationAllTimeView.status, func.date_trunc("day", NotificationAllTimeView.created_at).label("day"), @@ -592,8 +629,8 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): NotificationAllTimeView.status, func.date_trunc("day", NotificationAllTimeView.created_at), ) - .all() ) + return db.session.execute(stmt).all() def dao_fetch_stats_for_service_from_days_for_user( @@ -703,13 +740,19 @@ def dao_fetch_todays_stats_for_all_services( def dao_suspend_service(service_id): # have to eager load api keys so that we don't flush when we loop through them # to ensure that db.session still contains the models when it comes to creating history objects - service = ( - Service.query.options( - joinedload(Service.api_keys), - ) + # service = ( + # Service.query.options( + # joinedload(Service.api_keys), + # ) + # .filter(Service.id == service_id) + # .one() + # ) + stmt = ( + select(Service) + .options(joinedload(Service.api_keys)) .filter(Service.id == service_id) - .one() ) + service = db.session.execute(stmt).one() for api_key in service.api_keys: if not api_key.expiry_date: @@ -738,8 +781,29 @@ def dao_fetch_active_users_for_service(service_id): def dao_find_services_sending_to_tv_numbers(start_date, end_date, threshold=500): - return ( - db.session.query( + # return ( + # db.session.query( + # Notification.service_id.label("service_id"), + # func.count(Notification.id).label("notification_count"), + # ) + # .filter( + # Notification.service_id == Service.id, + # Notification.created_at >= start_date, + # Notification.created_at <= end_date, + # Notification.key_type != KeyType.TEST, + # Notification.notification_type == NotificationType.SMS, + # func.substr(Notification.normalised_to, 3, 7) == "7700900", + # Service.restricted == False, # noqa + # Service.active == True, # noqa + # ) + # .group_by( + # Notification.service_id, + # ) + # .having(func.count(Notification.id) > threshold) + # .all() + # ) + stmt = ( + select( Notification.service_id.label("service_id"), func.count(Notification.id).label("notification_count"), ) @@ -757,8 +821,8 @@ def dao_find_services_sending_to_tv_numbers(start_date, end_date, threshold=500) Notification.service_id, ) .having(func.count(Notification.id) > threshold) - .all() ) + return db.session.execute(stmt).all() def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10000): @@ -858,8 +922,29 @@ def get_live_services_with_organization(): def fetch_notification_stats_for_service_by_month_by_user( start_date, end_date, service_id, user_id ): - return ( - db.session.query( + # return ( + # db.session.query( + # func.date_trunc("month", NotificationAllTimeView.created_at).label("month"), + # NotificationAllTimeView.notification_type, + # (NotificationAllTimeView.status).label("notification_status"), + # func.count(NotificationAllTimeView.id).label("count"), + # ) + # .filter( + # NotificationAllTimeView.service_id == service_id, + # NotificationAllTimeView.created_at >= start_date, + # NotificationAllTimeView.created_at < end_date, + # NotificationAllTimeView.key_type != KeyType.TEST, + # NotificationAllTimeView.created_by_id == user_id, + # ) + # .group_by( + # func.date_trunc("month", NotificationAllTimeView.created_at).label("month"), + # NotificationAllTimeView.notification_type, + # NotificationAllTimeView.status, + # ) + # .all() + # ) + stmt = ( + select( func.date_trunc("month", NotificationAllTimeView.created_at).label("month"), NotificationAllTimeView.notification_type, (NotificationAllTimeView.status).label("notification_status"), @@ -877,8 +962,8 @@ def fetch_notification_stats_for_service_by_month_by_user( NotificationAllTimeView.notification_type, NotificationAllTimeView.status, ) - .all() ) + return db.session.execute(stmt).all() def get_specific_days_stats(data, start_date, days=None, end_date=None): From ee65f4e718d682157f1397a4a144c6ff3efe7090 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 10:18:41 -0700 Subject: [PATCH 049/109] use unique() --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 7bb6e9c2f..06801bd02 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -752,7 +752,7 @@ def dao_suspend_service(service_id): .options(joinedload(Service.api_keys)) .filter(Service.id == service_id) ) - service = db.session.execute(stmt).one() + service = db.session.execute(stmt).unique().one() for api_key in service.api_keys: if not api_key.expiry_date: From 5a75a68bb0b3015a58fcb4bc85abf3553f455f30 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 10:37:14 -0700 Subject: [PATCH 050/109] use unique() --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 06801bd02..82d806306 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -752,7 +752,7 @@ def dao_suspend_service(service_id): .options(joinedload(Service.api_keys)) .filter(Service.id == service_id) ) - service = db.session.execute(stmt).unique().one() + service = db.session.execute(stmt).scalars().unique().one() for api_key in service.api_keys: if not api_key.expiry_date: From b77173983a2340256e645855ebd6342a8cb236f7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 10:56:39 -0700 Subject: [PATCH 051/109] fix delete --- app/dao/services_dao.py | 47 ++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 82d806306..e9c40dce9 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -507,39 +507,42 @@ def dao_remove_user_from_service(service, user): def delete_service_and_all_associated_db_objects(service): - def _delete_commit(query): - query.delete(synchronize_session=False) + def _delete_commit(stmt): + # query.delete(synchronize_session=False) + db.session.execute(stmt) db.session.commit() - subq = db.session.query(Template.id).filter_by(service=service).subquery() - _delete_commit( - TemplateRedacted.query.filter(TemplateRedacted.template_id.in_(subq)) - ) + # subq = db.session.query(Template.id).filter_by(service=service).subquery() + subq = select(Template.id).filter_by(service=service).subquery() - _delete_commit(ServiceSmsSender.query.filter_by(service=service)) - _delete_commit(ServiceEmailReplyTo.query.filter_by(service=service)) - _delete_commit(InvitedUser.query.filter_by(service=service)) - _delete_commit(Permission.query.filter_by(service=service)) - _delete_commit(NotificationHistory.query.filter_by(service=service)) - _delete_commit(Notification.query.filter_by(service=service)) - _delete_commit(Job.query.filter_by(service=service)) - _delete_commit(Template.query.filter_by(service=service)) - _delete_commit(TemplateHistory.query.filter_by(service_id=service.id)) - _delete_commit(ServicePermission.query.filter_by(service_id=service.id)) - _delete_commit(ApiKey.query.filter_by(service=service)) - _delete_commit(ApiKey.get_history_model().query.filter_by(service_id=service.id)) - _delete_commit(AnnualBilling.query.filter_by(service_id=service.id)) + stmt = select(TemplateRedacted).filter(TemplateRedacted.template_id.in_(subq)) + _delete_commit(stmt) - verify_codes = VerifyCode.query.join(User).filter( - User.id.in_([x.id for x in service.users]) + _delete_commit(select(ServiceSmsSender).filter_by(service=service)) + _delete_commit(select(ServiceEmailReplyTo).filter_by(service=service)) + _delete_commit(select(InvitedUser).filter_by(service=service)) + _delete_commit(select(Permission).filter_by(service=service)) + _delete_commit(select(NotificationHistory).filter_by(service=service)) + _delete_commit(select(Notification).filter_by(service=service)) + _delete_commit(select(Job).filter_by(service=service)) + _delete_commit(select(Template).filter_by(service=service)) + _delete_commit(select(TemplateHistory).filter_by(service_id=service.id)) + _delete_commit(select(ServicePermission).filter_by(service_id=service.id)) + _delete_commit(select(ApiKey).filter_by(service=service)) + _delete_commit(select(ApiKey.get_history_model()).filter_by(service_id=service.id)) + _delete_commit(select(AnnualBilling).filter_by(service_id=service.id)) + + stmt = ( + select(VerifyCode).join(User).filter(User.id.in_([x.id for x in service.users])) ) + verify_codes = db.session.execute(stmt).scalar().all() list(map(db.session.delete, verify_codes)) db.session.commit() users = [x for x in service.users] for user in users: user.organizations = [] service.users.remove(user) - _delete_commit(Service.get_history_model().query.filter_by(id=service.id)) + _delete_commit(select(Service.get_history_model()).filter_by(id=service.id)) db.session.delete(service) db.session.commit() for user in users: From 4de9ca5c07b8247190b3bfdf40a4459b504955b0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 11:08:23 -0700 Subject: [PATCH 052/109] fix delete --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index e9c40dce9..8bac743dc 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -535,7 +535,7 @@ def delete_service_and_all_associated_db_objects(service): stmt = ( select(VerifyCode).join(User).filter(User.id.in_([x.id for x in service.users])) ) - verify_codes = db.session.execute(stmt).scalar().all() + verify_codes = db.session.execute(stmt).scalars().all() list(map(db.session.delete, verify_codes)) db.session.commit() users = [x for x in service.users] From 464dff64c73830f4b776ba4d9146d753ba284dae Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 11:25:45 -0700 Subject: [PATCH 053/109] fix delete --- app/dao/services_dao.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 8bac743dc..c7f2266c9 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -2,7 +2,7 @@ import uuid from datetime import timedelta from flask import current_app -from sqlalchemy import Float, cast, select +from sqlalchemy import Float, cast, delete, select from sqlalchemy.orm import joinedload from sqlalchemy.sql.expression import and_, asc, case, func @@ -515,22 +515,22 @@ def delete_service_and_all_associated_db_objects(service): # subq = db.session.query(Template.id).filter_by(service=service).subquery() subq = select(Template.id).filter_by(service=service).subquery() - stmt = select(TemplateRedacted).filter(TemplateRedacted.template_id.in_(subq)) + stmt = delete(TemplateRedacted).filter(TemplateRedacted.template_id.in_(subq)) _delete_commit(stmt) - _delete_commit(select(ServiceSmsSender).filter_by(service=service)) - _delete_commit(select(ServiceEmailReplyTo).filter_by(service=service)) - _delete_commit(select(InvitedUser).filter_by(service=service)) - _delete_commit(select(Permission).filter_by(service=service)) - _delete_commit(select(NotificationHistory).filter_by(service=service)) - _delete_commit(select(Notification).filter_by(service=service)) - _delete_commit(select(Job).filter_by(service=service)) - _delete_commit(select(Template).filter_by(service=service)) - _delete_commit(select(TemplateHistory).filter_by(service_id=service.id)) - _delete_commit(select(ServicePermission).filter_by(service_id=service.id)) - _delete_commit(select(ApiKey).filter_by(service=service)) - _delete_commit(select(ApiKey.get_history_model()).filter_by(service_id=service.id)) - _delete_commit(select(AnnualBilling).filter_by(service_id=service.id)) + _delete_commit(delete(ServiceSmsSender).filter_by(service=service)) + _delete_commit(delete(ServiceEmailReplyTo).filter_by(service=service)) + _delete_commit(delete(InvitedUser).filter_by(service=service)) + _delete_commit(delete(Permission).filter_by(service=service)) + _delete_commit(delete(NotificationHistory).filter_by(service=service)) + _delete_commit(delete(Notification).filter_by(service=service)) + _delete_commit(delete(Job).filter_by(service=service)) + _delete_commit(delete(Template).filter_by(service=service)) + _delete_commit(delete(TemplateHistory).filter_by(service_id=service.id)) + _delete_commit(delete(ServicePermission).filter_by(service_id=service.id)) + _delete_commit(delete(ApiKey).filter_by(service=service)) + _delete_commit(delete(ApiKey.get_history_model()).filter_by(service_id=service.id)) + _delete_commit(delete(AnnualBilling).filter_by(service_id=service.id)) stmt = ( select(VerifyCode).join(User).filter(User.id.in_([x.id for x in service.users])) @@ -542,7 +542,7 @@ def delete_service_and_all_associated_db_objects(service): for user in users: user.organizations = [] service.users.remove(user) - _delete_commit(select(Service.get_history_model()).filter_by(id=service.id)) + _delete_commit(delete(Service.get_history_model()).filter_by(id=service.id)) db.session.delete(service) db.session.commit() for user in users: From 3f2354909547cd5340ac02f6ef231fce10207916 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 11:45:26 -0700 Subject: [PATCH 054/109] fix delete --- app/dao/services_dao.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index c7f2266c9..f1e934bcf 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -695,7 +695,7 @@ def dao_fetch_todays_stats_for_all_services( end_date = get_midnight_in_utc(today + timedelta(days=1)) subquery = ( - db.session.query( + select( Notification.notification_type, Notification.status, Notification.service_id, @@ -714,8 +714,8 @@ def dao_fetch_todays_stats_for_all_services( subquery = subquery.subquery() - query = ( - db.session.query( + stmt = ( + select( Service.id.label("service_id"), Service.name, Service.restricted, @@ -730,9 +730,9 @@ def dao_fetch_todays_stats_for_all_services( ) if only_active: - query = query.filter(Service.active) + stmt = stmt.filter(Service.active) - return query.all() + return db.session.execute(stmt).scalars().all() @autocommit @@ -830,7 +830,7 @@ def dao_find_services_sending_to_tv_numbers(start_date, end_date, threshold=500) def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10000): subquery = ( - db.session.query( + select( func.count(Notification.id).label("total_count"), Notification.service_id.label("service_id"), ) @@ -851,8 +851,8 @@ def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10 subquery = subquery.subquery() - query = ( - db.session.query( + stmt = ( + select( Notification.service_id.label("service_id"), func.count(Notification.id).label("permanent_failure_count"), subquery.c.total_count.label("total_count"), @@ -880,7 +880,7 @@ def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10 ) ) - return query.all() + return db.session.execute(stmt).scalars().all() def get_live_services_with_organization(): From 337b7becc979af81c8cb7871a55dff2f9979e0c8 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 11:57:42 -0700 Subject: [PATCH 055/109] fix delete --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index f1e934bcf..e39d8ee46 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -633,7 +633,7 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): func.date_trunc("day", NotificationAllTimeView.created_at), ) ) - return db.session.execute(stmt).all() + return db.session.execute(stmt).scalars().all() def dao_fetch_stats_for_service_from_days_for_user( From 190c3cdbb5597f1a15217d08f4f0ce61a0ad4132 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 12:10:45 -0700 Subject: [PATCH 056/109] fix delete --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index e39d8ee46..cabd991d3 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -586,7 +586,7 @@ def dao_fetch_todays_stats_for_service(service_id): Notification.status, ) ) - return db.session.execute(stmt).all() + return db.session.execute(stmt).scalars().all() def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): From a4f0ff744014fb1fc7d872ef16f8cf9fbd2e6763 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 12:38:23 -0700 Subject: [PATCH 057/109] fix delete --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index cabd991d3..d08a69885 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -732,7 +732,7 @@ def dao_fetch_todays_stats_for_all_services( if only_active: stmt = stmt.filter(Service.active) - return db.session.execute(stmt).scalars().all() + return db.session.execute(stmt).all() @autocommit From c97ea3be1c671c2ee271074c120ad01a19b1141c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 12:55:08 -0700 Subject: [PATCH 058/109] fix delete --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index d08a69885..9f1a52182 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -586,7 +586,7 @@ def dao_fetch_todays_stats_for_service(service_id): Notification.status, ) ) - return db.session.execute(stmt).scalars().all() + return db.session.execute(stmt).all() def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): From 7eb58e9e4c0a5b0c3131e5b327c29b7b7184d026 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 13:04:28 -0700 Subject: [PATCH 059/109] fix delete --- app/dao/services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 9f1a52182..585fe83b1 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -880,7 +880,7 @@ def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10 ) ) - return db.session.execute(stmt).scalars().all() + return db.session.execute(stmt).all() def get_live_services_with_organization(): From 6114fe0705b6254779c07eb331ca2f7204620ff9 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 13:35:34 -0700 Subject: [PATCH 060/109] try to fix test code --- .ds.baseline | 4 +- tests/app/dao/test_services_dao.py | 100 +++++++++++++++++------------ 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index 1c279e018..4ac79c91f 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 265, + "line_number": 282, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-09-27T16:42:53Z" + "generated_at": "2024-10-10T20:35:29Z" } diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index e590eb5b4..83a6408f6 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -6,6 +6,7 @@ from unittest.mock import Mock import pytest import sqlalchemy from freezegun import freeze_time +from sqlalchemy import func, select from sqlalchemy.exc import IntegrityError from sqlalchemy.orm.exc import NoResultFound @@ -89,9 +90,25 @@ from tests.app.db import ( ) +def _get_service_query_count(): + stmt = select(func.count(Service.id)) + return db.session.execute(stmt).scalar() + + +def _get_first_service(): + stmt = select(Service).limit(1) + service = db.session.execute(stmt).scalars().first() + return service + + +def _get_service_by_id(service_id): + stmt = select(Service).where(id == service_id) + return db.session.execute(stmt).one() + + def test_create_service(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -101,8 +118,8 @@ def test_create_service(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 - service_db = Service.query.one() + assert _get_service_query_count() == 1 + service_db = _get_first_service() assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -120,7 +137,7 @@ def test_create_service_with_organization(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 service = Service( name="service_name", email_from="email_from", @@ -130,8 +147,8 @@ def test_create_service_with_organization(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 - service_db = Service.query.one() + assert _get_service_query_count()() == 1 + service_db = _get_first_service() organization = Organization.query.get(organization.id) assert service_db.name == "service_name" assert service_db.id == service.id @@ -151,7 +168,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 service = Service( name="service_name", email_from="email_from", @@ -161,8 +178,8 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 - service_db = Service.query.one() + assert _get_service_query_count() == 1 + service_db = _get_first_service() organization = Organization.query.get(organization.id) assert service_db.name == "service_name" assert service_db.id == service.id @@ -183,7 +200,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): def test_cannot_create_two_services_with_same_name(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 service1 = Service( name="service_name", email_from="email_from1", @@ -209,7 +226,7 @@ def test_cannot_create_two_services_with_same_name(notify_db_session): def test_cannot_create_two_services_with_same_email_from(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 service1 = Service( name="service_name1", email_from="email_from", @@ -235,7 +252,7 @@ def test_cannot_create_two_services_with_same_email_from(notify_db_session): def test_cannot_create_service_with_no_user(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 service = Service( name="service_name", email_from="email_from", @@ -258,7 +275,7 @@ def test_should_add_user_to_service(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert user in Service.query.first().users + assert user in _get_first_service().users new_user = User( name="Test User", email_address="new_user@digital.fake.gov", @@ -267,7 +284,7 @@ def test_should_add_user_to_service(notify_db_session): ) save_model_user(new_user, validated_email_access=True) dao_add_user_to_service(service, new_user) - assert new_user in Service.query.first().users + assert new_user in _get_first_service().users def test_dao_add_user_to_service_sets_folder_permissions(sample_user, sample_service): @@ -347,9 +364,9 @@ def test_should_remove_user_from_service(notify_db_session): ) save_model_user(new_user, validated_email_access=True) dao_add_user_to_service(service, new_user) - assert new_user in Service.query.first().users + assert new_user in _get_first_service().users dao_remove_user_from_service(service, new_user) - assert new_user not in Service.query.first().users + assert new_user not in _get_first_service().users def test_should_remove_user_from_service_exception(notify_db_session): @@ -668,7 +685,7 @@ def test_removing_all_permission_returns_service_with_no_permissions(notify_db_s def test_create_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", @@ -678,10 +695,10 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 + assert _get_service_query_count()() == 1 assert Service.get_history_model().query.count() == 1 - service_from_db = Service.query.first() + service_from_db = _get_first_service() service_history = Service.get_history_model().query.first() assert service_from_db.id == service_history.id @@ -694,7 +711,7 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses def test_update_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", @@ -705,17 +722,17 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses ) dao_create_service(service, user) - assert Service.query.count() == 1 - assert Service.query.first().version == 1 + assert _get_service_query_count() == 1 + assert _get_first_service().version == 1 assert Service.get_history_model().query.count() == 1 service.name = "updated_service_name" dao_update_service(service) - assert Service.query.count() == 1 + assert _get_service_query_count()() == 1 assert Service.get_history_model().query.count() == 2 - service_from_db = Service.query.first() + service_from_db = _get_first_service() assert service_from_db.version == 2 @@ -736,7 +753,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( notify_db_session, ): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", @@ -755,17 +772,17 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ], ) - assert Service.query.count() == 1 + assert _get_service_query_count()() == 1 service.permissions.append( ServicePermission(service_id=service.id, permission=ServicePermissionType.EMAIL) ) dao_update_service(service) - assert Service.query.count() == 1 + assert _get_service_query_count()() == 1 assert Service.get_history_model().query.count() == 2 - service_from_db = Service.query.first() + service_from_db = _get_first_service() assert service_from_db.version == 2 @@ -784,10 +801,10 @@ def test_update_service_permission_creates_a_history_record_with_current_data( service.permissions.remove(permission) dao_update_service(service) - assert Service.query.count() == 1 + assert _get_service_query_count()() == 1 assert Service.get_history_model().query.count() == 3 - service_from_db = Service.query.first() + service_from_db = _get_first_service() assert service_from_db.version == 3 _assert_service_permissions( service.permissions, @@ -797,20 +814,19 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ), ) - history = ( - Service.get_history_model() - .query.filter_by(name="service_name") + stmt = ( + select(Service.get_history_model()) + .filter_by(name="service_name") .order_by("version") - .all() ) - + history = db.session.execute(stmt).all() assert len(history) == 3 assert history[2].version == 3 def test_create_service_and_history_is_transactional(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert _get_service_query_count() == 0 assert Service.get_history_model().query.count() == 0 service = Service( name=None, @@ -828,7 +844,7 @@ def test_create_service_and_history_is_transactional(notify_db_session): in str(seeei) ) - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 assert Service.get_history_model().query.count() == 0 @@ -865,7 +881,7 @@ def test_delete_service_and_associated_objects(notify_db_session): assert Permission.query.count() == 0 assert User.query.count() == 0 assert InvitedUser.query.count() == 0 - assert Service.query.count() == 0 + assert _get_service_query_count()() == 0 assert Service.get_history_model().query.count() == 0 assert ServicePermission.query.count() == 0 # the organization hasn't been deleted @@ -1316,7 +1332,7 @@ def test_dao_fetch_todays_stats_for_all_services_can_exclude_from_test_key( def test_dao_suspend_service_with_no_api_keys(notify_db_session): service = create_service() dao_suspend_service(service.id) - service = Service.query.get(service.id) + service = _get_service_by_id(service.id) assert not service.active assert service.name == service.name assert service.api_keys == [] @@ -1329,7 +1345,7 @@ def test_dao_suspend_service_marks_service_as_inactive_and_expires_api_keys( service = create_service() api_key = create_api_key(service=service) dao_suspend_service(service.id) - service = Service.query.get(service.id) + service = _get_service_by_id(service.id) assert not service.active assert service.name == service.name @@ -1344,11 +1360,11 @@ def test_dao_resume_service_marks_service_as_active_and_api_keys_are_still_revok service = create_service() api_key = create_api_key(service=service) dao_suspend_service(service.id) - service = Service.query.get(service.id) + service = _get_service_by_id(service.id) assert not service.active dao_resume_service(service.id) - assert Service.query.get(service.id).active + assert _get_service_by_id(service.id).active api_key = ApiKey.query.get(api_key.id) assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00) From f3a1139a85786385821864680473539abb61e1f7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 13:41:33 -0700 Subject: [PATCH 061/109] try to fix test code --- tests/app/dao/test_services_dao.py | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 83a6408f6..810fdc91f 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -137,7 +137,7 @@ def test_create_service_with_organization(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -147,7 +147,7 @@ def test_create_service_with_organization(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert _get_service_query_count()() == 1 + assert _get_service_query_count() == 1 service_db = _get_first_service() organization = Organization.query.get(organization.id) assert service_db.name == "service_name" @@ -168,7 +168,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -200,7 +200,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): def test_cannot_create_two_services_with_same_name(notify_db_session): user = create_user() - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 service1 = Service( name="service_name", email_from="email_from1", @@ -226,7 +226,7 @@ def test_cannot_create_two_services_with_same_name(notify_db_session): def test_cannot_create_two_services_with_same_email_from(notify_db_session): user = create_user() - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 service1 = Service( name="service_name1", email_from="email_from", @@ -252,7 +252,7 @@ def test_cannot_create_two_services_with_same_email_from(notify_db_session): def test_cannot_create_service_with_no_user(notify_db_session): user = create_user() - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -685,7 +685,7 @@ def test_removing_all_permission_returns_service_with_no_permissions(notify_db_s def test_create_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", @@ -695,7 +695,7 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses created_by=user, ) dao_create_service(service, user) - assert _get_service_query_count()() == 1 + assert _get_service_query_count() == 1 assert Service.get_history_model().query.count() == 1 service_from_db = _get_first_service() @@ -711,7 +711,7 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses def test_update_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", @@ -729,7 +729,7 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses service.name = "updated_service_name" dao_update_service(service) - assert _get_service_query_count()() == 1 + assert _get_service_query_count() == 1 assert Service.get_history_model().query.count() == 2 service_from_db = _get_first_service() @@ -753,7 +753,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( notify_db_session, ): user = create_user() - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", @@ -772,14 +772,14 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ], ) - assert _get_service_query_count()() == 1 + assert _get_service_query_count() == 1 service.permissions.append( ServicePermission(service_id=service.id, permission=ServicePermissionType.EMAIL) ) dao_update_service(service) - assert _get_service_query_count()() == 1 + assert _get_service_query_count() == 1 assert Service.get_history_model().query.count() == 2 service_from_db = _get_first_service() @@ -801,7 +801,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( service.permissions.remove(permission) dao_update_service(service) - assert _get_service_query_count()() == 1 + assert _get_service_query_count() == 1 assert Service.get_history_model().query.count() == 3 service_from_db = _get_first_service() @@ -844,7 +844,7 @@ def test_create_service_and_history_is_transactional(notify_db_session): in str(seeei) ) - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 assert Service.get_history_model().query.count() == 0 @@ -881,7 +881,7 @@ def test_delete_service_and_associated_objects(notify_db_session): assert Permission.query.count() == 0 assert User.query.count() == 0 assert InvitedUser.query.count() == 0 - assert _get_service_query_count()() == 0 + assert _get_service_query_count() == 0 assert Service.get_history_model().query.count() == 0 assert ServicePermission.query.count() == 0 # the organization hasn't been deleted From 5c818b520ce03d6279a8aa1aaf1e756911212c02 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 13:52:29 -0700 Subject: [PATCH 062/109] try to fix test code --- tests/app/dao/test_services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 810fdc91f..25c6bd992 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -102,8 +102,8 @@ def _get_first_service(): def _get_service_by_id(service_id): - stmt = select(Service).where(id == service_id) - return db.session.execute(stmt).one() + stmt = select(Service).filter(id == service_id) + return db.session.execute(stmt).scalars().one() def test_create_service(notify_db_session): From 58d9b2d63ea0309f7ea8392ccad1e52baa50b652 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 14:03:11 -0700 Subject: [PATCH 063/109] try to fix test code --- .ds.baseline | 4 ++-- tests/app/dao/test_services_dao.py | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index 4ac79c91f..01fb2bf3d 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 282, + "line_number": 285, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-10-10T20:35:29Z" + "generated_at": "2024-10-10T21:03:06Z" } diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 25c6bd992..a7c2f7e77 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -102,8 +102,11 @@ def _get_first_service(): def _get_service_by_id(service_id): - stmt = select(Service).filter(id == service_id) - return db.session.execute(stmt).scalars().one() + stmt = select(Service).filter(Service.id == service_id) + + service = db.session.execute(stmt).scalars().one() + print(f"SERVICE Is {service}") + return service def test_create_service(notify_db_session): From b385e0863f8c5d792fc46b8df504ffbac073546a Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 14:14:35 -0700 Subject: [PATCH 064/109] try to fix test code --- tests/app/dao/test_services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index a7c2f7e77..7e01e8e1e 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -822,7 +822,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( .filter_by(name="service_name") .order_by("version") ) - history = db.session.execute(stmt).all() + history = db.session.execute(stmt).scalars().all() assert len(history) == 3 assert history[2].version == 3 From 97237f8e5da8af59308a90dc9526c78cc788c43a Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 14:35:43 -0700 Subject: [PATCH 065/109] try to fix test code --- .ds.baseline | 4 +- tests/app/dao/test_services_dao.py | 69 +++++++++++++++++++----------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index 01fb2bf3d..ee20a155d 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 285, + "line_number": 290, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-10-10T21:03:06Z" + "generated_at": "2024-10-10T21:35:38Z" } diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 7e01e8e1e..df08ce06e 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -95,6 +95,11 @@ def _get_service_query_count(): return db.session.execute(stmt).scalar() +def _get_service_history_query_count(): + stmt = select(Service.get_history_model()) + return db.session.execute(stmt).scalar() + + def _get_first_service(): stmt = select(Service).limit(1) service = db.session.execute(stmt).scalars().first() @@ -152,7 +157,7 @@ def test_create_service_with_organization(notify_db_session): dao_create_service(service, user) assert _get_service_query_count() == 1 service_db = _get_first_service() - organization = Organization.query.get(organization.id) + organization = db.session.get(Organization, organization.id) assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -183,7 +188,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): dao_create_service(service, user) assert _get_service_query_count() == 1 service_db = _get_first_service() - organization = Organization.query.get(organization.id) + organization = db.session.get(Organization, organization.id) assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -689,7 +694,7 @@ def test_removing_all_permission_returns_service_with_no_permissions(notify_db_s def test_create_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() assert _get_service_query_count() == 0 - assert Service.get_history_model().query.count() == 0 + assert _get_service_history_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -699,7 +704,7 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses ) dao_create_service(service, user) assert _get_service_query_count() == 1 - assert Service.get_history_model().query.count() == 1 + assert _get_service_history_query_count() == 1 service_from_db = _get_first_service() service_history = Service.get_history_model().query.first() @@ -715,7 +720,7 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses def test_update_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() assert _get_service_query_count() == 0 - assert Service.get_history_model().query.count() == 0 + assert _get_service_history_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -727,13 +732,13 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses assert _get_service_query_count() == 1 assert _get_first_service().version == 1 - assert Service.get_history_model().query.count() == 1 + assert _get_service_history_query_count() == 1 service.name = "updated_service_name" dao_update_service(service) assert _get_service_query_count() == 1 - assert Service.get_history_model().query.count() == 2 + assert _get_service_history_query_count() == 2 service_from_db = _get_first_service() @@ -757,7 +762,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ): user = create_user() assert _get_service_query_count() == 0 - assert Service.get_history_model().query.count() == 0 + assert _get_service_history_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -783,7 +788,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( dao_update_service(service) assert _get_service_query_count() == 1 - assert Service.get_history_model().query.count() == 2 + assert _get_service_history_query_count() == 2 service_from_db = _get_first_service() @@ -805,7 +810,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( dao_update_service(service) assert _get_service_query_count() == 1 - assert Service.get_history_model().query.count() == 3 + assert _get_service_history_query_count() == 3 service_from_db = _get_first_service() assert service_from_db.version == 3 @@ -830,7 +835,7 @@ def test_update_service_permission_creates_a_history_record_with_current_data( def test_create_service_and_history_is_transactional(notify_db_session): user = create_user() assert _get_service_query_count() == 0 - assert Service.get_history_model().query.count() == 0 + assert _get_service_history_query_count() == 0 service = Service( name=None, email_from="email_from", @@ -848,7 +853,7 @@ def test_create_service_and_history_is_transactional(notify_db_session): ) assert _get_service_query_count() == 0 - assert Service.get_history_model().query.count() == 0 + assert _get_service_history_query_count() == 0 def test_delete_service_and_associated_objects(notify_db_session): @@ -874,21 +879,35 @@ def test_delete_service_and_associated_objects(notify_db_session): ) delete_service_and_all_associated_db_objects(service) - assert VerifyCode.query.count() == 0 - assert ApiKey.query.count() == 0 - assert ApiKey.get_history_model().query.count() == 0 - assert Template.query.count() == 0 - assert TemplateHistory.query.count() == 0 - assert Job.query.count() == 0 - assert Notification.query.count() == 0 - assert Permission.query.count() == 0 - assert User.query.count() == 0 - assert InvitedUser.query.count() == 0 + stmt = select(VerifyCode) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(ApiKey) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(ApiKey.get_history_model()) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(Template) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(TemplateHistory) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(Job) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(Notification) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(Permission) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(User) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(InvitedUser) + assert db.session.execute(stmt).scalar() == 0 + assert _get_service_query_count() == 0 - assert Service.get_history_model().query.count() == 0 - assert ServicePermission.query.count() == 0 + assert _get_service_history_query_count() == 0 + stmt = select(ServicePermission) + assert db.session.execute(stmt).scalar() == 0 + # the organization hasn't been deleted - assert Organization.query.count() == 1 + stmt = select(Organization) + assert db.session.execute(stmt).scalar() == 1 def test_add_existing_user_to_another_service_doesnot_change_old_permissions( From 79d666f57037854d847868ff56f8bbc1d342fd3d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 14:55:39 -0700 Subject: [PATCH 066/109] try to fix test code --- .ds.baseline | 4 ++-- tests/app/dao/test_services_dao.py | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index ee20a155d..ae7f12d3e 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 290, + "line_number": 289, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-10-10T21:35:38Z" + "generated_at": "2024-10-10T21:55:35Z" } diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index df08ce06e..ca7fd67ba 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -92,12 +92,12 @@ from tests.app.db import ( def _get_service_query_count(): stmt = select(func.count(Service.id)) - return db.session.execute(stmt).scalar() + return db.session.execute(stmt).scalar() or 0 def _get_service_history_query_count(): stmt = select(Service.get_history_model()) - return db.session.execute(stmt).scalar() + return db.session.execute(stmt).scalar() or 0 def _get_first_service(): @@ -110,7 +110,6 @@ def _get_service_by_id(service_id): stmt = select(Service).filter(Service.id == service_id) service = db.session.execute(stmt).scalars().one() - print(f"SERVICE Is {service}") return service @@ -880,30 +879,30 @@ def test_delete_service_and_associated_objects(notify_db_session): delete_service_and_all_associated_db_objects(service) stmt = select(VerifyCode) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(ApiKey) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(ApiKey.get_history_model()) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(Template) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(TemplateHistory) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(Job) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(Notification) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(Permission) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(User) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None stmt = select(InvitedUser) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None assert _get_service_query_count() == 0 assert _get_service_history_query_count() == 0 stmt = select(ServicePermission) - assert db.session.execute(stmt).scalar() == 0 + assert db.session.execute(stmt).scalar() is None # the organization hasn't been deleted stmt = select(Organization) From 4302610d259a87d46598215b6d0187060e57ba14 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 10 Oct 2024 15:08:00 -0700 Subject: [PATCH 067/109] try to fix test code --- tests/app/dao/test_services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index ca7fd67ba..df642e173 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -96,7 +96,7 @@ def _get_service_query_count(): def _get_service_history_query_count(): - stmt = select(Service.get_history_model()) + stmt = select(func.count(Service.get_history_model().id)) return db.session.execute(stmt).scalar() or 0 @@ -905,7 +905,7 @@ def test_delete_service_and_associated_objects(notify_db_session): assert db.session.execute(stmt).scalar() is None # the organization hasn't been deleted - stmt = select(Organization) + stmt = select(func.count(Organization.id)) assert db.session.execute(stmt).scalar() == 1 From 6da190c1ed488a621c06bb96fb1d53371c5fd28e Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 07:07:10 -0700 Subject: [PATCH 068/109] try to fix test code --- tests/app/dao/test_services_dao.py | 71 +++++++++++++----------------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index df642e173..2efba7472 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -338,7 +338,8 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a other_service_folder = create_template_folder(other_service) folder_permissions = [str(other_service_folder.id)] - assert ServiceUser.query.count() == 2 + stmt = select(func.count(ServiceUser.id)) + assert db.session.execute(stmt).scalar() == 2 with pytest.raises(IntegrityError) as e: dao_add_user_to_service( @@ -350,7 +351,8 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a 'insert or update on table "user_folder_permissions" violates foreign key constraint' in str(e.value) ) - assert ServiceUser.query.count() == 2 + stmt = select(func.count(ServiceUser.id)) + assert db.session.execute(stmt).scalar() == 2 def test_should_remove_user_from_service(notify_db_session): @@ -406,11 +408,12 @@ def test_should_remove_user_from_service_exception(notify_db_session): def test_removing_a_user_from_a_service_deletes_their_permissions( sample_user, sample_service ): - assert len(Permission.query.all()) == 7 + stmt = select(Permission) + assert len(db.session.execute(stmt).all()) == 7 dao_remove_user_from_service(sample_service, sample_user) - assert Permission.query.all() == [] + assert db.session.execute(stmt).all() == [] def test_removing_a_user_from_a_service_deletes_their_folder_permissions_for_that_service( @@ -706,7 +709,8 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses assert _get_service_history_query_count() == 1 service_from_db = _get_first_service() - service_history = Service.get_history_model().query.first() + stmt = select(Service.get_history_model()) + service_history = db.session.execute(stmt).first() assert service_from_db.id == service_history.id assert service_from_db.name == service_history.name @@ -742,18 +746,10 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses service_from_db = _get_first_service() assert service_from_db.version == 2 - - assert ( - Service.get_history_model().query.filter_by(name="service_name").one().version - == 1 - ) - assert ( - Service.get_history_model() - .query.filter_by(name="updated_service_name") - .one() - .version - == 2 - ) + stmt = select(Service.get_history_model()).filter_by(name="service_name") + assert db.session.execute(stmt).one().version == 1 + stmt = select(Service.get_history_model()).filter_by(name="updated_service_name") + assert db.session.execute(stmt).one().version == 2 def test_update_service_permission_creates_a_history_record_with_current_data( @@ -868,8 +864,8 @@ def test_delete_service_and_associated_objects(notify_db_session): create_notification(template=template, api_key=api_key) create_invited_user(service=service) user.organizations = [organization] - - assert ServicePermission.query.count() == len( + stmt = select(func.count(ServicePermission.id)) + assert db.session.execute(stmt).scalar() == len( ( ServicePermissionType.SMS, ServicePermissionType.EMAIL, @@ -924,9 +920,8 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_create_service(service_one, user) assert user.id == service_one.users[0].id - test_user_permissions = Permission.query.filter_by( - service=service_one, user=user - ).all() + stmt = select(Permission).filter_by(service=service_one, user=user) + test_user_permissions = db.session.execute(stmt).all() assert len(test_user_permissions) == 7 other_user = User( @@ -946,14 +941,12 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_create_service(service_two, other_user) assert other_user.id == service_two.users[0].id - other_user_permissions = Permission.query.filter_by( - service=service_two, user=other_user - ).all() + stmt = select(Permission).filter_by(service=service_two, user=other_user) + other_user_permissions = db.session.execute(stmt).all() assert len(other_user_permissions) == 7 + stmt = select(Permission).filter_by(service=service_one, user=other_user) + other_user_service_one_permissions = db.session.execute(stmt).all() - other_user_service_one_permissions = Permission.query.filter_by( - service=service_one, user=other_user - ).all() assert len(other_user_service_one_permissions) == 0 # adding the other_user to service_one should leave all other_user permissions on service_two intact @@ -962,15 +955,12 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( permissions.append(Permission(permission=p)) dao_add_user_to_service(service_one, other_user, permissions=permissions) - - other_user_service_one_permissions = Permission.query.filter_by( - service=service_one, user=other_user - ).all() + stmt = select(Permission).filter_by(service=service_one, user=other_user) + other_user_service_one_permissions = db.session.execute(stmt).all() assert len(other_user_service_one_permissions) == 2 - other_user_service_two_permissions = Permission.query.filter_by( - service=service_two, user=other_user - ).all() + stmt = select(Permission).filter_by(service=service_two, user=other_user) + other_user_service_two_permissions = db.session.execute(stmt).all() assert len(other_user_service_two_permissions) == 7 @@ -993,9 +983,10 @@ def test_fetch_stats_filters_on_service(notify_db_session): def test_fetch_stats_ignores_historical_notification_data(sample_template): create_notification_history(template=sample_template) - - assert Notification.query.count() == 0 - assert NotificationHistory.query.count() == 1 + stmt = select(func.count(Notification.id)) + assert db.session.execute(stmt).scalar() == 0 + stmt = select(func.count(NotificationHistory.id)) + assert db.session.execute(stmt).scalar() == 1 stats = dao_fetch_todays_stats_for_service(sample_template.service_id) assert len(stats) == 0 @@ -1370,7 +1361,7 @@ def test_dao_suspend_service_marks_service_as_inactive_and_expires_api_keys( assert not service.active assert service.name == service.name - api_key = ApiKey.query.get(api_key.id) + api_key = db.session.get(ApiKey, api_key.id) assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00) @@ -1387,7 +1378,7 @@ def test_dao_resume_service_marks_service_as_active_and_api_keys_are_still_revok dao_resume_service(service.id) assert _get_service_by_id(service.id).active - api_key = ApiKey.query.get(api_key.id) + api_key = db.session.get(ApiKey, api_key.id) assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00) From 3021677d9e8a4982dd68366f04674ddfe85f6634 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 07:21:40 -0700 Subject: [PATCH 069/109] try to fix test code --- tests/app/dao/test_services_dao.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 2efba7472..613fc21df 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -338,7 +338,7 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a other_service_folder = create_template_folder(other_service) folder_permissions = [str(other_service_folder.id)] - stmt = select(func.count(ServiceUser.id)) + stmt = select(func.count(ServiceUser.service_id)) assert db.session.execute(stmt).scalar() == 2 with pytest.raises(IntegrityError) as e: @@ -351,7 +351,7 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a 'insert or update on table "user_folder_permissions" violates foreign key constraint' in str(e.value) ) - stmt = select(func.count(ServiceUser.id)) + stmt = select(func.count(ServiceUser.service_id)) assert db.session.execute(stmt).scalar() == 2 @@ -864,7 +864,7 @@ def test_delete_service_and_associated_objects(notify_db_session): create_notification(template=template, api_key=api_key) create_invited_user(service=service) user.organizations = [organization] - stmt = select(func.count(ServicePermission.id)) + stmt = select(func.count(ServicePermission.service_id)) assert db.session.execute(stmt).scalar() == len( ( ServicePermissionType.SMS, From b52070ff3302d55e2fe89122337ca9c328c04145 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 07:30:34 -0700 Subject: [PATCH 070/109] try to fix test code --- tests/app/dao/test_services_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 613fc21df..8c0b5e452 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -747,7 +747,7 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses assert service_from_db.version == 2 stmt = select(Service.get_history_model()).filter_by(name="service_name") - assert db.session.execute(stmt).one().version == 1 + assert db.session.execute(stmt).scalars().one().version == 1 stmt = select(Service.get_history_model()).filter_by(name="updated_service_name") assert db.session.execute(stmt).one().version == 2 From fa5af8e02cea56cb7c970ad2e7aa33a6bfe7a40b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 07:40:29 -0700 Subject: [PATCH 071/109] try to fix test code --- tests/app/dao/test_services_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 8c0b5e452..61fe99419 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -710,7 +710,7 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses service_from_db = _get_first_service() stmt = select(Service.get_history_model()) - service_history = db.session.execute(stmt).first() + service_history = db.session.execute(stmt).scalars().first() assert service_from_db.id == service_history.id assert service_from_db.name == service_history.name @@ -749,7 +749,7 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses stmt = select(Service.get_history_model()).filter_by(name="service_name") assert db.session.execute(stmt).scalars().one().version == 1 stmt = select(Service.get_history_model()).filter_by(name="updated_service_name") - assert db.session.execute(stmt).one().version == 2 + assert db.session.execute(stmt).scalars().one().version == 2 def test_update_service_permission_creates_a_history_record_with_current_data( From 3adedc535172252d6f5978e9cef8c1c92e49af3c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 07:53:47 -0700 Subject: [PATCH 072/109] try to fix test code --- .ds.baseline | 6 +++--- tests/app/dao/test_users_dao.py | 27 +++++++++++++++++---------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index ae7f12d3e..0d0277bfc 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -249,7 +249,7 @@ "filename": "tests/app/dao/test_users_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 52, + "line_number": 54, "is_secret": false }, { @@ -257,7 +257,7 @@ "filename": "tests/app/dao/test_users_dao.py", "hashed_secret": "f2c57870308dc87f432e5912d4de6f8e322721ba", "is_verified": false, - "line_number": 176, + "line_number": 184, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-10-10T21:55:35Z" + "generated_at": "2024-10-11T14:53:42Z" } diff --git a/tests/app/dao/test_users_dao.py b/tests/app/dao/test_users_dao.py index 9c8770913..e5fd8a8c1 100644 --- a/tests/app/dao/test_users_dao.py +++ b/tests/app/dao/test_users_dao.py @@ -3,6 +3,7 @@ from datetime import timedelta import pytest from freezegun import freeze_time +from sqlalchemy import func, select from sqlalchemy.exc import DataError from sqlalchemy.orm.exc import NoResultFound @@ -55,8 +56,10 @@ def test_create_user(notify_db_session, phone_number, expected_phone_number): } user = User(**data) save_model_user(user, password="password", validated_email_access=True) - assert User.query.count() == 1 - user_query = User.query.first() + stmt = select(func.count(User.id)) + assert db.session.execute(stmt).scalar() == 1 + stmt = select(User) + user_query = db.session.execute(stmt).scalars().first() assert user_query.email_address == email assert user_query.id == user.id assert user_query.mobile_number == expected_phone_number @@ -68,7 +71,8 @@ def test_get_all_users(notify_db_session): create_user(email="1@test.com") create_user(email="2@test.com") - assert User.query.count() == 2 + stmt = select(func.count(User.id)) + assert db.session.execute(stmt).scalar() == 2 assert len(get_user_by_id()) == 2 @@ -89,9 +93,10 @@ def test_get_user_invalid_id(notify_db_session): def test_delete_users(sample_user): - assert User.query.count() == 1 + stmt = select(func.count(User.id)) + assert db.session.execute(stmt).scalar() == 1 delete_model_user(sample_user) - assert User.query.count() == 0 + assert db.session.execute(stmt).scalar() == 0 def test_increment_failed_login_should_increment_failed_logins(sample_user): @@ -127,9 +132,10 @@ def test_get_user_by_email_is_case_insensitive(sample_user): def test_should_delete_all_verification_codes_more_than_one_day_old(sample_user): make_verify_code(sample_user, age=timedelta(hours=24), code="54321") make_verify_code(sample_user, age=timedelta(hours=24), code="54321") - assert VerifyCode.query.count() == 2 + stmt = select(func.count(VerifyCode.id)) + assert db.session.execute(stmt).scalar() == 2 delete_codes_older_created_more_than_a_day_ago() - assert VerifyCode.query.count() == 0 + assert db.session.execute(stmt).scalar() == 0 def test_should_not_delete_verification_codes_less_than_one_day_old(sample_user): @@ -137,10 +143,11 @@ def test_should_not_delete_verification_codes_less_than_one_day_old(sample_user) sample_user, age=timedelta(hours=23, minutes=59, seconds=59), code="12345" ) make_verify_code(sample_user, age=timedelta(hours=24), code="54321") - - assert VerifyCode.query.count() == 2 + stmt = select(func.count(VerifyCode)) + assert db.session.execute(stmt).scalar() == 2 delete_codes_older_created_more_than_a_day_ago() - assert VerifyCode.query.one()._code == "12345" + stmt = select(VerifyCode) + assert db.session.execute(stmt).scalars().one()._code == "12345" def make_verify_code(user, age=None, expiry_age=None, code="12335", code_used=False): From ad1ef5bfd2139e19e3850f3e004a3cb8c9ebf4ed Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 08:07:22 -0700 Subject: [PATCH 073/109] try to fix test code --- tests/app/dao/test_service_sms_sender_dao.py | 29 +++++++++++--------- tests/app/dao/test_users_dao.py | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tests/app/dao/test_service_sms_sender_dao.py b/tests/app/dao/test_service_sms_sender_dao.py index 9ca05e711..bd0bb8801 100644 --- a/tests/app/dao/test_service_sms_sender_dao.py +++ b/tests/app/dao/test_service_sms_sender_dao.py @@ -1,6 +1,7 @@ import uuid import pytest +from sqlalchemy import select from sqlalchemy.exc import SQLAlchemyError from app.dao.service_sms_sender_dao import ( @@ -13,6 +14,7 @@ from app.dao.service_sms_sender_dao import ( ) from app.exceptions import ArchiveValidationError from app.models import ServiceSmsSender +from tests.app import db from tests.app.db import ( create_inbound_number, create_service, @@ -97,10 +99,8 @@ def test_dao_add_sms_sender_for_service(notify_db_session): is_default=False, inbound_number_id=None, ) - - service_sms_senders = ServiceSmsSender.query.order_by( - ServiceSmsSender.created_at - ).all() + stmt = select(ServiceSmsSender).order_by(ServiceSmsSender.created_at) + service_sms_senders = db.session.execute(stmt).scalars().all() assert len(service_sms_senders) == 2 assert service_sms_senders[0].sms_sender == "testing" assert service_sms_senders[0].is_default @@ -116,10 +116,8 @@ def test_dao_add_sms_sender_for_service_switches_default(notify_db_session): is_default=True, inbound_number_id=None, ) - - service_sms_senders = ServiceSmsSender.query.order_by( - ServiceSmsSender.created_at - ).all() + stmt = select(ServiceSmsSender).order_by(ServiceSmsSender.created_at) + service_sms_senders = db.session.execute(stmt).scalars().all() assert len(service_sms_senders) == 2 assert service_sms_senders[0].sms_sender == "testing" assert not service_sms_senders[0].is_default @@ -128,7 +126,8 @@ def test_dao_add_sms_sender_for_service_switches_default(notify_db_session): def test_dao_update_service_sms_sender(notify_db_session): service = create_service() - service_sms_senders = ServiceSmsSender.query.filter_by(service_id=service.id).all() + stmt = select(ServiceSmsSender).filter_by(service_id=service.id) + service_sms_senders = db.session.execute(stmt).scalars().all() assert len(service_sms_senders) == 1 sms_sender_to_update = service_sms_senders[0] @@ -138,7 +137,8 @@ def test_dao_update_service_sms_sender(notify_db_session): is_default=True, sms_sender="updated", ) - sms_senders = ServiceSmsSender.query.filter_by(service_id=service.id).all() + stmt = select(ServiceSmsSender).filter_by(service_id=service.id) + sms_senders = db.sessions.execute(stmt).scalars().all() assert len(sms_senders) == 1 assert sms_senders[0].is_default assert sms_senders[0].sms_sender == "updated" @@ -159,7 +159,8 @@ def test_dao_update_service_sms_sender_switches_default(notify_db_session): is_default=True, sms_sender="updated", ) - sms_senders = ServiceSmsSender.query.filter_by(service_id=service.id).all() + stmt = select(ServiceSmsSender).filter_by(service_id=service.id) + sms_senders = db.session.execute(stmt).scalars().all() expected = {("testing", False), ("updated", True)} results = {(sender.sms_sender, sender.is_default) for sender in sms_senders} @@ -190,7 +191,8 @@ def test_update_existing_sms_sender_with_inbound_number(notify_db_session): service = create_service() inbound_number = create_inbound_number(number="12345", service_id=service.id) - existing_sms_sender = ServiceSmsSender.query.filter_by(service_id=service.id).one() + stmt = select(ServiceSmsSender).filter_by(service_id=service.id) + existing_sms_sender = db.session.execute(stmt).scalars().one() sms_sender = update_existing_sms_sender_with_inbound_number( service_sms_sender=existing_sms_sender, sms_sender=inbound_number.number, @@ -206,7 +208,8 @@ def test_update_existing_sms_sender_with_inbound_number_raises_exception_if_inbo notify_db_session, ): service = create_service() - existing_sms_sender = ServiceSmsSender.query.filter_by(service_id=service.id).one() + stmt = select(ServiceSmsSender).filter_by(service_id=service.id) + existing_sms_sender = db.session.execute(stmt).scalars().one() with pytest.raises(expected_exception=SQLAlchemyError): update_existing_sms_sender_with_inbound_number( service_sms_sender=existing_sms_sender, diff --git a/tests/app/dao/test_users_dao.py b/tests/app/dao/test_users_dao.py index e5fd8a8c1..3636593f9 100644 --- a/tests/app/dao/test_users_dao.py +++ b/tests/app/dao/test_users_dao.py @@ -143,7 +143,7 @@ def test_should_not_delete_verification_codes_less_than_one_day_old(sample_user) sample_user, age=timedelta(hours=23, minutes=59, seconds=59), code="12345" ) make_verify_code(sample_user, age=timedelta(hours=24), code="54321") - stmt = select(func.count(VerifyCode)) + stmt = select(func.count(VerifyCode.id)) assert db.session.execute(stmt).scalar() == 2 delete_codes_older_created_more_than_a_day_ago() stmt = select(VerifyCode) From aac64b2888443a2dfb0caed3b00b1d6f87604b8b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 08:39:55 -0700 Subject: [PATCH 074/109] try to fix test code --- tests/app/dao/test_service_sms_sender_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/dao/test_service_sms_sender_dao.py b/tests/app/dao/test_service_sms_sender_dao.py index bd0bb8801..b468d47f9 100644 --- a/tests/app/dao/test_service_sms_sender_dao.py +++ b/tests/app/dao/test_service_sms_sender_dao.py @@ -4,6 +4,7 @@ import pytest from sqlalchemy import select from sqlalchemy.exc import SQLAlchemyError +from app import db from app.dao.service_sms_sender_dao import ( archive_sms_sender, dao_add_sms_sender_for_service, @@ -14,7 +15,6 @@ from app.dao.service_sms_sender_dao import ( ) from app.exceptions import ArchiveValidationError from app.models import ServiceSmsSender -from tests.app import db from tests.app.db import ( create_inbound_number, create_service, From c6fee4a0b04cfbee8a55a52d026da1f5f1708dd9 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 08:47:23 -0700 Subject: [PATCH 075/109] try to fix test code --- tests/app/dao/test_service_sms_sender_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/dao/test_service_sms_sender_dao.py b/tests/app/dao/test_service_sms_sender_dao.py index b468d47f9..10bfd21f4 100644 --- a/tests/app/dao/test_service_sms_sender_dao.py +++ b/tests/app/dao/test_service_sms_sender_dao.py @@ -138,7 +138,7 @@ def test_dao_update_service_sms_sender(notify_db_session): sms_sender="updated", ) stmt = select(ServiceSmsSender).filter_by(service_id=service.id) - sms_senders = db.sessions.execute(stmt).scalars().all() + sms_senders = db.session.execute(stmt).scalars().all() assert len(sms_senders) == 1 assert sms_senders[0].is_default assert sms_senders[0].sms_sender == "updated" From b5f7977a481cce794533d2ce834666638b84813b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 09:16:19 -0700 Subject: [PATCH 076/109] fix core daos --- app/dao/notifications_dao.py | 106 +++++++++++++++++++++-------------- app/service_invite/rest.py | 2 +- 2 files changed, 65 insertions(+), 43 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index f7150d08f..360c6af35 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -1,7 +1,7 @@ from datetime import timedelta from flask import current_app -from sqlalchemy import asc, desc, or_, select, text, union +from sqlalchemy import asc, delete, desc, func, or_, select, text, union, update from sqlalchemy.orm import joinedload from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.sql import functions @@ -109,11 +109,12 @@ def _update_notification_status( def update_notification_status_by_id( notification_id, status, sent_by=None, provider_response=None, carrier=None ): - notification = ( - Notification.query.with_for_update() + stmt = ( + select(Notification) + .with_for_update() .filter(Notification.id == notification_id) - .first() ) + notification = db.session.execute(stmt).scalars().first() if not notification: current_app.logger.info( @@ -156,9 +157,8 @@ def update_notification_status_by_id( @autocommit def update_notification_status_by_reference(reference, status): # this is used to update emails - notification = Notification.query.filter( - Notification.reference == reference - ).first() + stmt = select(Notification).filter(Notification.reference == reference) + notification = db.session.execute(stmt).scalars().first() if not notification: current_app.logger.error( @@ -200,19 +200,20 @@ def get_notifications_for_job( def dao_get_notification_count_for_job_id(*, job_id): - return Notification.query.filter_by(job_id=job_id).count() + stmt = select(func.count(Notification.id)).filter_by(job_id=job_id) + return db.session.execute(stmt).scalar() def dao_get_notification_count_for_service(*, service_id): - notification_count = Notification.query.filter_by(service_id=service_id).count() - return notification_count + stmt = select(func.count(Notification.id)).filter_by(service_id=service_id) + return db.session.execute(stmt).scalar() def dao_get_failed_notification_count(): - failed_count = Notification.query.filter_by( + stmt = select(func.count(Notification.id)).filter_by( status=NotificationStatus.FAILED - ).count() - return failed_count + ) + return db.session.execute(stmt).scalar() def get_notification_with_personalisation(service_id, notification_id, key_type): @@ -220,11 +221,12 @@ def get_notification_with_personalisation(service_id, notification_id, key_type) if key_type: filter_dict["key_type"] = key_type - return ( - Notification.query.filter_by(**filter_dict) + stmt = ( + select(Notification) + .filter_by(**filter_dict) .options(joinedload(Notification.template)) - .one() ) + return db.session.execute(stmt).scalars().one() def get_notification_by_id(notification_id, service_id=None, _raise=False): @@ -233,9 +235,13 @@ def get_notification_by_id(notification_id, service_id=None, _raise=False): if service_id: filters.append(Notification.service_id == service_id) - query = Notification.query.filter(*filters) + stmt = select(Notification).filter(*filters) - return query.one() if _raise else query.first() + return ( + db.session.execute(stmt).scalars().one() + if _raise + else db.session.execute(stmt).scalars().first() + ) def get_notifications_for_service( @@ -415,12 +421,13 @@ def move_notifications_to_notification_history( deleted += delete_count_per_call # Deleting test Notifications, test notifications are not persisted to NotificationHistory - Notification.query.filter( + stmt = delete(Notification).filter( Notification.notification_type == notification_type, Notification.service_id == service_id, Notification.created_at < timestamp_to_delete_backwards_from, Notification.key_type == KeyType.TEST, - ).delete(synchronize_session=False) + ) + db.session.execute(stmt) db.session.commit() return deleted @@ -442,8 +449,9 @@ def dao_timeout_notifications(cutoff_time, limit=100000): current_statuses = [NotificationStatus.SENDING, NotificationStatus.PENDING] new_status = NotificationStatus.TEMPORARY_FAILURE - notifications = ( - Notification.query.filter( + stmt = ( + select(Notification) + .filter( Notification.created_at < cutoff_time, Notification.status.in_(current_statuses), Notification.notification_type.in_( @@ -451,14 +459,17 @@ def dao_timeout_notifications(cutoff_time, limit=100000): ), ) .limit(limit) - .all() ) + notifications = db.session.execute(stmt).scalars().all() - Notification.query.filter( - Notification.id.in_([n.id for n in notifications]), - ).update( - {"status": new_status, "updated_at": updated_at}, synchronize_session=False + stmt = ( + update(Notification) + .filter(Notification.id.in_([n.id for n in notifications])) + .update( + {"status": new_status, "updated_at": updated_at}, synchronize_session=False + ) ) + db.session.execute(stmt) db.session.commit() return notifications @@ -466,15 +477,21 @@ def dao_timeout_notifications(cutoff_time, limit=100000): @autocommit def dao_update_notifications_by_reference(references, update_dict): - updated_count = Notification.query.filter( - Notification.reference.in_(references) - ).update(update_dict, synchronize_session=False) + stmt = ( + update(Notification) + .filter(Notification.reference.in_(references)) + .update(update_dict) + ) + updated_count = db.stmt.execute(stmt) updated_history_count = 0 if updated_count != len(references): - updated_history_count = NotificationHistory.query.filter( - NotificationHistory.reference.in_(references) - ).update(update_dict, synchronize_session=False) + stmt = ( + select(NotificationHistory) + .filter(NotificationHistory.reference.in_(references)) + .update(update_dict, synchronize_session=False) + ) + updated_history_count = db.stmt.execute(stmt) return updated_count, updated_history_count @@ -541,18 +558,21 @@ def dao_get_notifications_by_recipient_or_reference( def dao_get_notification_by_reference(reference): - return Notification.query.filter(Notification.reference == reference).one() + stmt = select(Notification).filter(Notification.reference == reference) + return db.session.execute(stmt).scalars().one() def dao_get_notification_history_by_reference(reference): try: # This try except is necessary because in test keys and research mode does not create notification history. # Otherwise we could just search for the NotificationHistory object - return Notification.query.filter(Notification.reference == reference).one() + stmt = select(Notification).filter(Notification.reference == reference) + return db.session.execute(stmt).scalars().one() except NoResultFound: - return NotificationHistory.query.filter( + stmt = select(NotificationHistory).filter( NotificationHistory.reference == reference - ).one() + ) + return db.session.execute(stmt).scalars().one() def dao_get_notifications_processing_time_stats(start_date, end_date): @@ -590,11 +610,12 @@ def dao_get_notifications_processing_time_stats(start_date, end_date): def dao_get_last_notification_added_for_job_id(job_id): - last_notification_added = ( - Notification.query.filter(Notification.job_id == job_id) + stmt = ( + select(Notification) + .filter(Notification.job_id == job_id) .order_by(Notification.job_row_number.desc()) - .first() ) + last_notification_added = db.session.execute(stmt).scalars().first() return last_notification_added @@ -602,11 +623,12 @@ def dao_get_last_notification_added_for_job_id(job_id): def notifications_not_yet_sent(should_be_sending_after_seconds, notification_type): older_than_date = utc_now() - timedelta(seconds=should_be_sending_after_seconds) - notifications = Notification.query.filter( + stmt = select(Notification).filter( Notification.created_at <= older_than_date, Notification.notification_type == notification_type, Notification.status == NotificationStatus.CREATED, - ).all() + ) + notifications = db.session.execute(stmt).all() return notifications diff --git a/app/service_invite/rest.py b/app/service_invite/rest.py index f6d9627da..5728b3ed5 100644 --- a/app/service_invite/rest.py +++ b/app/service_invite/rest.py @@ -86,7 +86,7 @@ def _create_service_invite(invited_user, invite_link_host): redis_store.set( f"email-personalisation-{saved_notification.id}", json.dumps(personalisation), - ex=2*24*60*60, + ex=2 * 24 * 60 * 60, ) send_notification_to_queue(saved_notification, queue=QueueNames.NOTIFY) From 88c9af90505cf471e98b496dbd8ec2606261875e Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 09:31:47 -0700 Subject: [PATCH 077/109] fix core daos --- app/dao/notifications_dao.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 360c6af35..4d1fee9d1 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -465,7 +465,7 @@ def dao_timeout_notifications(cutoff_time, limit=100000): stmt = ( update(Notification) .filter(Notification.id.in_([n.id for n in notifications])) - .update( + .values( {"status": new_status, "updated_at": updated_at}, synchronize_session=False ) ) @@ -480,7 +480,7 @@ def dao_update_notifications_by_reference(references, update_dict): stmt = ( update(Notification) .filter(Notification.reference.in_(references)) - .update(update_dict) + .values(update_dict) ) updated_count = db.stmt.execute(stmt) @@ -489,7 +489,7 @@ def dao_update_notifications_by_reference(references, update_dict): stmt = ( select(NotificationHistory) .filter(NotificationHistory.reference.in_(references)) - .update(update_dict, synchronize_session=False) + .values(update_dict, synchronize_session=False) ) updated_history_count = db.stmt.execute(stmt) From 90b407241f971885d5d4c0c3aa9c4c9c001ef967 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 09:38:12 -0700 Subject: [PATCH 078/109] fix core daos --- app/dao/notifications_dao.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 4d1fee9d1..ca1646467 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -466,7 +466,7 @@ def dao_timeout_notifications(cutoff_time, limit=100000): update(Notification) .filter(Notification.id.in_([n.id for n in notifications])) .values( - {"status": new_status, "updated_at": updated_at}, synchronize_session=False + {"status": new_status, "updated_at": updated_at} ) ) db.session.execute(stmt) @@ -482,16 +482,16 @@ def dao_update_notifications_by_reference(references, update_dict): .filter(Notification.reference.in_(references)) .values(update_dict) ) - updated_count = db.stmt.execute(stmt) + updated_count = db.session.execute(stmt) updated_history_count = 0 if updated_count != len(references): stmt = ( select(NotificationHistory) .filter(NotificationHistory.reference.in_(references)) - .values(update_dict, synchronize_session=False) + .values(update_dict) ) - updated_history_count = db.stmt.execute(stmt) + updated_history_count = db.session.execute(stmt) return updated_count, updated_history_count From d8bb71bf39eaae872d8d1cc195de7b9f376115e9 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 09:47:00 -0700 Subject: [PATCH 079/109] fix core daos --- 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 ca1646467..d1c0d7202 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -487,7 +487,7 @@ def dao_update_notifications_by_reference(references, update_dict): updated_history_count = 0 if updated_count != len(references): stmt = ( - select(NotificationHistory) + update(NotificationHistory) .filter(NotificationHistory.reference.in_(references)) .values(update_dict) ) From 958861df59503eac58b6f75bc32e30b9f91bae8c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 09:59:16 -0700 Subject: [PATCH 080/109] fix core daos --- app/dao/notifications_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index d1c0d7202..1fbb637c9 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -482,7 +482,7 @@ def dao_update_notifications_by_reference(references, update_dict): .filter(Notification.reference.in_(references)) .values(update_dict) ) - updated_count = db.session.execute(stmt) + updated_count = db.session.execute(stmt).scalar() or 0 updated_history_count = 0 if updated_count != len(references): @@ -491,7 +491,7 @@ def dao_update_notifications_by_reference(references, update_dict): .filter(NotificationHistory.reference.in_(references)) .values(update_dict) ) - updated_history_count = db.session.execute(stmt) + updated_history_count = db.session.execute(stmt).scalar() or 0 return updated_count, updated_history_count From c44300a73707cf9d6e62c127a23bf8498b4b8e46 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 10:13:11 -0700 Subject: [PATCH 081/109] fix core daos --- app/dao/notifications_dao.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 1fbb637c9..802c2a287 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -465,9 +465,7 @@ def dao_timeout_notifications(cutoff_time, limit=100000): stmt = ( update(Notification) .filter(Notification.id.in_([n.id for n in notifications])) - .values( - {"status": new_status, "updated_at": updated_at} - ) + .values({"status": new_status, "updated_at": updated_at}) ) db.session.execute(stmt) @@ -482,7 +480,8 @@ def dao_update_notifications_by_reference(references, update_dict): .filter(Notification.reference.in_(references)) .values(update_dict) ) - updated_count = db.session.execute(stmt).scalar() or 0 + result = db.session.execute(stmt) + updated_count = result.rowcount updated_history_count = 0 if updated_count != len(references): @@ -491,7 +490,8 @@ def dao_update_notifications_by_reference(references, update_dict): .filter(NotificationHistory.reference.in_(references)) .values(update_dict) ) - updated_history_count = db.session.execute(stmt).scalar() or 0 + result = db.session.execute(stmt) + updated_history_count = result.rowcount return updated_count, updated_history_count From 84e46f1ef2e25fb9265e5ed5f199f9927271d46f Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 10:29:13 -0700 Subject: [PATCH 082/109] fix core daos --- app/dao/notifications_dao.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 802c2a287..e93f59e28 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -629,6 +629,7 @@ def notifications_not_yet_sent(should_be_sending_after_seconds, notification_typ Notification.status == NotificationStatus.CREATED, ) notifications = db.session.execute(stmt).all() + print(f"WE RETURN THIS FOR NOTIFICATIONS {notifications}") return notifications From ef6e4048c27368c7dd5914203cbcfe47e84919d5 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 10:38:28 -0700 Subject: [PATCH 083/109] fix core daos --- 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 e93f59e28..8659fca9b 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -628,7 +628,7 @@ def notifications_not_yet_sent(should_be_sending_after_seconds, notification_typ Notification.notification_type == notification_type, Notification.status == NotificationStatus.CREATED, ) - notifications = db.session.execute(stmt).all() + notifications = db.session.execute(stmt).scalars().all() print(f"WE RETURN THIS FOR NOTIFICATIONS {notifications}") return notifications From 4f20bfe2dbc1ba16dc75bf5f52769aad8a9f17e7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 11:30:35 -0700 Subject: [PATCH 084/109] fix core daos --- app/dao/users_dao.py | 55 ++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/app/dao/users_dao.py b/app/dao/users_dao.py index 897bb1b9e..07995ac6a 100644 --- a/app/dao/users_dao.py +++ b/app/dao/users_dao.py @@ -4,7 +4,7 @@ from secrets import randbelow import sqlalchemy from flask import current_app -from sqlalchemy import func, text +from sqlalchemy import delete, func, select, text from sqlalchemy.orm import joinedload from app import db @@ -37,8 +37,8 @@ def get_login_gov_user(login_uuid, email_address): login.gov uuids are. Eventually the code that checks by email address should be removed. """ - - user = User.query.filter_by(login_uuid=login_uuid).first() + stmt = select(User).filter_by(login_uuid=login_uuid) + user = db.session.execute(stmt).scalars().first() if user: if user.email_address != email_address: try: @@ -54,7 +54,8 @@ def get_login_gov_user(login_uuid, email_address): return user # Remove this 1 July 2025, all users should have login.gov uuids by now - user = User.query.filter(User.email_address.ilike(email_address)).first() + stmt = select(User).filter(User.email_address.ilike(email_address)) + user = db.session.execute(stmt).scalars().first() if user: save_user_attribute(user, {"login_uuid": login_uuid}) @@ -102,24 +103,27 @@ def create_user_code(user, code, code_type): def get_user_code(user, code, code_type): # Get the most recent codes to try and reduce the # time searching for the correct code. - codes = VerifyCode.query.filter_by(user=user, code_type=code_type).order_by( - VerifyCode.created_at.desc() + stmt = ( + select(VerifyCode) + .filter_by(user=user, code_type=code_type) + .order_by(VerifyCode.created_at.desc()) ) + codes = db.session.execute(stmt).scalars().all() return next((x for x in codes if x.check_code(code)), None) def delete_codes_older_created_more_than_a_day_ago(): - deleted = ( - db.session.query(VerifyCode) - .filter(VerifyCode.created_at < utc_now() - timedelta(hours=24)) - .delete() + stmt = delete(VerifyCode).filter( + VerifyCode.created_at < utc_now() - timedelta(hours=24) ) + + deleted = db.session.execute(stmt) db.session.commit() return deleted def use_user_code(id): - verify_code = VerifyCode.query.get(id) + verify_code = db.session.get(VerifyCode, id) verify_code.code_used = True db.session.add(verify_code) db.session.commit() @@ -131,36 +135,42 @@ def delete_model_user(user): def delete_user_verify_codes(user): - VerifyCode.query.filter_by(user=user).delete() + stmt = delete(VerifyCode).filter_by(user=user) + db.session.execute(stmt) db.session.commit() def count_user_verify_codes(user): - query = VerifyCode.query.filter( + stmt = select(func.count(VerifyCode.id)).filter( VerifyCode.user == user, VerifyCode.expiry_datetime > utc_now(), VerifyCode.code_used.is_(False), ) - return query.count() + result = db.session.execute(stmt) + return result.rowcount def get_user_by_id(user_id=None): if user_id: - return User.query.filter_by(id=user_id).one() - return User.query.filter_by().all() + stmt = select(User).filter_by(id=user_id) + return db.session.execute(stmt).scalars().one() + return get_users() def get_users(): - return User.query.all() + stmt = select(User) + return db.session.execute(stmt).scalars().all() def get_user_by_email(email): - return User.query.filter(func.lower(User.email_address) == func.lower(email)).one() + stmt = select(User).filter(func.lower(User.email_address) == func.lower(email)) + return db.session.execute(stmt).scalars().one() def get_users_by_partial_email(email): email = escape_special_characters(email) - return User.query.filter(User.email_address.ilike("%{}%".format(email))).all() + stmt = select(User).filter(User.email_address.ilike("%{}%".format(email))) + return db.session.execute(stmt).scalars().all() def increment_failed_login_count(user): @@ -188,16 +198,17 @@ def get_user_and_accounts(user_id): # TODO: With sqlalchemy 2.0 change as below because of the breaking change # at User.organizations.services, we need to verify that the below subqueryload # that we have put is functionally doing the same thing as before - return ( - User.query.filter(User.id == user_id) + stmt = ( + select(User) + .filter(User.id == user_id) .options( # eagerly load the user's services and organizations, and also the service's org and vice versa # (so we can see if the user knows about it) joinedload(User.services).joinedload(Service.organization), joinedload(User.organizations).subqueryload(Organization.services), ) - .one() ) + return db.session.execute(stmt).scalars().one() @autocommit From a5eceae07b3d1f0a2e50300e21f4256143366d33 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 11:39:48 -0700 Subject: [PATCH 085/109] fix core daos --- app/dao/users_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/users_dao.py b/app/dao/users_dao.py index 07995ac6a..b0b5f2679 100644 --- a/app/dao/users_dao.py +++ b/app/dao/users_dao.py @@ -146,8 +146,8 @@ def count_user_verify_codes(user): VerifyCode.expiry_datetime > utc_now(), VerifyCode.code_used.is_(False), ) - result = db.session.execute(stmt) - return result.rowcount + result = db.session.execute(stmt).scalar() + return result or 0 def get_user_by_id(user_id=None): From 1f6decebe2876d081bb0c066d5c2693d07ba48b1 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 12:00:04 -0700 Subject: [PATCH 086/109] fix core daos --- app/dao/users_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/users_dao.py b/app/dao/users_dao.py index b0b5f2679..690ecc7f9 100644 --- a/app/dao/users_dao.py +++ b/app/dao/users_dao.py @@ -208,7 +208,7 @@ def get_user_and_accounts(user_id): joinedload(User.organizations).subqueryload(Organization.services), ) ) - return db.session.execute(stmt).scalars().one() + return db.session.execute(stmt).scalars().unique().one() @autocommit From 54ab96e0737fb1bd5b223458e4d9b0d4cffd9833 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 12:26:55 -0700 Subject: [PATCH 087/109] fix core daos --- .ds.baseline | 6 +- .../notification_dao/test_notification_dao.py | 234 +++++++++++------- tests/app/dao/test_users_dao.py | 35 ++- 3 files changed, 176 insertions(+), 99 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index 1c279e018..37199f01f 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -249,7 +249,7 @@ "filename": "tests/app/dao/test_users_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 52, + "line_number": 69, "is_secret": false }, { @@ -257,7 +257,7 @@ "filename": "tests/app/dao/test_users_dao.py", "hashed_secret": "f2c57870308dc87f432e5912d4de6f8e322721ba", "is_verified": false, - "line_number": 176, + "line_number": 194, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-09-27T16:42:53Z" + "generated_at": "2024-10-11T19:26:50Z" } diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index 4bc1ce5ba..8e81db3a2 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -4,9 +4,11 @@ from functools import partial import pytest from freezegun import freeze_time +from sqlalchemy import func, select from sqlalchemy.exc import IntegrityError, SQLAlchemyError from sqlalchemy.orm.exc import NoResultFound +from app import db from app.dao.notifications_dao import ( dao_create_notification, dao_delete_notifications_by_id, @@ -55,7 +57,10 @@ def test_should_by_able_to_update_status_by_reference( notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.get(notification.id).status == NotificationStatus.SENDING + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.SENDING + ) notification.reference = "reference" dao_update_notification(notification) @@ -64,7 +69,8 @@ def test_should_by_able_to_update_status_by_reference( ) assert updated.status == NotificationStatus.DELIVERED assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) @@ -81,7 +87,10 @@ def test_should_by_able_to_update_status_by_id( dao_create_notification(notification) assert notification.status == NotificationStatus.SENDING - assert Notification.query.get(notification.id).status == NotificationStatus.SENDING + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.SENDING + ) with freeze_time("2000-01-02 12:00:00"): updated = update_notification_status_by_id( @@ -92,7 +101,8 @@ def test_should_by_able_to_update_status_by_id( assert updated.status == NotificationStatus.DELIVERED assert updated.updated_at == datetime(2000, 1, 2, 12, 0, 0) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) assert notification.updated_at == datetime(2000, 1, 2, 12, 0, 0) assert notification.status == NotificationStatus.DELIVERED @@ -107,15 +117,17 @@ def test_should_not_update_status_by_id_if_not_sending_and_does_not_update_job( job=sample_job, ) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) assert not update_notification_status_by_id( notification.id, NotificationStatus.FAILED ) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) - assert sample_job == Job.query.get(notification.job_id) + assert sample_job == db.session.get(Job, notification.job_id) def test_should_not_update_status_by_reference_if_not_sending_and_does_not_update_job( @@ -128,20 +140,22 @@ def test_should_not_update_status_by_reference_if_not_sending_and_does_not_updat job=sample_job, ) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) assert not update_notification_status_by_reference( "reference", NotificationStatus.FAILED ) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) - assert sample_job == Job.query.get(notification.job_id) + assert sample_job == db.session.get(Job, notification.job_id) def test_should_update_status_by_id_if_created(sample_template, sample_notification): assert ( - Notification.query.get(sample_notification.id).status + db.session.get(Notification, sample_notification.id).status == NotificationStatus.CREATED ) updated = update_notification_status_by_id( @@ -149,7 +163,7 @@ def test_should_update_status_by_id_if_created(sample_template, sample_notificat NotificationStatus.FAILED, ) assert ( - Notification.query.get(sample_notification.id).status + db.session.get(Notification, sample_notification.id).status == NotificationStatus.FAILED ) assert updated.status == NotificationStatus.FAILED @@ -244,11 +258,17 @@ def test_should_not_update_status_by_reference_if_not_sending(sample_template): status=NotificationStatus.CREATED, reference="reference", ) - assert Notification.query.get(notification.id).status == NotificationStatus.CREATED + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.CREATED + ) updated = update_notification_status_by_reference( "reference", NotificationStatus.FAILED ) - assert Notification.query.get(notification.id).status == NotificationStatus.CREATED + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.CREATED + ) assert not updated @@ -264,14 +284,18 @@ def test_should_by_able_to_update_status_by_id_from_pending_to_delivered( assert update_notification_status_by_id( notification_id=notification.id, status=NotificationStatus.PENDING ) - assert Notification.query.get(notification.id).status == NotificationStatus.PENDING + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.PENDING + ) assert update_notification_status_by_id( notification.id, NotificationStatus.DELIVERED, ) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) @@ -289,7 +313,10 @@ def test_should_by_able_to_update_status_by_id_from_pending_to_temporary_failure notification_id=notification.id, status=NotificationStatus.PENDING, ) - assert Notification.query.get(notification.id).status == NotificationStatus.PENDING + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.PENDING + ) assert update_notification_status_by_id( notification.id, @@ -297,7 +324,7 @@ def test_should_by_able_to_update_status_by_id_from_pending_to_temporary_failure ) assert ( - Notification.query.get(notification.id).status + db.session.get(Notification, notification.id).status == NotificationStatus.TEMPORARY_FAILURE ) @@ -312,14 +339,17 @@ def test_should_by_able_to_update_status_by_id_from_sending_to_permanent_failure ) notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.get(notification.id).status == NotificationStatus.SENDING + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.SENDING + ) assert update_notification_status_by_id( notification.id, status=NotificationStatus.PERMANENT_FAILURE, ) assert ( - Notification.query.get(notification.id).status + db.session.get(Notification, notification.id).status == NotificationStatus.PERMANENT_FAILURE ) @@ -331,7 +361,10 @@ def test_should_not_update_status_once_notification_status_is_delivered( template=sample_email_template, status=NotificationStatus.SENDING, ) - assert Notification.query.get(notification.id).status == NotificationStatus.SENDING + assert ( + db.session.get(Notification, notification.id).status + == NotificationStatus.SENDING + ) notification.reference = "reference" dao_update_notification(notification) @@ -340,7 +373,8 @@ def test_should_not_update_status_once_notification_status_is_delivered( NotificationStatus.DELIVERED, ) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) update_notification_status_by_reference( @@ -348,7 +382,8 @@ def test_should_not_update_status_once_notification_status_is_delivered( NotificationStatus.FAILED, ) assert ( - Notification.query.get(notification.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification.id).status + == NotificationStatus.DELIVERED ) @@ -370,7 +405,7 @@ def test_create_notification_creates_notification_with_personalisation( sample_template_with_placeholders, sample_job, ): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = create_notification( template=sample_template_with_placeholders, @@ -379,8 +414,8 @@ def test_create_notification_creates_notification_with_personalisation( status=NotificationStatus.CREATED, ) - assert Notification.query.count() == 1 - notification_from_db = Notification.query.all()[0] + assert _get_notification_query_count() == 1 + notification_from_db = _get_notification_query_all()[0] assert notification_from_db.id assert data.to == notification_from_db.to assert data.job_id == notification_from_db.job_id @@ -393,15 +428,15 @@ def test_create_notification_creates_notification_with_personalisation( def test_save_notification_creates_sms(sample_template, sample_job): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_template, job_id=sample_job.id) notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.count() == 1 - notification_from_db = Notification.query.all()[0] + assert _get_notification_query_count() == 1 + notification_from_db = _get_notification_query_all()[0] assert notification_from_db.id assert "1" == notification_from_db.to assert data["job_id"] == notification_from_db.job_id @@ -412,16 +447,36 @@ def test_save_notification_creates_sms(sample_template, sample_job): assert notification_from_db.status == NotificationStatus.CREATED +def _get_notification_query_all(): + stmt = select(Notification) + return db.execute(stmt).scalars().all() + + +def _get_notification_query_one(): + stmt = select(Notification) + return db.execute(stmt).scalars().one() + + +def _get_notification_query_count(): + stmt = select(func.count(Notification.id)) + return db.session.execute(stmt).scalar() or 0 + + +def _get_notification_history_query_count(): + stmt = select(func.count(NotificationHistory.id)) + return db.session.execute(stmt).scalar() or 0 + + def test_save_notification_and_create_email(sample_email_template, sample_job): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_email_template, job_id=sample_job.id) notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.count() == 1 - notification_from_db = Notification.query.all()[0] + assert _get_notification_query_count() == 1 + notification_from_db = _get_notification_query_all()[0] assert notification_from_db.id assert "1" == notification_from_db.to assert data["job_id"] == notification_from_db.job_id @@ -433,29 +488,29 @@ def test_save_notification_and_create_email(sample_email_template, sample_job): def test_save_notification(sample_email_template, sample_job): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_email_template, job_id=sample_job.id) notification_1 = Notification(**data) notification_2 = Notification(**data) dao_create_notification(notification_1) - assert Notification.query.count() == 1 + assert _get_notification_query_count() == 1 dao_create_notification(notification_2) - assert Notification.query.count() == 2 + assert _get_notification_query_count() == 2 def test_save_notification_does_not_creates_history(sample_email_template, sample_job): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_email_template, job_id=sample_job.id) notification_1 = Notification(**data) dao_create_notification(notification_1) - assert Notification.query.count() == 1 - assert NotificationHistory.query.count() == 0 + assert _get_notification_query_count() == 1 + assert _get_notification_history_query_count() == 0 def test_update_notification_with_research_mode_service_does_not_create_or_update_history( @@ -464,14 +519,14 @@ def test_update_notification_with_research_mode_service_does_not_create_or_updat sample_template.service.research_mode = True notification = create_notification(template=sample_template) - assert Notification.query.count() == 1 - assert NotificationHistory.query.count() == 0 + assert _get_notification_query_count() == 1 + assert _get_notification_history_query_count() == 0 notification.status = NotificationStatus.DELIVERED dao_update_notification(notification) - assert Notification.query.one().status == NotificationStatus.DELIVERED - assert NotificationHistory.query.count() == 0 + assert _get_notification_query_one().status == NotificationStatus.DELIVERED + assert _get_notification_history_query_count() == 0 def test_not_save_notification_and_not_create_stats_on_commit_error( @@ -479,26 +534,26 @@ def test_not_save_notification_and_not_create_stats_on_commit_error( ): random_id = str(uuid.uuid4()) - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_template, job_id=random_id) notification = Notification(**data) with pytest.raises(SQLAlchemyError): dao_create_notification(notification) - assert Notification.query.count() == 0 - assert Job.query.get(sample_job.id).notifications_sent == 0 + assert _get_notification_query_count() == 0 + assert db.session.get(Job, sample_job.id).notifications_sent == 0 def test_save_notification_and_increment_job(sample_template, sample_job, sns_provider): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_template, job_id=sample_job.id) notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.count() == 1 - notification_from_db = Notification.query.all()[0] + assert _get_notification_query_count() == 1 + notification_from_db = _get_notification_query_all()[0] assert notification_from_db.id assert "1" == notification_from_db.to assert data["job_id"] == notification_from_db.job_id @@ -510,21 +565,21 @@ def test_save_notification_and_increment_job(sample_template, sample_job, sns_pr notification_2 = Notification(**data) dao_create_notification(notification_2) - assert Notification.query.count() == 2 + assert _get_notification_query_count() == 2 def test_save_notification_and_increment_correct_job(sample_template, sns_provider): job_1 = create_job(sample_template) job_2 = create_job(sample_template) - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_template, job_id=job_1.id) notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.count() == 1 - notification_from_db = Notification.query.all()[0] + assert _get_notification_query_count() == 1 + notification_from_db = _get_notification_query_all()[0] assert notification_from_db.id assert "1" == notification_from_db.to assert data["job_id"] == notification_from_db.job_id @@ -537,14 +592,14 @@ def test_save_notification_and_increment_correct_job(sample_template, sns_provid def test_save_notification_with_no_job(sample_template, sns_provider): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_template) notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.count() == 1 - notification_from_db = Notification.query.all()[0] + assert _get_notification_query_count() == 1 + notification_from_db = _get_notification_query_all()[0] assert notification_from_db.id assert "1" == notification_from_db.to assert data["service"] == notification_from_db.service @@ -592,7 +647,7 @@ def test_get_notification_by_id_when_notification_exists_for_different_service( def test_get_notifications_by_reference(sample_template): client_reference = "some-client-ref" - assert len(Notification.query.all()) == 0 + assert len(_get_notification_query_all()) == 0 create_notification(sample_template, client_reference=client_reference) create_notification(sample_template, client_reference=client_reference) create_notification(sample_template, client_reference="other-ref") @@ -603,14 +658,14 @@ def test_get_notifications_by_reference(sample_template): def test_save_notification_no_job_id(sample_template): - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 data = _notification_json(sample_template) notification = Notification(**data) dao_create_notification(notification) - assert Notification.query.count() == 1 - notification_from_db = Notification.query.all()[0] + assert _get_notification_query_count() == 1 + notification_from_db = _get_notification_query_all()[0] assert notification_from_db.id assert "1" == notification_from_db.to assert data["service"] == notification_from_db.service @@ -687,13 +742,13 @@ def test_update_notification_sets_status(sample_notification): assert sample_notification.status == NotificationStatus.CREATED sample_notification.status = NotificationStatus.FAILED dao_update_notification(sample_notification) - notification_from_db = Notification.query.get(sample_notification.id) + notification_from_db = db.session.get(Notification, sample_notification.id) assert notification_from_db.status == NotificationStatus.FAILED @freeze_time("2016-01-10") def test_should_limit_notifications_return_by_day_limit_plus_one(sample_template): - assert len(Notification.query.all()) == 0 + assert len(_get_notification_query_all()) == 0 # create one notification a day between 1st and 9th, # with assumption that the local timezone is EST @@ -706,7 +761,7 @@ def test_should_limit_notifications_return_by_day_limit_plus_one(sample_template status=NotificationStatus.FAILED, ) - all_notifications = Notification.query.all() + all_notifications = _get_notification_query_all() assert len(all_notifications) == 10 all_notifications = get_notifications_for_service( @@ -722,19 +777,19 @@ def test_should_limit_notifications_return_by_day_limit_plus_one(sample_template def test_creating_notification_does_not_add_notification_history(sample_template): create_notification(template=sample_template) - assert Notification.query.count() == 1 - assert NotificationHistory.query.count() == 0 + assert _get_notification_query_count() == 1 + assert _get_notification_history_query_count() == 0 def test_should_delete_notification_for_id(sample_template): notification = create_notification(template=sample_template) - assert Notification.query.count() == 1 - assert NotificationHistory.query.count() == 0 + assert _get_notification_query_count() == 1 + assert _get_notification_history_query_count() == 0 dao_delete_notifications_by_id(notification.id) - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 def test_should_delete_notification_and_ignore_history_for_research_mode( @@ -744,31 +799,32 @@ def test_should_delete_notification_and_ignore_history_for_research_mode( notification = create_notification(template=sample_template) - assert Notification.query.count() == 1 + assert _get_notification_query_count() == 1 dao_delete_notifications_by_id(notification.id) - assert Notification.query.count() == 0 + assert _get_notification_query_count() == 0 def test_should_delete_only_notification_with_id(sample_template): notification_1 = create_notification(template=sample_template) notification_2 = create_notification(template=sample_template) - assert Notification.query.count() == 2 + assert _get_notification_query_count() == 2 dao_delete_notifications_by_id(notification_1.id) - assert Notification.query.count() == 1 - assert Notification.query.first().id == notification_2.id + assert _get_notification_query_count() == 1 + stmt = select(Notification) + assert db.session.execute(stmt).scalars().first().id == notification_2.id def test_should_delete_no_notifications_if_no_matching_ids(sample_template): create_notification(template=sample_template) - assert Notification.query.count() == 1 + assert _get_notification_query_count() == 1 dao_delete_notifications_by_id(uuid.uuid4()) - assert Notification.query.count() == 1 + assert _get_notification_query_count() == 1 def _notification_json(sample_template, job_id=None, id=None, status=None): @@ -814,16 +870,19 @@ def test_dao_timeout_notifications(sample_template): temporary_failure_notifications = dao_timeout_notifications(utc_now()) assert len(temporary_failure_notifications) == 2 - assert Notification.query.get(created.id).status == NotificationStatus.CREATED + assert db.session.get(Notification, created.id).status == NotificationStatus.CREATED assert ( - Notification.query.get(sending.id).status + db.session.get(Notification, sending.id).status == NotificationStatus.TEMPORARY_FAILURE ) assert ( - Notification.query.get(pending.id).status + db.session.get(Notification, pending.id).status == NotificationStatus.TEMPORARY_FAILURE ) - assert Notification.query.get(delivered.id).status == NotificationStatus.DELIVERED + assert ( + db.session.get(Notification, delivered.id).status + == NotificationStatus.DELIVERED + ) def test_dao_timeout_notifications_only_updates_for_older_notifications( @@ -842,8 +901,8 @@ def test_dao_timeout_notifications_only_updates_for_older_notifications( temporary_failure_notifications = dao_timeout_notifications(utc_now()) assert len(temporary_failure_notifications) == 0 - assert Notification.query.get(sending.id).status == NotificationStatus.SENDING - assert Notification.query.get(pending.id).status == NotificationStatus.PENDING + assert db.session.get(Notification, sending.id).status == NotificationStatus.SENDING + assert db.session.get(Notification, pending.id).status == NotificationStatus.PENDING def test_should_return_notifications_excluding_jobs_by_default( @@ -935,7 +994,7 @@ def test_get_notifications_created_by_api_or_csv_are_returned_correctly_excludin key_type=sample_test_api_key.key_type, ) - all_notifications = Notification.query.all() + all_notifications = _get_notification_query_all() assert len(all_notifications) == 4 # returns all real API derived notifications @@ -982,7 +1041,7 @@ def test_get_notifications_with_a_live_api_key_type( key_type=sample_test_api_key.key_type, ) - all_notifications = Notification.query.all() + all_notifications = _get_notification_query_all() assert len(all_notifications) == 4 # only those created with normal API key, no jobs @@ -1114,7 +1173,7 @@ def test_should_exclude_test_key_notifications_by_default( key_type=sample_test_api_key.key_type, ) - all_notifications = Notification.query.all() + all_notifications = _get_notification_query_all() assert len(all_notifications) == 4 all_notifications = get_notifications_for_service( @@ -1757,10 +1816,10 @@ def test_dao_update_notifications_by_reference_updated_notifications(sample_temp update_dict={"status": NotificationStatus.DELIVERED, "billable_units": 2}, ) assert updated_count == 2 - updated_1 = Notification.query.get(notification_1.id) + updated_1 = db.session.get(Notification, notification_1.id) assert updated_1.billable_units == 2 assert updated_1.status == NotificationStatus.DELIVERED - updated_2 = Notification.query.get(notification_2.id) + updated_2 = db.session.get(Notification, notification_2.id) assert updated_2.billable_units == 2 assert updated_2.status == NotificationStatus.DELIVERED @@ -1823,10 +1882,11 @@ def test_dao_update_notifications_by_reference_updates_history_when_one_of_two_n assert updated_count == 1 assert updated_history_count == 1 assert ( - Notification.query.get(notification2.id).status == NotificationStatus.DELIVERED + db.session.get(Notification, notification2.id).status + == NotificationStatus.DELIVERED ) assert ( - NotificationHistory.query.get(notification1.id).status + db.session.get(NotificationHistory, notification1.id).status == NotificationStatus.DELIVERED ) diff --git a/tests/app/dao/test_users_dao.py b/tests/app/dao/test_users_dao.py index 9c8770913..85149b246 100644 --- a/tests/app/dao/test_users_dao.py +++ b/tests/app/dao/test_users_dao.py @@ -3,6 +3,7 @@ from datetime import timedelta import pytest from freezegun import freeze_time +from sqlalchemy import func, select from sqlalchemy.exc import DataError from sqlalchemy.orm.exc import NoResultFound @@ -37,6 +38,21 @@ from tests.app.db import ( ) +def _get_user_query_count(): + stmt = select(func.count(User.id)) + return db.session.execute(stmt).scalar() or 0 + + +def _get_user_query_first(): + stmt = select(User) + return db.session.execute(stmt).scalars().first() + + +def _get_verify_code_query_count(): + stmt = select(func.count(VerifyCode.id)) + return db.session.execute(stmt).scalar() or 0 + + @freeze_time("2020-01-28T12:00:00") @pytest.mark.parametrize( "phone_number, expected_phone_number", @@ -55,8 +71,8 @@ def test_create_user(notify_db_session, phone_number, expected_phone_number): } user = User(**data) save_model_user(user, password="password", validated_email_access=True) - assert User.query.count() == 1 - user_query = User.query.first() + assert _get_user_query_count() == 1 + user_query = _get_user_query_first() assert user_query.email_address == email assert user_query.id == user.id assert user_query.mobile_number == expected_phone_number @@ -68,7 +84,7 @@ def test_get_all_users(notify_db_session): create_user(email="1@test.com") create_user(email="2@test.com") - assert User.query.count() == 2 + assert _get_user_query_count() == 2 assert len(get_user_by_id()) == 2 @@ -89,9 +105,9 @@ def test_get_user_invalid_id(notify_db_session): def test_delete_users(sample_user): - assert User.query.count() == 1 + assert _get_user_query_count() == 1 delete_model_user(sample_user) - assert User.query.count() == 0 + assert _get_user_query_count() == 0 def test_increment_failed_login_should_increment_failed_logins(sample_user): @@ -127,9 +143,9 @@ def test_get_user_by_email_is_case_insensitive(sample_user): def test_should_delete_all_verification_codes_more_than_one_day_old(sample_user): make_verify_code(sample_user, age=timedelta(hours=24), code="54321") make_verify_code(sample_user, age=timedelta(hours=24), code="54321") - assert VerifyCode.query.count() == 2 + assert _get_verify_code_query_count() == 2 delete_codes_older_created_more_than_a_day_ago() - assert VerifyCode.query.count() == 0 + assert _get_verify_code_query_count() == 0 def test_should_not_delete_verification_codes_less_than_one_day_old(sample_user): @@ -138,9 +154,10 @@ def test_should_not_delete_verification_codes_less_than_one_day_old(sample_user) ) make_verify_code(sample_user, age=timedelta(hours=24), code="54321") - assert VerifyCode.query.count() == 2 + assert _get_verify_code_query_count() == 2 delete_codes_older_created_more_than_a_day_ago() - assert VerifyCode.query.one()._code == "12345" + stmt = select(VerifyCode) + assert db.session.execute(stmt).scalars().one()._code == "12345" def make_verify_code(user, age=None, expiry_age=None, code="12335", code_used=False): From b84ed9c7befc872a5063c3c0b905db3912bf5ced Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 12:33:52 -0700 Subject: [PATCH 088/109] fix core daos --- tests/app/dao/notification_dao/test_notification_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index 8e81db3a2..e2ac10032 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -449,12 +449,12 @@ def test_save_notification_creates_sms(sample_template, sample_job): def _get_notification_query_all(): stmt = select(Notification) - return db.execute(stmt).scalars().all() + return db.session.execute(stmt).scalars().all() def _get_notification_query_one(): stmt = select(Notification) - return db.execute(stmt).scalars().one() + return db.session.execute(stmt).scalars().one() def _get_notification_query_count(): From 7e16eeb386a1e34f20f47ce611cb04995305ebae Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 13:30:59 -0700 Subject: [PATCH 089/109] upgrade org and template dao to sqlalchemy 2.0 --- app/dao/organization_dao.py | 12 +++++++----- app/service_invite/rest.py | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 9e44bcdd5..3a8a5e602 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -1,3 +1,4 @@ +from sqlalchemy import select from sqlalchemy.sql.expression import func from app import db @@ -6,14 +7,15 @@ from app.models import Domain, Organization, Service, User def dao_get_organizations(): - return Organization.query.order_by( + stmt = select(Organization).order_by( Organization.active.desc(), Organization.name.asc() - ).all() + ) + return db.session.execute(stmt).scalars().all() def dao_count_organizations_with_live_services(): - return ( - db.session.query(Organization.id) + stmt = ( + select(func.count(Organization.id)) .join(Organization.services) .filter( Service.active.is_(True), @@ -21,8 +23,8 @@ def dao_count_organizations_with_live_services(): Service.count_as_live.is_(True), ) .distinct() - .count() ) + return db.session.execute(stmt).scalar() or 0 def dao_get_organization_services(organization_id): diff --git a/app/service_invite/rest.py b/app/service_invite/rest.py index f6d9627da..5728b3ed5 100644 --- a/app/service_invite/rest.py +++ b/app/service_invite/rest.py @@ -86,7 +86,7 @@ def _create_service_invite(invited_user, invite_link_host): redis_store.set( f"email-personalisation-{saved_notification.id}", json.dumps(personalisation), - ex=2*24*60*60, + ex=2 * 24 * 60 * 60, ) send_notification_to_queue(saved_notification, queue=QueueNames.NOTIFY) From daac3bf0f34aa966ee25de907ada00a8c4a05b67 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 11 Oct 2024 14:18:35 -0700 Subject: [PATCH 090/109] upgrade org and template dao to sqlalchemy 2.0 --- app/dao/organization_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 3a8a5e602..761d1b576 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -22,9 +22,9 @@ def dao_count_organizations_with_live_services(): Service.restricted.is_(False), Service.count_as_live.is_(True), ) - .distinct() + ) - return db.session.execute(stmt).scalar() or 0 + return db.session.execute(stmt).distinct().scalar() or 0 def dao_get_organization_services(organization_id): From 88910f5718349d435b496477578d6e54a86f784c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 07:34:39 -0700 Subject: [PATCH 091/109] upgrade organization_dao to sqlalchemy 2.0 --- app/dao/organization_dao.py | 38 ++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 761d1b576..7fde65a2a 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -1,4 +1,4 @@ -from sqlalchemy import select +from sqlalchemy import delete, select from sqlalchemy.sql.expression import func from app import db @@ -22,41 +22,42 @@ def dao_count_organizations_with_live_services(): Service.restricted.is_(False), Service.count_as_live.is_(True), ) - ) return db.session.execute(stmt).distinct().scalar() or 0 def dao_get_organization_services(organization_id): - return Organization.query.filter_by(id=organization_id).one().services + stmt = select(Organization).filter_by(id=organization_id) + return db.session.execute(stmt).scalars().one().services def dao_get_organization_live_services(organization_id): - return Service.query.filter_by( - organization_id=organization_id, restricted=False - ).all() + stmt = select(Service).filter_by(organization_id=organization_id, restricted=False) + return db.session.execute(stmt).scalars().all() def dao_get_organization_by_id(organization_id): - return Organization.query.filter_by(id=organization_id).one() + stmt = select(Organization).filter_by(id=organization_id) + return db.session.execute(stmt).scalars().one() def dao_get_organization_by_email_address(email_address): email_address = email_address.lower().replace(".gsi.gov.uk", ".gov.uk") - - for domain in Domain.query.order_by(func.char_length(Domain.domain).desc()).all(): + stmt = select(Domain).order_by(func.char_length(Domain.domain).desc()) + domains = db.session.execute(stmt).scalars().all() + for domain in domains: if email_address.endswith( "@{}".format(domain.domain) ) or email_address.endswith(".{}".format(domain.domain)): - return Organization.query.filter_by(id=domain.organization_id).one() + stmt = select(Organization).filter_by(id=domain.organization_id) + return db.session.execute(stmt).scalars().one() return None def dao_get_organization_by_service_id(service_id): - return ( - Organization.query.join(Organization.services).filter_by(id=service_id).first() - ) + stmt = select(Organization).join(Organization.services).filter_by(id=service_id) + return db.session.execute(stmt).scalars().first() @autocommit @@ -70,7 +71,8 @@ def dao_update_organization(organization_id, **kwargs): num_updated = Organization.query.filter_by(id=organization_id).update(kwargs) if isinstance(domains, list): - Domain.query.filter_by(organization_id=organization_id).delete() + stmt = delete(Domain).filter_by(organization_id=organization_id) + db.session.execute(stmt) db.session.bulk_save_objects( [ Domain(domain=domain.lower(), organization_id=organization_id) @@ -78,7 +80,7 @@ def dao_update_organization(organization_id, **kwargs): ] ) - organization = Organization.query.get(organization_id) + organization = db.session.get(Organization, organization_id) if "organization_type" in kwargs: _update_organization_services( organization, "organization_type", only_where_none=False @@ -103,7 +105,8 @@ def _update_organization_services(organization, attribute, only_where_none=True) @autocommit @version_class(Service) def dao_add_service_to_organization(service, organization_id): - organization = Organization.query.filter_by(id=organization_id).one() + stmt = select(Organization).filter_by(id=organization_id) + organization = db.session.execute(stmt).scalars().one() service.organization_id = organization_id service.organization_type = organization.organization_type @@ -124,7 +127,8 @@ def dao_get_users_for_organization(organization_id): @autocommit def dao_add_user_to_organization(organization_id, user_id): organization = dao_get_organization_by_id(organization_id) - user = User.query.filter_by(id=user_id).one() + stmt = select(User).filter_by(id=user_id) + user = db.session.execute(stmt).scalars().one() user.organizations.append(organization) db.session.add(organization) return user From 9174efe53597e6502f9d09b458f90515da541d8b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 07:43:47 -0700 Subject: [PATCH 092/109] upgrade organization_dao to sqlalchemy 2.0 --- app/dao/organization_dao.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 7fde65a2a..366508cf0 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -23,7 +23,8 @@ def dao_count_organizations_with_live_services(): Service.count_as_live.is_(True), ) ) - return db.session.execute(stmt).distinct().scalar() or 0 + # TODO Need distinct here? + return db.session.execute(stmt).scalar() or 0 def dao_get_organization_services(organization_id): From fe85970a86e7e4f896df14d8db5266fb4dab8315 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 07:55:43 -0700 Subject: [PATCH 093/109] upgrade organization_dao to sqlalchemy 2.0 --- app/dao/organization_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 366508cf0..6f045144d 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -15,7 +15,7 @@ def dao_get_organizations(): def dao_count_organizations_with_live_services(): stmt = ( - select(func.count(Organization.id)) + select(func.count(Organization.id).distinct()).select_from(Organization) .join(Organization.services) .filter( Service.active.is_(True), From ca365858bbefbea96c7670f3142ef61a99b2ec43 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 08:05:23 -0700 Subject: [PATCH 094/109] upgrade organization_dao to sqlalchemy 2.0 --- app/dao/organization_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 6f045144d..c686e35a1 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -15,7 +15,7 @@ def dao_get_organizations(): def dao_count_organizations_with_live_services(): stmt = ( - select(func.count(Organization.id).distinct()).select_from(Organization) + select(func.count().distinct()).select_from(Organization) .join(Organization.services) .filter( Service.active.is_(True), From eac1122dae08ed6b1092bcf8a9d0be1121ae4ef8 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 08:14:12 -0700 Subject: [PATCH 095/109] upgrade organization_dao to sqlalchemy 2.0 --- app/dao/organization_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index c686e35a1..548327631 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -15,7 +15,7 @@ def dao_get_organizations(): def dao_count_organizations_with_live_services(): stmt = ( - select(func.count().distinct()).select_from(Organization) + select(func.count(func.distinct(Organization.id))) .join(Organization.services) .filter( Service.active.is_(True), From 5a48c359c6ba603cfdd08b84472967932f91e657 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 08:34:29 -0700 Subject: [PATCH 096/109] fix template folder dao --- app/dao/organization_dao.py | 5 +++-- app/dao/template_folder_dao.py | 10 ++++++--- app/dao/templates_dao.py | 40 +++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 548327631..34afd98e0 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -1,4 +1,4 @@ -from sqlalchemy import delete, select +from sqlalchemy import delete, select, update from sqlalchemy.sql.expression import func from app import db @@ -69,7 +69,8 @@ def dao_create_organization(organization): @autocommit def dao_update_organization(organization_id, **kwargs): domains = kwargs.pop("domains", None) - num_updated = Organization.query.filter_by(id=organization_id).update(kwargs) + stmt = update(Organization).where(id=organization_id).values(**kwargs) + num_updated = db.session.execute(stmt).rowcount if isinstance(domains, list): stmt = delete(Domain).filter_by(organization_id=organization_id) diff --git a/app/dao/template_folder_dao.py b/app/dao/template_folder_dao.py index ae1224179..269f407e0 100644 --- a/app/dao/template_folder_dao.py +++ b/app/dao/template_folder_dao.py @@ -1,16 +1,20 @@ +from sqlalchemy import select + from app import db from app.dao.dao_utils import autocommit from app.models import TemplateFolder def dao_get_template_folder_by_id_and_service_id(template_folder_id, service_id): - return TemplateFolder.query.filter( + stmt = select(TemplateFolder).filter( TemplateFolder.id == template_folder_id, TemplateFolder.service_id == service_id - ).one() + ) + return db.session.execute(stmt).scalars().one() def dao_get_valid_template_folders_by_id(folder_ids): - return TemplateFolder.query.filter(TemplateFolder.id.in_(folder_ids)).all() + stmt = select(TemplateFolder).filter(TemplateFolder.id.in_(folder_ids)) + return db.session.execute(stmt).scalars().all() @autocommit diff --git a/app/dao/templates_dao.py b/app/dao/templates_dao.py index 55d4363d6..7c5d7459e 100644 --- a/app/dao/templates_dao.py +++ b/app/dao/templates_dao.py @@ -1,6 +1,6 @@ import uuid -from sqlalchemy import asc, desc +from sqlalchemy import asc, desc, select from app import db from app.dao.dao_utils import VersionOptions, autocommit, version_class @@ -46,24 +46,29 @@ def dao_redact_template(template, user_id): def dao_get_template_by_id_and_service_id(template_id, service_id, version=None): if version is not None: - return TemplateHistory.query.filter_by( + stmt = select(TemplateHistory).filter_by( id=template_id, hidden=False, service_id=service_id, version=version - ).one() - return Template.query.filter_by( + ) + return db.session.execute(stmt).scalars().one() + stmt = select(Template).filter_by( id=template_id, hidden=False, service_id=service_id - ).one() + ) + return db.session.execute(stmt).scalars().one() def dao_get_template_by_id(template_id, version=None): if version is not None: - return TemplateHistory.query.filter_by(id=template_id, version=version).one() - return Template.query.filter_by(id=template_id).one() + stmt = select(TemplateHistory).filter_by(id=template_id, version=version) + return db.session.execute(stmt).scalars().one() + stmt = select(Template).filter_by(id=template_id) + return db.session.execute(stmt).scalars().one() def dao_get_all_templates_for_service(service_id, template_type=None): if template_type is not None: - return ( - Template.query.filter_by( + stmt = ( + select(Template) + .filter_by( service_id=service_id, template_type=template_type, hidden=False, @@ -73,26 +78,27 @@ def dao_get_all_templates_for_service(service_id, template_type=None): asc(Template.name), asc(Template.template_type), ) - .all() ) - - return ( - Template.query.filter_by(service_id=service_id, hidden=False, archived=False) + return db.session.execute(stmt).scalars().all() + stmt = ( + select(Template) + .filter_by(service_id=service_id, hidden=False, archived=False) .order_by( asc(Template.name), asc(Template.template_type), ) - .all() ) + return db.session.execute(stmt).scalars().all() def dao_get_template_versions(service_id, template_id): - return ( - TemplateHistory.query.filter_by( + stmt = ( + select(TemplateHistory) + .filter_by( service_id=service_id, id=template_id, hidden=False, ) .order_by(desc(TemplateHistory.version)) - .all() ) + return db.session.execute(stmt).scalars().all() From b4a45da4d413e4ca8c388f9cb3307016712d0ce6 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 08:50:04 -0700 Subject: [PATCH 097/109] fix template folder dao --- app/dao/organization_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 34afd98e0..8bb10f659 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -69,7 +69,7 @@ def dao_create_organization(organization): @autocommit def dao_update_organization(organization_id, **kwargs): domains = kwargs.pop("domains", None) - stmt = update(Organization).where(id=organization_id).values(**kwargs) + stmt = update(Organization).where(Organization.id==organization_id).values(**kwargs) num_updated = db.session.execute(stmt).rowcount if isinstance(domains, list): From c8a758aff63ea998d547c6e7e57c53405e7e77b1 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 08:52:50 -0700 Subject: [PATCH 098/109] fix template folder dao --- app/dao/organization_dao.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index 8bb10f659..f699e33bc 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -69,7 +69,9 @@ def dao_create_organization(organization): @autocommit def dao_update_organization(organization_id, **kwargs): domains = kwargs.pop("domains", None) - stmt = update(Organization).where(Organization.id==organization_id).values(**kwargs) + stmt = ( + update(Organization).where(Organization.id == organization_id).values(**kwargs) + ) num_updated = db.session.execute(stmt).rowcount if isinstance(domains, list): From 68b9d8a484beb43e6486052df4a819dba8b48c08 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 09:21:06 -0700 Subject: [PATCH 099/109] fix template folder dao --- .ds.baseline | 4 +- tests/app/dao/test_organization_dao.py | 29 +++-- tests/app/dao/test_services_dao.py | 174 +++++++++++++++---------- 3 files changed, 126 insertions(+), 81 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index 1c279e018..329763bf5 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 265, + "line_number": 266, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-09-27T16:42:53Z" + "generated_at": "2024-10-14T16:21:01Z" } diff --git a/tests/app/dao/test_organization_dao.py b/tests/app/dao/test_organization_dao.py index edffdd1d4..fb2e01d85 100644 --- a/tests/app/dao/test_organization_dao.py +++ b/tests/app/dao/test_organization_dao.py @@ -1,6 +1,7 @@ import uuid import pytest +from sqlalchemy import select from sqlalchemy.exc import IntegrityError, SQLAlchemyError from app import db @@ -57,7 +58,8 @@ def test_get_organization_by_id_gets_correct_organization(notify_db_session): def test_update_organization(notify_db_session): create_organization() - organization = Organization.query.one() + stmt = select(Organization) + organization = db.session.execute(stmt).scalars().one() user = create_user() email_branding = create_email_branding() @@ -78,7 +80,8 @@ def test_update_organization(notify_db_session): dao_update_organization(organization.id, **data) - organization = Organization.query.one() + stmt = select(Organization) + organization = db.session.execute(stmt).scalars().one() for attribute, value in data.items(): assert getattr(organization, attribute) == value @@ -102,7 +105,8 @@ def test_update_organization_domains_lowercases( ): create_organization() - organization = Organization.query.one() + stmt = select(Organization) + organization = db.session.execute(stmt).scalars().one() # Seed some domains dao_update_organization(organization.id, domains=["123", "456"]) @@ -121,7 +125,8 @@ def test_update_organization_domains_lowercases_integrity_error( ): create_organization() - organization = Organization.query.one() + stmt = select(Organization) + organization = db.session.execute(stmt).scalars().one() # Seed some domains dao_update_organization(organization.id, domains=["123", "456"]) @@ -175,11 +180,11 @@ def test_update_organization_updates_the_service_org_type_if_org_type_is_provide assert sample_organization.organization_type == OrganizationType.FEDERAL assert sample_service.organization_type == OrganizationType.FEDERAL + stmt = select(Service.get_history_model()).filter_by( + id=sample_service.id, version=2 + ) assert ( - Service.get_history_model() - .query.filter_by(id=sample_service.id, version=2) - .one() - .organization_type + db.session.execute(stmt).scalars().one().organization_type == OrganizationType.FEDERAL ) @@ -229,11 +234,11 @@ def test_add_service_to_organization(sample_service, sample_organization): assert sample_organization.services[0].id == sample_service.id assert sample_service.organization_type == sample_organization.organization_type + stmt = select(Service.get_history_model()).filter_by( + id=sample_service.id, version=2 + ) assert ( - Service.get_history_model() - .query.filter_by(id=sample_service.id, version=2) - .one() - .organization_type + db.session.execute(stmt).scalars().one().organization_type == sample_organization.organization_type ) assert sample_service.organization_id == sample_organization.id diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index e590eb5b4..487df6a29 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -6,6 +6,7 @@ from unittest.mock import Mock import pytest import sqlalchemy from freezegun import freeze_time +from sqlalchemy import func, select from sqlalchemy.exc import IntegrityError from sqlalchemy.orm.exc import NoResultFound @@ -91,7 +92,7 @@ from tests.app.db import ( def test_create_service(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -101,7 +102,7 @@ def test_create_service(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 + assert service_query_count() == 1 service_db = Service.query.one() assert service_db.name == "service_name" assert service_db.id == service.id @@ -120,7 +121,7 @@ def test_create_service_with_organization(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert Service.query.count() == 0 + assert service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -130,9 +131,9 @@ def test_create_service_with_organization(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 + assert service_query_count() == 1 service_db = Service.query.one() - organization = Organization.query.get(organization.id) + organization = db.session.get(Organization, organization.id) assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -151,7 +152,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert Service.query.count() == 0 + assert service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -161,9 +162,9 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 + assert service_query_count() == 1 service_db = Service.query.one() - organization = Organization.query.get(organization.id) + organization = db.session.get(Organization, organization.id) assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -183,7 +184,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): def test_cannot_create_two_services_with_same_name(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert service_query_count() == 0 service1 = Service( name="service_name", email_from="email_from1", @@ -209,7 +210,7 @@ def test_cannot_create_two_services_with_same_name(notify_db_session): def test_cannot_create_two_services_with_same_email_from(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert service_query_count() == 0 service1 = Service( name="service_name1", email_from="email_from", @@ -235,7 +236,7 @@ def test_cannot_create_two_services_with_same_email_from(notify_db_session): def test_cannot_create_service_with_no_user(notify_db_session): user = create_user() - assert Service.query.count() == 0 + assert service_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -258,7 +259,7 @@ def test_should_add_user_to_service(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert user in Service.query.first().users + assert user in service_query_first().users new_user = User( name="Test User", email_address="new_user@digital.fake.gov", @@ -267,7 +268,7 @@ def test_should_add_user_to_service(notify_db_session): ) save_model_user(new_user, validated_email_access=True) dao_add_user_to_service(service, new_user) - assert new_user in Service.query.first().users + assert new_user in service_query_first().users def test_dao_add_user_to_service_sets_folder_permissions(sample_user, sample_service): @@ -314,7 +315,8 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a other_service_folder = create_template_folder(other_service) folder_permissions = [str(other_service_folder.id)] - assert ServiceUser.query.count() == 2 + stmt = select(ServiceUser) + assert db.session.execute(stmt).scalar() == 2 with pytest.raises(IntegrityError) as e: dao_add_user_to_service( @@ -326,7 +328,8 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a 'insert or update on table "user_folder_permissions" violates foreign key constraint' in str(e.value) ) - assert ServiceUser.query.count() == 2 + stmt = select(ServiceUser) + assert db.session.execute(stmt).scalar() == 2 def test_should_remove_user_from_service(notify_db_session): @@ -347,9 +350,9 @@ def test_should_remove_user_from_service(notify_db_session): ) save_model_user(new_user, validated_email_access=True) dao_add_user_to_service(service, new_user) - assert new_user in Service.query.first().users + assert new_user in service_query_first().users dao_remove_user_from_service(service, new_user) - assert new_user not in Service.query.first().users + assert new_user not in service_query_first().users def test_should_remove_user_from_service_exception(notify_db_session): @@ -668,8 +671,8 @@ def test_removing_all_permission_returns_service_with_no_permissions(notify_db_s def test_create_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert Service.query.count() == 0 - assert Service.get_history_model().query.count() == 0 + assert service_query_count() == 0 + assert service_history_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -678,10 +681,10 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses created_by=user, ) dao_create_service(service, user) - assert Service.query.count() == 1 - assert Service.get_history_model().query.count() == 1 + assert service_query_count() == 1 + assert service_history_query_count() == 1 - service_from_db = Service.query.first() + service_from_db = service_query_first() service_history = Service.get_history_model().query.first() assert service_from_db.id == service_history.id @@ -692,10 +695,25 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses assert service_from_db.created_by.id == service_history.created_by_id +def service_query_count(): + stmt = select(func.count()).select_from(Service) + return db.session.execute(stmt).scalar() or 0 + + +def service_query_first(): + stmt = select(Service) + return db.session.execute(stmt).scalars().first() + + +def service_history_query_count(): + stmt = select(func.count()).select_from(Service.get_history_model()) + return db.session.execute(stmt).scalar() or 0 + + def test_update_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert Service.query.count() == 0 - assert Service.get_history_model().query.count() == 0 + assert service_query_count() == 0 + assert service_history_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -705,17 +723,17 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses ) dao_create_service(service, user) - assert Service.query.count() == 1 - assert Service.query.first().version == 1 - assert Service.get_history_model().query.count() == 1 + assert service_query_count() == 1 + assert service_query_first().version == 1 + assert service_history_query_count() == 1 service.name = "updated_service_name" dao_update_service(service) - assert Service.query.count() == 1 - assert Service.get_history_model().query.count() == 2 + assert service_query_count() == 1 + assert service_history_query_count() == 2 - service_from_db = Service.query.first() + service_from_db = service_query_first() assert service_from_db.version == 2 @@ -736,8 +754,8 @@ def test_update_service_permission_creates_a_history_record_with_current_data( notify_db_session, ): user = create_user() - assert Service.query.count() == 0 - assert Service.get_history_model().query.count() == 0 + assert service_query_count() == 0 + assert service_history_query_count() == 0 service = Service( name="service_name", email_from="email_from", @@ -755,17 +773,17 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ], ) - assert Service.query.count() == 1 + assert service_query_count() == 1 service.permissions.append( ServicePermission(service_id=service.id, permission=ServicePermissionType.EMAIL) ) dao_update_service(service) - assert Service.query.count() == 1 - assert Service.get_history_model().query.count() == 2 + assert service_query_count() == 1 + assert service_history_query_count() == 2 - service_from_db = Service.query.first() + service_from_db = service_query_first() assert service_from_db.version == 2 @@ -784,10 +802,10 @@ def test_update_service_permission_creates_a_history_record_with_current_data( service.permissions.remove(permission) dao_update_service(service) - assert Service.query.count() == 1 - assert Service.get_history_model().query.count() == 3 + assert service_query_count() == 1 + assert service_history_query_count() == 3 - service_from_db = Service.query.first() + service_from_db = service_query_first() assert service_from_db.version == 3 _assert_service_permissions( service.permissions, @@ -810,8 +828,8 @@ def test_update_service_permission_creates_a_history_record_with_current_data( def test_create_service_and_history_is_transactional(notify_db_session): user = create_user() - assert Service.query.count() == 0 - assert Service.get_history_model().query.count() == 0 + assert service_query_count() == 0 + assert service_history_query_count() == 0 service = Service( name=None, email_from="email_from", @@ -828,8 +846,8 @@ def test_create_service_and_history_is_transactional(notify_db_session): in str(seeei) ) - assert Service.query.count() == 0 - assert Service.get_history_model().query.count() == 0 + assert service_query_count() == 0 + assert service_history_query_count() == 0 def test_delete_service_and_associated_objects(notify_db_session): @@ -846,7 +864,8 @@ def test_delete_service_and_associated_objects(notify_db_session): create_invited_user(service=service) user.organizations = [organization] - assert ServicePermission.query.count() == len( + stmt = select(ServicePermission) + assert db.session.execute(stmt).scalar() == len( ( ServicePermissionType.SMS, ServicePermissionType.EMAIL, @@ -855,21 +874,41 @@ def test_delete_service_and_associated_objects(notify_db_session): ) delete_service_and_all_associated_db_objects(service) - assert VerifyCode.query.count() == 0 - assert ApiKey.query.count() == 0 - assert ApiKey.get_history_model().query.count() == 0 - assert Template.query.count() == 0 - assert TemplateHistory.query.count() == 0 - assert Job.query.count() == 0 - assert Notification.query.count() == 0 - assert Permission.query.count() == 0 - assert User.query.count() == 0 - assert InvitedUser.query.count() == 0 - assert Service.query.count() == 0 - assert Service.get_history_model().query.count() == 0 - assert ServicePermission.query.count() == 0 + stmt = select(VerifyCode) + assert db.session.execute(stmt).scalar() is None + stmt = select(ApiKey) + assert db.session.execute(stmt).scalar() is None + stmt = select(ApiKey.get_history_model()) + assert db.session.execute(stmt).scalar() is None + + stmt = select(Template) + assert db.session.execute(stmt).scalar() is None + + stmt = select(TemplateHistory) + assert db.session.execute(stmt).scalar() is None + + stmt = select(Job) + assert db.session.execute(stmt).scalar() is None + + stmt = select(Notification) + assert db.session.execute(stmt).scalar() is None + + stmt = select(Permission) + assert db.session.execute(stmt).scalar() is None + + stmt = select(User) + assert db.session.execute(stmt).scalar() is None + + stmt = select(InvitedUser) + assert db.session.execute(stmt).scalar() is None + stmt = select(ServicePermission) + assert db.session.execute(stmt).scalar() is None + + assert service_query_count() == 0 + assert service_history_query_count() == 0 # the organization hasn't been deleted - assert Organization.query.count() == 1 + stmt = select(Organization) + assert db.session.execute(stmt).scalar() == 1 def test_add_existing_user_to_another_service_doesnot_change_old_permissions( @@ -956,9 +995,10 @@ def test_fetch_stats_filters_on_service(notify_db_session): def test_fetch_stats_ignores_historical_notification_data(sample_template): create_notification_history(template=sample_template) - - assert Notification.query.count() == 0 - assert NotificationHistory.query.count() == 1 + stmt = select(Notification) + assert db.session.execute(stmt).scalar() is None + stmt = select(NotificationHistory) + assert db.session.execute(stmt).scalar() == 1 stats = dao_fetch_todays_stats_for_service(sample_template.service_id) assert len(stats) == 0 @@ -1316,7 +1356,7 @@ def test_dao_fetch_todays_stats_for_all_services_can_exclude_from_test_key( def test_dao_suspend_service_with_no_api_keys(notify_db_session): service = create_service() dao_suspend_service(service.id) - service = Service.query.get(service.id) + service = db.session.get(Service, service.id) assert not service.active assert service.name == service.name assert service.api_keys == [] @@ -1329,11 +1369,11 @@ def test_dao_suspend_service_marks_service_as_inactive_and_expires_api_keys( service = create_service() api_key = create_api_key(service=service) dao_suspend_service(service.id) - service = Service.query.get(service.id) + service = db.session.get(Service, service.id) assert not service.active assert service.name == service.name - api_key = ApiKey.query.get(api_key.id) + api_key = db.session.get(ApiKey, api_key.id) assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00) @@ -1344,13 +1384,13 @@ def test_dao_resume_service_marks_service_as_active_and_api_keys_are_still_revok service = create_service() api_key = create_api_key(service=service) dao_suspend_service(service.id) - service = Service.query.get(service.id) + service = db.session.get(Service, service.id) assert not service.active dao_resume_service(service.id) - assert Service.query.get(service.id).active + assert db.session.get(Service, service.id).active - api_key = ApiKey.query.get(api_key.id) + api_key = db.session.get(ApiKey, api_key.id) assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00) From 1eb46b39b1b09f44ea781c68029d6d93bc581a73 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 09:32:01 -0700 Subject: [PATCH 100/109] fix template folder dao --- tests/app/dao/test_services_dao.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 487df6a29..8640df2a5 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -315,7 +315,7 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a other_service_folder = create_template_folder(other_service) folder_permissions = [str(other_service_folder.id)] - stmt = select(ServiceUser) + stmt = select(func.count()).select_from(ServiceUser) assert db.session.execute(stmt).scalar() == 2 with pytest.raises(IntegrityError) as e: @@ -328,7 +328,7 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a 'insert or update on table "user_folder_permissions" violates foreign key constraint' in str(e.value) ) - stmt = select(ServiceUser) + stmt = select(func.count()).select_from(ServiceUser) assert db.session.execute(stmt).scalar() == 2 @@ -864,7 +864,7 @@ def test_delete_service_and_associated_objects(notify_db_session): create_invited_user(service=service) user.organizations = [organization] - stmt = select(ServicePermission) + stmt = select(func.count()).select_from(ServicePermission) assert db.session.execute(stmt).scalar() == len( ( ServicePermissionType.SMS, @@ -907,7 +907,7 @@ def test_delete_service_and_associated_objects(notify_db_session): assert service_query_count() == 0 assert service_history_query_count() == 0 # the organization hasn't been deleted - stmt = select(Organization) + stmt = select(func.count()).select_from(Organization) assert db.session.execute(stmt).scalar() == 1 @@ -997,7 +997,7 @@ def test_fetch_stats_ignores_historical_notification_data(sample_template): create_notification_history(template=sample_template) stmt = select(Notification) assert db.session.execute(stmt).scalar() is None - stmt = select(NotificationHistory) + stmt = select(func.count()).select_from(NotificationHistory) assert db.session.execute(stmt).scalar() == 1 stats = dao_fetch_todays_stats_for_service(sample_template.service_id) From ef5a45d6a255eb1b47c718708515deecca302fbb Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 10:28:44 -0700 Subject: [PATCH 101/109] fix template folder dao --- .ds.baseline | 4 +- tests/app/dao/test_services_dao.py | 67 +++++++++++++----------------- 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index 329763bf5..1a5a9727b 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 266, + "line_number": 269, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-10-14T16:21:01Z" + "generated_at": "2024-10-14T17:28:40Z" } diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 8640df2a5..c6d19c322 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -103,7 +103,8 @@ def test_create_service(notify_db_session): ) dao_create_service(service, user) assert service_query_count() == 1 - service_db = Service.query.one() + stmt = select(Service) + service_db = db.session.execute(stmt).scalars().one() assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -132,7 +133,8 @@ def test_create_service_with_organization(notify_db_session): ) dao_create_service(service, user) assert service_query_count() == 1 - service_db = Service.query.one() + stmt = select(Service) + service_db = db.session.execute(stmt).scalars().one() organization = db.session.get(Organization, organization.id) assert service_db.name == "service_name" assert service_db.id == service.id @@ -163,7 +165,8 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): ) dao_create_service(service, user) assert service_query_count() == 1 - service_db = Service.query.one() + stmt = select(Service) + service_db = db.session.execute(stmt).scalars().one() organization = db.session.get(Organization, organization.id) assert service_db.name == "service_name" assert service_db.id == service.id @@ -385,11 +388,12 @@ def test_should_remove_user_from_service_exception(notify_db_session): def test_removing_a_user_from_a_service_deletes_their_permissions( sample_user, sample_service ): - assert len(Permission.query.all()) == 7 + stmt = select(Permission) + assert len(db.session.execute(stmt).scalars().all()) == 7 dao_remove_user_from_service(sample_service, sample_user) - assert Permission.query.all() == [] + assert db.session.execute(stmt).scalars().all() == [] def test_removing_a_user_from_a_service_deletes_their_folder_permissions_for_that_service( @@ -685,7 +689,9 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses assert service_history_query_count() == 1 service_from_db = service_query_first() - service_history = Service.get_history_model().query.first() + stmt = select(Service.get_history_model()) + + service_history = db.session.execute(stmt).scalars().first() assert service_from_db.id == service_history.id assert service_from_db.name == service_history.name @@ -737,17 +743,10 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses assert service_from_db.version == 2 - assert ( - Service.get_history_model().query.filter_by(name="service_name").one().version - == 1 - ) - assert ( - Service.get_history_model() - .query.filter_by(name="updated_service_name") - .one() - .version - == 2 - ) + stmt = select(Service.get_history_model()).filter_by(name="service_name") + assert db.session.execute(stmt).scalars().one().version == 1 + stmt = select(Service.get_history_model()).filter_by(name="updated_service_name") + assert db.session.execute(stmt).scalars().one().version == 2 def test_update_service_permission_creates_a_history_record_with_current_data( @@ -815,12 +814,12 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ), ) - history = ( - Service.get_history_model() - .query.filter_by(name="service_name") + stmt = ( + select(Service.get_history_model()) + .filter_by(name="service_name") .order_by("version") - .all() ) + history = db.session.execute(stmt).scalars().all() assert len(history) == 3 assert history[2].version == 3 @@ -926,9 +925,8 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_create_service(service_one, user) assert user.id == service_one.users[0].id - test_user_permissions = Permission.query.filter_by( - service=service_one, user=user - ).all() + stmt = select(Permission).filter_by(service=service_one, user=user) + test_user_permissions = db.session.execute(stmt).scalars().all() assert len(test_user_permissions) == 7 other_user = User( @@ -948,14 +946,11 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_create_service(service_two, other_user) assert other_user.id == service_two.users[0].id - other_user_permissions = Permission.query.filter_by( - service=service_two, user=other_user - ).all() + stmt = select(Permission).filter_by(service=service_two, user=other_user) + other_user_permissions = db.session.execute(stmt).scalars().all() assert len(other_user_permissions) == 7 - - other_user_service_one_permissions = Permission.query.filter_by( - service=service_one, user=other_user - ).all() + stmt = select(Permission).filter_by(service=service_one, user=other_user) + other_user_service_one_permissions = db.session.execute(stmt).scalars().all() assert len(other_user_service_one_permissions) == 0 # adding the other_user to service_one should leave all other_user permissions on service_two intact @@ -965,14 +960,12 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_add_user_to_service(service_one, other_user, permissions=permissions) - other_user_service_one_permissions = Permission.query.filter_by( - service=service_one, user=other_user - ).all() + stmt = select(Permission).filter_by(service=service_one, user=other_user) + other_user_service_one_permissions = db.session.execute(stmt).scalars().all() assert len(other_user_service_one_permissions) == 2 - other_user_service_two_permissions = Permission.query.filter_by( - service=service_two, user=other_user - ).all() + stmt = select(Permission).filter_by(service=service_two, user=other_user) + other_user_service_two_permissions = db.session.execute(stmt).scalars().all() assert len(other_user_service_two_permissions) == 7 From 1c42508be72cdf0781939dcebb2c0a07b3098679 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 10:46:51 -0700 Subject: [PATCH 102/109] fix template folder dao --- .ds.baseline | 4 +- tests/app/dao/test_services_dao.py | 241 ++++++++++------------ tests/app/dao/test_template_folder_dao.py | 6 +- tests/app/dao/test_templates_dao.py | 67 +++--- 4 files changed, 154 insertions(+), 164 deletions(-) diff --git a/.ds.baseline b/.ds.baseline index 1a5a9727b..d8f938338 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 269, + "line_number": 265, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-10-14T17:28:40Z" + "generated_at": "2024-10-14T17:46:47Z" } diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index c6d19c322..e590eb5b4 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -6,7 +6,6 @@ from unittest.mock import Mock import pytest import sqlalchemy from freezegun import freeze_time -from sqlalchemy import func, select from sqlalchemy.exc import IntegrityError from sqlalchemy.orm.exc import NoResultFound @@ -92,7 +91,7 @@ from tests.app.db import ( def test_create_service(notify_db_session): user = create_user() - assert service_query_count() == 0 + assert Service.query.count() == 0 service = Service( name="service_name", email_from="email_from", @@ -102,9 +101,8 @@ def test_create_service(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert service_query_count() == 1 - stmt = select(Service) - service_db = db.session.execute(stmt).scalars().one() + assert Service.query.count() == 1 + service_db = Service.query.one() assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -122,7 +120,7 @@ def test_create_service_with_organization(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert service_query_count() == 0 + assert Service.query.count() == 0 service = Service( name="service_name", email_from="email_from", @@ -132,10 +130,9 @@ def test_create_service_with_organization(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert service_query_count() == 1 - stmt = select(Service) - service_db = db.session.execute(stmt).scalars().one() - organization = db.session.get(Organization, organization.id) + assert Service.query.count() == 1 + service_db = Service.query.one() + organization = Organization.query.get(organization.id) assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -154,7 +151,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): organization_type=OrganizationType.STATE, domains=["local-authority.gov.uk"], ) - assert service_query_count() == 0 + assert Service.query.count() == 0 service = Service( name="service_name", email_from="email_from", @@ -164,10 +161,9 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert service_query_count() == 1 - stmt = select(Service) - service_db = db.session.execute(stmt).scalars().one() - organization = db.session.get(Organization, organization.id) + assert Service.query.count() == 1 + service_db = Service.query.one() + organization = Organization.query.get(organization.id) assert service_db.name == "service_name" assert service_db.id == service.id assert service_db.email_from == "email_from" @@ -187,7 +183,7 @@ def test_fetch_service_by_id_with_api_keys(notify_db_session): def test_cannot_create_two_services_with_same_name(notify_db_session): user = create_user() - assert service_query_count() == 0 + assert Service.query.count() == 0 service1 = Service( name="service_name", email_from="email_from1", @@ -213,7 +209,7 @@ def test_cannot_create_two_services_with_same_name(notify_db_session): def test_cannot_create_two_services_with_same_email_from(notify_db_session): user = create_user() - assert service_query_count() == 0 + assert Service.query.count() == 0 service1 = Service( name="service_name1", email_from="email_from", @@ -239,7 +235,7 @@ def test_cannot_create_two_services_with_same_email_from(notify_db_session): def test_cannot_create_service_with_no_user(notify_db_session): user = create_user() - assert service_query_count() == 0 + assert Service.query.count() == 0 service = Service( name="service_name", email_from="email_from", @@ -262,7 +258,7 @@ def test_should_add_user_to_service(notify_db_session): created_by=user, ) dao_create_service(service, user) - assert user in service_query_first().users + assert user in Service.query.first().users new_user = User( name="Test User", email_address="new_user@digital.fake.gov", @@ -271,7 +267,7 @@ def test_should_add_user_to_service(notify_db_session): ) save_model_user(new_user, validated_email_access=True) dao_add_user_to_service(service, new_user) - assert new_user in service_query_first().users + assert new_user in Service.query.first().users def test_dao_add_user_to_service_sets_folder_permissions(sample_user, sample_service): @@ -318,8 +314,7 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a other_service_folder = create_template_folder(other_service) folder_permissions = [str(other_service_folder.id)] - stmt = select(func.count()).select_from(ServiceUser) - assert db.session.execute(stmt).scalar() == 2 + assert ServiceUser.query.count() == 2 with pytest.raises(IntegrityError) as e: dao_add_user_to_service( @@ -331,8 +326,7 @@ def test_dao_add_user_to_service_raises_error_if_adding_folder_permissions_for_a 'insert or update on table "user_folder_permissions" violates foreign key constraint' in str(e.value) ) - stmt = select(func.count()).select_from(ServiceUser) - assert db.session.execute(stmt).scalar() == 2 + assert ServiceUser.query.count() == 2 def test_should_remove_user_from_service(notify_db_session): @@ -353,9 +347,9 @@ def test_should_remove_user_from_service(notify_db_session): ) save_model_user(new_user, validated_email_access=True) dao_add_user_to_service(service, new_user) - assert new_user in service_query_first().users + assert new_user in Service.query.first().users dao_remove_user_from_service(service, new_user) - assert new_user not in service_query_first().users + assert new_user not in Service.query.first().users def test_should_remove_user_from_service_exception(notify_db_session): @@ -388,12 +382,11 @@ def test_should_remove_user_from_service_exception(notify_db_session): def test_removing_a_user_from_a_service_deletes_their_permissions( sample_user, sample_service ): - stmt = select(Permission) - assert len(db.session.execute(stmt).scalars().all()) == 7 + assert len(Permission.query.all()) == 7 dao_remove_user_from_service(sample_service, sample_user) - assert db.session.execute(stmt).scalars().all() == [] + assert Permission.query.all() == [] def test_removing_a_user_from_a_service_deletes_their_folder_permissions_for_that_service( @@ -675,8 +668,8 @@ def test_removing_all_permission_returns_service_with_no_permissions(notify_db_s def test_create_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert service_query_count() == 0 - assert service_history_query_count() == 0 + assert Service.query.count() == 0 + assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", email_from="email_from", @@ -685,13 +678,11 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses created_by=user, ) dao_create_service(service, user) - assert service_query_count() == 1 - assert service_history_query_count() == 1 + assert Service.query.count() == 1 + assert Service.get_history_model().query.count() == 1 - service_from_db = service_query_first() - stmt = select(Service.get_history_model()) - - service_history = db.session.execute(stmt).scalars().first() + service_from_db = Service.query.first() + service_history = Service.get_history_model().query.first() assert service_from_db.id == service_history.id assert service_from_db.name == service_history.name @@ -701,25 +692,10 @@ def test_create_service_creates_a_history_record_with_current_data(notify_db_ses assert service_from_db.created_by.id == service_history.created_by_id -def service_query_count(): - stmt = select(func.count()).select_from(Service) - return db.session.execute(stmt).scalar() or 0 - - -def service_query_first(): - stmt = select(Service) - return db.session.execute(stmt).scalars().first() - - -def service_history_query_count(): - stmt = select(func.count()).select_from(Service.get_history_model()) - return db.session.execute(stmt).scalar() or 0 - - def test_update_service_creates_a_history_record_with_current_data(notify_db_session): user = create_user() - assert service_query_count() == 0 - assert service_history_query_count() == 0 + assert Service.query.count() == 0 + assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", email_from="email_from", @@ -729,32 +705,39 @@ def test_update_service_creates_a_history_record_with_current_data(notify_db_ses ) dao_create_service(service, user) - assert service_query_count() == 1 - assert service_query_first().version == 1 - assert service_history_query_count() == 1 + assert Service.query.count() == 1 + assert Service.query.first().version == 1 + assert Service.get_history_model().query.count() == 1 service.name = "updated_service_name" dao_update_service(service) - assert service_query_count() == 1 - assert service_history_query_count() == 2 + assert Service.query.count() == 1 + assert Service.get_history_model().query.count() == 2 - service_from_db = service_query_first() + service_from_db = Service.query.first() assert service_from_db.version == 2 - stmt = select(Service.get_history_model()).filter_by(name="service_name") - assert db.session.execute(stmt).scalars().one().version == 1 - stmt = select(Service.get_history_model()).filter_by(name="updated_service_name") - assert db.session.execute(stmt).scalars().one().version == 2 + assert ( + Service.get_history_model().query.filter_by(name="service_name").one().version + == 1 + ) + assert ( + Service.get_history_model() + .query.filter_by(name="updated_service_name") + .one() + .version + == 2 + ) def test_update_service_permission_creates_a_history_record_with_current_data( notify_db_session, ): user = create_user() - assert service_query_count() == 0 - assert service_history_query_count() == 0 + assert Service.query.count() == 0 + assert Service.get_history_model().query.count() == 0 service = Service( name="service_name", email_from="email_from", @@ -772,17 +755,17 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ], ) - assert service_query_count() == 1 + assert Service.query.count() == 1 service.permissions.append( ServicePermission(service_id=service.id, permission=ServicePermissionType.EMAIL) ) dao_update_service(service) - assert service_query_count() == 1 - assert service_history_query_count() == 2 + assert Service.query.count() == 1 + assert Service.get_history_model().query.count() == 2 - service_from_db = service_query_first() + service_from_db = Service.query.first() assert service_from_db.version == 2 @@ -801,10 +784,10 @@ def test_update_service_permission_creates_a_history_record_with_current_data( service.permissions.remove(permission) dao_update_service(service) - assert service_query_count() == 1 - assert service_history_query_count() == 3 + assert Service.query.count() == 1 + assert Service.get_history_model().query.count() == 3 - service_from_db = service_query_first() + service_from_db = Service.query.first() assert service_from_db.version == 3 _assert_service_permissions( service.permissions, @@ -814,12 +797,12 @@ def test_update_service_permission_creates_a_history_record_with_current_data( ), ) - stmt = ( - select(Service.get_history_model()) - .filter_by(name="service_name") + history = ( + Service.get_history_model() + .query.filter_by(name="service_name") .order_by("version") + .all() ) - history = db.session.execute(stmt).scalars().all() assert len(history) == 3 assert history[2].version == 3 @@ -827,8 +810,8 @@ def test_update_service_permission_creates_a_history_record_with_current_data( def test_create_service_and_history_is_transactional(notify_db_session): user = create_user() - assert service_query_count() == 0 - assert service_history_query_count() == 0 + assert Service.query.count() == 0 + assert Service.get_history_model().query.count() == 0 service = Service( name=None, email_from="email_from", @@ -845,8 +828,8 @@ def test_create_service_and_history_is_transactional(notify_db_session): in str(seeei) ) - assert service_query_count() == 0 - assert service_history_query_count() == 0 + assert Service.query.count() == 0 + assert Service.get_history_model().query.count() == 0 def test_delete_service_and_associated_objects(notify_db_session): @@ -863,8 +846,7 @@ def test_delete_service_and_associated_objects(notify_db_session): create_invited_user(service=service) user.organizations = [organization] - stmt = select(func.count()).select_from(ServicePermission) - assert db.session.execute(stmt).scalar() == len( + assert ServicePermission.query.count() == len( ( ServicePermissionType.SMS, ServicePermissionType.EMAIL, @@ -873,41 +855,21 @@ def test_delete_service_and_associated_objects(notify_db_session): ) delete_service_and_all_associated_db_objects(service) - stmt = select(VerifyCode) - assert db.session.execute(stmt).scalar() is None - stmt = select(ApiKey) - assert db.session.execute(stmt).scalar() is None - stmt = select(ApiKey.get_history_model()) - assert db.session.execute(stmt).scalar() is None - - stmt = select(Template) - assert db.session.execute(stmt).scalar() is None - - stmt = select(TemplateHistory) - assert db.session.execute(stmt).scalar() is None - - stmt = select(Job) - assert db.session.execute(stmt).scalar() is None - - stmt = select(Notification) - assert db.session.execute(stmt).scalar() is None - - stmt = select(Permission) - assert db.session.execute(stmt).scalar() is None - - stmt = select(User) - assert db.session.execute(stmt).scalar() is None - - stmt = select(InvitedUser) - assert db.session.execute(stmt).scalar() is None - stmt = select(ServicePermission) - assert db.session.execute(stmt).scalar() is None - - assert service_query_count() == 0 - assert service_history_query_count() == 0 + assert VerifyCode.query.count() == 0 + assert ApiKey.query.count() == 0 + assert ApiKey.get_history_model().query.count() == 0 + assert Template.query.count() == 0 + assert TemplateHistory.query.count() == 0 + assert Job.query.count() == 0 + assert Notification.query.count() == 0 + assert Permission.query.count() == 0 + assert User.query.count() == 0 + assert InvitedUser.query.count() == 0 + assert Service.query.count() == 0 + assert Service.get_history_model().query.count() == 0 + assert ServicePermission.query.count() == 0 # the organization hasn't been deleted - stmt = select(func.count()).select_from(Organization) - assert db.session.execute(stmt).scalar() == 1 + assert Organization.query.count() == 1 def test_add_existing_user_to_another_service_doesnot_change_old_permissions( @@ -925,8 +887,9 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_create_service(service_one, user) assert user.id == service_one.users[0].id - stmt = select(Permission).filter_by(service=service_one, user=user) - test_user_permissions = db.session.execute(stmt).scalars().all() + test_user_permissions = Permission.query.filter_by( + service=service_one, user=user + ).all() assert len(test_user_permissions) == 7 other_user = User( @@ -946,11 +909,14 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_create_service(service_two, other_user) assert other_user.id == service_two.users[0].id - stmt = select(Permission).filter_by(service=service_two, user=other_user) - other_user_permissions = db.session.execute(stmt).scalars().all() + other_user_permissions = Permission.query.filter_by( + service=service_two, user=other_user + ).all() assert len(other_user_permissions) == 7 - stmt = select(Permission).filter_by(service=service_one, user=other_user) - other_user_service_one_permissions = db.session.execute(stmt).scalars().all() + + other_user_service_one_permissions = Permission.query.filter_by( + service=service_one, user=other_user + ).all() assert len(other_user_service_one_permissions) == 0 # adding the other_user to service_one should leave all other_user permissions on service_two intact @@ -960,12 +926,14 @@ def test_add_existing_user_to_another_service_doesnot_change_old_permissions( dao_add_user_to_service(service_one, other_user, permissions=permissions) - stmt = select(Permission).filter_by(service=service_one, user=other_user) - other_user_service_one_permissions = db.session.execute(stmt).scalars().all() + other_user_service_one_permissions = Permission.query.filter_by( + service=service_one, user=other_user + ).all() assert len(other_user_service_one_permissions) == 2 - stmt = select(Permission).filter_by(service=service_two, user=other_user) - other_user_service_two_permissions = db.session.execute(stmt).scalars().all() + other_user_service_two_permissions = Permission.query.filter_by( + service=service_two, user=other_user + ).all() assert len(other_user_service_two_permissions) == 7 @@ -988,10 +956,9 @@ def test_fetch_stats_filters_on_service(notify_db_session): def test_fetch_stats_ignores_historical_notification_data(sample_template): create_notification_history(template=sample_template) - stmt = select(Notification) - assert db.session.execute(stmt).scalar() is None - stmt = select(func.count()).select_from(NotificationHistory) - assert db.session.execute(stmt).scalar() == 1 + + assert Notification.query.count() == 0 + assert NotificationHistory.query.count() == 1 stats = dao_fetch_todays_stats_for_service(sample_template.service_id) assert len(stats) == 0 @@ -1349,7 +1316,7 @@ def test_dao_fetch_todays_stats_for_all_services_can_exclude_from_test_key( def test_dao_suspend_service_with_no_api_keys(notify_db_session): service = create_service() dao_suspend_service(service.id) - service = db.session.get(Service, service.id) + service = Service.query.get(service.id) assert not service.active assert service.name == service.name assert service.api_keys == [] @@ -1362,11 +1329,11 @@ def test_dao_suspend_service_marks_service_as_inactive_and_expires_api_keys( service = create_service() api_key = create_api_key(service=service) dao_suspend_service(service.id) - service = db.session.get(Service, service.id) + service = Service.query.get(service.id) assert not service.active assert service.name == service.name - api_key = db.session.get(ApiKey, api_key.id) + api_key = ApiKey.query.get(api_key.id) assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00) @@ -1377,13 +1344,13 @@ def test_dao_resume_service_marks_service_as_active_and_api_keys_are_still_revok service = create_service() api_key = create_api_key(service=service) dao_suspend_service(service.id) - service = db.session.get(Service, service.id) + service = Service.query.get(service.id) assert not service.active dao_resume_service(service.id) - assert db.session.get(Service, service.id).active + assert Service.query.get(service.id).active - api_key = db.session.get(ApiKey, api_key.id) + api_key = ApiKey.query.get(api_key.id) assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00) diff --git a/tests/app/dao/test_template_folder_dao.py b/tests/app/dao/test_template_folder_dao.py index 17b03e5df..2a872e775 100644 --- a/tests/app/dao/test_template_folder_dao.py +++ b/tests/app/dao/test_template_folder_dao.py @@ -1,3 +1,5 @@ +from sqlalchemy import select + from app import db from app.dao.service_user_dao import dao_get_service_user from app.dao.template_folder_dao import ( @@ -17,5 +19,5 @@ def test_dao_delete_template_folder_deletes_user_folder_permissions( dao_update_template_folder(folder) dao_delete_template_folder(folder) - - assert db.session.query(user_folder_permissions).all() == [] + stmt = select(user_folder_permissions) + assert db.session.execute(stmt).scalars().all() == [] diff --git a/tests/app/dao/test_templates_dao.py b/tests/app/dao/test_templates_dao.py index bfe0e59d1..8da454d30 100644 --- a/tests/app/dao/test_templates_dao.py +++ b/tests/app/dao/test_templates_dao.py @@ -2,8 +2,10 @@ from datetime import datetime import pytest from freezegun import freeze_time +from sqlalchemy import func, select from sqlalchemy.orm.exc import NoResultFound +from app import db from app.dao.templates_dao import ( dao_create_template, dao_get_all_templates_for_service, @@ -17,6 +19,16 @@ from app.models import Template, TemplateHistory, TemplateRedacted from tests.app.db import create_template +def template_query_count(): + stmt = select(func.count()).select_from(Template) + return db.session.execute(stmt).scalar or 0 + + +def template_history_query_count(): + stmt = select(func.count()).select_from(TemplateHistory) + return db.session.execute(stmt).scalar or 0 + + @pytest.mark.parametrize( "template_type, subject", [ @@ -37,7 +49,7 @@ def test_create_template(sample_service, sample_user, template_type, subject): template = Template(**data) dao_create_template(template) - assert Template.query.count() == 1 + assert template_query_count() == 1 assert len(dao_get_all_templates_for_service(sample_service.id)) == 1 assert ( dao_get_all_templates_for_service(sample_service.id)[0].name @@ -50,11 +62,13 @@ def test_create_template(sample_service, sample_user, template_type, subject): def test_create_template_creates_redact_entry(sample_service): - assert TemplateRedacted.query.count() == 0 + stmt = select(func.count()).select_from(TemplateRedacted) + assert db.session.execute(stmt).scalar() is None template = create_template(sample_service) - redacted = TemplateRedacted.query.one() + stmt = select(TemplateRedacted) + redacted = db.session.execute(stmt).scalars().one() assert redacted.template_id == template.id assert redacted.redact_personalisation is False assert redacted.updated_by_id == sample_service.created_by_id @@ -79,7 +93,8 @@ def test_update_template(sample_service, sample_user): def test_redact_template(sample_template): - redacted = TemplateRedacted.query.one() + stmt = select(TemplateRedacted) + redacted = db.session.execute(stmt).scalars().one() assert redacted.template_id == sample_template.id assert redacted.redact_personalisation is False @@ -96,7 +111,7 @@ def test_get_all_templates_for_service(service_factory): service_1 = service_factory.get("service 1", email_from="service.1") service_2 = service_factory.get("service 2", email_from="service.2") - assert Template.query.count() == 2 + assert template_query_count() == 2 assert len(dao_get_all_templates_for_service(service_1.id)) == 1 assert len(dao_get_all_templates_for_service(service_2.id)) == 1 @@ -119,7 +134,7 @@ def test_get_all_templates_for_service(service_factory): content="Template content", ) - assert Template.query.count() == 5 + assert template_query_count() == 5 assert len(dao_get_all_templates_for_service(service_1.id)) == 3 assert len(dao_get_all_templates_for_service(service_2.id)) == 2 @@ -144,7 +159,7 @@ def test_get_all_templates_for_service_is_alphabetised(sample_service): service=sample_service, ) - assert Template.query.count() == 3 + assert template_query_count() == 3 assert ( dao_get_all_templates_for_service(sample_service.id)[0].name == "Sample Template 1" @@ -171,7 +186,7 @@ def test_get_all_templates_for_service_is_alphabetised(sample_service): def test_get_all_returns_empty_list_if_no_templates(sample_service): - assert Template.query.count() == 0 + assert template_query_count() == 0 assert len(dao_get_all_templates_for_service(sample_service.id)) == 0 @@ -257,8 +272,8 @@ def test_get_template_by_id_and_service_returns_none_if_no_template( def test_create_template_creates_a_history_record_with_current_data( sample_service, sample_user ): - assert Template.query.count() == 0 - assert TemplateHistory.query.count() == 0 + assert template_query_count() == 0 + assert template_history_query_count() == 0 data = { "name": "Sample Template", "template_type": TemplateType.EMAIL, @@ -270,10 +285,12 @@ def test_create_template_creates_a_history_record_with_current_data( template = Template(**data) dao_create_template(template) - assert Template.query.count() == 1 + assert template_query_count() == 1 - template_from_db = Template.query.first() - template_history = TemplateHistory.query.first() + stmt = select(Template) + template_from_db = db.session.execute(stmt).scalars().first() + stmt = select(TemplateHistory) + template_history = db.session.execute(stmt).scalars().first() assert template_from_db.id == template_history.id assert template_from_db.name == template_history.name @@ -286,8 +303,8 @@ def test_create_template_creates_a_history_record_with_current_data( def test_update_template_creates_a_history_record_with_current_data( sample_service, sample_user ): - assert Template.query.count() == 0 - assert TemplateHistory.query.count() == 0 + assert template_query_count() == 0 + assert template_history_query_count() == 0 data = { "name": "Sample Template", "template_type": TemplateType.EMAIL, @@ -301,22 +318,26 @@ def test_update_template_creates_a_history_record_with_current_data( created = dao_get_all_templates_for_service(sample_service.id)[0] assert created.name == "Sample Template" - assert Template.query.count() == 1 - assert Template.query.first().version == 1 - assert TemplateHistory.query.count() == 1 + assert template_query_count() == 1 + stmt = select(Template) + assert db.session.execute(stmt).scalars().first().version == 1 + assert template_history_query_count() == 1 created.name = "new name" dao_update_template(created) - assert Template.query.count() == 1 - assert TemplateHistory.query.count() == 2 + assert template_query_count() == 1 + assert template_history_query_count() == 2 - template_from_db = Template.query.first() + stmt = select(Template) + template_from_db = db.session.execute(stmt).scalars().first() assert template_from_db.version == 2 - assert TemplateHistory.query.filter_by(name="Sample Template").one().version == 1 - assert TemplateHistory.query.filter_by(name="new name").one().version == 2 + stmt = select(TemplateHistory).filter_by(name="Sample Template") + assert db.session.execute(stmt).scalars().one().version == 1 + stmt = select(TemplateHistory).filter_by(name="new name") + assert db.session.execute(stmt).scalars().one().version == 2 def test_get_template_history_version(sample_user, sample_service, sample_template): From 758e12c901e77e9f0884824ff031e040b0273969 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 10:55:10 -0700 Subject: [PATCH 103/109] fix template folder dao --- tests/app/dao/test_templates_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/dao/test_templates_dao.py b/tests/app/dao/test_templates_dao.py index 8da454d30..5fe603a64 100644 --- a/tests/app/dao/test_templates_dao.py +++ b/tests/app/dao/test_templates_dao.py @@ -21,12 +21,12 @@ from tests.app.db import create_template def template_query_count(): stmt = select(func.count()).select_from(Template) - return db.session.execute(stmt).scalar or 0 + return db.session.execute(stmt).scalar() or 0 def template_history_query_count(): stmt = select(func.count()).select_from(TemplateHistory) - return db.session.execute(stmt).scalar or 0 + return db.session.execute(stmt).scalar() or 0 @pytest.mark.parametrize( From 4a7e4c79a83d5fdcea353cb5ff782666f43c0c56 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 14 Oct 2024 11:03:17 -0700 Subject: [PATCH 104/109] fix template folder dao --- tests/app/dao/test_templates_dao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/dao/test_templates_dao.py b/tests/app/dao/test_templates_dao.py index 5fe603a64..734a29c0a 100644 --- a/tests/app/dao/test_templates_dao.py +++ b/tests/app/dao/test_templates_dao.py @@ -63,7 +63,7 @@ def test_create_template(sample_service, sample_user, template_type, subject): def test_create_template_creates_redact_entry(sample_service): stmt = select(func.count()).select_from(TemplateRedacted) - assert db.session.execute(stmt).scalar() is None + assert db.session.execute(stmt).scalar() == 0 template = create_template(sample_service) From 261ea6fe8f6fc17eec227b557c90264cbffeba72 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 21 Oct 2024 10:32:28 -0700 Subject: [PATCH 105/109] fix commented out code --- migrations/versions/0044_jobs_to_notification_hist.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/migrations/versions/0044_jobs_to_notification_hist.py b/migrations/versions/0044_jobs_to_notification_hist.py index e813833b4..3312d9a49 100644 --- a/migrations/versions/0044_jobs_to_notification_hist.py +++ b/migrations/versions/0044_jobs_to_notification_hist.py @@ -31,10 +31,10 @@ def upgrade(): # # go_live = datetime.datetime.strptime('2016-05-18', '%Y-%m-%d') # notifications_history_start_date = datetime.datetime.strptime('2016-06-26 23:21:55', '%Y-%m-%d %H:%M:%S') - # jobs = session.query(Job).join(Template).filter(Job.service_id == '95316ff0-e555-462d-a6e7-95d26fbfd091', + # stmt = select(Job).join(Template).filter(Job.service_id == '95316ff0-e555-462d-a6e7-95d26fbfd091', # Job.created_at >= go_live, # Job.created_at < notifications_history_start_date).all() - # + # jobs = db.session.execute(stmt).scalars().all() # for job in jobs: # for i in range(0, job.notifications_delivered): # notification = NotificationHistory(id=uuid.uuid4(), @@ -76,12 +76,11 @@ def downgrade(): # # go_live = datetime.datetime.strptime('2016-05-18', '%Y-%m-%d') # notifications_history_start_date = datetime.datetime.strptime('2016-06-26 23:21:55', '%Y-%m-%d %H:%M:%S') - # - # session.query(NotificationHistory).filter( + # stmt = delete(NotificationHistory).where( # NotificationHistory.created_at >= go_live, # NotificationHistory.service_id == '95316ff0-e555-462d-a6e7-95d26fbfd091', - # NotificationHistory.created_at < notifications_history_start_date).delete() - # + # NotificationHistory.created_at < notifications_history_start_date) + # session.execute(stmt) # session.commit() # ### end Alembic commands ### pass From d5cc8b239f7d6b5e46f4067a2edfc2d6b3956ec6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 26 Oct 2024 00:08:57 +0000 Subject: [PATCH 106/109] Bump werkzeug from 3.0.3 to 3.0.6 Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.3 to 3.0.6. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/werkzeug/compare/3.0.3...3.0.6) --- updated-dependencies: - dependency-name: werkzeug dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 60ce4d0ae..dcdb5290b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4519,13 +4519,13 @@ test = ["websockets"] [[package]] name = "werkzeug" -version = "3.0.3" +version = "3.0.6" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.8" files = [ - {file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"}, - {file = "werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18"}, + {file = "werkzeug-3.0.6-py3-none-any.whl", hash = "sha256:1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17"}, + {file = "werkzeug-3.0.6.tar.gz", hash = "sha256:a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d"}, ] [package.dependencies] @@ -4803,4 +4803,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.12.2" -content-hash = "42172a923e16c5b0965ab06f717d41e8491ee35f7be674091b38014c48b7a89e" +content-hash = "cf18ae74630e47eec18cc6c5fea9e554476809d20589d82c54a8d761bb2c3de0" diff --git a/pyproject.toml b/pyproject.toml index 3e3a78aed..99858c09e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ psycopg2-binary = "==2.9.9" pyjwt = "==2.8.0" python-dotenv = "==1.0.1" sqlalchemy = "==2.0.31" -werkzeug = "^3.0.3" +werkzeug = "^3.0.6" faker = "^26.0.0" async-timeout = "^4.0.3" bleach = "^6.1.0" From a9385107b033541a727c837567dbff0cea53de93 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 28 Oct 2024 12:50:11 -0700 Subject: [PATCH 107/109] code review feedback --- app/dao/notifications_dao.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 8659fca9b..1d07473c1 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -629,7 +629,6 @@ def notifications_not_yet_sent(should_be_sending_after_seconds, notification_typ Notification.status == NotificationStatus.CREATED, ) notifications = db.session.execute(stmt).scalars().all() - print(f"WE RETURN THIS FOR NOTIFICATIONS {notifications}") return notifications From 829d9020d8716e0874068bfe66bb3b42a251efd9 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 28 Oct 2024 13:03:50 -0700 Subject: [PATCH 108/109] code review feedback --- app/dao/organization_dao.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/dao/organization_dao.py b/app/dao/organization_dao.py index f699e33bc..668ac6c25 100644 --- a/app/dao/organization_dao.py +++ b/app/dao/organization_dao.py @@ -23,7 +23,6 @@ def dao_count_organizations_with_live_services(): Service.count_as_live.is_(True), ) ) - # TODO Need distinct here? return db.session.execute(stmt).scalar() or 0 From 9638e2b4f079f5fa91a924195c3cc0813dcb63e2 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 28 Oct 2024 13:20:51 -0700 Subject: [PATCH 109/109] code review feedback --- app/dao/service_permissions_dao.py | 9 - app/dao/service_sms_sender_dao.py | 9 +- app/dao/service_user_dao.py | 13 -- app/dao/services_dao.py | 255 +---------------------------- 4 files changed, 4 insertions(+), 282 deletions(-) diff --git a/app/dao/service_permissions_dao.py b/app/dao/service_permissions_dao.py index 95a40c903..0793b35b6 100644 --- a/app/dao/service_permissions_dao.py +++ b/app/dao/service_permissions_dao.py @@ -6,9 +6,6 @@ from app.models import ServicePermission def dao_fetch_service_permissions(service_id): - # return ServicePermission.query.filter( - # ServicePermission.service_id == service_id - # ).all() stmt = select(ServicePermission).filter(ServicePermission.service_id == service_id) return db.session.execute(stmt).scalars().all() @@ -21,12 +18,6 @@ def dao_add_service_permission(service_id, permission): def dao_remove_service_permission(service_id, permission): - # deleted = ServicePermission.query.filter( - # ServicePermission.service_id == service_id, - # ServicePermission.permission == permission, - # ).delete() - # db.session.commit() - # return deleted stmt = delete(ServicePermission).where( ServicePermission.service_id == service_id, diff --git a/app/dao/service_sms_sender_dao.py b/app/dao/service_sms_sender_dao.py index df0f2a3e9..82796b05f 100644 --- a/app/dao/service_sms_sender_dao.py +++ b/app/dao/service_sms_sender_dao.py @@ -17,9 +17,6 @@ def insert_service_sms_sender(service, sms_sender): def dao_get_service_sms_senders_by_id(service_id, service_sms_sender_id): - # return ServiceSmsSender.query.filter_by( - # id=service_sms_sender_id, service_id=service_id, archived=False - # ).one() stmt = select(ServiceSmsSender).filter_by( id=service_sms_sender_id, service_id=service_id, archived=False ) @@ -27,11 +24,7 @@ def dao_get_service_sms_senders_by_id(service_id, service_sms_sender_id): def dao_get_sms_senders_by_service_id(service_id): - # return ( - # ServiceSmsSender.query.filter_by(service_id=service_id, archived=False) - # .order_by(desc(ServiceSmsSender.is_default)) - # .all() - # ) + stmt = ( select(ServiceSmsSender) .filter_by(service_id=service_id, archived=False) diff --git a/app/dao/service_user_dao.py b/app/dao/service_user_dao.py index b02005a3f..d60c92ba6 100644 --- a/app/dao/service_user_dao.py +++ b/app/dao/service_user_dao.py @@ -6,24 +6,11 @@ from app.models import ServiceUser, User def dao_get_service_user(user_id, service_id): - # TODO: This has been changed to account for the test case failure - # that used this method but have any service user to return. Somehow, this - # started to throw an error with one() method in sqlalchemy 2.0 unlike 1.4 - # return ServiceUser.query.filter_by( - # user_id=user_id, service_id=service_id - # ).one_or_none() stmt = select(ServiceUser).filter_by(user_id=user_id, service_id=service_id) return db.session.execute(stmt).scalars().one_or_none() def dao_get_active_service_users(service_id): - # query = ( - # db.session.query(ServiceUser) - # .join(User, User.id == ServiceUser.user_id) - # .filter(User.state == "active", ServiceUser.service_id == service_id) - # ) - - # return query.all() stmt = ( select(ServiceUser) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 585fe83b1..1f8956865 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -85,88 +85,6 @@ def dao_count_live_services(): def dao_fetch_live_services_data(): year_start_date, year_end_date = get_current_calendar_year() - # most_recent_annual_billing = ( - # db.session.query( - # AnnualBilling.service_id, - # func.max(AnnualBilling.financial_year_start).label("year"), - # ) - # .group_by(AnnualBilling.service_id) - # .subquery() - # ) - - # this_year_ft_billing = FactBilling.query.filter( - # FactBilling.local_date >= year_start_date, - # FactBilling.local_date <= year_end_date, - # ).subquery() - - # data = ( - # db.session.query( - # Service.id.label("service_id"), - # Service.name.label("service_name"), - # Organization.name.label("organization_name"), - # Organization.organization_type.label("organization_type"), - # Service.consent_to_research.label("consent_to_research"), - # User.name.label("contact_name"), - # User.email_address.label("contact_email"), - # User.mobile_number.label("contact_mobile"), - # Service.go_live_at.label("live_date"), - # Service.volume_sms.label("sms_volume_intent"), - # Service.volume_email.label("email_volume_intent"), - # case( - # ( - # this_year_ft_billing.c.notification_type == NotificationType.EMAIL, - # func.sum(this_year_ft_billing.c.notifications_sent), - # ), - # else_=0, - # ).label("email_totals"), - # case( - # ( - # this_year_ft_billing.c.notification_type == NotificationType.SMS, - # func.sum(this_year_ft_billing.c.notifications_sent), - # ), - # else_=0, - # ).label("sms_totals"), - # AnnualBilling.free_sms_fragment_limit, - # ) - # .join(Service.annual_billing) - # .join( - # most_recent_annual_billing, - # and_( - # Service.id == most_recent_annual_billing.c.service_id, - # AnnualBilling.financial_year_start == most_recent_annual_billing.c.year, - # ), - # ) - # .outerjoin(Service.organization) - # .outerjoin( - # this_year_ft_billing, Service.id == this_year_ft_billing.c.service_id - # ) - # .outerjoin(User, Service.go_live_user_id == User.id) - # .filter( - # Service.count_as_live.is_(True), - # Service.active.is_(True), - # Service.restricted.is_(False), - # ) - # .group_by( - # Service.id, - # Organization.name, - # Organization.organization_type, - # Service.name, - # Service.consent_to_research, - # Service.count_as_live, - # Service.go_live_user_id, - # User.name, - # User.email_address, - # User.mobile_number, - # Service.go_live_at, - # Service.volume_sms, - # Service.volume_email, - # this_year_ft_billing.c.notification_type, - # AnnualBilling.free_sms_fragment_limit, - # ) - # .order_by(asc(Service.go_live_at)) - # .all() - # ) - most_recent_annual_billing = ( select( AnnualBilling.service_id, @@ -297,12 +215,6 @@ def dao_fetch_service_by_inbound_number(number): def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): - # query = Service.query.filter_by(id=service_id).options(joinedload(Service.api_keys)) - - # if only_active: - # query = query.filter(Service.active) - - # return query.one() stmt = ( select(Service).filter_by(id=service_id).options(joinedload(Service.api_keys)) ) @@ -312,16 +224,6 @@ def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): def dao_fetch_all_services_by_user(user_id, only_active=False): - # query = ( - # Service.query.filter(Service.users.any(id=user_id)) - # .order_by(asc(Service.created_at)) - # .options(joinedload(Service.users)) - # ) - - # if only_active: - # query = query.filter(Service.active) - - # return query.all() stmt = ( select(Service) @@ -336,12 +238,6 @@ def dao_fetch_all_services_by_user(user_id, only_active=False): def dao_fetch_all_services_created_by_user(user_id): - # query = Service.query.filter_by(created_by_id=user_id).order_by( - # asc(Service.created_at) - # ) - - # return query.all() - stmt = ( select(Service) .filter_by(created_by_id=user_id) @@ -358,16 +254,6 @@ def dao_fetch_all_services_created_by_user(user_id): VersionOptions(Template, history_class=TemplateHistory, must_write_history=False), ) def dao_archive_service(service_id): - # have to eager load templates and api keys so that we don't flush when we loop through them - # to ensure that db.session still contains the models when it comes to creating history objects - # service = ( - # Service.query.options( - # joinedload(Service.templates).subqueryload(Template.template_redacted), - # joinedload(Service.api_keys), - # ) - # .filter(Service.id == service_id) - # .one() - # ) stmt = ( select(Service) .options( @@ -392,11 +278,6 @@ def dao_archive_service(service_id): def dao_fetch_service_by_id_and_user(service_id, user_id): - # return ( - # Service.query.filter(Service.users.any(id=user_id), Service.id == service_id) - # .options(joinedload(Service.users)) - # .one() - # ) stmt = ( select(Service) @@ -508,11 +389,9 @@ def dao_remove_user_from_service(service, user): def delete_service_and_all_associated_db_objects(service): def _delete_commit(stmt): - # query.delete(synchronize_session=False) db.session.execute(stmt) db.session.commit() - # subq = db.session.query(Template.id).filter_by(service=service).subquery() subq = select(Template.id).filter_by(service=service).subquery() stmt = delete(TemplateRedacted).filter(TemplateRedacted.template_id.in_(subq)) @@ -553,23 +432,6 @@ def delete_service_and_all_associated_db_objects(service): def dao_fetch_todays_stats_for_service(service_id): today = utc_now().date() start_date = get_midnight_in_utc(today) - # return ( - # db.session.query( - # Notification.notification_type, - # Notification.status, - # func.count(Notification.id).label("count"), - # ) - # .filter( - # Notification.service_id == service_id, - # Notification.key_type != KeyType.TEST, - # Notification.created_at >= start_date, - # ) - # .group_by( - # Notification.notification_type, - # Notification.status, - # ) - # .all() - # ) stmt = ( select( Notification.notification_type, @@ -593,27 +455,6 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): start_date = get_midnight_in_utc(start_date) end_date = get_midnight_in_utc(end_date + timedelta(days=1)) - # return ( - # db.session.query( - # NotificationAllTimeView.notification_type, - # NotificationAllTimeView.status, - # func.date_trunc("day", NotificationAllTimeView.created_at).label("day"), - # func.count(NotificationAllTimeView.id).label("count"), - # ) - # .filter( - # NotificationAllTimeView.service_id == service_id, - # NotificationAllTimeView.key_type != KeyType.TEST, - # NotificationAllTimeView.created_at >= start_date, - # NotificationAllTimeView.created_at < end_date, - # ) - # .group_by( - # NotificationAllTimeView.notification_type, - # NotificationAllTimeView.status, - # func.date_trunc("day", NotificationAllTimeView.created_at), - # ) - # .all() - # ) - stmt = ( select( NotificationAllTimeView.notification_type, @@ -642,27 +483,6 @@ def dao_fetch_stats_for_service_from_days_for_user( start_date = get_midnight_in_utc(start_date) end_date = get_midnight_in_utc(end_date + timedelta(days=1)) - # return ( - # db.session.query( - # NotificationAllTimeView.notification_type, - # NotificationAllTimeView.status, - # func.date_trunc("day", NotificationAllTimeView.created_at).label("day"), - # func.count(NotificationAllTimeView.id).label("count"), - # ) - # .filter( - # NotificationAllTimeView.service_id == service_id, - # NotificationAllTimeView.key_type != KeyType.TEST, - # NotificationAllTimeView.created_at >= start_date, - # NotificationAllTimeView.created_at < end_date, - # NotificationAllTimeView.created_by_id == user_id, - # ) - # .group_by( - # NotificationAllTimeView.notification_type, - # NotificationAllTimeView.status, - # func.date_trunc("day", NotificationAllTimeView.created_at), - # ) - # .all() - # ) stmt = ( select( NotificationAllTimeView.notification_type, @@ -741,15 +561,7 @@ def dao_fetch_todays_stats_for_all_services( VersionOptions(Service), ) def dao_suspend_service(service_id): - # have to eager load api keys so that we don't flush when we loop through them - # to ensure that db.session still contains the models when it comes to creating history objects - # service = ( - # Service.query.options( - # joinedload(Service.api_keys), - # ) - # .filter(Service.id == service_id) - # .one() - # ) + stmt = ( select(Service) .options(joinedload(Service.api_keys)) @@ -767,16 +579,12 @@ def dao_suspend_service(service_id): @autocommit @version_class(Service) def dao_resume_service(service_id): - # service = Service.query.get(service_id) service = db.session.get(Service, service_id) service.active = True def dao_fetch_active_users_for_service(service_id): - # query = User.query.filter(User.services.any(id=service_id), User.state == "active") - - # return query.all() stmt = select(User).where(User.services.any(id=service_id), User.state == "active") result = db.session.execute(stmt) @@ -784,27 +592,7 @@ def dao_fetch_active_users_for_service(service_id): def dao_find_services_sending_to_tv_numbers(start_date, end_date, threshold=500): - # return ( - # db.session.query( - # Notification.service_id.label("service_id"), - # func.count(Notification.id).label("notification_count"), - # ) - # .filter( - # Notification.service_id == Service.id, - # Notification.created_at >= start_date, - # Notification.created_at <= end_date, - # Notification.key_type != KeyType.TEST, - # Notification.notification_type == NotificationType.SMS, - # func.substr(Notification.normalised_to, 3, 7) == "7700900", - # Service.restricted == False, # noqa - # Service.active == True, # noqa - # ) - # .group_by( - # Notification.service_id, - # ) - # .having(func.count(Notification.id) > threshold) - # .all() - # ) + stmt = ( select( Notification.service_id.label("service_id"), @@ -884,23 +672,6 @@ def dao_find_services_with_high_failure_rates(start_date, end_date, threshold=10 def get_live_services_with_organization(): - # query = ( - # db.session.query( - # Service.id.label("service_id"), - # Service.name.label("service_name"), - # Organization.id.label("organization_id"), - # Organization.name.label("organization_name"), - # ) - # .outerjoin(Service.organization) - # .filter( - # Service.count_as_live.is_(True), - # Service.active.is_(True), - # Service.restricted.is_(False), - # ) - # .order_by(Organization.name, Service.name) - # ) - - # return query.all() stmt = ( select( @@ -925,27 +696,7 @@ def get_live_services_with_organization(): def fetch_notification_stats_for_service_by_month_by_user( start_date, end_date, service_id, user_id ): - # return ( - # db.session.query( - # func.date_trunc("month", NotificationAllTimeView.created_at).label("month"), - # NotificationAllTimeView.notification_type, - # (NotificationAllTimeView.status).label("notification_status"), - # func.count(NotificationAllTimeView.id).label("count"), - # ) - # .filter( - # NotificationAllTimeView.service_id == service_id, - # NotificationAllTimeView.created_at >= start_date, - # NotificationAllTimeView.created_at < end_date, - # NotificationAllTimeView.key_type != KeyType.TEST, - # NotificationAllTimeView.created_by_id == user_id, - # ) - # .group_by( - # func.date_trunc("month", NotificationAllTimeView.created_at).label("month"), - # NotificationAllTimeView.notification_type, - # NotificationAllTimeView.status, - # ) - # .all() - # ) + stmt = ( select( func.date_trunc("month", NotificationAllTimeView.created_at).label("month"),