From 83504085125fd3e282f5406057d2c3c576803f53 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Fri, 10 Nov 2023 16:14:03 -0500 Subject: [PATCH] Working on getting tests working. Signed-off-by: Cliff Hill --- app/celery/scheduled_tasks.py | 8 +++++-- app/dao/invited_user_dao.py | 20 ++++++++++++++--- app/models.py | 7 +++++- app/service_invite/rest.py | 7 ++++++ migrations/versions/0404_expire_invites.py | 22 +++++++++++++++++++ tests/app/celery/test_scheduled_tasks.py | 4 ++-- tests/app/organization/test_invite_rest.py | 2 +- .../test_service_invite_rest.py | 8 +++---- 8 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 migrations/versions/0404_expire_invites.py diff --git a/app/celery/scheduled_tasks.py b/app/celery/scheduled_tasks.py index ed325d84a..8111a347f 100644 --- a/app/celery/scheduled_tasks.py +++ b/app/celery/scheduled_tasks.py @@ -73,7 +73,9 @@ def expire_or_delete_invitations(): try: start = datetime.utcnow() expired_invites = expire_invitations_created_more_than_two_days_ago() - current_app.logger.info(f"Expire job started {start} finished {datetime.utcnow()} expired {len(expired_invites)} invitations") + current_app.logger.info( + f"Expire job started {start} finished {datetime.utcnow()} expired {expired_invites} invitations" + ) except SQLAlchemyError: current_app.logger.exception("Failed to expire invitations") raise @@ -81,7 +83,9 @@ def expire_or_delete_invitations(): try: start = datetime.utcnow() deleted_invites = delete_org_invitations_created_more_than_two_days_ago() - current_app.logger.info(f"Delete job started {start} finished {datetime.utcnow()} deleted {len(deleted_invites)} invitations") + current_app.logger.info( + f"Delete job started {start} finished {datetime.utcnow()} deleted {deleted_invites} invitations" + ) except SQLAlchemyError: current_app.logger.exception("Failed to delete invitations") raise diff --git a/app/dao/invited_user_dao.py b/app/dao/invited_user_dao.py index 5b9b63947..20ec5288c 100644 --- a/app/dao/invited_user_dao.py +++ b/app/dao/invited_user_dao.py @@ -10,15 +10,29 @@ def save_invited_user(invited_user): def get_invited_user_by_service_and_id(service_id, invited_user_id): - return InvitedUser.query.filter_by(service_id=service_id, id=invited_user_id).one() + return InvitedUser.query.filter( + InvitedUser.service_id == service_id, + InvitedUser.id == invited_user_id, + InvitedUser.status != INVITE_EXPIRED, + ).one() def get_invited_user_by_id(invited_user_id): - return InvitedUser.query.filter_by(id=invited_user_id).one() + return InvitedUser.query.filter( + InvitedUser.id == invited_user_id, InvitedUser.status != INVITE_EXPIRED + ).one() + + +def get_expired_invited_users_for_service(service_id): + return InvitedUser.query.filter( + InvitedUser.service_id == service_id, InvitedUser.status == INVITE_EXPIRED + ).all() def get_invited_users_for_service(service_id): - return InvitedUser.query.filter_by(service_id=service_id).all() + return InvitedUser.query.filter( + InvitedUser.service_id == service_id, InvitedUser.status != INVITE_EXPIRED + ).all() def expire_invitations_created_more_than_two_days_ago(): diff --git a/app/models.py b/app/models.py index 7fe596a61..a46b95a6e 100644 --- a/app/models.py +++ b/app/models.py @@ -1888,7 +1888,12 @@ INVITE_PENDING = "pending" INVITE_ACCEPTED = "accepted" INVITE_CANCELLED = "cancelled" INVITE_EXPIRED = "expired" -INVITED_USER_STATUS_TYPES = [INVITE_PENDING, INVITE_ACCEPTED, INVITE_CANCELLED, INVITE_EXPIRED] +INVITED_USER_STATUS_TYPES = [ + INVITE_PENDING, + INVITE_ACCEPTED, + INVITE_CANCELLED, + INVITE_EXPIRED, +] class InviteStatusType(db.Model): diff --git a/app/service_invite/rest.py b/app/service_invite/rest.py index 668edcb39..b5f9c95a7 100644 --- a/app/service_invite/rest.py +++ b/app/service_invite/rest.py @@ -4,6 +4,7 @@ from notifications_utils.url_safe_token import check_token, generate_token from app.config import QueueNames from app.dao.invited_user_dao import ( + get_expired_invited_users_for_service, get_invited_user_by_id, get_invited_user_by_service_and_id, get_invited_users_for_service, @@ -58,6 +59,12 @@ def create_invited_user(service_id): return jsonify(data=invited_user_schema.dump(invited_user)), 201 +@service_invite.route("/service//invite/expired", methods=["GET"]) +def get_expired_invited_users_by_service(service_id): + expired_invited_users = get_expired_invited_users_for_service(service_id) + return jsonify(data=invited_user_schema.dump(expired_invited_users, many=True)), 200 + + @service_invite.route("/service//invite", methods=["GET"]) def get_invited_users_by_service(service_id): invited_users = get_invited_users_for_service(service_id) diff --git a/migrations/versions/0404_expire_invites.py b/migrations/versions/0404_expire_invites.py new file mode 100644 index 000000000..c6065a8cb --- /dev/null +++ b/migrations/versions/0404_expire_invites.py @@ -0,0 +1,22 @@ +""" + +Revision ID: 0404_expire_invites +Revises: 0403_add_carrier +Create Date: 2023-11-10 15:52:07.348485 + +""" +from re import I +from alembic import op +import sqlalchemy as sa + + +revision = "0404_expire_invites" +down_revision = "0403_add_carrier" + + +def upgrade(): + op.execute("insert into invite_status_type values ('expired')") + + +def downgrade(): + op.execute("delete from invite_status_type where name = 'expired'") diff --git a/tests/app/celery/test_scheduled_tasks.py b/tests/app/celery/test_scheduled_tasks.py index 83098c52d..97b9f903e 100644 --- a/tests/app/celery/test_scheduled_tasks.py +++ b/tests/app/celery/test_scheduled_tasks.py @@ -11,8 +11,8 @@ from app.celery.scheduled_tasks import ( check_for_missing_rows_in_completed_jobs, check_for_services_with_high_failure_rates_or_sending_to_tv_numbers, check_job_status, - expire_or_delete_invitations, delete_verify_codes, + expire_or_delete_invitations, replay_created_notifications, run_scheduled_jobs, ) @@ -40,7 +40,7 @@ def test_should_call_delete_codes_on_delete_verify_codes_task( ) -def test_should_call_delete_invotations_on_delete_invitations_task( +def test_should_call_expire_or_delete_invotations_on_expire_or_delete_invitations_task( notify_db_session, mocker ): mocker.patch( diff --git a/tests/app/organization/test_invite_rest.py b/tests/app/organization/test_invite_rest.py index 48c6ee348..097fa92e4 100644 --- a/tests/app/organization/test_invite_rest.py +++ b/tests/app/organization/test_invite_rest.py @@ -198,7 +198,7 @@ def test_update_org_invited_user_for_invalid_data_returns_400( assert len(json_resp["errors"]) == 1 assert ( json_resp["errors"][0]["message"] - == "status garbage is not one of [pending, accepted, cancelled]" + == "status garbage is not one of [pending, accepted, cancelled, expired]" ) diff --git a/tests/app/service_invite/test_service_invite_rest.py b/tests/app/service_invite/test_service_invite_rest.py index 90621b9b8..595303bc8 100644 --- a/tests/app/service_invite/test_service_invite_rest.py +++ b/tests/app/service_invite/test_service_invite_rest.py @@ -40,7 +40,7 @@ def test_create_invited_user( permissions="send_messages,manage_service,manage_api_keys", auth_type=EMAIL_AUTH_TYPE, folder_permissions=["folder_1", "folder_2", "folder_3"], - **extra_args + **extra_args, ) json_resp = admin_request.post( @@ -127,7 +127,7 @@ def test_create_invited_user_invalid_email(client, sample_service, mocker, fake_ auth_header = create_admin_authorization_header() response = client.post( - "/service/{}/invite".format(sample_service.id), + f"/service/{sample_service.id}/invite", headers=[("Content-Type", "application/json"), auth_header], data=data, ) @@ -145,7 +145,7 @@ def test_get_all_invited_users_by_service(client, notify_db_session, sample_serv invited_user = create_invited_user(sample_service, to_email_address=email) invites.append(invited_user) - url = "/service/{}/invite".format(sample_service.id) + url = f"/service/{sample_service.id}/invite" auth_header = create_admin_authorization_header() @@ -167,7 +167,7 @@ def test_get_all_invited_users_by_service(client, notify_db_session, sample_serv def test_get_invited_users_by_service_with_no_invites( client, notify_db_session, sample_service ): - url = "/service/{}/invite".format(sample_service.id) + url = f"/service/{sample_service.id}/invite" auth_header = create_admin_authorization_header()