Skip to content

Commit

Permalink
Merge pull request #2658 from GSA-TTS/main
Browse files Browse the repository at this point in the history
2023-10-31 main -> prod
  • Loading branch information
asteel-gsa authored Oct 31, 2023
2 parents 7f447d8 + e75b450 commit ab2dd30
Show file tree
Hide file tree
Showing 11 changed files with 646 additions and 88 deletions.
2 changes: 2 additions & 0 deletions backend/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.humanize",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.postgres",
"django.contrib.staticfiles",
]

Expand Down
5 changes: 4 additions & 1 deletion backend/dissemination/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ def search_general(
# TODO: use something like auditee_name__contains
# SELECT * WHERE auditee_name LIKE '%SomeString%'
if names:
names_match = Q(Q(auditee_name__in=names) | Q(auditor_firm_name__in=names))
names_match = Q()
for name in names:
names_match.add(Q(auditee_name__search=name), Q.OR)
names_match.add(Q(auditor_firm_name__search=name), Q.OR)
query.add(names_match, Q.AND)

if uei_or_eins:
Expand Down
472 changes: 409 additions & 63 deletions backend/dissemination/templates/summary.html

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions backend/dissemination/templatetags/getkey.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""
Custom tag to pull a key with a space out of a dictionary.
Example:
{{ data.'Notes to SEFA' }} does not work.
Instead, {{ data|getkey:"Notes to SEFA" }}
"""
from django import template

register = template.Library()


@register.filter(name="getkey")
def getkey(value, arg):
return value.get(arg, [])
32 changes: 28 additions & 4 deletions backend/dissemination/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,32 @@ def test_name_multiple(self):
assert_all_results_public(self, results)
self.assertEqual(len(results), 2)

def test_name_matches_inexact(self):
"""
Given a partial name, search_general should return records whose name fields contain the term, even if not an exact match
"""
auditee_match = baker.make(
General, is_public=True, auditee_name="the university of somewhere"
)
auditor_match = baker.make(
General, is_public=True, auditor_firm_name="auditors unite, LLC"
)
baker.make(General, is_public=True, auditee_name="not looking for this auditee")
baker.make(
General,
is_public=True,
auditor_firm_name="not looking for this auditor firm",
)

results = search_general(
names=["UNIVERSITY", "unitE", "there is not match for this one"]
)

assert_all_results_public(self, results)
self.assertEqual(len(results), 2)
self.assertEqual(results[0], auditee_match)
self.assertEqual(results[1], auditor_match)

def test_uei_or_ein_matches_uei(self):
"""
Given a uei_or_ein, search_general should return records with a matching UEI
Expand Down Expand Up @@ -194,13 +220,13 @@ def test_oversight_agency(self):
baker.make(General, is_public=True, oversight_agency="02")

results = search_general(
cog_or_oversight="cog",
cog_or_oversight="oversight",
agency_name="01",
)

assert_all_results_public(self, results)
self.assertEqual(len(results), 1)
self.assertEqual(results[0].cognizant_agency, "01")
self.assertEqual(results[0].oversight_agency, "01")

def test_audit_year(self):
"""
Expand All @@ -225,5 +251,3 @@ def test_audit_year(self):
audit_years=[2020, 2021, 2022],
)
self.assertEqual(len(results), 3)

return
146 changes: 146 additions & 0 deletions backend/dissemination/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
from django.test import Client, TestCase
from django.urls import reverse

from audit.models import (
ExcelFile,
SingleAuditChecklist,
SingleAuditReportFile,
generate_sac_report_id,
)
from dissemination.models import General

from model_bakery import baker
from unittest.mock import patch


class PdfDownloadViewTests(TestCase):
def setUp(self):
self.client = Client()

def _make_sac_and_general(self):
sac = baker.make(
SingleAuditChecklist,
report_id=generate_sac_report_id(end_date="2023-12-31"),
)
general = baker.make(General, is_public=True, report_id=sac.report_id)
return sac, general

def test_bad_report_id_returns_404(self):
url = reverse("dissemination:PdfDownload", kwargs={"report_id": "not-real"})

response = self.client.get(url)

self.assertEqual(response.status_code, 404)

def test_not_public_returns_403(self):
general = baker.make(General, is_public=False)

url = reverse(
"dissemination:PdfDownload", kwargs={"report_id": general.report_id}
)

response = self.client.get(url)

self.assertEqual(response.status_code, 403)

def test_no_file_returns_404(self):
sac, general = self._make_sac_and_general()

url = reverse(
"dissemination:PdfDownload", kwargs={"report_id": general.report_id}
)

response = self.client.get(url)

self.assertEqual(response.status_code, 404)

@patch("audit.file_downloads.file_exists")
def test_file_exists_returns_302(self, mock_file_exists):
mock_file_exists.return_value = True

sac, general = self._make_sac_and_general()

file = baker.make(SingleAuditReportFile, sac=sac)

url = reverse(
"dissemination:PdfDownload", kwargs={"report_id": general.report_id}
)

response = self.client.get(url)

self.assertEqual(response.status_code, 302)
self.assertIn(file.filename, response.url)


class XlsxDownloadViewTests(TestCase):
def setUp(self):
self.client = Client()

def _make_sac_and_general(self):
sac = baker.make(
SingleAuditChecklist,
report_id=generate_sac_report_id(end_date="2023-12-31"),
)
general = baker.make(General, is_public=True, report_id=sac.report_id)
return sac, general

def test_bad_report_id_returns_404(self):
url = reverse(
"dissemination:XlsxDownload",
kwargs={"report_id": "not-real", "file_type": "FederalAwardsExpended"},
)

response = self.client.get(url)

self.assertEqual(response.status_code, 404)

def test_not_public_returns_403(self):
general = baker.make(General, is_public=False)

url = reverse(
"dissemination:XlsxDownload",
kwargs={
"report_id": general.report_id,
"file_type": "FederalAwardsExpended",
},
)

response = self.client.get(url)

self.assertEqual(response.status_code, 403)

def test_no_file_returns_404(self):
sac, general = self._make_sac_and_general()

url = reverse(
"dissemination:XlsxDownload",
kwargs={
"report_id": general.report_id,
"file_type": "FederalAwardsExpended",
},
)

response = self.client.get(url)

self.assertEqual(response.status_code, 404)

@patch("audit.file_downloads.file_exists")
def test_file_exists_returns_302(self, mock_file_exists):
mock_file_exists.return_value = True

sac, general = self._make_sac_and_general()

file = baker.make(ExcelFile, sac=sac, form_section="FederalAwardsExpended")

url = reverse(
"dissemination:XlsxDownload",
kwargs={
"report_id": general.report_id,
"file_type": "FederalAwardsExpended",
},
)

response = self.client.get(url)

self.assertEqual(response.status_code, 302)
self.assertIn(file.filename, response.url)
8 changes: 1 addition & 7 deletions backend/dissemination/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from dissemination.models import (
General,
FederalAward,
Passthrough,
Finding,
FindingText,
CapText,
Expand Down Expand Up @@ -124,7 +123,6 @@ def test_summary_context(self):
"""
baker.make(General, report_id="2022-12-GSAFAC-0000000001", is_public=True)
award = baker.make(FederalAward, report_id="2022-12-GSAFAC-0000000001")
passthrough = baker.make(Passthrough, report_id="2022-12-GSAFAC-0000000001")
finding = baker.make(Finding, report_id="2022-12-GSAFAC-0000000001")
finding_text = baker.make(FindingText, report_id="2022-12-GSAFAC-0000000001")
cap_text = baker.make(CapText, report_id="2022-12-GSAFAC-0000000001")
Expand All @@ -139,10 +137,6 @@ def test_summary_context(self):
response.context["data"]["Awards"][0]["additional_award_identification"],
award.additional_award_identification,
)
self.assertEquals(
response.context["data"]["Passthrough Entities"][0]["award_reference"],
passthrough.award_reference,
)
self.assertEquals(
response.context["data"]["Audit Findings"][0]["reference_number"],
finding.reference_number,
Expand All @@ -158,6 +152,6 @@ def test_summary_context(self):
cap_text.contains_chart_or_table,
)
self.assertEquals(
response.context["data"]["Notes"][0]["accounting_policies"],
response.context["data"]["Notes to SEFA"][0]["accounting_policies"],
note.accounting_policies,
)
11 changes: 10 additions & 1 deletion backend/dissemination/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@
app_name = "dissemination"

urlpatterns = [
path("pdf/<str:report_id>", views.PdfDownloadView.as_view(), name="PdfDownload"),
path(
"workbook/xlsx/<str:file_type>/<str:report_id>",
views.XlsxDownloadView.as_view(),
name="XlsxDownload",
),
path(
"report/pdf/<str:report_id>",
views.PdfDownloadView.as_view(),
name="PdfDownload",
),
path("search/", views.Search.as_view(), name="Search"),
path("summary/<str:report_id>", views.AuditSummaryView.as_view(), name="Summary"),
]
40 changes: 29 additions & 11 deletions backend/dissemination/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
from dissemination.models import (
General,
FederalAward,
Passthrough,
Finding,
FindingText,
CapText,
Note,
SecondaryAuditor,
AdditionalEin,
AdditionalUei,
)


Expand Down Expand Up @@ -97,20 +99,22 @@ def get_audit_content(self, report_id):
further. I.e. remove DB ids or something.
"""
awards = FederalAward.objects.filter(report_id=report_id)
passthrough_entities = Passthrough.objects.filter(report_id=report_id)
audit_findings = Finding.objects.filter(report_id=report_id)
audit_findings_text = FindingText.objects.filter(report_id=report_id)
corrective_action_plan = CapText.objects.filter(report_id=report_id)
notes_to_sefa = Note.objects.filter(report_id=report_id)
secondary_auditors = SecondaryAuditor.objects.filter(report_id=report_id)
additional_ueis = AdditionalUei.objects.filter(report_id=report_id)
additional_eins = AdditionalEin.objects.filter(report_id=report_id)

data = {}

data["Awards"] = [
x for x in awards.values()
] # Take QuerySet to a list of objects

if passthrough_entities.exists():
data["Passthrough Entities"] = [x for x in passthrough_entities.values()]
if notes_to_sefa.exists():
data["Notes to SEFA"] = [x for x in notes_to_sefa.values()]
if audit_findings.exists():
data["Audit Findings"] = [x for x in audit_findings.values()]
if audit_findings_text.exists():
Expand All @@ -119,13 +123,12 @@ def get_audit_content(self, report_id):
data["Corrective Action Plan"] = [
x for x in corrective_action_plan.values()
]
if notes_to_sefa.exists():
data["Notes"] = [x for x in notes_to_sefa.values()]

for key in data:
for item in data[key]:
del item["id"]
del item["report_id"]
if secondary_auditors.exists():
data["Secondary Auditors"] = [x for x in secondary_auditors.values()]
if additional_ueis.exists():
data["Additional UEIs"] = [x for x in additional_ueis.values()]
if additional_eins.exists():
data["Additional EINs"] = [x for x in additional_eins.values()]

return data

Expand All @@ -143,3 +146,18 @@ def get(self, request, report_id):
filename = get_filename(sac, "report")

return redirect(get_download_url(filename))


class XlsxDownloadView(View):
def get(self, request, report_id, file_type):
# only allow xlsx downloads from disseminated submissions
disseminated = get_object_or_404(General, report_id=report_id)

# only allow xlsx downloads for public submissions
if not disseminated.is_public:
raise PermissionDenied("You do not have access to this file.")

sac = get_object_or_404(SingleAuditChecklist, report_id=report_id)
filename = get_filename(sac, file_type)

return redirect(get_download_url(filename))
2 changes: 2 additions & 0 deletions backend/static/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
$theme-font-path: '../fonts',
$theme-image-path: '../img',
$theme-font-type-sans: 'public-sans',
$theme-font-weight-semibold: 600,
$theme-type-scale-md: 7,
$theme-type-scale-2xl: 13,
$theme-color-success-lighter: #eef8eb,
$theme-color-base-lighter: #efefef,
);
@forward 'uswds';
@use '_home.scss';
Expand Down
2 changes: 1 addition & 1 deletion backend/templates/audit-metadata.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- Audit metadata. Included at the bottom of several screens. -->
{% comment %} Audit metadata. Included at the bottom of several screens. {% endcomment %}
<div class="audit-metadata">
<div class="grid-container">
<dl class="grid-row grid-gap">
Expand Down

0 comments on commit ab2dd30

Please sign in to comment.