Skip to content

Commit

Permalink
Added tests to make sure all Views use CommitteeOwnedViewMixin and al…
Browse files Browse the repository at this point in the history
…l models use CommitteeOwnedModel, with some exceptions
  • Loading branch information
sasha-dresden committed Dec 16, 2024
1 parent 6e1d268 commit 094451d
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 11 deletions.
42 changes: 38 additions & 4 deletions django-backend/fecfiler/committee_accounts/test_models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.apps import apps
from django.test import TestCase
from .models import CommitteeAccount
from .models import CommitteeAccount, CommitteeOwnedModel


class CommitteeAccountTestCase(TestCase):
Expand All @@ -16,9 +17,7 @@ def test_get_contact(self):

def test_save_and_delete(self):
self.valid_committee_account.save()
committee_account_from_db = CommitteeAccount.objects.get(
committee_id="C87654321"
)
committee_account_from_db = CommitteeAccount.objects.get(committee_id="C87654321")
self.assertIsInstance(committee_account_from_db, CommitteeAccount)
self.assertEquals(committee_account_from_db.committee_id, "C87654321")
committee_account_from_db.delete()
Expand All @@ -39,3 +38,38 @@ def test_save_and_delete(self):
CommitteeAccount.all_objects.get,
committee_id="C87654321",
)

def test_all_models_include_committee_owned_mixin(self):
ignore_list = [
"Permission",
"Group",
"ContentType",
"Session",
"CommitteeAccount",
"Membership",
"Form3X",
"Form24",
"Form99",
"Form1M",
"ReportTransaction",
"ScheduleA",
"ScheduleB",
"ScheduleC",
"ScheduleC1",
"ScheduleC2",
"ScheduleD",
"ScheduleE",
"DotFEC",
"UploadSubmission",
"WebPrintSubmission",
"User",
]
app_models = apps.get_models()

for model in app_models:
with self.subTest(model=model):
if model.__name__ not in ignore_list:
self.assertTrue(
issubclass(model, CommitteeOwnedModel),
f"{model.__name__} does not include CommitteeOwnedModel mixin.",
)
75 changes: 73 additions & 2 deletions django-backend/fecfiler/committee_accounts/test_views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
from importlib import import_module
import inspect
import os
from uuid import UUID
from django.test import RequestFactory, TestCase
from fecfiler.committee_accounts.models import Membership
from fecfiler.committee_accounts.views import CommitteeMembershipViewSet, CommitteeViewSet

from fecfiler.committee_accounts.views import (
CommitteeMembershipViewSet,
CommitteeOwnedViewMixin,
CommitteeViewSet,
)
from rest_framework.viewsets import ViewSetMixin
from fecfiler.user.models import User
from unittest.mock import Mock, patch

Expand Down Expand Up @@ -221,3 +228,67 @@ def test_get_committee_account_data_from_redis(self):
self.assertNotEqual(len(was_called_with), 0)
self.assertIn("C12345678", was_called_with)
self.assertEqual(response.data["name"], "TEST")

def test_all_viewsets_include_mixin(self):
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.join(script_dir, "../..")
exclude_dirs = ["venv", "__pycache__"]

exclude_list = [
"CommitteeViewSet",
"UserViewSet",
"SystemStatusViewSet",
"WebServicesViewSet",
"SummaryViewSet",
"FeedbackViewSet",
]

subclasses = find_subclasses(ViewSetMixin, project_root, exclude_dirs)
missing_mixin = [
subclass
for subclass in subclasses
if not issubclass(subclass, CommitteeOwnedViewMixin)
and subclass.__name__ not in exclude_list
]

self.assertEqual(
len(missing_mixin),
0,
f"The following subclasses of GenericViewSet "
f"do not include CommitteeOwnedViewMixin:"
f"{', '.join([f'{cls.__module__}.{cls.__name__}' for cls in missing_mixin])}",
)


def find_subclasses(base_class, project_path, exclude_dirs=None):
subclasses = []
exclude_dirs = exclude_dirs or []

for root, dirs, files in os.walk(project_path):
dirs[:] = [d for d in dirs if d not in exclude_dirs]

for file in files:
if (
file.endswith("views.py")
and not file.startswith("__init__")
and "test_views" not in file
):
module_path = os.path.join(root, file)
module_name = (
module_path.replace(project_path, "")
.replace(os.sep, ".")
.lstrip(".")
.replace(".py", "")
)
try:
module = import_module(module_name)
except (ModuleNotFoundError, ImportError):
print(f"module not found: {module_name}")
continue

for name, obj in inspect.getmembers(module, inspect.isclass):
if obj.__module__ == module.__name__:
if issubclass(obj, base_class) and obj != base_class:
subclasses.append(obj)

return subclasses
3 changes: 1 addition & 2 deletions django-backend/fecfiler/memo_text/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from .models import MemoText
from .serializers import MemoTextSerializer
from fecfiler.committee_accounts.views import CommitteeOwnedViewMixin
from fecfiler.reports.views import ReportViewMixin
from rest_framework.viewsets import ModelViewSet


class MemoTextViewSet(CommitteeOwnedViewMixin, ReportViewMixin, ModelViewSet):
class MemoTextViewSet(ReportViewMixin, ModelViewSet):
def get_queryset(self):
memos = super().get_queryset()
query_params = self.request.query_params.keys()
Expand Down
2 changes: 1 addition & 1 deletion django-backend/fecfiler/reports/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def list(self, request, *args, **kwargs):
return super().list(request, args, kwargs)


class ReportViewMixin(GenericViewSet):
class ReportViewMixin(CommitteeOwnedViewMixin, GenericViewSet):
def get_queryset(self):
return filter_by_report(super().get_queryset(), self)

Expand Down
4 changes: 2 additions & 2 deletions django-backend/fecfiler/web_services/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
from .models import DotFEC, UploadSubmission, WebPrintSubmission
from fecfiler.reports.models import Report, FORMS_TO_CALCULATE
from celery.result import AsyncResult

from fecfiler.committee_accounts.views import CommitteeOwnedViewMixin
import structlog

logger = structlog.get_logger(__name__)


class WebServicesViewSet(viewsets.ViewSet):
class WebServicesViewSet(CommitteeOwnedViewMixin, viewsets.ViewSet):
"""
A viewset that provides actions to start web service tasks and
retrieve thier statuses and results
Expand Down

0 comments on commit 094451d

Please sign in to comment.