Skip to content

Commit

Permalink
Move coverage view to management command
Browse files Browse the repository at this point in the history
  • Loading branch information
timobrembeck authored and claudep committed Nov 15, 2023
1 parent 905ab74 commit ca004a9
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 128 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Unreleased

* Move coverage view to management command (Timo Brembeck, #187)
* Add new management command `linkcheck_suggest_config`
* Delete coverage view
* Improve formatting for `NameResolutionError` (Timo Brembeck, #192)
* Fix internal redirect checker (Timo Ludwig, #180)
* Fix SSL status of unreachable domains (Timo Ludwig, #184)
Expand Down
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Basic usage
#) can be the target of a link - i.e. is addressed by a url - in this case
make sure it has an instance method named 'get_absolute_url'

*Hint:* You can create a sample config for your model with::

manage.py linkcheck_suggest_config --model sampleapp.SampleModel > sampleapp/linklists.py

#. Run ``./manage.py migrate``.

#. Add to your root url config::
Expand Down Expand Up @@ -116,6 +120,15 @@ interval can be adapted per-invocation by using the ``--externalinterval``
You can also limit the maximum number of links to be checked by passing a number
to the ``--limit`` (``--l``) command option.

linkcheck_suggest_config
~~~~~~~~~~~~~~~~~~~~~~~~

This command goes through all models and checks whether they contain fields that
can potentially be checked by linkcheck.
If they are not yet registered, a sample config is suggested.

You can also pass the option ``--model`` to generate a sample config for the given model.

Settings
--------

Expand Down
35 changes: 35 additions & 0 deletions linkcheck/management/commands/linkcheck_suggest_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from django.apps import apps
from django.core.management.base import BaseCommand, CommandError
from django.utils.termcolors import make_style

from linkcheck.utils import get_coverage_data, get_suggested_linklist_config


class Command(BaseCommand):

cyan = staticmethod(make_style(fg='cyan'))

help = 'Go through all models and check whether they are registered with linkcheck'

def add_arguments(self, parser):
parser.add_argument(
'--model',
help="Generate the suggested config for this model",
)

def handle(self, *args, model, **options):
if model:
try:
model_class = apps.get_model(model)
except Exception as e:
raise CommandError(
f'Model "{model}" does not exist.'
) from e
self.stdout.write(get_suggested_linklist_config(model_class))
else:
covered, uncovered = get_coverage_data()
self.stdout.write('All covered models:\n')
self.stdout.write(', '.join(map(self.cyan, covered)))
for model, suggested_config in uncovered:
self.stdout.write(f'\nSuggested config for model {model}:')
self.stdout.write(self.cyan(suggested_config))
40 changes: 0 additions & 40 deletions linkcheck/templates/linkcheck/coverage.html

This file was deleted.

3 changes: 0 additions & 3 deletions linkcheck/templates/linkcheck/suggested_configs.html

This file was deleted.

14 changes: 0 additions & 14 deletions linkcheck/templates/linkcheck/suggested_linklist.html

This file was deleted.

17 changes: 0 additions & 17 deletions linkcheck/templatetags/linkcheck_coverage_tags.py

This file was deleted.

8 changes: 8 additions & 0 deletions linkcheck/tests/sampleapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ class Journal(models.Model):
title = models.CharField(max_length=50)
description = models.TextField()
version = models.PositiveIntegerField(default=0)


class UncoveredModel(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
website = models.URLField(blank=True)

def get_absolute_url(self):
return f'/uncovered/{self.id}'
72 changes: 58 additions & 14 deletions linkcheck/tests/test_linkcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.conf import settings
from django.contrib.auth.models import User
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test import LiveServerTestCase, TestCase
from django.test.utils import override_settings
from django.urls import reverse
Expand Down Expand Up @@ -924,6 +925,52 @@ def test_findlinks_command(self):
)


class ManagementCommandTestCase(TestCase):

def test_linkcheck_suggest_config(self):
"""
Test that the config of uncovered models is correctly suggested
"""
out, err = get_command_output('linkcheck_suggest_config')
self.assertEqual(
out,
'All covered models:\n'
'\x1b[36msampleapp.Book\x1b[0m, \x1b[36msampleapp.Page\x1b[0m\n\n'
'Suggested config for model sampleapp.UncoveredModel:\n'
'\x1b[36mfrom sampleapp.models import UncoveredModel\n\n'
'class UncoveredModelLinklist(Linklist):\n'
' model = UncoveredModel\n\n'
'linklists = {\n'
' "UncoveredModel": UncoveredModelLinklist,\n'
'}\n\x1b[0m\n'
)
self.assertEqual(err, '')

def test_linkcheck_suggest_config_model(self):
"""
Test that the config of given model is correctly printed
"""
out, err = get_command_output('linkcheck_suggest_config', '--model', 'sampleapp.Author')
self.assertEqual(
out,
'from sampleapp.models import Author\n\n'
'class AuthorLinklist(Linklist):\n'
' model = Author\n\n'
'linklists = {\n'
' "Author": AuthorLinklist,\n'
'}\n'
)
self.assertEqual(err, '')

def test_linkcheck_suggest_config_model_non_existing(self):
"""
Test that the command raises an error when the model does not exist
"""
with self.assertRaises(CommandError) as cm:
get_command_output('linkcheck_suggest_config', '--model', 'non-existing')
self.assertEqual(str(cm.exception), 'Model "non-existing" does not exist.')


class ObjectsUpdateTestCase(TestCase):
def test_update_object(self):
"""
Expand Down Expand Up @@ -1068,17 +1115,6 @@ def test_report_recheck(self):
'message': '404 Not Found',
})

def test_coverage_view(self):
self.client.force_login(self.user)
response = self.client.get(reverse('linkcheck_coverage'))
self.assertContains(
response,
'<tr><td>sampleapp.Book</td>'
'<td style="font-weight: bold;color:green;">Yes</td>'
'<td style="font-weight: bold;color:green;"></td></tr>',
html=True,
)


class GetJqueryMinJsTestCase(TestCase):
def test(self):
Expand Down Expand Up @@ -1115,10 +1151,18 @@ def test_filter_callable(self):
)


def get_command_output(command, *args, **kwargs):
"""
Helper function for running a management command and checking its output
"""
out = StringIO()
err = StringIO()
call_command(command, *args, stdout=out, stderr=err, **kwargs)
return out.getvalue(), err.getvalue()


def findlinks():
"""
Helper function for running the findlinks command and checking its output
"""
out = StringIO()
call_command('findlinks', stdout=out)
return out.getvalue()
return get_command_output('findlinks')[0]
1 change: 0 additions & 1 deletion linkcheck/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
from . import views

urlpatterns = [
path('coverage/', views.coverage, name='linkcheck_coverage'),
path('', views.report, name='linkcheck_report'),
]
Loading

0 comments on commit ca004a9

Please sign in to comment.