diff --git a/.github/workflows/staging-scheduled-deploy.yml b/.github/workflows/staging-scheduled-deploy.yml index 35657a866..4ea67d849 100644 --- a/.github/workflows/staging-scheduled-deploy.yml +++ b/.github/workflows/staging-scheduled-deploy.yml @@ -1,49 +1,49 @@ ---- -name: Scheduled Deploy From Main to Staging -on: - # schedule: - # Invoke every Mon-Sat - # - cron: '0 10 * * 1-6' - workflow_dispatch: null - -jobs: - trivy-scan: - uses: ./.github/workflows/trivy.yml - secrets: inherit - permissions: - contents: read - packages: write - actions: read - security-events: write - - build-container: - needs: - - trivy-scan - uses: ./.github/workflows/build-docker-container.yml - secrets: inherit - permissions: - contents: read - packages: write - with: - docker-name: fac - image-name: web-container - repo-name: gsa-tts/fac - work-dir: ./backend - - testing: - name: Run Django, Lighthouse, a11y and lint - needs: - - build-container - uses: ./.github/workflows/testing-from-ghcr.yml - secrets: inherit - - linting: - uses: ./.github/workflows/linting.yml - secrets: inherit - - create-pr: - needs: - - testing - name: Create Pull Request to Staging - uses: ./.github/workflows/create-pull-request-to-staging.yml - secrets: inherit +--- +name: Scheduled Deploy From Main to Staging +on: + # schedule: + # Invoke every Mon-Sat + # - cron: '0 10 * * 1-6' + workflow_dispatch: null + +jobs: + trivy-scan: + uses: ./.github/workflows/trivy.yml + secrets: inherit + permissions: + contents: read + packages: write + actions: read + security-events: write + + build-container: + needs: + - trivy-scan + uses: ./.github/workflows/build-docker-container.yml + secrets: inherit + permissions: + contents: read + packages: write + with: + docker-name: fac + image-name: web-container + repo-name: gsa-tts/fac + work-dir: ./backend + + testing: + name: Run Django and lint + needs: + - build-container + uses: ./.github/workflows/testing-from-ghcr.yml + secrets: inherit + + linting: + uses: ./.github/workflows/linting.yml + secrets: inherit + + create-pr: + needs: + - testing + name: Create Pull Request to Staging + uses: ./.github/workflows/create-pull-request-to-staging.yml + secrets: inherit diff --git a/.github/workflows/testing-from-build.yml b/.github/workflows/testing-from-build.yml index 7bf1de547..61b6c2e33 100644 --- a/.github/workflows/testing-from-build.yml +++ b/.github/workflows/testing-from-build.yml @@ -78,10 +78,8 @@ jobs: # run: | # touch .env # docker compose -f docker-compose.yml up -d - # - # - name: Run Lighthouse CI and pa11y + # - name: Run A11y tests # working-directory: ./backend # run: | # sudo npm ci - # npm run test:a11y:lighthouse - # npm run test:a11y:pa11y + # npx cypress run --spec "cypress/e2e/accessibility.cy.js" diff --git a/.github/workflows/testing-from-ghcr.yml b/.github/workflows/testing-from-ghcr.yml index 2ba353bd0..98379c5a1 100644 --- a/.github/workflows/testing-from-ghcr.yml +++ b/.github/workflows/testing-from-ghcr.yml @@ -80,9 +80,8 @@ jobs: # run: | # touch .env # docker compose -f docker-compose.yml up -d - # - name: Run Lighthouse CI and pa11y + # - name: Run A11y tests # working-directory: ./backend # run: | # sudo npm ci - # npm run test:a11y:lighthouse - # npm run test:a11y:pa11y + # npx cypress run --spec "cypress/e2e/accessibility.cy.js" diff --git a/.gitignore b/.gitignore index 3bd252bac..0e95d7bbf 100644 --- a/.gitignore +++ b/.gitignore @@ -166,8 +166,6 @@ node_modules/ backend/static/compiled staticfiles/ -# pa11y_tests/screenshots/*.png - # Things that folks might want to have in their local directories # that don't need to be checked in .local/ diff --git a/.pa11yci b/.pa11yci deleted file mode 100644 index 31f8a2050..000000000 --- a/.pa11yci +++ /dev/null @@ -1,21 +0,0 @@ -{ - "urls": [ - "http://localhost:8000/", - "http://localhost:8000/report_submission/eligibility", - "http://localhost:8000/report_submission/auditeeinfo", - "http://localhost:8000/report_submission/accessandsubmission", - "http://localhost:8000/audit" - ], - "defaults": { - "timeout": 60000, - "standard": "WCAG2AA", - "runners": [ - "htmlcs", - "axe" - ], - "hideElements": ".pa11y-ignore, .usa-select, .usa-step-indicator__segment-label, .is-hidden, #upload-worksheet, .usa-file-input__instructions, #my-submissions", - "chromeLaunchConfig": { - "executablePath": "/usr/bin/google-chrome" - } - } -} diff --git a/backend/.stylelintignore b/backend/.stylelintignore index 3c49cb3ff..2470d7044 100644 --- a/backend/.stylelintignore +++ b/backend/.stylelintignore @@ -1,3 +1,2 @@ **/uswds static/compiled/** -.lighthouseci/** diff --git a/backend/audit/fixtures/dissemination.py b/backend/audit/fixtures/dissemination.py new file mode 100644 index 000000000..0aac2b551 --- /dev/null +++ b/backend/audit/fixtures/dissemination.py @@ -0,0 +1,38 @@ +""" +Fixtures for dissemination models. +We want a few example submissions for testing front end accessibility. +""" + +import logging +from model_bakery import baker +from dissemination.models import ( + General, + FederalAward, +) + +logger = logging.getLogger(__name__) + +sac_info_without_findings = { + "auditee_name": "Test SAC - No findings", + "auditee_uei": "GSA_TESTDATA", + "audit_year": "2024", + "report_id": "2024-06-TSTDAT-0000000001", +} + + +def load_dissemination(): + """ + Generate an example SAC with an accompanying award. + """ + logger.info("Creating example SACs for dissemination.") + + report_id_no_findings = sac_info_without_findings.get("report_id", "") + sac_no_findings = General.objects.filter( + report_id=report_id_no_findings, + ).first() + if sac_no_findings is None: + general_no_findings = baker.make(General, **sac_info_without_findings) + baker.make(FederalAward, report_id=general_no_findings) + logger.info("Created SAC example %s", report_id_no_findings) + else: + logger.info("SAC %s already exists, skipping.", report_id_no_findings) diff --git a/backend/audit/fixtures/single_audit_checklist.py b/backend/audit/fixtures/single_audit_checklist.py index 2c5fef00d..abde66455 100644 --- a/backend/audit/fixtures/single_audit_checklist.py +++ b/backend/audit/fixtures/single_audit_checklist.py @@ -119,12 +119,13 @@ def fake_auditee_certification(): return data_step_1, data_step_2 -def _create_sac(user, auditee_name): +def _create_sac(user, auditee_name, submission_status="in_progress"): """Create a single example SAC.""" SingleAuditChecklist = apps.get_model("audit.SingleAuditChecklist") sac = SingleAuditChecklist.objects.create( submitted_by=user, general_information=_fake_general_information(auditee_name), + submission_status=submission_status, ) Access = apps.get_model("audit.Access") @@ -134,6 +135,18 @@ def _create_sac(user, auditee_name): email=user.email, role="editor", ) + Access.objects.create( + sac=sac, + user=user, + email=user.email, + role="certifying_auditor_contact", + ) + Access.objects.create( + sac=sac, + user=user, + email=user.email, + role="certifying_auditee_contact", + ) logger.info("Created single audit checklist %s", sac) return sac @@ -193,9 +206,10 @@ def _post_create_federal_awards(this_sac, this_user): SACS = [ {"auditee_name": "SAC in progress"}, { - "auditee_name": "Federal awards submitted", - "post_create_callable": _post_create_federal_awards, + "auditee_name": "SAC ready for certification", + "submission_status": "ready_for_certification", }, + {"auditee_name": "SAC fully submitted", "submission_status": "disseminated"}, ] @@ -205,12 +219,13 @@ def _load_single_audit_checklists_for_user(user): SingleAuditChecklist = apps.get_model("audit.SingleAuditChecklist") for item_info in SACS: auditee_name = item_info["auditee_name"] + submission_status = item_info.get("submission_status", "in_progress") sac = SingleAuditChecklist.objects.filter( submitted_by=user, general_information__auditee_name=auditee_name ).first() if sac is None: # need to make this object - sac = _create_sac(user, auditee_name) + sac = _create_sac(user, auditee_name, submission_status) def load_single_audit_checklists(): diff --git a/backend/audit/management/commands/load_fixtures.py b/backend/audit/management/commands/load_fixtures.py index dfa0196cb..9341cf878 100644 --- a/backend/audit/management/commands/load_fixtures.py +++ b/backend/audit/management/commands/load_fixtures.py @@ -13,7 +13,7 @@ load_single_audit_checklists, load_single_audit_checklists_for_email_address, ) - +from audit.fixtures.dissemination import load_dissemination from users.fixtures import load_users logger = logging.getLogger(__name__) @@ -33,6 +33,7 @@ def handle(self, *args, **options): if not options.get("email_addresses"): load_users() load_single_audit_checklists() + load_dissemination() logger.info("All fixtures loaded.") else: # We assume each arg is an email address: diff --git a/backend/audit/mixins.py b/backend/audit/mixins.py index 626836611..19387a0c1 100644 --- a/backend/audit/mixins.py +++ b/backend/audit/mixins.py @@ -4,6 +4,7 @@ from django.http.request import HttpRequest from django.http.response import HttpResponse from django.core.exceptions import PermissionDenied +from django.conf import settings from .models import Access, SingleAuditChecklist @@ -50,7 +51,7 @@ def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpRespo sac = SingleAuditChecklist.objects.get(report_id=kwargs["report_id"]) - if not has_access(sac, request.user): + if not has_access(sac, request.user) and not settings.DISABLE_AUTH: raise PermissionDenied(PERMISSION_DENIED_MESSAGE) except SingleAuditChecklist.DoesNotExist: raise PermissionDenied(PERMISSION_DENIED_MESSAGE) diff --git a/backend/audit/templates/audit/audit-info-form.html b/backend/audit/templates/audit/audit-info-form.html index b57dd2930..b589c4318 100644 --- a/backend/audit/templates/audit/audit-info-form.html +++ b/backend/audit/templates/audit/audit-info-form.html @@ -244,6 +244,7 @@