Skip to content
This repository was archived by the owner on Apr 16, 2023. It is now read-only.
Closed
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
Empty file added conman/redirects/admin.py
Empty file.
42 changes: 42 additions & 0 deletions conman/routes/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from django.contrib import admin
from polymorphic_tree.admin import (
PolymorphicMPTTChildModelAdmin,
PolymorphicMPTTParentModelAdmin,
)

from .models import Route


class BaseRouteChildAdmin(PolymorphicMPTTChildModelAdmin):
"""Common base of all Route subclass admin classes."""
GENERAL_FIELDSET = (None, {
'fields': ('slug', 'parent'),
})

base_model = Route
base_fieldsets = (GENERAL_FIELDSET,)


class RouteParentAdmin(PolymorphicMPTTParentModelAdmin):
"""The master admin class for Route."""
base_model = Route
list_display = ('__str__', 'actions_column')
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make FKs raw_id field.

polymorphic_list = True
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test content of list for this.


class Media:
css = {
'all': ('admin/treenode/admin.css',)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs check to ensure that polymorphic_tree is in INSTALLED_APPS.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this css do anyway?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

def get_child_models(self):
"""Collect the admin classes of all subclasses of Route."""
subclasses = self.base_model.__subclasses__()

child_models = []
for subclass in subclasses:
admin_class = subclass.get_admin_class()
if admin_class is not None:
child_models.append((subclass, admin_class))
return child_models

admin.site.register(Route, RouteParentAdmin)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@register(Route)

1 change: 1 addition & 0 deletions conman/routes/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ class RouteConfig(AppConfig):
def ready(self):
"""Register checks for conman routes."""
register(checks.polymorphic_installed)
register(checks.polymorphic_tree_installed)
register(checks.subclasses_available)
16 changes: 16 additions & 0 deletions conman/routes/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ def polymorphic_installed(app_configs, **kwargs):
return errors


def polymorphic_tree_installed(app_configs, **kwargs):
"""Check that Django Polymorphic Tree is installed correctly."""
errors = []
try:
apps.get_app_config('polymorphic_tree')
except LookupError:
error = Error(
'Django Polymorpic Tree must be in INSTALLED_APPS.',
hint="Add 'polymorphic_tree' to INSTALLED_APPS.",
id='conman.routes.E003',
)
errors.append(error)

return errors


def subclasses_available(app_configs, **kwargs):
"""Check that at least one Route subclass is available."""
errors = []
Expand Down
12 changes: 12 additions & 0 deletions conman/routes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Route(PolymorphicMPTTModel):
slug = models.SlugField(
max_length=255,
default='',
blank=True,
help_text=_('The url fragment at this point in the Route hierarchy.'),
)
# Cached location in tree. Reflects parent and slug on self and ancestors.
Expand All @@ -76,6 +77,17 @@ def __str__(self):
"""Display a Route's class and url."""
return '{} @ {}'.format(self.__class__.__name__, self.url)

@classmethod
def get_admin_class(cls):
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@property?

"""
Return the class to use in the admin.

This is only used for subclasses of Route. To disable the
subclass in the admin, make this method return None.
"""
from .admin import BaseRouteChildAdmin
return BaseRouteChildAdmin
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There;s probably a nicer way to get this done. Possibly using apps.py?


def get_handler_class(self):
"""Import a class from the python path string in `self.handler`."""
return import_from_dotted_path(self.handler)
Expand Down
33 changes: 33 additions & 0 deletions conman/routes/tests/test_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from incuna_test_utils.testcases.integration import BaseAdminIntegrationTestCase

from conman.tests.factories import AdminFactory
from .factories import RootRouteFactory
from ..models import Route


class TestRouteAdmin(BaseAdminIntegrationTestCase):
"""Test the functionality of the Route admin."""
user_factory = AdminFactory
model = Route

def test_add_page(self):
"""Ensure the add page is accessible."""
response = self.get_admin_add_page()
self.assertEqual(response.status_code, 200)

def test_changelist_page(self):
"""Ensure the list page is accessible."""
response = self.get_admin_changelist_page()
self.assertEqual(response.status_code, 200)

def test_change_page(self):
"""Ensure the update page is accessible."""
route = RootRouteFactory.create()
response = self.get_admin_change_page(route)
self.assertEqual(response.status_code, 200)

def test_delete_page(self):
"""Ensure the delete page is accessible."""
route = RootRouteFactory.create()
response = self.get_admin_delete_page(route)
self.assertEqual(response.status_code, 200)
41 changes: 36 additions & 5 deletions conman/routes/tests/test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,24 @@

class TestPolymorphicInstalled(SimpleTestCase):
"""Test checks.polymorphic_installed."""
check = staticmethod(checks.polymorphic_installed)

def test_registered(self):
"""checks.polymorphic_installed is a registered check."""
registered_checks = registry.get_checks()
self.assertIn(checks.polymorphic_installed, registered_checks)
self.assertIn(self.check, registered_checks)

def test_installed(self):
"""The check passes if django polymorphic is installed."""
"""The check passes if django-polymorphic is installed."""
with self.settings(INSTALLED_APPS=['conman.routes', 'polymorphic']):
errors = checks.polymorphic_installed(app_configs=None)
errors = self.check(app_configs=None)

self.assertEqual(errors, [])

def test_not_installed(self):
"""The check fails if django polymorphic is not installed."""
"""The check fails if django-polymorphic is not installed."""
with self.settings(INSTALLED_APPS=['conman.routes']):
errors = checks.polymorphic_installed(app_configs=None)
errors = self.check(app_configs=None)

error = Error(
'Django Polymorpic must be in INSTALLED_APPS.',
Expand All @@ -34,6 +36,35 @@ def test_not_installed(self):
self.assertEqual(errors, [error])


class TestPolymorphicTreeInstalled(SimpleTestCase):
"""Test checks.polymorphic_tree_installed."""
check = staticmethod(checks.polymorphic_tree_installed)

def test_registered(self):
"""checks.polymorphic_tree_installed is a registered check."""
registered_checks = registry.get_checks()
self.assertIn(self.check, registered_checks)

def test_installed(self):
"""The check passes if django-polymorphic-tree is installed."""
with self.settings(INSTALLED_APPS=['conman.routes', 'polymorphic_tree']):
errors = self.check(app_configs=None)

self.assertEqual(errors, [])

def test_not_installed(self):
"""The check fails if django polymorphic is not installed."""
with self.settings(INSTALLED_APPS=['conman.routes']):
errors = self.check(app_configs=None)

error = Error(
'Django Polymorpic Tree must be in INSTALLED_APPS.',
hint="Add 'polymorphic_tree' to INSTALLED_APPS.",
id='conman.routes.E003',
)
self.assertEqual(errors, [error])


class TestSubclassesAvailable(SimpleTestCase):
"""Test checks.subclasses_available."""
def test_registered(self):
Expand Down
14 changes: 14 additions & 0 deletions conman/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,17 @@ class UserFactory(factory.DjangoModelFactory):
"""Create instances of User for testing."""
class Meta:
model = settings.AUTH_USER_MODEL

@factory.post_generation
def password(self, create, extracted, **kwargs):
"""Set and store a password for access in tests."""
self.raw_password = 'default_password' if extracted is None else extracted
self.set_password(self.raw_password)
if create:
self.save()


class AdminFactory(UserFactory):
"""Create instances of Admin for testing."""
is_staff = True
is_superuser = True
5 changes: 4 additions & 1 deletion conman/tests/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
PASSWORD_HASHERS=('django.contrib.auth.hashers.MD5PasswordHasher',),
SITE_ID=1,
ROOT_URLCONF='conman.tests.urls',
MIDDLEWARE_CLASSES=(),
MIDDLEWARE_CLASSES=(
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
),
)


Expand Down
2 changes: 2 additions & 0 deletions conman/tests/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.conf.urls import include, url
from django.contrib import admin


urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'', include('conman.routes.urls')),
]
4 changes: 4 additions & 0 deletions example/example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
'conman.pages',
'conman.redirects',

'polymorphic',
'polymorphic_tree',
'sirtrevor',

'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
Expand Down
3 changes: 3 additions & 0 deletions example/example/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from django.conf.urls import include, url
from django.contrib import admin


urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^sirtrevor/', include('sirtrevor.urls')),
url(r'', include('conman.routes.urls')),
]
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
'django-mptt>=0.7.4,<=0.8',
'django-polymorphic-tree>=1.1,<2',
'django-sirtrevor>=0.2.4,<0.3',
'pillow>=2.9.0,<3',
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was required by django-sirtrevor...

],
)