Skip to content

Commit

Permalink
Merge pull request #3000 from GSA-TTS/main
Browse files Browse the repository at this point in the history
2023-12-13 main -> prod
  • Loading branch information
jadudm authored Dec 14, 2023
2 parents 900440c + 980e1d6 commit 6511c62
Show file tree
Hide file tree
Showing 77 changed files with 1,100 additions and 288 deletions.
28 changes: 18 additions & 10 deletions backend/audit/templates/audit/manage-submission-change-access.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,24 @@
method="post">
{% csrf_token %}
<fieldset class="usa-fieldset">
<h1 id="auditor-certification">Change {{ friendly_role }}</h1>
<p class="font-sans-md">
There may only be one {{ friendly_role }} per single audit submission. By submitting a new official, you will be removing the current official listed below.
</p>
<p>
<strong>Name: </strong>{{ certifier_name }}
</p>
<p>
<strong>Email: </strong>{{ email }}
</p>

{% if role != "editor" %}
<h1 id="role-management">Change {{ friendly_role }}</h1>
<p class="font-sans-md">
There may only be one {{ friendly_role }} per single audit submission. By submitting a new official, you will be removing the current official listed below.
</p>
<p>
<strong>Name: </strong>{{ certifier_name }}
</p>
<p>
<strong>Email: </strong>{{ email }}
</p>
{% else %}
<h1 id="role-management">Add editor</h1>
<p class="font-sans-md">
Grant basic access to this submission to a new user by entering their name and email address below:
</p>
{% endif %}
<hr />
{% if errors %}
<ul>
Expand Down
2 changes: 1 addition & 1 deletion backend/audit/templates/audit/my_submissions.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h1 class="font-sans-xl">Audits in progress</h1>
<tr>
<td>
<a class="usa-link" href="{% url 'audit:SubmissionProgress' item.report_id %}">{{ item.submission_status }}</a>
{% if item.submission_status == "Ready For Certification" %}
{% if item.submission_status == "Ready for Certification" %}
<p class="margin-0">
<a class="usa-link" href="{% url 'audit:UnlockAfterCertification' item.report_id %}">
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
Expand Down
88 changes: 88 additions & 0 deletions backend/audit/test_manage_submission_access_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,94 @@ def _make_user_and_sac(**kwargs):
return user, sac


class ChangeOrAddRoleViewTests(TestCase):
"""
GET and POST tests for adding editors to a submission.
"""

role = "editor"
view = "audit:ChangeOrAddRoleView"

def test_basic_get(self):
"""
A user should be able to access this page for a SAC they're associated with.
"""
user, sac = _make_user_and_sac()
baker.make(Access, user=user, sac=sac, role="editor")
sac.general_information = {"auditee_uei": "YESIAMAREALUEI"}
sac.save()

self.client.force_login(user)
url = reverse(self.view, kwargs={"report_id": sac.report_id})
response = self.client.get(url)

self.assertEqual(response.status_code, 200)
self.assertIn("YESIAMAREALUEI", response.content.decode("UTF-8"))

def test_basic_post(self):
"""
Submitting the form with a new email address should create a new Access.
"""
user = baker.make(User, email="[email protected]")
sac = baker.make(SingleAuditChecklist)
baker.make(Access, user=user, sac=sac, role="editor")
sac.general_information = {"auditee_uei": "YESIAMAREALUEI"}
sac.save()
self.client.force_login(user)

data = {
"fullname": "The New Editor",
"email": "[email protected]",
}

url = reverse(self.view, kwargs={"report_id": sac.report_id})
response = self.client.post(url, data=data)
self.assertEqual(302, response.status_code)

newaccess = Access.objects.get(
sac=sac, fullname=data["fullname"], email=data["email"]
)
self.assertEqual(self.role, newaccess.role)

def test_login_required(self):
"""When an unauthenticated request is made"""

response = self.client.get(
reverse(
self.view,
kwargs={"report_id": "12345"},
)
)

self.assertEqual(response.status_code, 403)

def test_bad_report_id_returns_403(self):
"""
When a request is made for a malformed or nonexistent report_id,
a 403 error should be returned
"""
user = baker.make(User)

self.client.force_login(user)

response = self.client.get(
reverse(self.view, kwargs={"report_id": "this is not a report id"})
)

self.assertEqual(response.status_code, 403)

def test_inaccessible_audit_returns_403(self):
"""When a request is made for an audit that is inaccessible for this user, a 403 error should be returned"""
user, sac = _make_user_and_sac()

self.client.force_login(user)
response = self.client.post(
reverse(self.view, kwargs={"report_id": sac.report_id})
)

self.assertEqual(response.status_code, 403)


class ChangeAuditorCertifyingOfficialViewTests(TestCase):
"""
GET and POST tests for changing auditor certifying official.
Expand Down
5 changes: 5 additions & 0 deletions backend/audit/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ def camel_to_hyphen(raw: str) -> str:
views.ChangeAuditeeCertifyingOfficialView.as_view(),
name="ChangeAuditeeCertifyingOfficial",
),
path(
"manage-submission/add-editor/<str:report_id>",
views.ChangeOrAddRoleView.as_view(),
name="ChangeOrAddRoleView",
),
]

for form_section in FORM_SECTIONS:
Expand Down
2 changes: 2 additions & 0 deletions backend/audit/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .home import Home
from .manage_submission import ManageSubmissionView
from .manage_submission_access import (
ChangeOrAddRoleView,
ChangeAuditeeCertifyingOfficialView,
ChangeAuditorCertifyingOfficialView,
)
Expand Down Expand Up @@ -36,6 +37,7 @@
AuditorCertificationStep1View,
AuditorCertificationStep2View,
CertificationView,
ChangeOrAddRoleView,
ChangeAuditeeCertifyingOfficialView,
ChangeAuditorCertifyingOfficialView,
CrossValidationView,
Expand Down
35 changes: 24 additions & 11 deletions backend/audit/views/manage_submission_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,37 @@ class ChangeAccessForm(forms.Form):
# )


class ChangeAuditorCertifyingOfficialView(
SingleAuditChecklistAccessRequiredMixin, generic.View
):
class ChangeOrAddRoleView(SingleAuditChecklistAccessRequiredMixin, generic.View):
"""
View for changing the auditor certifying official
View for adding a new editor; also has logic for changing certifying roles.
"""

role = "certifying_auditor_contact"
other_role = "certifying_auditee_contact"
role = "editor"
other_role = ""

def get(self, request, *args, **kwargs):
"""
Show the current auditor certifying official and the form.
"""
report_id = kwargs["report_id"]
sac = SingleAuditChecklist.objects.get(report_id=report_id)
access = Access.objects.get(sac=sac, role=self.role)
context = {
"role": self.role,
"friendly_role": access.get_friendly_role(),
"friendly_role": None,
"auditee_uei": sac.general_information["auditee_uei"],
"auditee_name": sac.general_information.get("auditee_name"),
"certifier_name": access.fullname,
"email": access.email,
"certifier_name": None,
"email": None,
"report_id": report_id,
"errors": [],
}
if self.role != "editor":
access = Access.objects.get(sac=sac, role=self.role)
context = context | {
"friendly_role": access.get_friendly_role(),
"certifier_name": access.fullname,
"email": access.email,
}

return render(request, "audit/manage-submission-change-access.html", context)

Expand Down Expand Up @@ -114,7 +118,16 @@ def post(self, request, *args, **kwargs):
return redirect(url)


class ChangeAuditeeCertifyingOfficialView(ChangeAuditorCertifyingOfficialView):
class ChangeAuditorCertifyingOfficialView(ChangeOrAddRoleView):
"""
View for changing the auditor certifying official
"""

role = "certifying_auditor_contact"
other_role = "certifying_auditee_contact"


class ChangeAuditeeCertifyingOfficialView(ChangeOrAddRoleView):
"""
View for changing the auditee certifying official
"""
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
21 changes: 12 additions & 9 deletions backend/census_historical_migration/historic_data_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,23 @@ def load_historic_data_for_year(audit_year, page_size, pages):
# Migrate a single submission
run_end_to_end(user, submission, result)

result_log[(audit_year, submission.DBKEY)] = result
result_log[(submission.AUDITYEAR, submission.DBKEY)] = result
total_count += 1

migration_status = "SUCCESS"
if len(result["errors"]) > 0:
migration_status = "FAILURE"
has_failed = len(result["errors"]) > 0

record_migration_status(audit_year, submission.DBKEY, migration_status)
record_migration_status(audit_year, submission.DBKEY, has_failed)

if len(result["errors"]) > 0:
if has_failed:
error_count += 1
if total_count % 5 == 0:
print(f"Processed = {total_count}, Errors = {error_count}")
if error_count > 5:
break

print_results(result_log, error_count, total_count)


def print_results(result_log, error_count, total_count):
"""Prints the results of the migration"""

print("********* Loader Summary ***************")

Expand Down Expand Up @@ -75,7 +77,8 @@ def create_or_get_user():
return user


def record_migration_status(audit_year, dbkey, status):
def record_migration_status(audit_year, dbkey, has_failed):
status = "FAILURE" if has_failed else "SUCCESS"
ReportMigrationStatus(
audit_year=audit_year,
dbkey=dbkey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
import logging
import sys
from census_historical_migration.sac_general_lib.utils import (
normalize_year_string,
normalize_year_string_or_exit,
)
from census_historical_migration.workbooklib.excel_creation_utils import (
get_audit_header,
)
from census_historical_migration.historic_data_loader import (
create_or_get_user,
print_results,
record_migration_status,
)
from census_historical_migration.workbooklib.end_to_end_core import run_end_to_end
Expand All @@ -28,7 +29,9 @@ def initiate_migration(self, dbkeys_str, years_str):
dbkeys = dbkeys_str.split(",")

if years_str:
years = [normalize_year_string(year) for year in years_str.split(",")]
years = [
normalize_year_string_or_exit(year) for year in years_str.split(",")
]
if len(dbkeys) != len(years):
logger.error(
"Received {} dbkeys and {} years. Must be equal. Exiting.".format(
Expand All @@ -43,6 +46,8 @@ def initiate_migration(self, dbkeys_str, years_str):
logger.info(
f"Generating test reports for DBKEYS: {dbkeys_str} and YEARS: {years_str}"
)
result_log = {}
total_count = error_count = 0
for dbkey, year in zip(dbkeys, years):
logger.info("Running {}-{} end-to-end".format(dbkey, year))
result = {"success": [], "errors": []}
Expand All @@ -53,13 +58,15 @@ def initiate_migration(self, dbkeys_str, years_str):
continue

run_end_to_end(user, audit_header, result)
logger.info(result)
result_log[(year, dbkey)] = result
total_count += 1
has_failed = len(result["errors"]) > 0
if has_failed:
error_count += 1

migration_status = "SUCCESS"
if len(result["errors"]) > 0:
migration_status = "FAILURE"
record_migration_status(year, dbkey, has_failed)

record_migration_status(year, dbkey, migration_status)
print_results(result_log, error_count, total_count)

def handle(self, *args, **options):
dbkeys_str = options["dbkeys"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from census_historical_migration.workbooklib.excel_creation_utils import (
get_audit_header,
)
from census_historical_migration.sac_general_lib.utils import normalize_year_string
from census_historical_migration.sac_general_lib.utils import (
normalize_year_string_or_exit,
)
from census_historical_migration.workbooklib.workbook_builder import (
generate_workbook,
)
Expand Down Expand Up @@ -48,7 +50,7 @@ def handle(self, *args, **options): # noqa: C901
logger.info(e)
logger.info(f"Could not create directory {out_basedir}")
sys.exit()
year = normalize_year_string(options["year"])
year = normalize_year_string_or_exit(options["year"])
outdir = os.path.join(out_basedir, f'{options["dbkey"]}-{year[-2:]}')

if not os.path.exists(outdir):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from census_historical_migration.sac_general_lib.utils import normalize_year_string
from census_historical_migration.sac_general_lib.utils import (
normalize_year_string_or_exit,
)
from ...historic_data_loader import load_historic_data_for_year

from django.core.management.base import BaseCommand
Expand Down Expand Up @@ -27,7 +29,7 @@ def add_arguments(self, parser):
parser.add_argument("--pages", type=str, required=False, default="1")

def handle(self, *args, **options):
year = normalize_year_string(options.get("year"))
year = normalize_year_string_or_exit(options.get("year"))

try:
pages_str = options["pages"]
Expand Down
Loading

0 comments on commit 6511c62

Please sign in to comment.