import sys import unittest from django.conf import settings from django.contrib.admindocs import utils from django.contrib.admindocs.views import get_return_data_type, simplify_regex from django.contrib.auth.models import User from django.contrib.sites.models import Site from django.test import TestCase, modify_settings, override_settings from django.test.utils import captured_stderr from django.urls import reverse from .models import Company, Person class TestDataMixin(object): @classmethod def setUpTestData(cls): cls.superuser = User.objects.create_superuser(username='super', password='secret', email='super@example.com') @override_settings(ROOT_URLCONF='admin_docs.urls') @modify_settings(INSTALLED_APPS={'append': 'django.contrib.admindocs'}) class AdminDocsTestCase(TestCase): pass class MiscTests(AdminDocsTestCase): def setUp(self): superuser = User.objects.create_superuser('super', None, 'secret') self.client.force_login(superuser) @modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}) @override_settings(SITE_ID=None) # will restore SITE_ID after the test def test_no_sites_framework(self): """ Without the sites framework, should not access SITE_ID or Site objects. Deleting settings is fine here as UserSettingsHolder is used. """ Site.objects.all().delete() del settings.SITE_ID self.client.get('/admindocs/views/') # should not raise @unittest.skipUnless(utils.docutils_is_available, "no docutils installed.") class AdminDocViewTests(TestDataMixin, AdminDocsTestCase): def setUp(self): self.client.force_login(self.superuser) def test_index(self): self.client.logout() response = self.client.get(reverse('django-admindocs-docroot'), follow=True) # Should display the login screen self.assertContains(response, '', html=True) self.client.force_login(self.superuser) response = self.client.get(reverse('django-admindocs-docroot')) self.assertContains(response, '
test:func
.')
def test_view_detail(self):
url = reverse('django-admindocs-views-detail', args=['django.contrib.admindocs.views.BaseAdminDocsView'])
response = self.client.get(url)
# View docstring
self.assertContains(response, 'Base view for admindocs views.')
@override_settings(ROOT_URLCONF='admin_docs.namespace_urls')
def test_namespaced_view_detail(self):
url = reverse('django-admindocs-views-detail', args=['admin_docs.views.XViewClass'])
response = self.client.get(url)
self.assertContains(response, 'reST, interpreted text, default role.
\n' parts = docutils.core.publish_parts(source=source, writer_name="html4css1") self.assertEqual(parts['fragment'], markup) @unittest.skipUnless(utils.docutils_is_available, "no docutils installed.") class TestModelDetailView(TestDataMixin, AdminDocsTestCase): """ Tests that various details render correctly """ def setUp(self): self.client.force_login(self.superuser) with captured_stderr() as self.docutils_stderr: self.response = self.client.get(reverse('django-admindocs-models-detail', args=['admin_docs', 'Person'])) def test_method_excludes(self): """ Methods that begin with strings defined in ``django.contrib.admindocs.views.MODEL_METHODS_EXCLUDE`` should not get displayed in the admin docs. """ self.assertContains(self.response, "Get the full name of the person
") link = '%s' markup = 'the related %s object
' company_markup = markup % (link % ("admin_docs.company", "admin_docs.Company")) # foreign keys self.assertContains(self.response, company_markup) # foreign keys with help text self.assertContains(self.response, "%s\n - place of work" % company_markup) # many to many fields self.assertContains( self.response, "number of related %s objects" % (link % ("admin_docs.group", "admin_docs.Group")) ) self.assertContains( self.response, "all related %s objects" % (link % ("admin_docs.group", "admin_docs.Group")) ) # "raw" and "include" directives are disabled self.assertContains(self.response, '"raw" directive disabled.
',) self.assertContains(self.response, '.. raw:: html\n :file: admin_docs/evilfile.txt') self.assertContains(self.response, '"include" directive disabled.
',) self.assertContains(self.response, '.. include:: admin_docs/evilfile.txt') out = self.docutils_stderr.getvalue() self.assertIn('"raw" directive disabled', out) self.assertIn('"include" directive disabled', out) def test_model_with_many_to_one(self): link = '%s' response = self.client.get( reverse('django-admindocs-models-detail', args=['admin_docs', 'company']) ) self.assertContains( response, "number of related %s objects" % (link % ("admin_docs.person", "admin_docs.Person")) ) self.assertContains( response, "all related %s objects" % (link % ("admin_docs.person", "admin_docs.Person")) ) def test_model_with_no_backward_relations_render_only_relevant_fields(self): """ A model with ``related_name`` of `+` should not show backward relationship links in admin docs """ response = self.client.get(reverse('django-admindocs-models-detail', args=['admin_docs', 'family'])) fields = response.context_data.get('fields') self.assertEqual(len(fields), 2) def test_model_docstring_renders_correctly(self): summary = ( 'Stores information about a person, related to myapp.Company.
' ) subheading = 'Notes
' body = 'Use save_changes() when saving this object.
' model_body = ( 'This __doc__ output is required for testing. I copied this ' 'example from\nadmindocs documentation. ' '(TITLE)
\n' ) self.assertHTMLEqual(title_output, title_rendered) def test_description_output(self): title, description, metadata = utils.parse_docstring(self.docstring) description_output = utils.parse_rst(description, 'model', 'model:admindocs') description_rendered = ( 'Display an individual myapp.MyModel.
\n' 'Context
\n' 'RequestContext
\nTemplate:
' '\nmyapp/my_template.html (DESCRIPTION)' '
\n' ) self.assertHTMLEqual(description_output, description_rendered) def test_initial_header_level(self): header = 'should be h3...\n\nHeader\n------\n' output = utils.parse_rst(header, 'header') self.assertIn('