Skip to content

Commit bcad213

Browse files
committed
Activate draft page content at the view level rather than in the model
Doing this in model.save() is buggy, because the modelform logic calls this before child objects have been written. In particular, experiments that are created in the live state would fail to activate the page content.
1 parent 424f7e4 commit bcad213

File tree

3 files changed

+89
-14
lines changed

3 files changed

+89
-14
lines changed

experiments/models.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,16 @@ def __init__(self, *args, **kwargs):
5252
super(Experiment, self).__init__(*args, **kwargs)
5353
self._initial_status = self.status
5454

55-
def save(self, *args, **kwargs):
56-
result = super(Experiment, self).save(*args, **kwargs)
57-
if self._initial_status == 'draft' and self.status == 'live':
58-
# For any alternative pages that are unpublished, copy the latest draft revision
59-
# to the main table (with is_live=False) so that the revision shown as an alternative
60-
# is not an out-of-date one
61-
for alternative in self.alternatives.select_related('page'):
62-
if not alternative.page.live:
63-
revision = alternative.page.get_latest_revision_as_page()
64-
revision.live = False
65-
revision.has_unpublished_changes = True
66-
revision.save()
67-
68-
return result
55+
def activate_alternative_draft_content(self):
56+
# For any alternative pages that are unpublished, copy the latest draft revision
57+
# to the main table (with is_live=False) so that the revision shown as an alternative
58+
# is not an out-of-date one
59+
for alternative in self.alternatives.select_related('page'):
60+
if not alternative.page.live:
61+
revision = alternative.page.get_latest_revision_as_page()
62+
revision.live = False
63+
revision.has_unpublished_changes = True
64+
revision.save()
6965

7066
def get_variations(self):
7167
return [self.control_page] + [alt.page for alt in self.alternatives.select_related('page')]

experiments/wagtail_hooks.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from experiments import admin_urls
88
from wagtail.contrib.modeladmin.helpers import ButtonHelper
99
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
10+
from wagtail.contrib.modeladmin.views import CreateView, EditView
1011
from wagtail.wagtailcore import hooks
1112

1213
from .models import Experiment
@@ -44,10 +45,29 @@ def get_buttons_for_obj(self, obj, exclude=[], classnames_add=[],
4445
return btns
4546

4647

48+
class CreateExperimentView(CreateView):
49+
def form_valid(self, form):
50+
response = super(CreateExperimentView, self).form_valid(form)
51+
if form.instance.status == 'live':
52+
form.instance.activate_alternative_draft_content()
53+
return response
54+
55+
56+
class EditExperimentView(EditView):
57+
def form_valid(self, form):
58+
response = super(EditExperimentView, self).form_valid(form)
59+
if self.instance._initial_status == 'draft' and self.instance.status == 'live':
60+
self.instance.activate_alternative_draft_content()
61+
62+
return response
63+
64+
4765
class ExperimentModelAdmin(ModelAdmin):
4866
model = Experiment
4967
add_to_settings_menu = True
5068
button_helper_class = ExperimentButtonHelper
69+
create_view_class = CreateExperimentView
70+
edit_view_class = EditExperimentView
5171

5272
modeladmin_register(ExperimentModelAdmin)
5373

tests/tests.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,34 @@ def test_draft_page_content_is_activated_when_experiment_goes_live(self):
364364
homepage_alternative_1 = Page.objects.get(pk=self.homepage_alternative_1.pk).specific
365365
self.assertEqual(homepage_alternative_1.body, 'updated')
366366

367+
def test_draft_page_content_is_activated_when_creating_experiment_as_live(self):
368+
# make a draft edit to homepage_alternative_1
369+
self.homepage_alternative_1.body = 'updated'
370+
self.homepage_alternative_1.save_revision()
371+
372+
# create a new experiment with an immediate live status
373+
response = self.client.post('/admin/experiments/experiment/create/', {
374+
'name': "Another experiment",
375+
'slug': 'another-experiment',
376+
'control_page': self.homepage.pk,
377+
'alternatives-TOTAL_FORMS': 1,
378+
'alternatives-INITIAL_FORMS': 0,
379+
'alternatives-MIN_NUM_FORMS': 0,
380+
'alternatives-MAX_NUM_FORMS': 1000,
381+
'alternatives-0-page': self.homepage_alternative_1.pk,
382+
'alternatives-0-id': '',
383+
'alternatives-0-ORDER': '1',
384+
'alternatives-0-DELETE': '',
385+
'goal': '',
386+
'status': 'live',
387+
})
388+
389+
self.assertRedirects(response, '/admin/experiments/experiment/')
390+
391+
# page content should be updated to follow the draft revision now
392+
homepage_alternative_1 = Page.objects.get(pk=self.homepage_alternative_1.pk).specific
393+
self.assertEqual(homepage_alternative_1.body, 'updated')
394+
367395
def test_draft_page_content_is_not_activated_on_published_pages(self):
368396
# publish homepage_alternative_1
369397
self.homepage_alternative_1.save_revision().publish()
@@ -387,6 +415,37 @@ def test_draft_page_content_is_not_activated_on_published_pages(self):
387415
homepage_alternative_1 = Page.objects.get(pk=self.homepage_alternative_1.pk).specific
388416
self.assertEqual(homepage_alternative_1.body, "Welcome to our site! It's lovely to meet you.")
389417

418+
def test_draft_page_content_is_not_activated_on_published_pages_when_creating_experiment_as_live(self):
419+
# publish homepage_alternative_1
420+
self.homepage_alternative_1.save_revision().publish()
421+
422+
# make a draft edit to homepage_alternative_1
423+
self.homepage_alternative_1.body = 'updated'
424+
self.homepage_alternative_1.save_revision()
425+
426+
# create a new experiment with an immediate live status
427+
response = self.client.post('/admin/experiments/experiment/create/', {
428+
'name': "Another experiment",
429+
'slug': 'another-experiment',
430+
'control_page': self.homepage.pk,
431+
'alternatives-TOTAL_FORMS': 1,
432+
'alternatives-INITIAL_FORMS': 0,
433+
'alternatives-MIN_NUM_FORMS': 0,
434+
'alternatives-MAX_NUM_FORMS': 1000,
435+
'alternatives-0-page': self.homepage_alternative_1.pk,
436+
'alternatives-0-id': '',
437+
'alternatives-0-ORDER': '1',
438+
'alternatives-0-DELETE': '',
439+
'goal': '',
440+
'status': 'live',
441+
})
442+
443+
self.assertRedirects(response, '/admin/experiments/experiment/')
444+
445+
# page content should still be unchanged
446+
homepage_alternative_1 = Page.objects.get(pk=self.homepage_alternative_1.pk).specific
447+
self.assertEqual(homepage_alternative_1.body, "Welcome to our site! It's lovely to meet you.")
448+
390449
def test_experiment_delete(self):
391450
response = self.client.get('/admin/experiments/experiment/delete/%d/' % self.experiment.pk)
392451
self.assertEqual(response.status_code, 200)

0 commit comments

Comments
 (0)