cells: add a cell type "list of links" (#11006)

This commit is contained in:
Lauréline Guérin 2020-01-07 15:27:44 +01:00
parent a00b640090
commit 24619ce6db
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
14 changed files with 662 additions and 12 deletions

View File

@ -36,14 +36,18 @@ from .utils import get_wcs_json, is_wcs_enabled, get_wcs_services
@register_cell_class
class WcsFormCell(CellBase):
template_name = 'combo/wcs/form.html'
formdef_reference = models.CharField(_('Form'), max_length=150)
cached_title = models.CharField(_('Title'), max_length=150)
cached_url = models.URLField(_('URL'))
cached_json = JSONField(blank=True)
template_name = 'combo/wcs/form.html'
add_as_link_label = _('add a form link')
add_link_label = _('New form link')
edit_link_label = _('Edit form link')
add_as_link_code = 'form-link'
is_enabled = classmethod(is_wcs_enabled)
class Meta:

View File

@ -18,7 +18,7 @@ import copy
from django import forms
from .models import Page, ParametersCell, MenuCell, LinkCell, ConfigJsonCell
from .models import Page, ParametersCell, MenuCell, LinkCell, LinkListCell, ConfigJsonCell
from jsonfield.widgets import JSONWidget
from combo.utils import cache_during_request
@ -41,6 +41,7 @@ class ParametersForm(forms.Form):
break
return self.cleaned_data
class ParametersCellForm(forms.ModelForm):
class Meta:
model = ParametersCell
@ -61,6 +62,7 @@ def get_page_choices():
pages = Page.get_as_reordered_flat_hierarchy(Page.objects.all())
return [(x.id, '%s %s' % (u'\u00a0' * x.level * 2, x.title)) for x in pages]
class MenuCellForm(forms.ModelForm):
class Meta:
model = MenuCell
@ -82,6 +84,15 @@ class LinkCellForm(forms.ModelForm):
choices=[(None, '-----')] + get_page_choices())
class LinkListCellForm(forms.ModelForm):
class Meta:
model = LinkListCell
fields = ['title']
def __init__(self, *args, **kwargs):
super(LinkListCellForm, self).__init__(*args, **kwargs)
class ConfigJsonForm(forms.ModelForm):
formdef = []

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('auth', '0008_alter_user_username_max_length'),
('data', '0038_increase_jsoncell_url_max_length'),
]
operations = [
migrations.CreateModel(
name='LinkListCell',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('placeholder', models.CharField(max_length=20)),
('order', models.PositiveIntegerField()),
('slug', models.SlugField(blank=True, verbose_name='Slug')),
('extra_css_class', models.CharField(blank=True, max_length=100, verbose_name='Extra classes for CSS styling')),
('public', models.BooleanField(default=True, verbose_name='Public')),
('restricted_to_unlogged', models.BooleanField(default=False, verbose_name='Restrict to unlogged users')),
('last_update_timestamp', models.DateTimeField(auto_now=True)),
('groups', models.ManyToManyField(blank=True, to='auth.Group', verbose_name='Groups')),
('title', models.CharField(max_length=150, verbose_name='Title', blank=True)),
],
options={
'verbose_name': 'List of links',
},
),
migrations.AddField(
model_name='linklistcell',
name='page',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='data.Page'),
),
]

View File

@ -451,6 +451,8 @@ class Page(models.Model):
new_page.groups.set(self.groups.all())
for cell in self.get_cells():
if cell.placeholder and cell.placeholder.startswith('_'):
continue
cell.duplicate(page_target=new_page)
return new_page
@ -756,12 +758,14 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
def import_subobjects(self, cell_json):
pass
def duplicate(self, page_target=None):
def duplicate(self, page_target=None, placeholder=None):
# clone current cell
new_cell = copy.deepcopy(self)
new_cell.pk = None
# set page
new_cell.page = page_target or self.page
# set placeholder
new_cell.placeholder = placeholder or new_cell.placeholder
# store new cell
new_cell.save()
@ -905,6 +909,10 @@ class LinkCell(CellBase):
anchor = models.CharField(_('Anchor'), max_length=150, blank=True)
template_name = 'combo/link-cell.html'
add_as_link_label = _('add a link')
add_link_label = _('New link')
edit_link_label = _('Edit link')
add_as_link_code = 'link'
class Meta:
verbose_name = _('Link')
@ -950,6 +958,76 @@ class LinkCell(CellBase):
return []
@register_cell_class
class LinkListCell(CellBase):
title = models.CharField(_('Title'), max_length=150, blank=True)
template_name = 'combo/link-list-cell.html'
manager_form_template = 'combo/manager/link-list-cell-form.html'
class Meta:
verbose_name = _('List of links')
@property
def link_placeholder(self):
return '_linkslist:{}'.format(self.pk)
def get_items(self):
return CellBase.get_cells(
page=self.page,
placeholder=self.link_placeholder,
cell_filter=lambda x: hasattr(x, 'add_as_link_label'))
def get_additional_label(self):
title = self.title
if not title:
return None
return utils.ellipsize(title)
def get_cell_extra_context(self, context):
extra_context = super(LinkListCell, self).get_cell_extra_context(context)
links = []
for cell in context.get('page_cells', []):
if not hasattr(cell, 'add_as_link_label'):
continue
if not cell.placeholder == self.link_placeholder:
continue
links.append(cell.get_cell_extra_context(context))
extra_context['links'] = links
extra_context['title'] = self.title
return extra_context
def get_link_cell_classes(self):
return CellBase.get_cell_classes(lambda x: hasattr(x, 'add_as_link_label'))
def get_default_form_class(self):
from .forms import LinkListCellForm
return LinkListCellForm
def render_for_search(self):
return ''
def export_subobjects(self):
return {'links': json.loads(
serializers.serialize(
'json',
self.get_items(),
use_natural_foreign_keys=True,
use_natural_primary_keys=True)
)}
def import_subobjects(self, cell_json):
for link in cell_json['links']:
link['fields']['placeholder'] = self.link_placeholder
for link in serializers.deserialize('json', json.dumps(cell_json['links'])):
link.save()
def duplicate_m2m(self, new_cell):
# duplicate also link items
for link in self.get_items():
link.duplicate(page_target=new_cell.page, placeholder=new_cell.link_placeholder)
@register_cell_class
class FeedCell(CellBase):
title = models.CharField(_('Title'), max_length=150, blank=True)

View File

@ -0,0 +1,46 @@
{% extends "combo/cell_form.html" %}
{% load i18n %}
{% block cell-form %}
{{ form.as_p }}
{% with cell.get_items as links %}
{% if links %}
<p><label>{% trans "Links:" %}</label></p>
<div>
<ul class="objects-list list-of-links" id="list-of-links-{{ cell.pk }}"
data-link-list-order-url="{% url 'combo-manager-link-list-order' page_pk=page.pk cell_reference=cell.get_reference %}">
{% for link in links %}
<li data-link-item-id="{{ link.pk }}"><span class="handle"></span>
<span title="{{ link }}">{{ link|truncatechars:100 }}</span>
<a rel="popup" title="{% trans "Edit" %}" class="link-action-icon edit" href="{% url 'combo-manager-page-list-cell-edit-link' page_pk=page.id cell_reference=cell.get_reference link_cell_reference=link.get_reference %}">{% trans "Edit" %}</a>
<a rel="popup" title="{% trans "Delete" %}" class="link-action-icon delete" href="{% url 'combo-manager-page-list-cell-delete-link' page_pk=page.id cell_reference=cell.get_reference link_cell_reference=link.get_reference %}">{% trans "Delete" %}</a>
</li>
{% endfor %}
</ul>
</div>
<script>
$(function () {
$('#list-of-links-{{ cell.pk }}').sortable({
handle: '.handle',
update: function(event, ui) {
var new_order = Object();
$(this).find('li').each(function(i, x) {
var suffix = $(x).data('link-item-id');
new_order['pos_' + suffix] = i;
});
$.ajax({
url: $(this).data('link-list-order-url'),
data: new_order
});
}
});
});
</script>
{% endif %}
{% endwith %}
<div class="buttons">
{% for klass in cell.get_link_cell_classes %}
<a rel="popup" href="{% url 'combo-manager-page-list-cell-add-link' page_pk=page.id cell_reference=cell.get_reference link_code=klass.add_as_link_code %}">{{ klass.add_as_link_label }}</a> {% if not forloop.last %}|{% endif %}
{% endfor %}
</div>
{% endblock %}

View File

@ -480,3 +480,41 @@ ul.gallery li:last-child a {
text-align: center;
padding: 45px 1ex 1ex 1ex;
}
ul.objects-list.list-of-links li {
padding-left: 0;
}
ul.objects-list.list-of-links li a.link-action-icon {
height: 100%;
position: absolute;
right: 0;
top: 0;
width: 3em;
display: block;
overflow: hidden;
text-decoration: none;
border: none;
text-indent: -1000px;
line-height: 3em;
}
ul.objects-list.list-of-links li a.link-action-icon::before {
font-family: FontAwesome;
text-indent: 0px;
text-align: center;
display: block;
width: 100%;
}
ul.objects-list.list-of-links li a.link-action-icon.delete::before {
content: "\f057"; /* remove-sign */
}
ul.objects-list.list-of-links li a.link-action-icon.edit {
right: 3em;
}
ul.objects-list.list-of-links li a.link-action-icon.edit::before {
content: "\f044";
}

View File

@ -0,0 +1,22 @@
{% extends "combo/manager_base.html" %}
{% load i18n %}
{% block appbar %}
{% if form.instance.pk %}
<h2>{{ form.instance.edit_link_label }}</h2>
{% else %}
<h2>{{ form.instance.add_link_label }}</h2>
{% endif %}
{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="buttons">
<button class="submit-button">{% trans "Save" %}</button>
<a class="cancel" href="{% url 'combo-manager-page-view' pk=form.instance.page_id %}">{% trans 'Cancel' %}</a>
</div>
</form>
{% endblock %}

View File

@ -75,6 +75,18 @@ urlpatterns = [
name='combo-manager-page-visibility-cell'),
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/label$',
views.page_get_additional_label, name='combo-manager-page-get-additional-label'),
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/add-link/(?P<link_code>[\w-]+)$',
views.page_list_cell_add_link,
name='combo-manager-page-list-cell-add-link'),
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/link/(?P<link_cell_reference>[\w_-]+)/$',
views.page_list_cell_edit_link,
name='combo-manager-page-list-cell-edit-link'),
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/link/(?P<link_cell_reference>[\w_-]+)/delete$',
views.page_list_cell_delete_link,
name='combo-manager-page-list-cell-delete-link'),
url(r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/order$',
views.link_list_order,
name='combo-manager-link-list-order'),
url(r'^pages/(?P<page_pk>\d+)/order$', views.cell_order,
name='combo-manager-cell-order'),
url(r'^pages/order$', views.page_order,

View File

@ -33,7 +33,7 @@ from django.views.decorators.csrf import requires_csrf_token
from django.views.generic import (RedirectView, DetailView,
CreateView, UpdateView, ListView, DeleteView, FormView)
from combo.data.models import Page, CellBase, ParentContentCell, PageSnapshot
from combo.data.models import Page, CellBase, ParentContentCell, PageSnapshot, LinkListCell
from combo.data.library import get_cell_class
from combo.data.utils import export_site, import_site, MissingGroups
from combo import plugins
@ -124,7 +124,6 @@ class PageAddChildView(PageAddView):
return super(CreateView, self).get_initial()
def dispatch(self, request, *args, **kwargs):
print(request.POST)
self.parent = get_object_or_404(Page, pk=kwargs['pk'])
return super(PageAddChildView, self).dispatch(request, *args, **kwargs)
@ -399,6 +398,7 @@ class PageEditCellView(UpdateView):
def get_context_data(self, **kwargs):
context = super(PageEditCellView, self).get_context_data(**kwargs)
context['cell'] = self.get_object()
context['page'] = context['cell'].page
return context
def get_object(self, queryset=None):
@ -564,3 +564,143 @@ def menu_json(request):
response = HttpResponse(content_type=content_type)
response.write(json_str)
return response
class PageListCellAddLinkView(CreateView):
template_name = 'combo/link_cell_form.html'
def dispatch(self, request, *args, **kwargs):
try:
self.cell = CellBase.get_cell(kwargs['cell_reference'], page=kwargs['page_pk'])
except LinkListCell.DoesNotExist:
raise Http404
for klass in self.cell.get_link_cell_classes():
if klass.add_as_link_code == kwargs['link_code']:
self.model = klass
break
if self.model is None:
raise Http404
return super(PageListCellAddLinkView, self).dispatch(request, *args, **kwargs)
def get_form_class(self):
return self.model().get_default_form_class()
def get_form_kwargs(self):
kwargs = super(PageListCellAddLinkView, self).get_form_kwargs()
kwargs['instance'] = self.model(page=self.cell.page, placeholder=self.cell.link_placeholder)
return kwargs
def form_valid(self, form):
orders = [x.order for x in self.cell.get_items()]
if orders:
form.instance.order = max(orders)+1
else:
form.instance.order = 1
return super(PageListCellAddLinkView, self).form_valid(form)
def get_success_url(self):
return '%s#cell-%s' % (
reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')}),
self.kwargs['cell_reference'])
page_list_cell_add_link = PageListCellAddLinkView.as_view()
class PageListCellEditLinkView(UpdateView):
template_name = 'combo/link_cell_form.html'
def dispatch(self, request, *args, **kwargs):
try:
self.cell = CellBase.get_cell(kwargs['cell_reference'], page=kwargs['page_pk'])
except LinkListCell.DoesNotExist:
raise Http404
try:
self.object = CellBase.get_cell(kwargs['link_cell_reference'], page=kwargs['page_pk'])
except ObjectDoesNotExist:
raise Http404
if self.object.placeholder != self.cell.link_placeholder:
raise Http404
self.model = self.object.__class__
return super(PageListCellEditLinkView, self).dispatch(request, *args, **kwargs)
def get_object(self, *args, **kwargs):
return self.object
def get_form_class(self):
return self.model().get_default_form_class()
def form_valid(self, form):
if self.request.is_ajax():
self.object = form.save()
response = self.form_invalid(form) # avoid redirection
else:
response = super(PageListCellEditLinkView, self).form_valid(form)
PageSnapshot.take(self.cell.page, request=self.request, comment=_('changed cell "%s"') % self.cell)
return response
def get_success_url(self):
return '%s#cell-%s' % (
reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')}),
self.kwargs['cell_reference'])
page_list_cell_edit_link = PageListCellEditLinkView.as_view()
class PageListCellDeleteLinkView(DeleteView):
template_name = 'combo/generic_confirm_delete.html'
def dispatch(self, request, *args, **kwargs):
try:
self.cell = CellBase.get_cell(kwargs['cell_reference'], page=kwargs['page_pk'])
except LinkListCell.DoesNotExist:
raise Http404
try:
self.object = CellBase.get_cell(kwargs['link_cell_reference'], page=kwargs['page_pk'])
except ObjectDoesNotExist:
raise Http404
if self.object.placeholder != self.cell.link_placeholder:
raise Http404
self.model = self.object.__class__
return super(PageListCellDeleteLinkView, self).dispatch(request, *args, **kwargs)
def get_object(self, *args, **kwargs):
return self.object
def delete(self, request, *args, **kwargs):
response = super(PageListCellDeleteLinkView, self).delete(request, *args, **kwargs)
PageSnapshot.take(self.cell.page, request=self.request, comment=_('changed cell "%s"') % self.cell)
return response
def get_success_url(self):
return '%s#cell-%s' % (
reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')}),
self.kwargs['cell_reference'])
page_list_cell_delete_link = PageListCellDeleteLinkView.as_view()
def link_list_order(request, page_pk, cell_reference):
try:
cell = CellBase.get_cell(cell_reference, page=page_pk)
except LinkListCell.DoesNotExist:
raise Http404
has_changes = False
for link in cell.get_items():
old_order = link.order
try:
new_order = int(request.GET.get('pos_' + str(link.pk)))
except TypeError:
continue
if new_order != old_order:
link.order = new_order
has_changes = True
link.save(update_fields=['order'])
if has_changes:
PageSnapshot.take(cell.page, request=request, comment=_('reordered cells'))
return HttpResponse(status=204)

View File

@ -0,0 +1,12 @@
{% block cell-content %}
{% spaceless %}
<div class="links-list">
{% if title %}<h2>{{title}}</h2>{% endif %}
<ul>
{% for link in links %}
<li><a href="{{ link.url }}">{{ link.title }}</a></li>
{% endfor %}
</ul>
</div>
{% endspaceless %}
{% endblock %}

View File

@ -4,7 +4,10 @@ import os
import pytest
import requests
from combo.data.models import Page, CellBase, TextCell, LinkCell, MenuCell, JsonCellBase, JsonCell, ConfigJsonCell
from combo.data.models import (
Page, CellBase, TextCell, LinkCell, MenuCell, JsonCellBase,
JsonCell, ConfigJsonCell, LinkListCell
)
from django.conf import settings
from django.db import connection
from django.forms.widgets import Media
@ -93,6 +96,7 @@ def test_text_cell_variadic_url():
assert 'href=""' in cell.render(ctx)
assert 'href="/plop"' in cell.render(ctx)
def test_link_cell():
page = Page(title='example page', slug='example-page')
page.save()
@ -130,6 +134,37 @@ def test_link_cell():
assert cell.render(ctx).strip() == '<a href="http://example.net/#anchor">altertitle</a>'
def test_link_list_cell():
page = Page.objects.create(title='example page', slug='example-page')
cell = LinkListCell.objects.create(order=0, page=page)
item = LinkCell.objects.create(
page=page,
placeholder=cell.link_placeholder,
title='Example Site',
url='http://example.net/',
order=0,
)
ctx = {'page_cells': [item]}
assert '<ul><li><a href="http://example.net/">Example Site</a></li></ul>' in cell.render(ctx)
item.title = ''
assert '<ul><li><a href="http://example.net/">http://example.net/</a></li></ul>' in cell.render(ctx)
item.link_page = page
assert '<ul><li><a href="/example-page/">example page</a></li></ul>' in cell.render(ctx)
item.title = 'altertitle'
assert '<ul><li><a href="/example-page/">altertitle</a></li></ul>' in cell.render(ctx)
item.anchor = 'anchor'
assert '<ul><li><a href="/example-page/#anchor">altertitle</a></li></ul>' in cell.render(ctx)
item.link_page = None
assert '<ul><li><a href="http://example.net/#anchor">altertitle</a></li></ul>' in cell.render(ctx)
def test_menu_cell():
Page.objects.all().delete()
parent = page = Page(title='Page1', slug='page1', template_name='standard')
@ -728,3 +763,27 @@ def test_related_cell_types_tracking():
TextCell(page=page, placeholder='content', order=0, text='hello').save()
assert set(Page.objects.get(id=page.id).related_cells['cell_types']) == set(['data_textcell', 'data_linkcell'])
def test_link_list_cell_duplicate():
page = Page.objects.create(title='xxx', slug='new', template_name='standard')
cell = LinkListCell.objects.create(order=0, page=page)
item = LinkCell.objects.create(
page=page,
placeholder=cell.link_placeholder,
title='Example Site',
url='http://example.net/',
link_page=page,
order=1,
)
new_cell = cell.duplicate()
assert LinkCell.objects.count() == 2
assert len(new_cell.get_items()) == 1
new_item = new_cell.get_items()[0]
assert new_item.page == page
assert new_item.placeholder == new_cell.link_placeholder
assert new_item.pk != item.pk
assert new_item.title == item.title
assert new_item.url == item.url
assert new_item.link_page == item.link_page

View File

@ -21,7 +21,7 @@ from webtest import TestApp
from webtest import Upload
from combo.wsgi import application
from combo.data.models import Page, CellBase, TextCell, LinkCell, ConfigJsonCell, JsonCell, PageSnapshot
from combo.data.models import Page, CellBase, TextCell, LinkCell, ConfigJsonCell, JsonCell, PageSnapshot, LinkListCell
from combo.apps.assets.models import Asset
from combo.apps.family.models import FamilyInfosCell
from combo.apps.search.models import SearchCell
@ -1373,3 +1373,73 @@ def test_json_cell_syntax_validation(app, admin_user):
assert 'syntax error' not in resp.text
assert JsonCell.objects.count() == 1
assert JsonCell.objects.first().template_string == '{{ ok }}'
def test_add_edit_delete_list_link_item(app, admin_user):
Page.objects.all().delete()
page = Page.objects.create(title='One', slug='one', template_name='standard')
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
app = login(app)
resp = app.get('/manage/pages/%s/' % page.pk)
resp = resp.click(href='.*/add-link/link$')
resp.forms[0]['title'] = 'Hello world'
resp.forms[0]['url'] = 'http://example.com'
resp = resp.forms[0].submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
assert LinkCell.objects.count() == 1
item = LinkCell.objects.get()
assert item.title == 'Hello world'
assert item.url == 'http://example.com'
assert item.page == page
assert item.placeholder == cell.link_placeholder
resp = resp.follow()
resp = resp.click(href='.*/link/%s/$' % item.get_reference())
resp.forms[0]['title'] = 'Hello world 2'
resp.forms[0]['url'] = 'http://example2.com'
resp = resp.forms[0].submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
assert LinkCell.objects.count() == 1
item.refresh_from_db()
assert item.title == 'Hello world 2'
assert item.url == 'http://example2.com'
resp = resp.follow()
resp = resp.click(href='.*/link/%s/delete' % item.get_reference())
resp = resp.forms[0].submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
assert LinkCell.objects.count() == 0
def test_edit_link_list_order(app, admin_user):
Page.objects.all().delete()
page = Page.objects.create(title='One', slug='one', template_name='standard')
cell = LinkListCell.objects.create(order=0, page=page)
items = []
for i in range(5):
items.append(
LinkCell.objects.create(
page=page,
placeholder=cell.link_placeholder,
title='Foo %s' % i,
url='http://example.net/',
link_page=page,
order=i+1,
)
)
params = []
new_order = [2, 3, 1, 4, 5]
for i, (item, new_pos) in enumerate(zip(items, new_order)):
params.append(('pos_%s' % item.pk, str(new_pos)))
app = login(app)
resp = app.get('/manage/pages/%s/cell/%s/order?%s' % (page.pk, cell.get_reference(), urlencode(params)))
assert resp.status_code == 204
for i, item in enumerate(items):
item.refresh_from_db()
assert item.order == new_order[i]

View File

@ -9,7 +9,7 @@ from django.test import override_settings
from django.test.client import RequestFactory
from django.utils.six import StringIO
from django.utils.timezone import now
from combo.data.models import Page, PageSnapshot, CellBase, TextCell, LinkCell
from combo.data.models import Page, PageSnapshot, CellBase, TextCell, LinkCell, LinkListCell
from combo.data.management.commands.import_site import Command as ImportSiteCommand
from combo.data.management.commands.export_site import Command as ExportSiteCommand
from combo.manager.forms import PageVisibilityForm
@ -182,6 +182,22 @@ def test_import_export_pages_with_links():
cell2 = LinkCell(page=page2, title='foo', placeholder='content', link_page=page, order=1)
cell2.save()
cell3 = LinkListCell.objects.create(page=page, placeholder='content', order=2)
item1 = LinkCell.objects.create(
page=page,
placeholder=cell3.link_placeholder,
title='Example Site',
url='http://example.net/',
order=0,
)
item2 = LinkCell.objects.create(
page=page,
placeholder=cell3.link_placeholder,
title='blah',
link_page=page2,
order=1,
)
site_export = [x.get_serialized_page() for x in Page.objects.all()]
Page.objects.all().delete()
@ -189,8 +205,21 @@ def test_import_export_pages_with_links():
new_page_1 = Page.objects.all().order_by('order')[0]
new_page_2 = Page.objects.all().order_by('order')[1]
assert CellBase.get_cells(page_id=new_page_1.id)[0].link_page_id == new_page_2.id
assert CellBase.get_cells(page_id=new_page_2.id)[0].link_page_id == new_page_1.id
new_cells_1 = CellBase.get_cells(page_id=new_page_1.id, placeholder='content')
new_cells_2 = CellBase.get_cells(page_id=new_page_2.id, placeholder='content')
assert new_cells_1[0].link_page_id == new_page_2.id
assert new_cells_2[0].link_page_id == new_page_1.id
assert len(new_cells_1[1].get_items()) == 2
new_item_1 = new_cells_1[1].get_items()[0]
assert isinstance(new_item_1, LinkCell)
assert new_item_1.title == item1.title
assert new_item_1.url == item1.url
assert new_item_1.link_page is None
new_item_2 = new_cells_1[1].get_items()[1]
assert isinstance(new_item_2, LinkCell)
assert new_item_2.title == item2.title
assert new_item_2.url == ''
assert new_item_2.link_page == new_page_2
def test_duplicate_page():

View File

@ -22,7 +22,7 @@ from django.utils.six.moves.urllib import parse as urlparse
import mock
from combo.data.models import Page
from combo.data.models import CellBase, LinkListCell, Page
from combo.apps.search.engines import engines
from combo.apps.wcs.models import (WcsFormCell, WcsCurrentFormsCell,
WcsFormsOfCategoryCell, WcsCurrentDraftsCell, WcsCategoryCell,
@ -901,3 +901,93 @@ def test_backoffice_submission_cell_render(context):
result = cell.render(context)
assert '/backoffice/submission/a-private-form/' in result
@wcs_present
def test_manager_link_list_cell_duplicate():
page = Page.objects.create(title='xxx', slug='new', template_name='standard')
cell = LinkListCell.objects.create(order=0, page=page)
item = WcsFormCell.objects.create(
page=page,
placeholder=cell.link_placeholder,
cached_title='A title',
cached_url='http://example.com',
cached_json={'foo': 'bar'},
order=1)
new_cell = cell.duplicate()
assert WcsFormCell.objects.count() == 2
assert len(new_cell.get_items()) == 1
new_item = new_cell.get_items()[0]
assert new_item.page == page
assert new_item.placeholder == new_cell.link_placeholder
assert new_item.pk != item.pk
assert new_item.cached_title == item.cached_title
assert new_item.cached_url == item.cached_url
assert new_item.cached_json == item.cached_json
@wcs_present
def test_manager_add_edit_delete_list_link_item(app, admin_user):
Page.objects.all().delete()
page = Page.objects.create(title='One', slug='one', template_name='standard')
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
app = login(app)
resp = app.get('/manage/pages/%s/' % page.pk)
resp = resp.click(href='.*/add-link/form-link$')
resp.forms[0]['formdef_reference'] = 'default:form-title'
resp = resp.forms[0].submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
assert WcsFormCell.objects.count() == 1
item = WcsFormCell.objects.get()
assert item.formdef_reference == 'default:form-title'
assert item.page == page
assert item.placeholder == cell.link_placeholder
resp = resp.follow()
resp = resp.click(href='.*/link/%s/$' % item.get_reference())
resp.forms[0]['formdef_reference'] = 'default:a-private-form'
resp = resp.forms[0].submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
assert WcsFormCell.objects.count() == 1
item.refresh_from_db()
assert item.formdef_reference == 'default:a-private-form'
resp = resp.follow()
resp = resp.click(href='.*/link/%s/delete' % item.get_reference())
resp = resp.forms[0].submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.pk, cell.get_reference()))
assert WcsFormCell.objects.count() == 0
def test_import_export_pages_with_links():
page = Page(title=u'bar', slug='bar', order=1)
page.save()
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
item = WcsFormCell.objects.create(
page=page,
placeholder=cell.link_placeholder,
cached_title='A title',
cached_url='http://example.com',
cached_json={'foo': 'bar'},
order=0,
)
site_export = [x.get_serialized_page() for x in Page.objects.all()]
Page.objects.all().delete()
Page.load_serialized_pages(site_export)
new_page = Page.objects.get()
new_cells = CellBase.get_cells(page_id=new_page.id, placeholder='content')
assert len(new_cells[0].get_items()) == 1
new_item = new_cells[0].get_items()[0]
assert isinstance(new_item, WcsFormCell)
assert new_item.cached_title == item.cached_title
assert new_item.cached_url == item.cached_url
assert new_item.cached_json == item.cached_json