diff --git a/backend/audit/management/commands/delete_blank_access_entries.py b/backend/audit/management/commands/delete_blank_access_entries.py new file mode 100644 index 0000000000..b6ec426960 --- /dev/null +++ b/backend/audit/management/commands/delete_blank_access_entries.py @@ -0,0 +1,76 @@ +from audit.models import ( + Access, + DeletedAccess, + delete_access_and_create_record, +) + +from django.core.management.base import BaseCommand + +import logging +import sys + + +logger = logging.getLogger(__name__) + + +class Command(BaseCommand): + """ + Django management command for deleting Access entries with blank email + fields. A DeletedAccess entry is created for each deleted Access entry by + using audit.models.delete_access_and_create_record. + """ + + def add_arguments(self, parser): + parser.add_argument( + "--count", + action="store_true", + help="Only logs the blank Access entries count without deleting", + ) + parser.add_argument( + "--limit", + type=int, + help="Limits the number of blank Access entries to delete", + default=None, + ) + + def handle(self, *args, **options): + access_start_count = len(Access.objects.all()) + logger.info(f"Access count: {access_start_count}") + + deleted_access_start_count = len(DeletedAccess.objects.all()) + logger.info(f"DeletedAccess count: {deleted_access_start_count}") + + blank_accesses = Access.objects.filter(email="") + logger.info(f"Blank Access count: {len(blank_accesses)}") + + if options.get("count"): + sys.exit(0) + + limit = options.get("limit") + if limit is not None: + logger.info(f"Deletion limit: {limit}") + + deleted_count = 0 + + for blank_access in blank_accesses: + if deleted_count == limit: + logger.info("Deletion limit reached") + break + + logger.info( + f"Deleting blank Access for {blank_access.sac.report_id}, {blank_access.fullname}" + ) + + _, deletion_record = delete_access_and_create_record(blank_access) + + logger.info(f"Created DeletedAccess {deletion_record.id}") + + deleted_count += 1 + + logger.info(f"Deleted {deleted_count} blank Access entries") + + access_finish_count = len(Access.objects.all()) + logger.info(f"Final Access count: {access_finish_count}") + + deleted_access_finish_count = len(DeletedAccess.objects.all()) + logger.info(f"Final DeletedAccess count: {deleted_access_finish_count}") diff --git a/backend/audit/models/__init__.py b/backend/audit/models/__init__.py index 71c1cea138..f5eeacc1d1 100644 --- a/backend/audit/models/__init__.py +++ b/backend/audit/models/__init__.py @@ -1,4 +1,8 @@ -from .access import Access, remove_email_from_submission_access +from .access import ( + Access, + delete_access_and_create_record, + remove_email_from_submission_access, +) from .deleted_access import DeletedAccess from .access_roles import ACCESS_ROLES from .models import ( @@ -33,6 +37,7 @@ User, ] _functions = [ + delete_access_and_create_record, excel_file_path, generate_sac_report_id, remove_email_from_submission_access, diff --git a/backend/cypress/e2e/accessibility.cy.js b/backend/cypress/e2e/accessibility.cy.js index 6c986c6234..d80ee980fc 100644 --- a/backend/cypress/e2e/accessibility.cy.js +++ b/backend/cypress/e2e/accessibility.cy.js @@ -48,7 +48,7 @@ describe('A11y Testing on search pages', () => { before(() => { cy.visit('/dissemination/search/'); cy.get('label').contains('All years').click(); - cy.get('[id="search-form"]').submit(); + cy.get('[id="audit-search-form"]').submit(); cy.get('tbody > :nth-child(1) > td > a') .invoke('attr', 'href') .as('summary_url'); diff --git a/backend/dissemination/templates/search.html b/backend/dissemination/templates/search.html index d6b8c0df69..597c6cf42e 100644 --- a/backend/dissemination/templates/search.html +++ b/backend/dissemination/templates/search.html @@ -9,13 +9,16 @@

Filters

{% csrf_token %} {% comment %} Submission {% endcomment %}
- + @@ -54,7 +57,10 @@

Filters

{% comment %} Submission {% endcomment %}
- + @@ -98,8 +104,7 @@

Search single audit reports

{% if results_count <= summary_report_download_limit %}