Skip to content

Commit

Permalink
modify the site models to reflect Remote Signer capabilities.
Browse files Browse the repository at this point in the history
attach admin rcrainfo profile to a haztrak site instead of the user's profile
rename last_sync_date to last_rcrainfo_manifest_sync to be more clear on what is being synced
add properties to haztrak profile to use an admin's rcrainfo profile
rename last_rcra_sync to last_rcrainfo_manifest_sync for clarity
  • Loading branch information
dpgraham4401 committed Nov 8, 2023
1 parent a692ce4 commit 6461c5b
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 24 deletions.
6 changes: 5 additions & 1 deletion server/apps/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,11 @@ def haztrak_profile_factory(db, user_factory):

def create_profile(
user: Optional[User] = None,
) -> RcraProfile:
admin_rcrainfo_profile: Optional[RcraProfile] = None,
) -> HaztrakProfile:
return HaztrakProfile.objects.create(
user=user or user_factory(),
admin_rcrainfo_profile=admin_rcrainfo_profile,
)

yield create_profile
Expand Down Expand Up @@ -206,10 +208,12 @@ def site_factory(db, rcra_site_factory):
def create_site(
rcra_site: Optional[RcraSite] = None,
name: Optional[str] = "my site name",
admin_rcrainfo_profile: Optional[RcraProfile] = None,
) -> Site:
return Site.objects.create(
rcra_site=rcra_site or rcra_site_factory(),
name=name,
admin_rcrainfo_profile=admin_rcrainfo_profile,
)

yield create_site
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.7 on 2023-11-08 17:29

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("core", "0003_alter_haztrakprofile_user"),
]

operations = [
migrations.AddField(
model_name="haztrakprofile",
name="admin_rcrainfo_profile",
field=models.ForeignKey(
default=None,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="core.rcraprofile",
),
),
]
14 changes: 9 additions & 5 deletions server/apps/core/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.functional import cached_property

from haztrak import settings

Expand Down Expand Up @@ -36,9 +37,12 @@ class Meta:
on_delete=models.CASCADE,
related_name="haztrak_profile",
)

def __str__(self):
return f"{self.user.username}"
admin_rcrainfo_profile = models.ForeignKey(
"RcraProfile",
on_delete=models.SET_NULL,
null=True,
default=None,
)


class RcraProfile(CoreBaseModel):
Expand Down Expand Up @@ -80,8 +84,8 @@ def __str__(self):
return f"{self.user.username}"

@property
def is_api_user(self) -> bool:
def has_api_credentials(self) -> bool:
"""Returns true if the use has Rcrainfo API credentials"""
if self.rcra_username and self.rcra_api_id and self.rcra_api_key:
if self.rcra_api_id and self.rcra_api_key:
return True
return False
2 changes: 1 addition & 1 deletion server/apps/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class RcraProfileSerializer(ModelSerializer):
required=False,
)
apiUser = serializers.BooleanField(
source="is_api_user",
source="has_api_credentials",
required=False,
allow_null=False,
)
Expand Down
2 changes: 1 addition & 1 deletion server/apps/core/services/rcrainfo_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(
def has_api_user(self) -> bool:
"""returns boolean if the assigned API user has credentials"""
try:
return self.profile.is_api_user
return self.profile.has_api_credentials
except AttributeError:
return False

Expand Down
4 changes: 2 additions & 2 deletions server/apps/sites/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class SitePermissionAdmin(admin.ModelAdmin):

@admin.register(Site)
class SiteAdmin(admin.ModelAdmin):
list_display = ["__str__", "related_handler", "last_rcra_sync"]
list_display = ["__str__", "related_handler", "last_rcrainfo_manifest_sync"]
list_display_links = ["__str__", "related_handler"]

@admin.display(description="EPA Site")
Expand Down Expand Up @@ -61,7 +61,7 @@ def related_user(self, user):
return format_html("<a href='{}'>{}</a>", url, user)

def api_user(self, profile: RcraProfile) -> bool:
return profile.is_api_user
return profile.has_api_credentials

api_user.boolean = True
api_user.short_description = "Rcrainfo API User"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2.7 on 2023-11-08 19:32

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("sites", "0002_sitepermissions"),
]

operations = [
migrations.AlterField(
model_name="site",
name="last_rcra_sync",
field=models.DateTimeField(
blank=True, null=True, verbose_name="last RCRAInfo manifest sync date"
),
),
]
23 changes: 23 additions & 0 deletions server/apps/sites/migrations/0004_site_admin_rcrainfo_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.7 on 2023-11-08 19:38

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("core", "0004_haztrakprofile_admin_rcrainfo_profile"),
("sites", "0003_alter_site_last_rcrainfo_manifest_sync"),
]

operations = [
migrations.AddField(
model_name="site",
name="admin_rcrainfo_profile",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="core.rcraprofile",
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.7 on 2023-11-08 20:02

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("sites", "0004_site_admin_rcrainfo_profile"),
]

operations = [
migrations.RenameField(
model_name="site",
old_name="last_rcra_sync",
new_name="last_rcrainfo_manifest_sync",
),
]
16 changes: 14 additions & 2 deletions server/apps/sites/models/site_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,23 @@ class Meta:
to=RcraSite,
on_delete=models.CASCADE,
)
last_rcra_sync = models.DateTimeField(
verbose_name="last sync with RCRAInfo",
last_rcrainfo_manifest_sync = models.DateTimeField(
verbose_name="last RCRAInfo manifest sync date",
null=True,
blank=True,
)
admin_rcrainfo_profile = models.ForeignKey(
"core.RcraProfile",
on_delete=models.SET_NULL,
null=True,
)

@property
def admin_has_rcrainfo_api_credentials(self) -> bool:
"""Returns True if the admin user has RcraInfo API credentials"""
if self.admin_rcrainfo_profile.has_api_credentials:
return True
return False

def __str__(self):
"""Used in StringRelated fields in serializer classes"""
Expand Down
4 changes: 2 additions & 2 deletions server/apps/sites/services/site_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ def sync_manifests(self, *, site_id: str) -> PullManifestsResult:
try:
site = Site.objects.get(rcra_site__epa_id=site_id)
updated_mtn = self._get_updated_mtn(
site_id=site.rcra_site.epa_id, last_sync_date=site.last_rcra_sync
site_id=site.rcra_site.epa_id, last_sync_date=site.last_rcrainfo_manifest_sync
)
updated_mtn = updated_mtn[:15] # temporary limit to 15
logger.info(f"Pulling {updated_mtn} from RCRAInfo")
manifest = ManifestService(username=self.username, rcrainfo=self.rcrainfo)
results: PullManifestsResult = manifest.pull_manifests(tracking_numbers=updated_mtn)
site.last_rcra_sync = datetime.now(UTC)
site.last_rcrainfo_manifest_sync = datetime.now(UTC)
site.save()
return results
except Site.DoesNotExist:
Expand Down
43 changes: 35 additions & 8 deletions server/apps/sites/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.db import IntegrityError

from apps.core.models import RcraProfile
from apps.sites.models import Address, Contact
from apps.sites.models import Address, Contact, Site


@pytest.mark.django_db
Expand Down Expand Up @@ -42,21 +42,48 @@ def test_rcra_profile_saves(self, rcra_profile_factory):
rcra_profile = rcra_profile_factory()
assert isinstance(rcra_profile, RcraProfile)

@pytest.mark.parametrize("rcra_username", ["username", None])
@pytest.mark.parametrize("rcra_api_id", ["id", None])
@pytest.mark.parametrize("rcra_api_key", ["key", None])
def test_rcra_profile_is_not_api_user_if_one_missing(
self, rcra_profile_factory, rcra_username, rcra_api_id, rcra_api_key
self, rcra_profile_factory, rcra_api_id, rcra_api_key
):
"""If any of the three are None, the user should not be considered an API user"""
# Arrange
expected = True
if rcra_username is None or rcra_api_id is None or rcra_api_key is None:
if rcra_api_id is None or rcra_api_key is None:
expected = False
rcra_profile = rcra_profile_factory(
rcra_username=rcra_username, rcra_api_id=rcra_api_id, rcra_api_key=rcra_api_key
)
rcra_profile = rcra_profile_factory(rcra_api_id=rcra_api_id, rcra_api_key=rcra_api_key)
# Act
api_user = rcra_profile.is_api_user
api_user = rcra_profile.has_api_credentials
# Assert
assert api_user is expected


class TestHaztrakSiteModel:
def test_haztrak_site_model_factory(self, site_factory):
haztrak_site = site_factory()
assert isinstance(haztrak_site, Site)

def test_returns_true_if_admin_has_provided_api_credentials(
self, site_factory, rcra_profile_factory, user_factory
):
admin = user_factory(username="admin")
admin_rcrainfo_profile = rcra_profile_factory(
user=admin,
rcra_api_id="mock_id",
rcra_api_key="mock_key",
)
haztrak_profile = site_factory(admin_rcrainfo_profile=admin_rcrainfo_profile)
assert haztrak_profile.admin_has_rcrainfo_api_credentials

def test_returns_false_if_admin_has_not_provided_api_credentials(
self, site_factory, rcra_profile_factory, user_factory
):
admin = user_factory(username="admin")
admin_rcrainfo_profile = rcra_profile_factory(
user=admin,
rcra_api_id=None,
rcra_api_key=None,
)
haztrak_profile = site_factory(admin_rcrainfo_profile=admin_rcrainfo_profile)
assert not haztrak_profile.admin_has_rcrainfo_api_credentials
2 changes: 1 addition & 1 deletion server/apps/trak/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

class IsApiUser(admin.SimpleListFilter):
title = "API User"
parameter_name = "is_api_user"
parameter_name = "has_api_credentials"

def lookups(self, request, model_admin):
return ("True", True), ("False", False)
Expand Down
2 changes: 1 addition & 1 deletion server/fixtures/dev_data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
fields:
name: VA TEST GEN 2021
rcra_site: 1
last_rcra_sync: null
last_rcrainfo_manifest_sync: null
- model: sites.rcrasitepermission
pk: 1
fields:
Expand Down

0 comments on commit 6461c5b

Please sign in to comment.