Skip to content

Commit

Permalink
Disabling SF-SAC download button when unavailable (#4139)
Browse files Browse the repository at this point in the history
* Handling disabling SF-SAC download button

* Lint

* Using tooltip instead of title

* Fixing button styling

* Lint

* Fixing unit tests

* Lint

* Lint

* Adding unit test

* Lint

* Lint

* Adding noreferrer

* Using real FAQ link
  • Loading branch information
phildominguez-gsa authored Aug 7, 2024
1 parent 5f89fd8 commit 074cf7b
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 42 deletions.
50 changes: 36 additions & 14 deletions backend/dissemination/templates/summary.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,44 @@ <h1 class="usa-legend usa-legend--large font-sans-2xl">Single audit summary</h1>
</div>
<div class="grid-col-12 tablet:grid-col-5 tablet:display-flex flex-column tablet:flex-justify-end">
<div class="margin-0 flex-align-self-end margin-top-2">

<a class="usa-button display-flex font-sans-xl margin-bottom-2"
href="{% url 'dissemination:SummaryReportDownload' report_id=report_id %}"
target="_blank">
<svg class="usa-icon margin-right-1 flex-align-self-center"
aria-hidden="true"
role="img">
{% uswds_sprite "file_download" %}
</svg>
<p class="margin-0">SF-SAC</p>
</a>

<div class="display-flex flex-row">
<a class="usa-button display-flex flex-fill font-sans-xl margin-bottom-2"
target="_blank"
rel="noopener noreferrer"
{% if is_sf_sac_downloadable %}
href="{% url 'dissemination:SummaryReportDownload' report_id=report_id %}"
{% else %}
aria-disabled="true"
{% endif %}
>
<svg class="usa-icon margin-right-1 flex-align-self-center"
aria-hidden="true"
role="img">
{% uswds_sprite "file_download" %}
</svg>
<p class="margin-0">SF-SAC</p>
</a>

{% if not is_sf_sac_downloadable %}
<a class="tooltip flex-align-self-center margin-bottom-2"
href="https://support.fac.gov/hc/en-us/articles/29043839561869-I-just-submitted-my-audit-report-Why-can-t-I-download-my-report-from-Search-Is-there-an-error-with-my-submission"
target="_blank"
rel="noopener noreferrer">
<svg class="usa-icon"
aria-hidden="true"
role="img">
{% uswds_sprite "help" %}
</svg>
<span class="tooltiptext">SF-SACs are typically available for download a day after submission. Click to learn more.</span>
</a>
{% endif %}
</div>

{% if general.is_public or include_private %}
<a class="usa-button display-flex font-sans-xl"
href="{% url 'dissemination:PdfDownload' report_id=report_id %}"
target="_blank">
href="{% url 'dissemination:PdfDownload' report_id=report_id %}"
target="_blank"
rel="noopener noreferrer">
<svg class="usa-icon margin-right-1 flex-align-self-center"
aria-hidden="true"
role="img">
Expand Down
31 changes: 31 additions & 0 deletions backend/dissemination/test_materialized_view_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os
from django.db import connection
from django.test import TestCase

# Use this TestMaterializedViewBuilder class as a base class for TestCases that
# make use of a materialized view.


class TestMaterializedViewBuilder(TestCase):
def setUp(self):
super().setUp()
self.execute_sql_file("dissemination/sql/create_materialized_views.sql")

def tearDown(self):
self.execute_sql_file("dissemination/sql/drop_materialized_views.sql")
super().tearDown()

def execute_sql_file(self, relative_path):
"""Execute the SQL commands in the file at the given path."""
full_path = os.path.join(os.getcwd(), relative_path)
try:
with open(full_path, "r") as file:
sql_commands = file.read()
with connection.cursor() as cursor:
cursor.execute(sql_commands)
except Exception as e:
print(f"Error executing SQL command: {e}")

def refresh_materialized_view(self):
"""Refresh the materialized view"""
self.execute_sql_file("dissemination/sql/refresh_materialized_views.sql")
28 changes: 1 addition & 27 deletions backend/dissemination/test_search.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import os
from django.db import connection
from django.test import TestCase
from dissemination.models import (
DisseminationCombined,
Expand All @@ -15,6 +13,7 @@
search,
is_advanced_search,
)
from dissemination.test_materialized_view_builder import TestMaterializedViewBuilder

from model_bakery import baker

Expand Down Expand Up @@ -453,31 +452,6 @@ def test_report_id(self):
self.assertEqual(len(results), 2)


class TestMaterializedViewBuilder(TestCase):
def setUp(self):
super().setUp()
self.execute_sql_file("dissemination/sql/create_materialized_views.sql")

def tearDown(self):
self.execute_sql_file("dissemination/sql/drop_materialized_views.sql")
super().tearDown()

def execute_sql_file(self, relative_path):
"""Execute the SQL commands in the file at the given path."""
full_path = os.path.join(os.getcwd(), relative_path)
try:
with open(full_path, "r") as file:
sql_commands = file.read()
with connection.cursor() as cursor:
cursor.execute(sql_commands)
except Exception as e:
print(f"Error executing SQL command: {e}")

def refresh_materialized_view(self):
"""Refresh the materialized view"""
self.execute_sql_file("dissemination/sql/refresh_materialized_views.sql")


class SearchALNTests(TestMaterializedViewBuilder):
def test_aln_search(self):
"""Given an ALN (or ALNs), search_general should only return records with awards under one of these ALNs."""
Expand Down
34 changes: 33 additions & 1 deletion backend/dissemination/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,9 @@ def test_private_returns_302_for_permissioned(self, mock_file_exists):
self.assertIn(file.filename, response.url)


class SummaryViewTests(TestCase):
class SummaryViewTests(TestMaterializedViewBuilder):
def setUp(self):
super().setUp()
self.client = Client()

def test_public_summary(self):
Expand Down Expand Up @@ -602,6 +603,37 @@ def test_summary_context(self):
note.accounting_policies,
)

def test_sac_download_available(self):
"""
Ensures is_sf_sac_downloadable is True when a submission's SF-SAC is downloadable
"""
gen_object = baker.make(
General, is_public=True, report_id="2022-12-GSAFAC-0000000001"
)
baker.make(
FederalAward,
report_id=gen_object,
)
self.refresh_materialized_view()
url = reverse(
"dissemination:Summary", kwargs={"report_id": "2022-12-GSAFAC-0000000001"}
)

response = self.client.get(url)
self.assertEquals(response.context["is_sf_sac_downloadable"], True)

def test_sac_download_not_available(self):
"""
Ensures is_sf_sac_downloadable is False when a submission's SF-SAC is not downloadable
"""
baker.make(General, report_id="2022-12-GSAFAC-0000000001", is_public=True)
url = reverse(
"dissemination:Summary", kwargs={"report_id": "2022-12-GSAFAC-0000000001"}
)

response = self.client.get(url)
self.assertEquals(response.context["is_sf_sac_downloadable"], False)


class SummaryReportDownloadViewTests(TestMaterializedViewBuilder):
def setUp(self):
Expand Down
5 changes: 5 additions & 0 deletions backend/dissemination/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
AdditionalEin,
AdditionalUei,
OneTimeAccess,
DisseminationCombined,
)

from dissemination.summary_reports import generate_summary_report
Expand Down Expand Up @@ -347,6 +348,9 @@ def get(self, request, report_id):
include_private = include_private_results(request)
include_private_and_public = include_private or general_data["is_public"]
data = self.get_audit_content(report_id, include_private_and_public)
is_sf_sac_downloadable = DisseminationCombined.objects.filter(
report_id=report_id
).exists()

# Add entity name and UEI to the context, for the footer.
context = {
Expand All @@ -356,6 +360,7 @@ def get(self, request, report_id):
"general": general_data,
"include_private": include_private,
"data": data,
"is_sf_sac_downloadable": is_sf_sac_downloadable,
}

return render(request, "summary.html", context)
Expand Down
24 changes: 24 additions & 0 deletions backend/static/scss/_form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,27 @@ ul.usa-error-message {
.cross-validation-loader {
text-align: center;
}

.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}

.tooltip .tooltiptext {
visibility: hidden;
width: 200px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;

/* Position the tooltip */
position: absolute;
z-index: 1;
}

.tooltip:hover .tooltiptext {
visibility: visible;
}

0 comments on commit 074cf7b

Please sign in to comment.