diff --git a/accessibility_monitoring_platform/apps/audits/admin.py b/accessibility_monitoring_platform/apps/audits/admin.py index 86e7cab50..055c550ac 100644 --- a/accessibility_monitoring_platform/apps/audits/admin.py +++ b/accessibility_monitoring_platform/apps/audits/admin.py @@ -45,13 +45,14 @@ class CheckResultAdmin(admin.ModelAdmin): """Django admin configuration for CheckResult model""" search_fields = [ + "issue_identifier", "audit__case__organisation_name", "audit__case__case_number", "wcag_definition__name", "page__name", "page__page_type", ] - list_display = ["__str__", "audit", "page"] + list_display = ["issue_identifier", "__str__", "audit", "page"] list_filter = ["check_result_state"] @@ -75,7 +76,14 @@ class StatementCheckAdmin(admin.ModelAdmin): """Django admin configuration for StatementCheck model""" search_fields = ["label", "success_criteria", "report_text"] - list_display = ["label", "type", "position", "date_start", "date_end"] + list_display = [ + "issue_number", + "label", + "type", + "position", + "date_start", + "date_end", + ] list_filter = ["type"] fieldsets = ( ( @@ -97,12 +105,13 @@ class StatementCheckResultAdmin(admin.ModelAdmin): """Django admin configuration for StatementCheck model""" search_fields = [ + "issue_identifier", "audit__case__organisation_name", "statement_check__label", "statement_check__success_criteria", "statement_check__report_text", ] - list_display = ["statement_check", "audit", "is_deleted"] + list_display = ["issue_identifier", "statement_check", "audit", "is_deleted"] list_filter = ["is_deleted", "check_result_state", "retest_state"] fieldsets = ( ( @@ -154,12 +163,14 @@ class RetestCheckResultAdmin(admin.ModelAdmin): """Django admin configuration for RetestCheckResult model""" search_fields = [ + "issue_identifier", "check_result__wcag_definition__name", "retest__case__organisation_name", "retest_page__page__name", "retest_page__page__url", ] list_display = [ + "issue_identifier", "check_result", "retest", "retest_page", @@ -182,13 +193,14 @@ class RetestStatementCheckResultAdmin(admin.ModelAdmin): """Django admin configuration for RetestStatementCheckResult model""" search_fields = [ + "issue_identifier", "retest__case__case_number", "retest__case__organisation_name", "statement_check__label", "comment", ] list_display = [ - "id", + "issue_identifier", "retest", "type", "check_result_state", diff --git a/accessibility_monitoring_platform/apps/audits/migrations/0012_retestcheckresult_id_within_case_and_more.py b/accessibility_monitoring_platform/apps/audits/migrations/0012_retestcheckresult_id_within_case_and_more.py new file mode 100644 index 000000000..619e49d42 --- /dev/null +++ b/accessibility_monitoring_platform/apps/audits/migrations/0012_retestcheckresult_id_within_case_and_more.py @@ -0,0 +1,77 @@ +# Generated by Django 5.1.4 on 2025-01-21 08:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("audits", "0011_remove_audit_accessibility_statement_backup_url_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="checkresult", + name="issue_identifier", + field=models.CharField(max_length=20, default=""), + ), + migrations.AddField( + model_name="retestcheckresult", + name="id_within_case", + field=models.IntegerField(blank=True, default=0), + ), + migrations.AddField( + model_name="retestcheckresult", + name="issue_identifier", + field=models.CharField(max_length=20, default=""), + ), + migrations.AddField( + model_name="reteststatementcheckresult", + name="id_within_case", + field=models.IntegerField(blank=True, default=0), + ), + migrations.AddField( + model_name="reteststatementcheckresult", + name="issue_identifier", + field=models.CharField(max_length=20, default=""), + ), + migrations.AddField( + model_name="statementcheck", + name="issue_number", + field=models.IntegerField(blank=True, default=0), + ), + migrations.AddField( + model_name="statementcheckresult", + name="id_within_case", + field=models.IntegerField(blank=True, default=0), + ), + migrations.AddField( + model_name="statementcheckresult", + name="issue_identifier", + field=models.CharField(max_length=20, default=""), + ), + migrations.AddIndex( + model_name="checkresult", + index=models.Index( + fields=["issue_identifier"], name="audits_chec_issue_i_a8fd9c_idx" + ), + ), + migrations.AddIndex( + model_name="retestcheckresult", + index=models.Index( + fields=["issue_identifier"], name="audits_rete_issue_i_4df993_idx" + ), + ), + migrations.AddIndex( + model_name="reteststatementcheckresult", + index=models.Index( + fields=["issue_identifier"], name="audits_rete_issue_i_a854a4_idx" + ), + ), + migrations.AddIndex( + model_name="statementcheckresult", + index=models.Index( + fields=["issue_identifier"], name="audits_stat_issue_i_d20fe4_idx" + ), + ), + ] diff --git a/accessibility_monitoring_platform/apps/audits/migrations/0013_populate_ids_within_case.py b/accessibility_monitoring_platform/apps/audits/migrations/0013_populate_ids_within_case.py new file mode 100644 index 000000000..a6eb75aeb --- /dev/null +++ b/accessibility_monitoring_platform/apps/audits/migrations/0013_populate_ids_within_case.py @@ -0,0 +1,94 @@ +# Generated by Django 5.1.4 on 2025-01-21 08:48 + +from django.db import migrations + +ISSUE_IDENTIFIER_WCAG: str = "A" +ISSUE_IDENTIFIER_STATEMENT: str = "S" +CUSTOM_ISSUE: str = "C" + + +def build_issue_identifier(case, issue, issue_type): + """Format and return issue identifier""" + return f"{case.case_number}-{issue_type}-{issue.id_within_case}" + + +def populate_id_within_case(apps, schema_editor): # pylint: disable=unused-argument + Audit = apps.get_model("audits", "Audit") + CheckResult = apps.get_model("audits", "CheckResult") + StatementCheck = apps.get_model("audits", "StatementCheck") + StatementCheckResult = apps.get_model("audits", "StatementCheckResult") + Retest = apps.get_model("audits", "Retest") + RetestCheckResult = apps.get_model("audits", "RetestCheckResult") + RetestStatementCheckResult = apps.get_model("audits", "RetestStatementCheckResult") + + issue_number = 0 + for statement_check in StatementCheck.objects.all(): + issue_number += 1 + statement_check.issue_number = issue_number + statement_check.save() + + for audit in Audit.objects.all(): + for check_result in CheckResult.objects.filter(audit=audit): + check_result.issue_identifier = build_issue_identifier( + case=audit.case, + issue=check_result, + issue_type=ISSUE_IDENTIFIER_WCAG, + ) + check_result.save() + id_within_case = 0 + + for statement_check_result in StatementCheckResult.objects.filter(audit=audit): + id_within_case += 1 + statement_check_result.id_within_case = id_within_case + issue_type = ISSUE_IDENTIFIER_STATEMENT + if statement_check_result.statement_check is None: + issue_type += CUSTOM_ISSUE + statement_check_result.issue_identifier = build_issue_identifier( + case=audit.case, + issue=statement_check_result, + issue_type=issue_type, + ) + statement_check_result.save() + + for retest in Retest.objects.all(): + for retest_check_result in RetestCheckResult.objects.filter(retest=retest): + retest_check_result.id_within_case = ( + retest_check_result.check_result.id_within_case + ) + retest_check_result.issue_identifier = build_issue_identifier( + case=audit.case, + issue=retest_check_result, + issue_type=ISSUE_IDENTIFIER_WCAG, + ) + retest_check_result.save() + + id_within_case = 0 + for retest_statement_check_result in RetestStatementCheckResult.objects.filter( + retest=retest + ): + id_within_case += 1 + retest_statement_check_result.id_within_case = id_within_case + issue_type = ISSUE_IDENTIFIER_STATEMENT + if retest_statement_check_result.statement_check is None: + issue_type += CUSTOM_ISSUE + retest_statement_check_result.issue_identifier = build_issue_identifier( + case=retest.case, + issue=retest_statement_check_result, + issue_type=issue_type, + ) + retest_statement_check_result.save() + + +def reverse_code(apps, schema_editor): # pylint: disable=unused-argument + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ("audits", "0012_retestcheckresult_id_within_case_and_more"), + ] + + operations = [ + migrations.RunPython(populate_id_within_case, reverse_code=reverse_code), + ] diff --git a/accessibility_monitoring_platform/apps/audits/models.py b/accessibility_monitoring_platform/apps/audits/models.py index 05eb7e459..4bf1e5ca8 100644 --- a/accessibility_monitoring_platform/apps/audits/models.py +++ b/accessibility_monitoring_platform/apps/audits/models.py @@ -2,11 +2,13 @@ Models - audits (called tests by the users) """ +from __future__ import annotations + from datetime import date from django.db import models from django.db.models import Case as DjangoCase -from django.db.models import Q, When +from django.db.models import Max, Q, When from django.db.models.query import QuerySet from django.urls import reverse from django.utils import timezone @@ -16,6 +18,30 @@ from ..common.models import Boolean, StartEndDateManager, VersionModel from ..common.utils import amp_format_date, calculate_percentage +ISSUE_IDENTIFIER_WCAG: str = "A" +ISSUE_IDENTIFIER_STATEMENT: str = "S" + + +def build_issue_identifier( + case: Case, + issue: ( + CheckResult + | StatementCheckResult + | RetestCheckResult + | RetestStatementCheckResult + ), + custom_issue: bool = False, +) -> str: + """Format and return issue identifier""" + issue_type: str = ( + ISSUE_IDENTIFIER_WCAG + if isinstance(issue, (CheckResult, RetestCheckResult)) + else ISSUE_IDENTIFIER_STATEMENT + ) + if custom_issue: + issue_type += "C" + return f"{case.case_number}-{issue_type}-{issue.id_within_case}" + class Audit(VersionModel): """ @@ -202,7 +228,7 @@ class Meta: ordering = ["-id"] def __str__(self) -> str: - return str(f"{self.case}" f" (Test {amp_format_date(self.date_of_test)})") + return f"{self.case} (Test {amp_format_date(self.date_of_test)})" def get_absolute_url(self) -> str: return reverse("audits:edit-audit-metadata", kwargs={"pk": self.pk}) @@ -647,7 +673,7 @@ class Meta: def __str__(self) -> str: if self.description: - return str(f"{self.name}: {self.description} ({self.get_type_display()})") + return f"{self.name}: {self.description} ({self.get_type_display()})" return f"{self.name} ({self.get_type_display()})" def get_absolute_url(self) -> str: @@ -676,6 +702,7 @@ class RetestResult(models.TextChoices): Page, on_delete=models.PROTECT, related_name="checkresult_page" ) id_within_case = models.IntegerField(default=0, blank=True) + issue_identifier = models.CharField(max_length=20, default="") is_deleted = models.BooleanField(default=False) type = models.CharField( max_length=20, @@ -712,16 +739,24 @@ def dict_for_retest(self) -> dict[str, str]: class Meta: ordering = ["id"] + indexes = [ + models.Index( + fields=[ + "issue_identifier", + ] + ), + ] def __str__(self) -> str: - return str( - f"{self.page} | {self.wcag_definition} | {self.unique_id_within_case}" - ) + return f"{self.page} | {self.wcag_definition} | {self.issue_identifier}" def save(self, *args, **kwargs) -> None: self.updated = timezone.now() if not self.id: self.id_within_case = self.audit.checkresult_audit.all().count() + 1 + self.issue_identifier = build_issue_identifier( + case=self.audit.case, issue=self + ) super().save(*args, **kwargs) @property @@ -733,11 +768,6 @@ def matching_wcag_with_retest_notes_check_results(self) -> dict[str, str]: .exclude(retest_notes="") ) - @property - def unique_id_within_case(self) -> str: - """Unique identifies of check result within case to aid QA audit communication""" - return f"#E{self.id_within_case}" - class StatementCheck(models.Model): """ @@ -758,6 +788,7 @@ class Type(models.TextChoices): choices=Type.choices, default=Type.CUSTOM, ) + issue_number = models.IntegerField(default=0, blank=True) label = models.TextField(default="", blank=True) success_criteria = models.TextField(default="", blank=True) report_text = models.TextField(default="", blank=True) @@ -772,11 +803,14 @@ class Meta: def __str__(self) -> str: if self.success_criteria: - return str( - f"{self.label}: {self.success_criteria} ({self.get_type_display()})" - ) + return f"{self.label}: {self.success_criteria} ({self.get_type_display()})" return f"{self.label} ({self.get_type_display()})" + def save(self, *args, **kwargs) -> None: + if not self.id: + self.issue_number = StatementCheck.objects.all().count() + 1 + super().save(*args, **kwargs) + def get_absolute_url(self) -> str: return reverse("audits:statement-check-update", kwargs={"pk": self.pk}) @@ -800,6 +834,8 @@ class Result(models.TextChoices): NOT_TESTED = "not-tested", "Not tested" audit = models.ForeignKey(Audit, on_delete=models.PROTECT) + id_within_case = models.IntegerField(default=0, blank=True) + issue_identifier = models.CharField(max_length=20, default="") statement_check = models.ForeignKey( StatementCheck, on_delete=models.PROTECT, null=True, blank=True ) @@ -825,13 +861,30 @@ class Result(models.TextChoices): class Meta: ordering = ["statement_check__position", "id"] + indexes = [ + models.Index( + fields=[ + "issue_identifier", + ] + ), + ] def __str__(self) -> str: if self.statement_check is None: - return str(f"{self.audit} | Custom") - return str(f"{self.audit} | {self.statement_check}") + return f"{self.audit} | Custom ({self.issue_identifier})" + return f"{self.audit} | {self.statement_check} ({self.issue_identifier})" def save(self, *args, **kwargs) -> None: + if not self.id: + if self.statement_check: + self.id_within_case = self.statement_check.issue_number + else: + self.id_within_case = self.audit.statement_check_results.count() + 1 + self.issue_identifier = build_issue_identifier( + case=self.audit.case, + issue=self, + custom_issue=self.statement_check is None, + ) super().save(*args, **kwargs) @property @@ -906,7 +959,7 @@ def get_absolute_url(self) -> str: def __str__(self) -> str: if self.id_within_case == 0: return "12-week retest" - return str(f"Retest #{self.id_within_case}") + return f"Retest #{self.id_within_case}" @property def is_incomplete(self) -> bool: @@ -1079,6 +1132,8 @@ class RetestCheckResult(models.Model): """ retest = models.ForeignKey(Retest, on_delete=models.PROTECT) + id_within_case = models.IntegerField(default=0, blank=True) + issue_identifier = models.CharField(max_length=20, default="") retest_page = models.ForeignKey(RetestPage, on_delete=models.PROTECT) check_result = models.ForeignKey(CheckResult, on_delete=models.PROTECT) is_deleted = models.BooleanField(default=False) @@ -1103,12 +1158,25 @@ def matching_wcag_retest_check_results(self) -> dict[str, str]: class Meta: ordering = ["id"] + indexes = [ + models.Index( + fields=[ + "issue_identifier", + ] + ), + ] def __str__(self) -> str: - return str(f"{self.retest_page} | {self.check_result}") + return f"{self.retest_page} | {self.check_result}" def save(self, *args, **kwargs) -> None: self.updated = timezone.now() + if not self.id: + if self.id_within_case == 0: + self.id_within_case = self.check_result.id_within_case + self.issue_identifier = build_issue_identifier( + case=self.retest.case, issue=self + ) super().save(*args, **kwargs) @property @@ -1153,6 +1221,8 @@ class Result(models.TextChoices): NOT_TESTED = "not-tested", "Not tested" retest = models.ForeignKey(Retest, on_delete=models.PROTECT) + id_within_case = models.IntegerField(default=0, blank=True) + issue_identifier = models.CharField(max_length=20, default="") statement_check = models.ForeignKey( StatementCheck, on_delete=models.PROTECT, null=True, blank=True ) @@ -1171,11 +1241,34 @@ class Result(models.TextChoices): class Meta: ordering = ["statement_check__position", "id"] + indexes = [ + models.Index( + fields=[ + "issue_identifier", + ] + ), + ] + + def save(self, *args, **kwargs) -> None: + if not self.id: + if self.id_within_case == 0: + self.id_within_case = ( + RetestStatementCheckResult.objects.filter( + retest__case=self.retest.case + ).aggregate(Max("id_within_case", default=0))["id_within_case__max"] + + 1 + ) + self.issue_identifier = build_issue_identifier( + case=self.retest.case, + issue=self, + custom_issue=self.statement_check is None, + ) + super().save(*args, **kwargs) def __str__(self) -> str: if self.statement_check is None: - return str(f"{self.retest} | Custom") - return str(f"{self.retest} | {self.statement_check}") + return f"{self.retest} | Custom ({self.issue_identifier})" + return f"{self.retest} | {self.statement_check} ({self.issue_identifier})" @property def label(self): diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_comparison_update.html b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_comparison_update.html index f8155bf7b..f46f54fce 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_comparison_update.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_comparison_update.html @@ -109,6 +109,9 @@

{{ wcag_definition.name }}

{{ retest_check_result.retest_page.page.location }}

{% endif %} +
  • + {% include 'audits/helpers/issue_identifier.html' with issue=retest_check_result %} +
  • diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_page_checks.html b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_page_checks.html index d363edffa..75082ce77 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_page_checks.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/equality_body_retest_page_checks.html @@ -106,7 +106,10 @@

    {{ sitemap.current_platform_pa

    - +
    Previous test notes diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/page_checks.html b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/page_checks.html index 90a148137..5ee5837fc 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/page_checks.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/page_checks.html @@ -52,7 +52,7 @@ {% for wcag_definition, form, matching_issues in definitions_forms_errors %}

    diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/twelve_week_retest_page_checks.html b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/twelve_week_retest_page_checks.html index 4e9f26c96..578756abd 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/forms/twelve_week_retest_page_checks.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/forms/twelve_week_retest_page_checks.html @@ -89,11 +89,11 @@ {% for check_result, form in check_results_and_forms %}

    - +
    {{ check_result.notes|markdown_to_html }}
    {% include 'common/form_hidden_fields.html' with hidden_fields=form.hidden_fields %} {% include 'audits/helpers/amp_wcag_state_field.html' with field=form.retest_state %} diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/amp_wcag_state_field.html b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/amp_wcag_state_field.html index 536f4baa4..9154f1213 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/amp_wcag_state_field.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/amp_wcag_state_field.html @@ -1,6 +1,9 @@
    {% if field.help_text or wcag_definition.hint %}
    {{ field.help_text }} {{ wcag_definition.hint }}
    {% endif %} {% include 'common/field_errors.html' with errors=field.errors %} diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_retest_page_comparison_table.html b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_retest_page_comparison_table.html index d662813b3..802a62a8e 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_retest_page_comparison_table.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_retest_page_comparison_table.html @@ -8,6 +8,9 @@ +
    + {% include 'audits/helpers/issue_identifier.html' with issue=retest_check_result %} +
    diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_statement_check_result_field.html b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_statement_check_result_field.html index 25a9dddab..2a9cbd9fd 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_statement_check_result_field.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/equality_body_statement_check_result_field.html @@ -4,6 +4,9 @@

    {{ statement_check_result_form.instance.label }}

    + {% if statement_check_result_form.instance.statement_check.success_criteria %} diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/issue_identifier.html b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/issue_identifier.html new file mode 100644 index 000000000..fc114e4b6 --- /dev/null +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/issue_identifier.html @@ -0,0 +1 @@ +Issue identifier: {{ issue.issue_identifier }} diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/statement_check_result_field.html b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/statement_check_result_field.html index b0fbc20b2..db7c641ee 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/statement_check_result_field.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/statement_check_result_field.html @@ -1,9 +1,12 @@
    -

    +

    {{ statement_check_result_form.instance.label }}

    +

    {{ statement_check_result_form.instance.statement_check.success_criteria }}

    diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary.html b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary.html index 8b60d9bc7..99980562b 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary.html @@ -163,7 +163,10 @@

    {% for failure in failures %} - {{ failure.wcag_definition.name }} | {{ failure.unique_id_within_case }} + + {{ failure.wcag_definition.name }}
    + {% include 'audits/helpers/issue_identifier.html' with issue=failure %} +

    {{ failure.get_check_result_state_display }}

    {{ failure.notes|markdown_to_html }} @@ -207,32 +210,36 @@

    -

    {{ failure.page }} | {{ failure.unique_id_within_case }}

    +

    {{ failure.page }}

    {{ failure.get_check_result_state_display }}

    diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary_statement_content.html b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary_statement_content.html index 1f9b1c133..b07bd7bd4 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary_statement_content.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/helpers/test_summary_statement_content.html @@ -34,7 +34,8 @@

    - {{ statement_check_result.label }} + {{ statement_check_result.label }}
    + {% include 'audits/helpers/issue_identifier.html' with issue=statement_check_result %}

    {{ statement_check_result.get_check_result_state_display }}

    diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_custom.html b/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_custom.html index 74dbc5dcf..915bfb7aa 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_custom.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_custom.html @@ -33,9 +33,14 @@ {% for statement_check_result_form in retest_statement_check_results_formset %}
    -

    - Custom issue #{{ forloop.counter }} +

    + Custom issue

    + {% if statement_check_result_form.instance.id %} + + {% endif %} {% include 'common/form_hidden_fields.html' with hidden_fields=statement_check_result_form.hidden_fields %} {% include 'common/amp_field.html' with field=statement_check_result_form.comment %}
    diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_results_table.html b/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_results_table.html index c2a23c5fa..ab8465cd6 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_results_table.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/equality_body_retest_statement_results_table.html @@ -9,7 +9,10 @@ {% for statement_check_result in statement_check_results %} - {{ statement_check_result.label }} +
      +
    • {{ statement_check_result.label }}
    • +
    • {% include 'audits/helpers/issue_identifier.html' with issue=statement_check_result %}
    • +
    {{ statement_check_result.get_check_result_state_display }} diff --git a/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/statement_custom.html b/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/statement_custom.html index d1a4f4517..48504b8c7 100644 --- a/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/statement_custom.html +++ b/accessibility_monitoring_platform/apps/audits/templates/audits/statement_checks/statement_custom.html @@ -14,7 +14,12 @@
    -

    Custom issue #{{ forloop.counter }}

    +

    Custom issue

    + {% if custom_form.instance.id %} + + {% endif %} {% include 'common/form_errors.html' with errors=custom_form.non_field_errors %} {% include 'common/form_hidden_fields.html' with hidden_fields=custom_form.hidden_fields %} {% for field in custom_form.visible_fields %} diff --git a/accessibility_monitoring_platform/apps/audits/tests/test_models.py b/accessibility_monitoring_platform/apps/audits/tests/test_models.py index 31a735157..7f0d3ec63 100644 --- a/accessibility_monitoring_platform/apps/audits/tests/test_models.py +++ b/accessibility_monitoring_platform/apps/audits/tests/test_models.py @@ -23,7 +23,9 @@ StatementCheckResult, StatementPage, WcagDefinition, + build_issue_identifier, ) +from ..utils import create_checkresults_for_retest TODAY = date.today() PAGE_NAME = "Page name" @@ -768,14 +770,17 @@ def test_statement_check_results_str(): assert ( statement_check_result.__str__() - == f"{audit} | {statement_check_result.statement_check}" + == f"{audit} | {statement_check_result.statement_check} ({statement_check_result.issue_identifier})" ) custom_statement_check_result: StatementCheckResult = ( audit.custom_statement_check_results.first() ) - assert custom_statement_check_result.__str__() == f"{audit} | Custom" + assert ( + custom_statement_check_result.__str__() + == f"{audit} | Custom ({custom_statement_check_result.issue_identifier})" + ) @pytest.mark.django_db @@ -1710,7 +1715,10 @@ def test_retest_statement_check_results_str(): RetestStatementCheckResult.objects.create(retest=retest) ) - assert retest_statement_check_result.__str__() == "Retest #1 | Custom" + assert ( + retest_statement_check_result.__str__() + == f"{retest} | Custom ({retest_statement_check_result.issue_identifier})" + ) statement_check: StatementCheck = StatementCheck.objects.get( id=ACCESSIBILITY_PAGE_STATEMENT_CHECK_ID @@ -1720,7 +1728,7 @@ def test_retest_statement_check_results_str(): assert ( retest_statement_check_result.__str__() - == "Retest #1 | Is there an accessibility page?: An accessibility page is found on the website (Statement overview)" + == f"{retest} | {statement_check} ({retest_statement_check_result.issue_identifier})" ) @@ -1897,8 +1905,8 @@ def test_statement_check_result_display_value(): @pytest.mark.django_db -def test_check_result_unique_id_within_case(): - """Test check result gets unique id withn Case""" +def test_check_result_issue_identifier(): + """Test check result gets unique identifier""" wcag_definition: WcagDefinition = WcagDefinition.objects.create( type=WcagDefinition.Type.AXE, name=WCAG_TYPE_AXE_NAME ) @@ -1914,7 +1922,7 @@ def test_check_result_unique_id_within_case(): wcag_definition=wcag_definition, ) - assert check_result_1a.unique_id_within_case == "#E1" + assert check_result_1a.issue_identifier == "1-A-1" check_result_1b: CheckResult = CheckResult.objects.create( audit=audit_1, @@ -1925,7 +1933,7 @@ def test_check_result_unique_id_within_case(): wcag_definition=wcag_definition, ) - assert check_result_1b.unique_id_within_case == "#E2" + assert check_result_1b.issue_identifier == "1-A-2" case_2: Case = Case.objects.create() audit_2: Audit = Audit.objects.create(case=case_2) @@ -1939,4 +1947,180 @@ def test_check_result_unique_id_within_case(): wcag_definition=wcag_definition, ) - assert check_result_2a.unique_id_within_case == "#E1" + assert check_result_2a.issue_identifier == "2-A-1" + + +@pytest.mark.django_db +def test_issue_identifier(): + """ + Test issue_identifier property is populated on CheckResult, StatementCheckResult, + RetestCheckResult and RetestStatementCheckResult creation. + """ + + case: Case = Case.objects.create() + audit: Audit = Audit.objects.create(case=case) + wcag_definition: WcagDefinition = WcagDefinition.objects.create( + type=WcagDefinition.Type.AXE, name=WCAG_TYPE_AXE_NAME + ) + page: Page = Page.objects.create( + audit=audit, page_type=Page.Type.HOME, url="https://example.com" + ) + + first_check_result: CheckResult = CheckResult.objects.create( + audit=audit, + page=page, + check_result_state=CheckResult.Result.ERROR, + retest_state=CheckResult.RetestResult.NOT_FIXED, + type=wcag_definition.type, + wcag_definition=wcag_definition, + ) + + assert first_check_result.issue_identifier == "1-A-1" + + second_check_result: CheckResult = CheckResult.objects.create( + audit=audit, + page=page, + check_result_state=CheckResult.Result.ERROR, + retest_state=CheckResult.RetestResult.NOT_FIXED, + type=wcag_definition.type, + wcag_definition=wcag_definition, + ) + + assert second_check_result.issue_identifier == "1-A-2" + + statement_check: StatementCheck = StatementCheck.objects.all().first() + first_statement_check_result: StatementCheckResult = ( + StatementCheckResult.objects.create( + audit=audit, + type=statement_check.type, + statement_check=statement_check, + ) + ) + + assert first_statement_check_result.issue_identifier == "1-S-1" + + second_statement_check_result: StatementCheckResult = ( + StatementCheckResult.objects.create( + audit=audit, + report_comment="Custom statement issue", + ) + ) + + assert second_statement_check_result.issue_identifier == "1-SC-2" + + retest: Retest = Retest.objects.create(case=case) + create_checkresults_for_retest(retest=retest) + + first_retest_check_result: RetestCheckResult = ( + retest.retestcheckresult_set.all().first() + ) + second_retest_check_result: RetestCheckResult = ( + retest.retestcheckresult_set.all().last() + ) + + assert first_retest_check_result.issue_identifier == "1-A-1" + assert second_retest_check_result.issue_identifier == "1-A-2" + + assert retest.reteststatementcheckresult_set.count() > 2 + + first_retest_statement_check_result: RetestStatementCheckResult = ( + retest.reteststatementcheckresult_set.all().first() + ) + second_retest_statement_check_result: RetestStatementCheckResult = ( + retest.reteststatementcheckresult_set.all().last() + ) + + assert first_retest_statement_check_result.issue_identifier == "1-S-1" + assert second_retest_statement_check_result.issue_identifier == "1-S-42" + + new_custom_retest_statement_check_result: RetestStatementCheckResult = ( + RetestStatementCheckResult.objects.create( + retest=retest, + ) + ) + + assert new_custom_retest_statement_check_result.issue_identifier == "1-SC-43" + + +@pytest.mark.django_db +def test_build_issue_identifier(): + """Test building issue identifiers""" + + wcag_definition: WcagDefinition = WcagDefinition.objects.create( + type=WcagDefinition.Type.AXE, name=WCAG_TYPE_AXE_NAME + ) + case: Case = Case.objects.create() + audit: Audit = Audit.objects.create(case=case) + page: Page = Page.objects.create(audit=audit, page_type=Page.Type.HOME) + check_result: CheckResult = CheckResult.objects.create( + audit=audit, + page=page, + check_result_state=CheckResult.Result.ERROR, + retest_state=CheckResult.RetestResult.NOT_FIXED, + type=wcag_definition.type, + wcag_definition=wcag_definition, + ) + + assert build_issue_identifier(case=case, issue=check_result) == "1-A-1" + + statement_check: StatementCheck = StatementCheck.objects.all().first() + statement_check_result: StatementCheckResult = StatementCheckResult.objects.create( + audit=audit, + type=statement_check.type, + statement_check=statement_check, + ) + + assert build_issue_identifier(case=case, issue=statement_check_result) == "1-S-1" + + custom_statement_check_result: StatementCheck = StatementCheckResult.objects.create( + audit=audit, + report_comment="Custom statement issue", + ) + + assert ( + build_issue_identifier( + case=case, issue=custom_statement_check_result, custom_issue=True + ) + == "1-SC-2" + ) + + retest: Retest = Retest.objects.create(case=case) + retest_page: RetestPage = RetestPage.objects.create( + retest=retest, + page=page, + ) + retest_check_result: RetestCheckResult = RetestCheckResult.objects.create( + retest=retest, + id_within_case=check_result.id_within_case, + retest_page=retest_page, + check_result=check_result, + ) + + assert build_issue_identifier(case=case, issue=retest_check_result) == "1-A-1" + + retest_statement_check_result: RetestStatementCheckResult = ( + RetestStatementCheckResult.objects.create( + retest=retest, + type=statement_check.type, + statement_check=statement_check, + ) + ) + + assert ( + build_issue_identifier(case=case, issue=retest_statement_check_result) + == "1-S-1" + ) + + custom_retest_statement_check_result: RetestStatementCheckResult = ( + RetestStatementCheckResult.objects.create( + retest=retest, + comment="Custom statement issue", + ) + ) + + assert ( + build_issue_identifier( + case=case, issue=custom_retest_statement_check_result, custom_issue=True + ) + == "1-SC-2" + ) diff --git a/accessibility_monitoring_platform/apps/audits/tests/test_utils.py b/accessibility_monitoring_platform/apps/audits/tests/test_utils.py index 9977ff9ce..9d19cc593 100644 --- a/accessibility_monitoring_platform/apps/audits/tests/test_utils.py +++ b/accessibility_monitoring_platform/apps/audits/tests/test_utils.py @@ -423,7 +423,7 @@ def test_get_all_possible_check_results_for_page(): "wcag_definition": WcagDefinition.objects.get(type=WcagDefinition.Type.PDF), "check_result_state": "not-tested", "notes": "", - "id_within_case": None, + "issue_identifier": "", }, { "wcag_definition": WcagDefinition.objects.get( @@ -431,13 +431,13 @@ def test_get_all_possible_check_results_for_page(): ), "check_result_state": "not-tested", "notes": "", - "id_within_case": 1, + "issue_identifier": "1-A-1", }, { "wcag_definition": WcagDefinition.objects.get(type=WcagDefinition.Type.AXE), "check_result_state": "not-tested", "notes": "", - "id_within_case": None, + "issue_identifier": "", }, ] diff --git a/accessibility_monitoring_platform/apps/audits/tests/test_views.py b/accessibility_monitoring_platform/apps/audits/tests/test_views.py index bc0fbe8c6..00852796a 100644 --- a/accessibility_monitoring_platform/apps/audits/tests/test_views.py +++ b/accessibility_monitoring_platform/apps/audits/tests/test_views.py @@ -1782,7 +1782,15 @@ def test_add_custom_statement_check_result_form_appears(admin_client): follow=True, ) assert response.status_code == 200 - assertContains(response, "Custom issue #1") + assertContains(response, "Custom issue") + + audit_from_db: Audit = Audit.objects.get(id=audit.id) + custom_statment_check_result: StatementCheckResult | None = ( + audit_from_db.custom_statement_check_results.first() + ) + + assert custom_statment_check_result is not None + assertContains(response, custom_statment_check_result.issue_identifier) def test_add_custom_statement_check_result(admin_client): diff --git a/accessibility_monitoring_platform/apps/audits/utils.py b/accessibility_monitoring_platform/apps/audits/utils.py index 46831fc36..72d5a53ca 100644 --- a/accessibility_monitoring_platform/apps/audits/utils.py +++ b/accessibility_monitoring_platform/apps/audits/utils.py @@ -133,17 +133,17 @@ def get_all_possible_check_results_for_page( ] check_result_state: str = check_result.check_result_state notes: str = check_result.notes - id_within_case: int | None = check_result.id_within_case + issue_identifier: str = check_result.issue_identifier else: check_result_state: str = CheckResult.Result.NOT_TESTED notes: str = "" - id_within_case: int | None = None + issue_identifier: str = "" check_results.append( { "wcag_definition": wcag_definition, "check_result_state": check_result_state, "notes": notes, - "id_within_case": id_within_case, + "issue_identifier": issue_identifier, } ) return check_results @@ -320,9 +320,14 @@ def create_checkresults_for_retest(retest: Retest) -> None: ) today: date = date.today() + id_within_case: int = 0 for statement_check in StatementCheck.objects.on_date(today): + id_within_case += 1 RetestStatementCheckResult.objects.create( - retest=retest, statement_check=statement_check, type=statement_check.type + retest=retest, + statement_check=statement_check, + type=statement_check.type, + id_within_case=id_within_case, ) diff --git a/accessibility_monitoring_platform/apps/audits/views/initial.py b/accessibility_monitoring_platform/apps/audits/views/initial.py index 1a4f4d8c7..50d13e329 100644 --- a/accessibility_monitoring_platform/apps/audits/views/initial.py +++ b/accessibility_monitoring_platform/apps/audits/views/initial.py @@ -284,12 +284,7 @@ def get_context_data(self, **kwargs: dict[str, Any]) -> dict[str, Any]: ] = [] for count, check_results_form in enumerate(check_results_formset.forms): wcag_definition: WcagDefinition = wcag_definitions[count] - if check_results_form.initial.get("id_within_case") is not None: - check_results_form.fields["check_result_state"].label = ( - f'{wcag_definition} | #E{check_results_form.initial["id_within_case"]}' - ) - else: - check_results_form.fields["check_result_state"].label = wcag_definition + check_results_form.fields["check_result_state"].label = wcag_definition definitions_forms_errors.append( ( wcag_definition, diff --git a/accessibility_monitoring_platform/apps/cases/models.py b/accessibility_monitoring_platform/apps/cases/models.py index 943a171ec..b2c6084dc 100644 --- a/accessibility_monitoring_platform/apps/cases/models.py +++ b/accessibility_monitoring_platform/apps/cases/models.py @@ -454,7 +454,7 @@ class Meta: ordering = ["-id"] def __str__(self) -> str: - return str(f"{self.organisation_name} | #{self.case_number}") + return f"{self.organisation_name} | #{self.case_number}" def get_absolute_url(self) -> str: return reverse("cases:case-detail", kwargs={"pk": self.pk}) @@ -1406,7 +1406,7 @@ class Meta: ordering = ["event_time"] def __str__(self) -> str: - return str(f"{self.case.organisation_name}: {self.message}") + return f"{self.case.organisation_name}: {self.message}" class EqualityBodyCorrespondence(models.Model): @@ -1445,7 +1445,7 @@ class Meta: ordering = ["-id"] def __str__(self) -> str: - return str(f"Equality body correspondence #{self.id_within_case}") + return f"Equality body correspondence #{self.id_within_case}" def get_absolute_url(self) -> str: return reverse( @@ -1478,7 +1478,7 @@ class Meta: ordering = ["-id"] def __str__(self) -> str: - return str(self.url) + return self.url def get_absolute_url(self) -> str: return reverse("cases:update-zendesk-ticket", kwargs={"pk": self.id}) diff --git a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_page_wcag_results.html b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_page_wcag_results.html index ebbbf61eb..04ebbe600 100644 --- a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_page_wcag_results.html +++ b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_page_wcag_results.html @@ -6,7 +6,10 @@ {% for check_result in case_detail_page.page.instance.failed_check_results %} - {{ check_result.wcag_definition }} + + {{ check_result.wcag_definition }}
    + {% include 'audits/helpers/issue_identifier.html' with issue=check_result %} + {{ check_result.notes|markdown_to_html }} {% endfor %} diff --git a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_statement_checks.html b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_statement_checks.html index 701c61ea4..d2465f5ec 100644 --- a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_statement_checks.html +++ b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_initial_statement_checks.html @@ -7,7 +7,8 @@ {% for statement_check_result in statement_check_results %} - {{ statement_check_result.label }} + {{ statement_check_result.label }}
    + {% include 'audits/helpers/issue_identifier.html' with issue=statement_check_result %}

    {{ statement_check_result.get_check_result_state_display }}

    diff --git a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_page_wcag_results.html b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_page_wcag_results.html index a32575aa7..ba1829dc2 100644 --- a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_page_wcag_results.html +++ b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_page_wcag_results.html @@ -13,6 +13,7 @@ + {% include 'audits/helpers/issue_identifier.html' with issue=check_result %} diff --git a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_statement_checks.html b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_statement_checks.html index a50bcbd47..d4b652553 100644 --- a/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_statement_checks.html +++ b/accessibility_monitoring_platform/apps/cases/templates/cases/details/details_twelve_week_statement_checks.html @@ -14,7 +14,8 @@ {% for statement_check_result in statement_check_results %} - {{ statement_check_result.label }} + {{ statement_check_result.label }}
    + {% include 'audits/helpers/issue_identifier.html' with issue=statement_check_result %} {{ statement_check_result.get_check_result_state_display }} diff --git a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/4-12-week-update-request.html b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/4-12-week-update-request.html index 7a6d4786e..8a42423c8 100644 --- a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/4-12-week-update-request.html +++ b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/4-12-week-update-request.html @@ -55,7 +55,6 @@

    {{ issues_table.page }}{% if issues_table.page.page_type != 'pdf' %} page{% - @@ -64,7 +63,6 @@

    {{ issues_table.page }}{% if issues_table.page.page_type != 'pdf' %} page{%

    {% for row in issues_table.rows %} - @@ -94,16 +92,17 @@

    Accessibility statement comments

    # Issue and description Where the issue was found 12-week update
    {{ forloop.counter }} {{ row.cell_content_1|markdown_to_html }} {{ row.cell_content_2|markdown_to_html }}
    - - - + + {% for statement_check_result in case.audit.failed_statement_check_results %} - - - + {% endfor %} diff --git a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5a-outstanding-issues-initial-test-notes.html b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5a-outstanding-issues-initial-test-notes.html index db1b76d16..f6e61fb49 100644 --- a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5a-outstanding-issues-initial-test-notes.html +++ b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5a-outstanding-issues-initial-test-notes.html @@ -16,7 +16,6 @@

    {{ page }}{% if page.page_type != 'pdf' %} page{% endif %} issues

    #Issue and description12-week updateIssue and description12-week update
    {{ forloop.counter }} + + Issue identifier: {{ statement_check_result.issue_identifier }} +
    +
    {{ statement_check_result.statement_check.report_text }} {% if statement_check_result.report_comment %}
    @@ -111,7 +110,7 @@

    Accessibility statement comments

    {{ statement_check_result.report_comment }} {% endif %}
    - @@ -25,9 +24,9 @@

    {{ page }}{% if page.page_type != 'pdf' %} page{% endif %} issues

    {% for check_result in page.unfixed_check_results %} - @@ -48,20 +47,19 @@

    Your statement

    # Issue and description Notes Organisation update
    {{ forloop.counter }} - {{ check_result.wcag_definition.name }} +

    Issue identifier: {{ check_result.issue_identifier }}

    +

    {{ check_result.wcag_definition.name }}

    {{ check_result.notes|markdown_to_html }}
    - - - + + {% for statement_check_result in case.audit.outstanding_statement_check_results %} - - - diff --git a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5b-outstanding-issues-12-week-retest-notes.html b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5b-outstanding-issues-12-week-retest-notes.html index 7056fc6db..11e666b43 100644 --- a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5b-outstanding-issues-12-week-retest-notes.html +++ b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5b-outstanding-issues-12-week-retest-notes.html @@ -20,7 +20,6 @@

    {{ page }}{% if page.page_type != 'pdf' %} page{% endif %} issues

    #IssueOrganisation updateIssueOrganisation update
    {{ forloop.counter }} + +

    Issue identifier: {{ statement_check_result.issue_identifier }}

    {{ statement_check_result.statement_check.report_text }}

    {{ statement_check_result.report_comment|markdown_to_html }}
    + {{ statement_check_result.retest_comment|markdown_to_html }}
    - @@ -29,8 +28,8 @@

    {{ page }}{% if page.page_type != 'pdf' %} page{% endif %} issues

    {% for check_result in page.unfixed_check_results %} - @@ -60,7 +59,6 @@

    Your statement

    # Issue and description Retest notes Organisation update
    {{ forloop.counter }} +

    Issue identifier: {{ check_result.issue_identifier }}

    {{ check_result.wcag_definition.name }}

    {{ check_result.notes|markdown_to_html }}
    - @@ -69,8 +67,8 @@

    Your statement

    {% for statement_check_result in case.audit.outstanding_statement_check_results %} -
    # Issue Notes Organisation update
    {{ forloop.counter }} +

    Issue identifier: {{ statement_check_result.issue_identifier }}

    {{ statement_check_result.statement_check.report_text }}

    diff --git a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5c-outstanding-issues-12-week-retest-notes-statement-only.html b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5c-outstanding-issues-12-week-retest-notes-statement-only.html index 5b13996b2..70f4e4d73 100644 --- a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5c-outstanding-issues-12-week-retest-notes-statement-only.html +++ b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/5c-outstanding-issues-12-week-retest-notes-statement-only.html @@ -11,7 +11,6 @@

    Your statement

    - @@ -20,8 +19,8 @@

    Your statement

    {% for statement_check_result in case.audit.outstanding_statement_check_results %} -
    # Issue Notes Organisation update
    {{ forloop.counter }} +

    Issue identifier: {{ statement_check_result.issue_identifier }}

    {{ statement_check_result.statement_check.report_text }}

    diff --git a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7a-equality-body-retest-all-issues.html b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7a-equality-body-retest-all-issues.html index 806bde7ae..9f0fe5a09 100644 --- a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7a-equality-body-retest-all-issues.html +++ b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7a-equality-body-retest-all-issues.html @@ -110,7 +110,6 @@

    Errors found in retest

    - @@ -119,8 +118,10 @@

    Errors found in retest

    {% for retest_check_result in retest_page.original_check_results %} -
    # Issue and description Where the issue was found Retest outcome
    {{ forloop.counter }} + Issue identifier: {{ retest_check_result.issue_identifier }} +
    +
    {% if retest_check_result.check_result.wcag_definition.url_on_w3 %} {{ retest_check_result.check_result.wcag_definition.name }} @@ -184,15 +185,16 @@

    Statement assessment

    - - + {% for failed_statement_check_result in retest.failed_statement_check_results %} - -
    #IssueIssue
    {{ forloop.counter }} + + Issue identifier: {{ failed_statement_check_result.issue_identifier }} +
    +
    {{ failed_statement_check_result.statement_check.report_text }} {% if failed_statement_check_result.comment %}
    diff --git a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7b-equality-body-retest-unfixed-issues.html b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7b-equality-body-retest-unfixed-issues.html index 5e8741a81..73e9fc583 100644 --- a/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7b-equality-body-retest-unfixed-issues.html +++ b/accessibility_monitoring_platform/apps/common/templates/common/emails/backup/7b-equality-body-retest-unfixed-issues.html @@ -117,7 +117,6 @@

    Errors found in retest

    - @@ -126,8 +125,10 @@

    Errors found in retest

    {% for retest_check_result in retest_page.unfixed_check_results %} -
    # Issue and description Where the issue was found Retest outcome
    {{ forloop.counter }} + Issue identifier: {{ retest_check_result.issue_identifier }} +
    +
    {% if retest_check_result.check_result.wcag_definition.url_on_w3 %} {{ retest_check_result.check_result.wcag_definition.name }} @@ -192,15 +193,16 @@

    Statement assessment

    - - + {% for failed_statement_check_result in retest.failed_statement_check_results %} - -
    #IssueIssue
    {{ forloop.counter }} + + Issue identifier: {{ failed_statement_check_result.issue_identifier }} +
    +
    {{ failed_statement_check_result.statement_check.report_text }} {% if failed_statement_check_result.comment %}
    diff --git a/accessibility_monitoring_platform/apps/reports/migrations/0006_alter_report_report_version.py b/accessibility_monitoring_platform/apps/reports/migrations/0006_alter_report_report_version.py new file mode 100644 index 000000000..0394092c1 --- /dev/null +++ b/accessibility_monitoring_platform/apps/reports/migrations/0006_alter_report_report_version.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.4 on 2025-01-22 14:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("reports", "0005_alter_report_report_version"), + ] + + operations = [ + migrations.AlterField( + model_name="report", + name="report_version", + field=models.TextField(default="v1_6_0__20250122"), + ), + ] diff --git a/accessibility_monitoring_platform/apps/reports/models.py b/accessibility_monitoring_platform/apps/reports/models.py index 5900d2cdf..7e9cea984 100644 --- a/accessibility_monitoring_platform/apps/reports/models.py +++ b/accessibility_monitoring_platform/apps/reports/models.py @@ -15,7 +15,7 @@ from ..common.utils import amp_format_datetime from ..s3_read_write.models import S3Report -REPORT_VERSION_DEFAULT: str = "v1_5_0__20241125" +REPORT_VERSION_DEFAULT: str = "v1_6_0__20250122" WRAPPER_TEXT_FIELDS: list[str] = [ "title", "sent_by", diff --git a/accessibility_monitoring_platform/apps/reports/tests/test_models.py b/accessibility_monitoring_platform/apps/reports/tests/test_models.py index a7327af2d..b2c6f77b7 100644 --- a/accessibility_monitoring_platform/apps/reports/tests/test_models.py +++ b/accessibility_monitoring_platform/apps/reports/tests/test_models.py @@ -63,7 +63,7 @@ def test_report_template_path_is_correct(): assert ( report.template_path - == "reports_common/accessibility_report_v1_5_0__20241125.html" + == "reports_common/accessibility_report_v1_6_0__20250122.html" ) diff --git a/accessibility_monitoring_platform/apps/reports/utils.py b/accessibility_monitoring_platform/apps/reports/utils.py index 493886b70..ccf829c89 100644 --- a/accessibility_monitoring_platform/apps/reports/utils.py +++ b/accessibility_monitoring_platform/apps/reports/utils.py @@ -16,7 +16,9 @@ from ..s3_read_write.utils import S3ReadWriteReport from .models import Report -WCAG_DEFINITION_BOILERPLATE_TEMPLATE: str = """{% if wcag_definition.url_on_w3 %}[{{ wcag_definition.name }}]({{ wcag_definition.url_on_w3 }}){% if wcag_definition.description and wcag_definition.type != 'manual' %}: {% endif %}{% else %}{{ wcag_definition.name }}{% if wcag_definition.description and wcag_definition.type != 'manual' %}: {% endif %}{% endif %}{% if wcag_definition.description and wcag_definition.type != 'manual' %}{{ wcag_definition.description|safe }}.{% endif %} +WCAG_DEFINITION_BOILERPLATE_TEMPLATE: str = """Issue identifier: {{ check_result.issue_identifier }} + +{% if wcag_definition.url_on_w3 %}[{{ wcag_definition.name }}]({{ wcag_definition.url_on_w3 }}){% if wcag_definition.description and wcag_definition.type != 'manual' %}: {% endif %}{% else %}{{ wcag_definition.name }}{% if wcag_definition.description and wcag_definition.type != 'manual' %}: {% endif %}{% endif %}{% if wcag_definition.description and wcag_definition.type != 'manual' %}{{ wcag_definition.description|safe }}.{% endif %} {% if first_use_of_wcag_definition %} {{ wcag_definition.report_boilerplate|safe }} {% endif %}""" @@ -135,6 +137,7 @@ def build_issue_table_rows( { "wcag_definition": check_result.wcag_definition, "first_use_of_wcag_definition": first_use_of_wcag_definition, + "check_result": check_result, } ) check_result_context: Context = Context({"check_result": check_result}) diff --git a/common/static/scss/_global.scss b/common/static/scss/_global.scss index 77ea4499d..ed2337a8a 100644 --- a/common/static/scss/_global.scss +++ b/common/static/scss/_global.scss @@ -692,11 +692,6 @@ img, .amp-max-width-100 { table[id^='issues-table-'] { page-break-before: always; - tr td:nth-child(1) { - width: 1%; - white-space: nowrap; - } - td+td { width: 50%; } @@ -705,11 +700,6 @@ img, .amp-max-width-100 { table[id^='email-issues-table-'] { table-layout:fixed; - tr td:nth-child(1) { - width: 1%; - white-space: nowrap; - } - td { width: 33%; } diff --git a/common/templates/reports_common/accessibility_report_v1_6_0__20250122.html b/common/templates/reports_common/accessibility_report_v1_6_0__20250122.html new file mode 100644 index 000000000..bb1bdaaba --- /dev/null +++ b/common/templates/reports_common/accessibility_report_v1_6_0__20250122.html @@ -0,0 +1,294 @@ +{% load static %} + + + +
    +

    Introduction

    +

    + Website accessibility regulations came into force on 23 September 2018. + The regulations mean that public sector bodies now have a legal obligation to + meet accessibility requirements for their websites. +

    +

    + To check how well the public sector are meeting the requirements, the Government + Digital Service has been monitoring a sample of + public sector websites. +

    +

    + You’ve been sent this report because + {% if audit.case.website_name %} + {{ audit.case.website_name }} + ({{ audit.case.home_page_url }}) + {% else %} + {{ audit.case.home_page_url }} + {% endif %} + is one of the websites we’ve monitored. This report explains: +

    +
      +
    • which parts of your website we looked at
    • +
    • how we checked the accessibility of those pages
    • +
    • the accessibility issues found and how important they are
    • +
    • what you need to do next to fix the issues
    • +
    +

    + You can + read more about the web accessibility regulations. +

    + +
    +

    How accessible the website is

    +

    + We checked + {% if audit.case.website_name %} + {{ audit.case.website_name }} + ({{ audit.case.home_page_url }}) + {% else %} + {{ audit.case.home_page_url }} + {% endif %} + on + {{ audit.date_of_test|date:"j F Y" }} + against the + Web Content Accessibility Guidelines (WCAG) 2.2 AA + standard. +

    +

    + {% if audit.case.compliance.website_compliance_state_initial == 'not-compliant' %} + Based on our testing, this site is not compliant with WCAG 2.2 AA. + This means there are some things which would cause significant barriers + to users with certain accessibility needs. + {% elif audit.case.compliance.website_compliance_state_initial == 'partially-compliant' %} + Based on our testing, this site is partially compliant with WCAG 2.2 AA. + This means there are some things which are not fully accessible. + {% elif audit.case.compliance.website_compliance_state_initial == 'compliant' %} + Based on our testing, this site is compliant with WCAG 2.2 AA. + This means no serious or critical issues were found during our testing. + We run basic tests on a small part of your website so we can't say for + certain that your entire site will meet the regulations. + {% endif %} +

    + +
    +

    How we checked

    +

    + We use a mixture of simple manual checks and automated tests to find only + the most common barriers to users with accessibility needs. + We would expect your organisation to fully audit the website to find any + other accessibility issues. +

    +

    + Manual checks included using each page without a mouse, viewing the page at + different zoom settings, and simulating viewing the page on a small screen. +

    +

    + The automated tests were completed using the latest version of + Axe. +

    +

    + Tests were completed using different settings in the Google Chrome browser + on Mac OSX with a {{ audit.get_screen_size_display }} screen. +

    + +
    +

    Pages we checked

    + + + + + + + + + + {% for page in audit.testable_pages %} + + + + + {% endfor %} + +
    Names and URLs of the pages we checked
    Page NameURL
    {{ page }}{{ page.url }} {{ page.location }}
    + +
    +

    The issues we found

    +

    + Only serious accessibility issues on the sample of pages we tested are + listed in this report – these will cause problems for users with access + needs when using your website. There are likely to be smaller errors which + will make things more difficult for some users. You must carry out your own + audit to find and fix issues. +

    + +{% for issues_table in issues_tables %} +
    +

    + {{ issues_table.page }}{% if issues_table.page.page_type != 'pdf' %} page{% endif %} accessibility issues +

    +

    + {{ issues_table.page.url }} + {{ issues_table.page.location }} +

    + {% if issues_table.rows %} + + + + + + + + + + {% for row in issues_table.rows %} + + + + + {% endfor %} + +
    Issues found on page
    Issue and descriptionWhere the issue was found
    {{ row.cell_content_1|markdown_to_html }}{{ row.cell_content_2|markdown_to_html }}
    + {% else %} +

    We found no major accessibility issues.

    + {% endif %} +{% endfor %} + +
    +

    Your accessibility statement

    +

    + As part of the regulations you must publish an accessibility statement. +

    +

    +{% if audit.accessibility_statement_found and audit.statement_check_result_statement_found %} + {% if audit.failed_statement_check_results %} +

    + An accessibility statement for the website was found but we found the following issues. +

    + + + + + + + + + {% for statement_check_result in audit.failed_statement_check_results %} + + + + {% endfor %} + +
    Issues found on accessibility statement
    Issue
    + Issue identifier: {{ statement_check_result.issue_identifier }} + {{ statement_check_result.statement_check.report_text|markdown_to_html }} + {% if statement_check_result.report_comment %} + {{ statement_check_result.report_comment|markdown_to_html }} + {% endif %} +
    + {% else %} +

    + An accessibility statement for the website was found in the correct format. +

    + {% endif %} +{% else %} + {% if audit.statement_found_check.check_result_state != 'yes' %} +

    {{ audit.statement_found_check.statement_check.report_text|markdown_to_html }}

    + {% elif audit.statement_structure_check.check_result_state != 'yes' %} +

    {{ audit.statement_structure_check.statement_check.report_text|markdown_to_html }}

    + {% else %} +

    + An accessibility page for the website could not be found or the accessibility page did + not include a statement. Every public sector website must include an + accessibility statement and it is against the law to not have one. +

    + {% endif %} +{% endif %} +{{ audit.statement_extra_report_text|markdown_to_html }} +

    + More information about accessibility statements can be found at + https://www.gov.uk/guidance/accessibility-requirements-for-public-sector-websites-and-apps. +

    +

    + The model statement can be found at + https://www.gov.uk/guidance/model-accessibility-statement. +

    + +
    +

    What to do next

    +

    + It is a requirement of The Public Sector Bodies (Websites and Mobile + Applications) (No. 2) Accessibility Regulations 2018 that public sector + websites are accessible. +

    +

    + You should fix any issues that were found and do your own accessibility + audit to check for issues that go beyond the scope of simple accessibility + testing. +

    + +
    +

    Enforcement

    +

    + On behalf of the Minister for the Cabinet Office we provide the + {% if audit.case.enforcement_body == 'ehrc' %} + Equality and Human Rights Commission (EHRC) + {% else %} + Equality Commission for Northern Ireland (ECNI) + {% endif %} + with details about public sector bodies who have been monitored. If + accessibility issues remain after giving you time to fix them, the + {% if audit.case.enforcement_body == 'ehrc' %} + EHRC + {% else %} + ECNI + {% endif %} + may take further action. +

    +

    + Public sector bodies must publish an accessibility statement and review it + regularly. If the decision is taken that a public sector body has failed to + publish an accessibility statement or that the accessibility statement is + incorrect, the Minister for the Cabinet Office may publish the name of the + body and a copy of the decision. +

    +

    + The enforcement process can be found at + https://www.gov.uk/guidance/accessibility-requirements-for-public-sector-websites-and-apps#how-the-accessibility-regulations-will-be-monitored-and-enforced. +

    + +
    +

    Contact and more information

    +

    + This test was conducted by the Government Digital Service on behalf of the + Minister of the Cabinet Office as part of their obligations to monitor the + accessibility of public sector websites in the United Kingdom. +

    +

    + As the monitoring body we cannot offer specific advice on approaches or + general accessibility queries other than questions directly related to the + items in this report. +

    +

    + Any questions about this report can be sent to + accessibility-monitoring@digital.cabinet-office.gov.uk. +

    +

    + Further information on guidance and tools for digital accessibility can be found at + https://www.gov.uk/guidance/guidance-and-tools-for-digital-accessibility. +

    +

    + Help with accessibility auditing and publishing an accessibility statement can be found at + https://www.gov.uk/guidance/make-your-website-or-app-accessible-and-publish-an-accessibility-statement. +