Skip to content

feat: Reworked form fields and added the ability to show draft snippets #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
6b142d1
Added missing field for form
adam-murray Oct 14, 2021
253cddc
Fixed form
adam-murray Oct 15, 2021
a6f8329
Fixed form save method
adam-murray Oct 15, 2021
291bc94
Added model property for snippet grouper
adam-murray Oct 15, 2021
1fe4fbf
Added fix for bug in demo
adam-murray Oct 15, 2021
b281e45
Update djangocms_snippet/forms.py
adam-murray Oct 15, 2021
3c8fa93
Added test case for verisoning state machine snippet/page
adam-murray Oct 15, 2021
7032daf
added test case for snippet version rendering
adam-murray Oct 15, 2021
6723e57
Fixed issue with form save method and updated tests.
adam-murray Oct 15, 2021
62d1c2f
Removed unused factories
adam-murray Oct 15, 2021
3451165
Updated plugin test cases
adam-murray Oct 15, 2021
bfc3b6e
Remove unused import in factories
adam-murray Oct 15, 2021
c779f3f
Simplified from unecessary helpers
adam-murray Oct 18, 2021
d0b975e
Removed unused helpers
adam-murray Oct 18, 2021
4d926f2
added test case for forms with commit=False
adam-murray Oct 18, 2021
f3609a6
updated test case
adam-murray Oct 18, 2021
5862325
Remove debugger
adam-murray Oct 18, 2021
c5a97cd
Refactored plugin tests
adam-murray Oct 18, 2021
3f1fbb2
Updated snippet fetch method to get return appropriate snipper versio…
adam-murray Oct 19, 2021
c9cb424
Linting
adam-murray Oct 19, 2021
8900700
Updated old comments
adam-murray Oct 19, 2021
3acf07f
Updated to check requests in models
adam-murray Oct 19, 2021
2b0331c
Updated snippet grouper snippet method
adam-murray Oct 19, 2021
333f5cb
remove unused code
adam-murray Oct 19, 2021
928c738
Updated endpoint logic
adam-murray Oct 19, 2021
3bc134b
Linting
adam-murray Oct 19, 2021
77a6080
Updated SnipeptGrouper snippet method, and added comments
adam-murray Oct 19, 2021
d8aad53
Add additional logic to prevent archived content being returned befor…
adam-murray Oct 20, 2021
59f3b6a
Updated Comment
adam-murray Oct 20, 2021
d67d31a
Updated Comment
adam-murray Oct 20, 2021
c31fca7
Comment Update tests/test_plugins.py
adam-murray Oct 20, 2021
6f579ea
Suggestions from code review
adam-murray Oct 20, 2021
7fd5e40
Updated comment in models.
adam-murray Oct 20, 2021
82962b4
Added filtering for correct version states in grouper snippet return …
adam-murray Oct 20, 2021
35456da
Update model so we don't have to pass the request object to the grouper
adam-murray Oct 20, 2021
4e4d840
Updated render method to prevent request object being passed to models.
adam-murray Oct 20, 2021
08c5939
removed unused property, added __str__ method back on grouper
adam-murray Oct 20, 2021
cc60686
Updated test criteria to reflect removal of property on plugin
adam-murray Oct 20, 2021
def0196
Fixed test criteria
adam-murray Oct 20, 2021
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
2 changes: 2 additions & 0 deletions djangocms_snippet/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class SnippetAdmin(*snippet_admin_classes):
formfield_overrides = {
models.TextField: {'widget': Textarea(attrs=text_area_attrs)}
}
# This was move here from model, otherwise first() and last() return the same when handling grouper queries
ordering = ('name',)

class Meta:
model = Snippet
Expand Down
14 changes: 8 additions & 6 deletions djangocms_snippet/cms_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from cms.plugin_pool import plugin_pool

from .models import SnippetPtr
from .utils import show_draft_content


CACHE_ENABLED = getattr(settings, "DJANGOCMS_SNIPPET_CACHE", False)
Expand All @@ -22,19 +23,20 @@ class SnippetPlugin(CMSPluginBase):
cache = CACHE_ENABLED

def render(self, context, instance, placeholder):
snippet = instance.snippet_grouper.snippet(show_editable=show_draft_content(context["request"]))
try:
if instance.snippet.template:
if snippet.template:
context = context.flatten()
context.update({"html": mark_safe(instance.snippet.html)})
t = template.loader.get_template(instance.snippet.template)
context.update({"html": mark_safe(snippet.html)})
t = template.loader.get_template(snippet.template)
content = t.render(context)
else:
# only html provided
t = template.Template(instance.snippet.html)
t = template.Template(snippet.html)
content = t.render(context)
except template.TemplateDoesNotExist:
content = _("Template %(template)s does not exist.") % {
"template": instance.snippet.template
"template": snippet.template
}
except Exception as e:
content = escape(str(e))
Expand All @@ -43,7 +45,7 @@ def render(self, context, instance, placeholder):
{
"placeholder": placeholder,
"object": instance,
"html": mark_safe(instance.snippet.html),
"html": mark_safe(snippet.html),
"content": content,
}
)
Expand Down
13 changes: 8 additions & 5 deletions djangocms_snippet/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Meta:
"html",
"slug",
"snippet_grouper",
"template",
)

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -55,8 +56,10 @@ def clean(self):

@transaction.atomic
def save(self, **kwargs):
if not self.cleaned_data.get("snippet_grouper"):
super().save(commit=False)
self.save_m2m()
self.instance.snippet_grouper = SnippetGrouper.objects.create()
return super().save()
commit = kwargs.get("commit", True)
snippet = super().save(commit=False)
if commit:
if not hasattr(snippet, "snippet_grouper"):
snippet.snippet_grouper = SnippetGrouper.objects.create()
snippet.save()
return snippet
17 changes: 17 additions & 0 deletions djangocms_snippet/migrations/0014_auto_20211019_0522.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 2.2.24 on 2021-10-19 10:22

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('djangocms_snippet', '0013_auto_20210915_0751'),
]

operations = [
migrations.AlterModelOptions(
name='snippet',
options={'verbose_name': 'Snippet', 'verbose_name_plural': 'Snippets'},
),
]
20 changes: 15 additions & 5 deletions djangocms_snippet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,34 @@

from cms.models import CMSPlugin

from djangocms_versioning.constants import DRAFT, PUBLISHED


# Search is enabled by default to keep backwards compatibility.
SEARCH_ENABLED = getattr(settings, 'DJANGOCMS_SNIPPET_SEARCH', False)


class SnippetGrouper(models.Model):
"""
The Grouper model for snippet, this is required for versioning
"""
@property
def name(self):
snippet_qs = Snippet._base_manager.filter(
snippet_grouper=self
)
return snippet_qs.first().name or super().__str__

def snippet(self, show_editable=False):
if show_editable:
# When in "edit" or "preview" mode we should be able to see the latest content
return Snippet._base_manager.filter(
versions__state__in=[DRAFT, PUBLISHED],
snippet_grouper=self,
).order_by("-pk").first()
# When in "live" mode we should only be able to see the default published version
return Snippet.objects.filter(snippet_grouper=self).first()

def __str__(self):
return self.name

Expand Down Expand Up @@ -68,7 +83,6 @@ def get_preview_url(self):
)

class Meta:
ordering = ['name']
verbose_name = _('Snippet')
verbose_name_plural = _('Snippets')

Expand All @@ -95,7 +109,3 @@ class SnippetPtr(CMSPlugin):
class Meta:
verbose_name = _('Snippet Ptr')
verbose_name_plural = _('Snippet Ptrs')

@property
def snippet(self):
return self.snippet_grouper.snippet_set.first()
11 changes: 11 additions & 0 deletions djangocms_snippet/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from cms.toolbar.utils import get_toolbar_from_request


def show_draft_content(request=None):
"""
Returns True if draft contents should be shown.
"""
if not request:
return False
request_toolbar = get_toolbar_from_request(request)
return request_toolbar.edit_mode_active or request_toolbar.preview_mode_active
11 changes: 7 additions & 4 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
from djangocms_snippet import admin as snippet_admin
from djangocms_snippet import cms_config
from djangocms_snippet.forms import SnippetForm
from djangocms_snippet.models import Snippet

from .utils.factories import SnippetWithVersionFactory
from djangocms_snippet.models import Snippet, SnippetGrouper


class SnippetAdminTestCase(CMSTestCase):
def setUp(self):
self.snippet = SnippetWithVersionFactory()
self.snippet = Snippet.objects.create(
name="Test Snippet",
slug="test-snippet",
html="<h1>This is a test</h1>",
snippet_grouper=SnippetGrouper.objects.create(),
)
self.snippet_admin = snippet_admin.SnippetAdmin(Snippet, admin)
self.snippet_admin_request = RequestFactory().get("/admin/djangocms_snippet")

Expand Down
63 changes: 47 additions & 16 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from importlib import reload

from django.test import override_settings

from cms.test_utils.testcases import CMSTestCase

from djangocms_snippet.forms import SnippetForm
from djangocms_snippet import cms_config, forms
from djangocms_snippet.models import Snippet, SnippetGrouper

from .utils.factories import SnippetWithVersionFactory
Expand All @@ -16,17 +18,19 @@ def test_snippet_form_creates_grouper_no_versioning(self):
Without versioning enabled, the application still has the grouper implemented, therefore the form
should be creating one for each new snippet created.
"""
reload(cms_config)
reload(forms)
form_data = {
"name": "test_snippet",
"slug": "test_snippet",
"html": "<h1>Test Title</h1>"
}
form = SnippetForm(form_data)
form = forms.SnippetForm(form_data)

self.assertTrue(form.is_valid())

form.clean()
form.save()
form.save(commit=True)

self.assertEqual(SnippetGrouper.objects.count(), 1)
self.assertEqual(Snippet._base_manager.count(), 1)
Expand All @@ -36,52 +40,77 @@ def test_snippet_form_creates_grouper_with_versioning(self):
"""
With versioning enabled, groupers should also be created in the background.
"""
reload(cms_config)
reload(forms)
form_data = {
"name": "test_snippet",
"slug": "test_snippet",
"html": "<h1>Test Title</h1>"
}
form = SnippetForm(form_data)
form = forms.SnippetForm(form_data)

self.assertTrue(form.is_valid())

form.clean()
form.save()
form.save(commit=True)

self.assertEqual(SnippetGrouper.objects.count(), 1)
self.assertEqual(Snippet._base_manager.count(), 1)

@override_settings(DJANGOCMS_SNIPPET_VERSIONING_ENABLED=True)
def test_snippet_form_doesnt_create_grouper_or_snippet_with_no_commit(self):
"""
With versioning enabled, but commit=False, models should not be created
"""
reload(cms_config)
reload(forms)
form_data = {
"name": "test_snippet",
"slug": "test_snippet",
"html": "<h1>Test Title</h1>"
}
form = forms.SnippetForm(form_data)

self.assertTrue(form.is_valid())

form.clean()
form.save(commit=False)

self.assertEqual(SnippetGrouper.objects.count(), 0)
self.assertEqual(Snippet._base_manager.count(), 0)

@override_settings(DJANGOCMS_SNIPPET_VERSIONING_ENABLED=True)
def test_snippet_form_adds_to_existing_grouper_with_versioning(self):
"""
With versioning enabled, if a grouper already exists, a new one shouldn't be created
"""

reload(cms_config)
reload(forms)
grouper = SnippetGrouper.objects.create()
form_data = {
"name": "test_snippet",
"slug": "test_snippet",
"html": "<h1>Test Title</h1>",
"snippet_grouper": grouper.id,
}
form = SnippetForm(form_data)
form = forms.SnippetForm(form_data)

self.assertTrue(form.is_valid())

form.clean()
form.save()
form.save(commit=True)

self.assertEqual(SnippetGrouper.objects.count(), 1)
self.assertEqual(Snippet._base_manager.count(), 1)

form_data["html"] = "<h2>Test Title</h2>"

form = SnippetForm(form_data)
form = forms.SnippetForm(form_data)

self.assertTrue(form.is_valid())

form.clean()
form.save()
form.save(commit=True)

self.assertEqual(SnippetGrouper.objects.count(), 1)
self.assertEqual(Snippet._base_manager.count(), 2)
Expand All @@ -92,21 +121,21 @@ def test_snippet_form_versioning_enabled(self):
With versioning enabled, the snippet form doesn't have to create groupers, but does have to validate
that no other active (i.e. the latest published snippet from a given grouper) shares the same name or slug.
"""
reload(cms_config)
reload(forms)
form_data = {
"name": "test_snippet",
"slug": "test_snippet",
"html": "<h1>Test Title</h1>",
}
form = SnippetForm(form_data)
form = forms.SnippetForm(form_data)

self.assertTrue(form.is_valid())

# Clean and save the form
form.clean()
form.save()
snippet = form.save(commit=True)

# Publish the old created version
snippet = Snippet._base_manager.last()
version = snippet.versions.create(created_by=self.get_superuser())
version.publish(user=self.get_superuser())

Expand All @@ -116,7 +145,7 @@ def test_snippet_form_versioning_enabled(self):
"html": "<h1>Another Test Title</h1>",
}

new_form = SnippetForm(new_form_data)
new_form = forms.SnippetForm(new_form_data)

self.assertFalse(new_form.is_valid())

Expand All @@ -128,6 +157,8 @@ def test_snippet_form_validation_multiple_version_states_in_grouper(self):
"""
Snippet forms should be valid regardless of the versions, or states which already exist within its grouper.
"""
reload(cms_config)
reload(forms)
# snippet_to_archive starts as draft
snippet_to_archive = SnippetWithVersionFactory()
# Then it is published it
Expand All @@ -154,6 +185,6 @@ def test_snippet_form_validation_multiple_version_states_in_grouper(self):
"snippet_grouper": snippet_to_archive.snippet_grouper.id,
}

form = SnippetForm(form_data)
form = forms.SnippetForm(form_data)

self.assertTrue(form.is_valid())
Loading