Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2024-07-26 | MAIN --> PROD | DEV (7f52c1a) --> STAGING #4116

Merged
merged 3 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions backend/api/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from unittest import TestCase

from unittest.mock import patch
from django.utils import timezone as django_timezone
from datetime import timedelta
from django.test import SimpleTestCase
from model_bakery import baker

Expand Down Expand Up @@ -110,6 +112,25 @@ def test_waived_uei_payload(self):
mock_get.return_value.json.return_value = json.loads(missing_uei_results)
self.assertTrue(UEISerializer(data=valid).is_valid())

def test_expired_waived_uei_payload(self):
"""
A UEI with an expired validation waiver should not pass.
"""
yesterday = django_timezone.now() - timedelta(days=1)
expired = {"auditee_uei": "SUPERC00LUE1", "expiration": yesterday}

baker.make(
UeiValidationWaiver,
uei=expired["auditee_uei"],
expiration=expired["expiration"],
)

# Invalid due to the waiver being expired. Mock the SAM call as though the entity doesnt exist.
with patch("api.uei.SESSION.get") as mock_get:
mock_get.return_value.status_code = 200
mock_get.return_value.json.return_value = json.loads(missing_uei_results)
self.assertFalse(UEISerializer(data=expired).is_valid())

def test_quirky_uei_payload(self):
"""
It turns out that some entries can be missing fields that we thought would
Expand Down
10 changes: 4 additions & 6 deletions backend/api/uei.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.utils import timezone as django_timezone
import logging
import requests
import ssl
Expand Down Expand Up @@ -161,13 +162,10 @@ def get_uei_info_from_sam_gov(uei: str) -> dict:
if results["valid"] and (not results.get("errors")):
return results

# To honor expiration dates:
# from datetime import date
# today = date.today()
# waiver = UeiValidationWaiver.objects.filter(uei=uei, expiration__gte=today).first()

# 3. Check for a waiver.
waiver = UeiValidationWaiver.objects.filter(uei=uei).first()
waiver = UeiValidationWaiver.objects.filter(
uei=uei, expiration__gte=django_timezone.now()
).first()
if not waiver:
return {"valid": False, "errors": ["UEI was not found in SAM.gov"]}

Expand Down
2 changes: 2 additions & 0 deletions backend/audit/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,10 @@ class UeiValidationWaiverAdmin(admin.ModelAdmin):
"id",
"uei",
"timestamp",
"expiration",
"approver_email",
"requester_email",
"justification",
)
search_fields = (
"id",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 5.0.4 on 2024-07-23 15:54

import audit.models.models
import django.utils.timezone
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("audit", "0010_alter_ueivalidationwaiver_uei"),
]

operations = [
migrations.AddField(
model_name="ueivalidationwaiver",
name="expiration",
field=models.DateTimeField(
default=audit.models.models.one_month_from_today,
verbose_name="When the waiver will expire",
),
),
migrations.AddField(
model_name="ueivalidationwaiver",
name="timestamp",
field=models.DateTimeField(
default=django.utils.timezone.now,
verbose_name="When the waiver was created",
),
),
]
21 changes: 11 additions & 10 deletions backend/audit/models/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime, timezone
from datetime import datetime, timezone, timedelta
from itertools import chain
import json
import logging
Expand Down Expand Up @@ -71,6 +71,10 @@ def generate_sac_report_id(end_date=None, source="GSAFAC", count=None):
return report_id


def one_month_from_today():
return django_timezone.now() + timedelta(days=30)


class SingleAuditChecklistManager(models.Manager):
"""Manager for SAC"""

Expand Down Expand Up @@ -704,16 +708,13 @@ def __str__(self):

# Not unique, in the case that one UEI needs to be waived several times with different expiration dates.
uei = models.TextField("UEI")
timestamp = (
models.DateTimeField(
"When the waiver was created",
default=django_timezone.now,
),
timestamp = models.DateTimeField(
"When the waiver was created",
default=django_timezone.now,
)
expiration = (
models.DateTimeField(
"When the waiver expires",
),
expiration = models.DateTimeField(
"When the waiver will expire",
default=one_month_from_today,
)
approver_email = models.TextField(
"Email address of FAC staff member approving the waiver",
Expand Down
64 changes: 29 additions & 35 deletions backend/dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --generate-hashes --output-file=dev-requirements.txt ./requirements/dev-requirements.in
Expand All @@ -8,7 +8,7 @@ asgiref==3.8.1 \
--hash=sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47 \
--hash=sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# django
bandit==1.7.6 \
--hash=sha256:36da17c67fc87579a5d20c323c8d0b1643a890a2b93f00b3d1229966624694ff \
Expand Down Expand Up @@ -52,7 +52,12 @@ click==8.1.7 \
colorama==0.4.6 \
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
# via djlint
# via
# bandit
# build
# click
# djlint
# tqdm
coverage==7.4.0 \
--hash=sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca \
--hash=sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471 \
Expand Down Expand Up @@ -114,7 +119,7 @@ django==5.0.4 \
--hash=sha256:4bd01a8c830bb77a8a3b0e7d8b25b887e536ad17a81ba2dce5476135c73312bd \
--hash=sha256:916423499d75d62da7aa038d19aef23d23498d8df229775eb0a6309ee1013775
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# django-debug-toolbar
# model-bakery
django-debug-toolbar==4.2.0 \
Expand All @@ -135,7 +140,7 @@ faker==24.9.0 \
--hash=sha256:73b1e7967b0ceeac42fc99a8c973bb49e4499cc4044d20d17ab661d5cb7eda1d \
--hash=sha256:97c7874665e8eb7b517f97bf3b59f03bf3f07513fe2c159e98b6b9ea6b9f2b3d
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# -r ./requirements/dev-requirements.in
flake8==7.0.0 \
--hash=sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132 \
Expand Down Expand Up @@ -260,13 +265,13 @@ numpy==1.26.4 \
--hash=sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3 \
--hash=sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# pandas
packaging==24.0 \
--hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \
--hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# black
# build
pandas==2.2.2 \
Expand Down Expand Up @@ -300,7 +305,7 @@ pandas==2.2.2 \
--hash=sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce \
--hash=sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# -r ./requirements/dev-requirements.in
pathspec==0.12.1 \
--hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \
Expand Down Expand Up @@ -340,14 +345,14 @@ python-dateutil==2.9.0.post0 \
--hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \
--hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# faker
# pandas
pytz==2024.1 \
--hash=sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812 \
--hash=sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# pandas
pyyaml==6.0.1 \
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
Expand Down Expand Up @@ -402,7 +407,7 @@ pyyaml==6.0.1 \
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# bandit
# djlint
regex==2023.12.25 \
Expand Down Expand Up @@ -508,19 +513,19 @@ six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# cssbeautifier
# jsbeautifier
# python-dateutil
smmap==5.0.1 \
--hash=sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62 \
--hash=sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da
# via gitdb
sqlparse==0.4.4 \
--hash=sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3 \
--hash=sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c
sqlparse==0.5.0 \
--hash=sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93 \
--hash=sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# django
# django-debug-toolbar
stevedore==5.1.0 \
Expand All @@ -535,16 +540,6 @@ toml==0.10.2 \
--hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
--hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
# via -r ./requirements/dev-requirements.in
tomli==2.0.1 \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
# via
# black
# build
# djlint
# mypy
# pip-tools
# pyproject-hooks
tqdm==4.66.1 \
--hash=sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386 \
--hash=sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7
Expand All @@ -565,21 +560,20 @@ typing-extensions==4.11.0 \
--hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \
--hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a
# via
# -c ./requirements/../requirements.txt
# asgiref
# black
# -c ./requirements\../requirements.txt
# mypy
tzdata==2024.1 \
--hash=sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd \
--hash=sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# django
# pandas
urllib3==2.2.1 \
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
urllib3==2.2.2 \
--hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
--hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# types-requests
wheel==0.42.0 \
--hash=sha256:177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d \
Expand All @@ -602,5 +596,5 @@ setuptools==69.4.0 \
--hash=sha256:659e902e587e77fab8212358f5b03977b5f0d18d4724310d4a093929fee4ca1a \
--hash=sha256:b6df12d754b505e4ca283c61582d5578db83ae2f56a979b3bc9a8754705ae3bf
# via
# -c ./requirements/../requirements.txt
# -c ./requirements\../requirements.txt
# pip-tools
9 changes: 5 additions & 4 deletions backend/dissemination/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django import forms
from .searchlib.search_constants import text_input_delimiters, report_id_delimiters
from datetime import date


def clean_text_field(text_input, delimiters=text_input_delimiters):
Expand Down Expand Up @@ -58,8 +59,8 @@ class AdvancedSearchForm(forms.Form):

# Multiple choice field Tuples. "choices" variable in field declaration.
AY_choices = (("all_years", "All years"),) + tuple(
(x, str(x)) for x in reversed(range(2016, 2024))
)
(x, str(x)) for x in reversed(range(2016, date.today().year + 1))
) # (("all_years", "All years"), (2016, "2016"), ..., (currentYear, "currentYear"))
findings_choices = list(zip(*findings_field_mapping.values()))
direct_funding_choices = (
("direct_funding", "Direct funding"),
Expand Down Expand Up @@ -207,8 +208,8 @@ class SearchForm(forms.Form):

# Multiple choice field Tuples. "choices" variable in field declaration.
AY_choices = (("all_years", "All years"),) + tuple(
(x, str(x)) for x in reversed(range(2016, 2024))
)
(x, str(x)) for x in reversed(range(2016, date.today().year + 1))
) # (("all_years", "All years"), (2016, "2016"), ..., (currentYear, "currentYear"))
entity_type_choices = list(zip(*entity_type_field_mapping.values()))

# Query params
Expand Down
11 changes: 8 additions & 3 deletions backend/dissemination/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import timedelta
from datetime import date, timedelta
import logging
import math
import time
Expand Down Expand Up @@ -43,6 +43,11 @@

logger = logging.getLogger(__name__)

default_checked_audit_years = [
date.today().year,
date.today().year - 1,
] # Auto-check this and last year


def _add_search_params_to_newrelic(search_parameters):
is_advanced = search_parameters["advanced_search_flag"]
Expand Down Expand Up @@ -145,7 +150,7 @@ def get(self, request, *args, **kwargs):
{
"advanced_search_flag": True,
"form": form,
"form_user_input": {"audit_year": ["2023"]},
"form_user_input": {"audit_year": default_checked_audit_years},
"state_abbrevs": STATE_ABBREVS,
"summary_report_download_limit": SUMMARY_REPORT_DOWNLOAD_LIMIT,
},
Expand Down Expand Up @@ -242,7 +247,7 @@ def get(self, request, *args, **kwargs):
{
"advanced_search_flag": False,
"form": form,
"form_user_input": {"audit_year": ["2023"]},
"form_user_input": {"audit_year": default_checked_audit_years},
"state_abbrevs": STATE_ABBREVS,
"summary_report_download_limit": SUMMARY_REPORT_DOWNLOAD_LIMIT,
},
Expand Down
Loading
Loading