combo/tests/test_manager.py

1102 lines
43 KiB
Python
Raw Normal View History

import base64
import json
import os
import re
import shutil
import mock
from django.core.files.storage import default_storage
from django.core.urlresolvers import reverse
from django.conf import settings
from django.contrib.auth.models import User, Group
from django.template import TemplateSyntaxError
from django.test import override_settings
from django.utils.http import urlencode
from django.utils.six import BytesIO
from django.utils.six.moves.urllib import parse as urlparse
2015-01-17 15:32:23 +01:00
import pytest
from webtest import TestApp
from webtest import Upload
2015-01-17 15:32:23 +01:00
from combo.wsgi import application
2018-04-01 15:23:01 +02:00
from combo.data.models import Page, CellBase, TextCell, LinkCell, ConfigJsonCell, JsonCell, PageSnapshot
from combo.apps.assets.models import Asset
from combo.apps.family.models import FamilyInfosCell
2017-02-22 16:15:37 +01:00
from combo.apps.search.models import SearchCell
2015-01-17 15:32:23 +01:00
pytestmark = pytest.mark.django_db
TESTS_DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
2015-01-17 15:32:23 +01:00
def login(app, username='admin', password='admin'):
2015-01-30 12:04:10 +01:00
login_page = app.get('/login/')
2015-01-17 15:32:23 +01:00
login_form = login_page.forms[0]
login_form['username'] = username
login_form['password'] = password
resp = login_form.submit()
assert resp.status_int == 302
return app
def test_unlogged_access(app):
2015-01-17 15:32:23 +01:00
# connect while not being logged in
assert app.get('/manage/', status=302).location.endswith('/login/?next=/manage/')
2015-01-17 15:32:23 +01:00
def test_access(app, admin_user):
app = login(app)
2015-01-17 15:32:23 +01:00
resp = app.get('/manage/', status=200)
assert 'Pages' in resp.text
assert "This site doesn't have any page yet." in resp.text
2015-01-17 15:32:23 +01:00
def test_add_page(app, admin_user):
app = login(app)
2015-01-17 15:32:23 +01:00
resp = app.get('/manage/', status=200)
resp = resp.click('New')
assert resp.forms[0]['title'].value == 'Home' # default title for first page
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/pages/1/')
assert Page.objects.get(slug='index').title == 'Home'
assert Page.objects.get(slug='index').template_name == 'standard' # first one was taken
2015-01-17 15:32:23 +01:00
def test_add_second_page(app, admin_user):
2015-01-17 15:32:23 +01:00
Page.objects.all().delete()
page = Page(title='One', slug='one')
page.save()
app = login(app)
2015-01-17 15:32:23 +01:00
resp = app.get('/manage/', status=200)
resp = resp.click('New')
# assert there's no defaul title for the second page
2015-01-17 15:32:23 +01:00
assert resp.forms[0]['title'].value == ''
resp.forms[0]['title'].value = 'Foobar'
resp = resp.forms[0].submit()
assert Page.objects.get(slug='foobar').title == 'Foobar'
def test_edit_page(app, admin_user):
Page.objects.all().delete()
app = login(app)
resp = app.get('/manage/', status=200)
resp = resp.click('New')
resp = resp.forms[0].submit()
resp = resp.follow()
# title
resp = resp.click(href='.*/title')
resp.form['title'].value = 'Home 2'
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.all()[0].title == 'Home 2'
# slug
resp = resp.click(href='.*/slug')
resp.form['slug'].value = 'foobar'
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.all()[0].slug == 'foobar'
2018-04-19 10:08:51 +02:00
# description
resp = resp.click(href='.*/description')
resp.form['description'].value = 'second home page'
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.all()[0].description == 'second home page'
# template name
resp = resp.click(href='.*/template')
assert resp.form['template_name'].value == 'standard'
assert len(resp.form['template_name'].options) == 2 # by default there are 2 templates
resp.form['template_name'].value = 'standard-sidebar'
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.all()[0].template_name == 'standard-sidebar'
assert resp.click(href='.*/template').form['template_name'].value == 'standard-sidebar'
# redirection
resp = resp.click(href='.*/redirection')
resp.form['redirect_url'].value = 'http://www.example.net'
resp = resp.form.submit()
resp = resp.follow()
assert 'http://www.example.net' in resp.text
assert Page.objects.all()[0].redirect_url == 'http://www.example.net'
# exclude from nav
resp = resp.click(href='.*/exclude-from-navigation')
resp.form['exclude_from_navigation'].checked = True
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.all()[0].exclude_from_navigation is True
def test_edit_page_unknown_template(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='broken')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
assert 'Unknown (broken)' in resp.text
def test_page_edit_slug(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
page = Page(title='Two', slug='two', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='.*/slug')
resp.form['slug'].value = 'two' # no change
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.get(id=page.id).slug == 'two'
resp = resp.click(href='.*/slug')
resp.form['slug'].value = 'two2' # valid change
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.get(id=page.id).slug == 'two2'
resp = resp.click(href='.*/slug')
resp.form['slug'].value = 'one' # duplicate
resp = resp.form.submit()
assert 'Slug must be unique' in resp.text
assert Page.objects.get(id=page.id).slug == 'two2'
2015-01-17 15:32:23 +01:00
def test_page_edit_picture(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='.*/picture/')
resp.form['picture'] = Upload('black.jpeg',
open(os.path.join(TESTS_DATA_DIR, 'black.jpeg'), mode='rb').read(), 'image/jpeg')
resp = resp.form.submit()
assert resp.location.endswith('/manage/pages/%s/' % page.id)
resp = resp.follow()
assert '<h2>Page - One</h2>' in resp.text
assert '<img' in resp.text
resp = resp.click(href='.*/remove-picture/')
resp = resp.follow()
assert '<h2>Page - One</h2>' in resp.text
assert not '<img' in resp.text
def test_delete_page(app, admin_user):
2015-01-17 15:32:23 +01:00
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
2015-01-17 15:32:23 +01:00
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click('delete')
assert '<button class="delete-button">Delete</button>' in resp.text
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/')
assert Page.objects.count() == 0
def test_delete_page_keep_child(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
page2 = Page(title='Two', slug='two', parent=page, template_name='standard')
page2.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click('delete')
assert '<button class="delete-button">Delete</button>' in resp.text
assert 'Delete only this page' in resp.text
assert 'Delete this page and all subpages' in resp.text
resp.form['choice'].value = 'delete-one'
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/')
assert Page.objects.count() == 1
assert Page.objects.get(id=page2.id) == page2
def test_delete_page_and_subpage(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
page2 = Page(title='Two', slug='two', parent=page, template_name='standard')
page2.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click('delete')
assert '<button class="delete-button">Delete</button>' in resp.text
assert 'Delete only this page' in resp.text
assert 'Delete this page and all subpages' in resp.text
resp.form['choice'].value = 'delete-all'
2015-01-17 15:32:23 +01:00
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/')
2015-01-17 15:32:23 +01:00
assert Page.objects.count() == 0
def test_page_reorder(app, admin_user):
Page.objects.all().delete()
page1 = Page(title='One', slug='one', parent=None, order=0, template_name='standard')
page1.save()
page2 = Page(title='Two', slug='two', parent=None, order=1, template_name='standard')
page2.save()
page3 = Page(title='Three', slug='three', parent=page2, order=2, template_name='standard')
page3.save()
page4 = Page(title='Four', slug='four', parent=page2, order=3, template_name='standard')
page4.save()
ordered_ids = [x.id for x in Page.get_as_reordered_flat_hierarchy(Page.objects.all())]
ordered_ids = [page1.id, page2.id, page3.id, page4.id]
# move page4 before page3
app = login(app)
resp = app.get('/manage/pages/order', params={
'moved-page-id': page4.id,
'moved-page-new-parent': page2.id,
'new-order': ','.join([str(x) for x in [page1.id, page2.id, page4.id, page3.id]])})
ordered_ids = [x.id for x in Page.get_as_reordered_flat_hierarchy(Page.objects.all())]
ordered_ids = [page1.id, page2.id, page4.id, page3.id]
# move page4 to level0
resp = app.get('/manage/pages/order', params={
'moved-page-id': page4.id,
'moved-page-new-parent': '',
'new-order': ','.join([str(x) for x in [page1.id, page4.id, page2.id, page3.id]])})
ordered_ids = [x.id for x in Page.get_as_reordered_flat_hierarchy(Page.objects.all())]
ordered_ids = [page1.id, page4.id, page2.id, page3.id]
# change slug to check for autochange on duplicate
page4.slug = 'three'
page4.save()
# move it as a sibling of page3
resp = app.get('/manage/pages/order', params={
'moved-page-id': page4.id,
'moved-page-new-parent': page2.id,
'new-order': ','.join([str(x) for x in [page1.id, page2.id, page4.id, page3.id]])})
assert Page.objects.get(id=page4.id).slug.startswith('three-')
def test_export_page(app, admin_user):
2015-01-18 19:50:43 +01:00
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
2015-01-18 19:50:43 +01:00
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click('export')
assert resp.headers['content-type'] == 'application/json'
assert resp.json['pages'][0].get('fields').get('slug') == 'one'
2015-01-18 19:50:43 +01:00
def test_export_page_order():
Page.objects.all().delete()
page1 = Page(title='One', slug='one', template_name='standard')
page2 = Page(title='Two', slug='two', parent=page1, template_name='standard')
page3 = Page(title='Three', slug='three', parent=page2, template_name='standard')
page4 = Page(title='Four', slug='four', parent=page1, template_name='standard')
random_list = [page3, page4, page1, page2]
ordered_list = Page.get_as_reordered_flat_hierarchy(random_list)
assert ordered_list[0] == page1
assert ordered_list[1] == page4
assert ordered_list[2] == page2
assert ordered_list[3] == page3
def test_site_export_import(app, admin_user):
Page.objects.all().delete()
page1 = Page(title='One', slug='one', template_name='standard')
page1.save()
page2 = Page(title='Two', slug='two', parent=page1, template_name='standard')
page2.save()
page3 = Page(title='Three', slug='three', parent=page2, template_name='standard')
page3.save()
page4 = Page(title='Four', slug='four', parent=page1, template_name='standard')
page4.save()
cell = TextCell(page=page1, placeholder='content', text='Foobar', order=0)
cell.save()
cell = LinkCell(page=page1, placeholder='content', link_page=page2, order=0)
cell.save()
cell = LinkCell(page=page2, placeholder='content', link_page=page1, order=0)
cell.save()
app = login(app)
resp = app.get('/manage/')
resp = resp.click('Export Site')
assert resp.headers['content-type'] == 'application/json'
site_export = resp.body
Page.objects.all().delete()
assert LinkCell.objects.count() == 0
app = login(app)
resp = app.get('/manage/')
resp = resp.click('Import Site')
resp.form['site_json'] = Upload('site-export.json', site_export, 'application/json')
resp = resp.form.submit()
assert Page.objects.count() == 4
assert LinkCell.objects.count() == 2
assert LinkCell.objects.get(page__slug='one').link_page.slug == 'two'
assert LinkCell.objects.get(page__slug='two').link_page.slug == 'one'
# check with invalid file
resp = app.get('/manage/')
resp = resp.click('Import Site')
resp.form['site_json'] = Upload('site-export.json', b'invalid content', 'application/json')
resp = resp.form.submit()
assert 'File is not in the expected JSON format.' in resp.text
def test_add_edit_cell(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
# click on first option link, this should add a text cell
resp = app.get(resp.html.find('option').get('data-add-url'))
assert resp.location.endswith('/manage/pages/1/')
cells = CellBase.get_cells(page_id=page.id)
assert len(cells) == 1
assert isinstance(cells[0], TextCell)
resp = app.get('/manage/pages/%s/' % page.id)
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text
resp.forms[0]['c%s-text' % cells[0].get_reference()].value = 'Hello world'
resp = resp.forms[0].submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/1/')
resp = app.get('/manage/pages/%s/' % page.id)
assert resp.forms[0]['c%s-text' % cells[0].get_reference()].value == 'Hello world'
2015-04-17 14:36:55 +02:00
resp = app.get('/manage/pages/%s/' % page.id)
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text
resp.forms[0]['c%s-text' % cells[0].get_reference()].value = 'World Hello'
resp = resp.forms[0].submit(xhr=True)
assert resp.status_int == 200
assert resp.text.strip().startswith('<p><label')
resp = app.get('/manage/pages/%s/' % page.id)
assert resp.forms[0]['c%s-text' % cells[0].get_reference()].value == 'World Hello'
def test_add_all_basic_cell_types(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
for option in resp.html.find_all('option'):
if not '/data_' in option.get('data-add-url'):
continue
resp = app.get(option.get('data-add-url'))
resp = resp.follow()
2017-02-22 16:15:37 +01:00
SEARCH_SERVICES = {
'search1': {
'label': 'Search 1',
'url': 'http://www.example.net/search/?q=%(q)s',
}
}
class SearchServices(object):
def __init__(self, search_services):
self.search_services = search_services
def __enter__(self):
settings.COMBO_SEARCH_SERVICES = self.search_services
def __exit__(self, *args, **kwargs):
settings.COMBO_SEARCH_SERVICES = {}
2017-02-22 16:15:37 +01:00
def test_search_cell(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
# add
app = login(app)
assert SearchCell.objects.count() == 0
with SearchServices(SEARCH_SERVICES):
resp = app.get('/manage/pages/%s/' % page.id)
for option in resp.html.find_all('option'):
if 'content/search_' in option.get('data-add-url'):
resp = app.get(option.get('data-add-url'))
resp = resp.follow()
assert SearchCell.objects.count() == 1
cell = SearchCell.objects.first()
# delete
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/search_searchcell-%s/delete' % cell.id)
resp = resp.form.submit()
assert SearchCell.objects.count() == 0
2016-07-11 14:13:20 +02:00
def test_delete_cell(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
cell = TextCell(page=page, placeholder='content', text='Foobar', order=0)
cell.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/delete' % cell.id)
resp = resp.form.submit()
assert TextCell.objects.count() == 0
def test_edit_cell_visibility(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
cell = TextCell(page=page, placeholder='content', text='Foobar', order=0)
cell.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id)
assert resp.form['cdata_textcell-%s-visibility' % cell.id].value == 'all'
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'logged'
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).public is False
assert TextCell.objects.get(id=cell.id).restricted_to_unlogged is False
assert TextCell.objects.get(id=cell.id).groups.count() == 0
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id)
assert resp.form['cdata_textcell-%s-visibility' % cell.id].value == 'logged'
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'unlogged'
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).restricted_to_unlogged is True
assert TextCell.objects.get(id=cell.id).public is True
assert TextCell.objects.get(id=cell.id).groups.count() == 0
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id)
assert resp.form['cdata_textcell-%s-visibility' % cell.id].value == 'unlogged'
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'all'
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).restricted_to_unlogged is False
assert TextCell.objects.get(id=cell.id).public is True
assert TextCell.objects.get(id=cell.id).groups.count() == 0
group1 = Group(name='A group')
group1.save()
group2 = Group(name='Another group')
group2.save()
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id)
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'groups-any'
resp.form['cdata_textcell-%s-groups' % cell.id] = [group1.id]
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).restricted_to_unlogged is False
assert TextCell.objects.get(id=cell.id).public is False
assert TextCell.objects.get(id=cell.id).groups.count() == 1
assert TextCell.objects.get(id=cell.id).groups.all()[0].name == 'A group'
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id)
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'groups-none'
resp.form['cdata_textcell-%s-groups' % cell.id] = [group2.id]
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).restricted_to_unlogged is True
assert TextCell.objects.get(id=cell.id).public is False
assert TextCell.objects.get(id=cell.id).groups.count() == 1
assert TextCell.objects.get(id=cell.id).groups.all()[0].name == 'Another group'
def test_edit_cell_options(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
cell = TextCell(page=page, placeholder='content', text='Foobar', order=0)
cell.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/options' % cell.id)
assert resp.form['cdata_textcell-%s-slug' % cell.id].value == ''
assert resp.form['cdata_textcell-%s-extra_css_class' % cell.id].value == ''
resp.form['cdata_textcell-%s-slug' % cell.id] = 'SLUG'
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).slug == 'SLUG'
assert 'SLUG' in app.get('/manage/pages/%s/' % page.id)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/options' % cell.id)
resp.form['cdata_textcell-%s-slug' % cell.id] = ''
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).slug == ''
assert not 'SLUG' in app.get('/manage/pages/%s/' % page.id)
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/options' % cell.id)
resp.form['cdata_textcell-%s-extra_css_class' % cell.id] = 'CSS'
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).extra_css_class == 'CSS'
assert '[CSS]' in app.get('/manage/pages/%s/' % page.id)
2016-07-11 14:35:38 +02:00
def test_edit_cell_order(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
cells = []
for i in range(5):
cells.append(TextCell(page=page, placeholder='content', text='Foobar%s' % i, order=i))
cells[-1].save()
params = []
new_order = [2, 3, 1, 4, 5]
for i, (cell, new_pos) in enumerate(zip(cells, new_order)):
params.append(('ph_data_textcell-%s' % cell.id, 'content')) # no placeholder change
params.append(('pos_data_textcell-%s' % cell.id, str(new_order[i])))
app = login(app)
resp = app.get('/manage/pages/%s/order?%s' % (page.id, urlencode(params)))
assert resp.status_code == 204
2016-07-11 14:35:38 +02:00
for i, cell in enumerate(cells):
assert TextCell.objects.get(id=cell.id).order == new_order[i]
def test_edit_text_cell(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
data_add_url = [x for x in resp.html.find_all('option') if x.text == 'Text'][0].get('data-add-url')
resp = app.get(data_add_url)
assert resp.location.endswith('/manage/pages/%s/' % page.id)
cells = CellBase.get_cells(page_id=page.id)
assert len(cells) == 1
assert isinstance(cells[0], TextCell)
resp = app.get('/manage/pages/%s/' % page.id)
resp.form['cdata_textcell-%s-text' % cells[0].id].value = 'Hello : World'
resp = resp.form.submit()
assert TextCell.objects.get(id=cells[0].id).text == 'Hello : World'
with override_settings(LANGUAGE_CODE='fr-fr'):
resp = app.get('/manage/pages/%s/' % page.id)
resp.form['cdata_textcell-%s-text' % cells[0].id].value = 'Hello : World'
resp = resp.form.submit()
assert TextCell.objects.get(id=cells[0].id).text == u'Hello\u00a0: World'
def test_edit_config_json_cell(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
options = [x.text for x in resp.html.find_all('option')]
assert not 'Foobar' in options
templates_settings = [settings.TEMPLATES[0].copy()]
templates_settings[0]['DIRS'] = ['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))]
with override_settings(JSON_CELL_TYPES={'test-config-json-cell': {'name': 'Foobar', 'url': 'http://test/'}},
TEMPLATES=templates_settings):
resp = app.get('/manage/pages/%s/' % page.id)
options = [x.text for x in resp.html.find_all('option')]
assert 'Foobar' in options
data_add_url = [x for x in resp.html.find_all('option') if x.text == 'Foobar'][0].get('data-add-url')
resp = app.get(data_add_url)
assert resp.location.endswith('/manage/pages/%s/' % page.id)
cells = CellBase.get_cells(page_id=page.id)
assert len(cells) == 1
assert isinstance(cells[0], ConfigJsonCell)
assert cells[0].key == 'test-config-json-cell'
resp = app.get('/manage/pages/%s/' % page.id)
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text
assert 'There are no options for this cell.' in resp.form.text
# make it configurable
with override_settings(JSON_CELL_TYPES=
{'test-config-json-cell': {
'name': 'Foobar',
'url': 'http://test/',
'form': [
{
'label': 'Test',
'type': 'string',
'varname': 'test',
},
{
'label': 'Test bool',
'type': 'bool',
'varname': 'test2',
'required': False,
},
{
'label': 'Test no type is string',
'varname': 'test3',
},
{
'label': 'Test text',
'type': 'text',
'varname': 'test4',
'required': False,
},
]}},
TEMPLATES=templates_settings):
resp = app.get('/manage/pages/%s/' % page.id)
assert not 'There are no options for this cell.' in resp.form.text
resp.form['c%s-test' % cells[0].get_reference()].value = 'Hello world'
resp.form['c%s-test3' % cells[0].get_reference()].value = 'Hello again'
resp = resp.form.submit()
assert resp.status_int == 302
assert resp.location.endswith('/manage/pages/%s/' % page.id)
resp = app.get('/manage/pages/%s/' % page.id)
assert resp.form['c%s-test' % cells[0].get_reference()].value == 'Hello world'
assert resp.form['c%s-test2' % cells[0].get_reference()].checked is False
assert resp.form['c%s-test3' % cells[0].get_reference()].value == 'Hello again'
resp = app.get('/manage/pages/%s/' % page.id)
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text
resp.forms[0]['c%s-test' % cells[0].get_reference()].value = 'World Hello'
resp.forms[0]['c%s-test2' % cells[0].get_reference()].checked = True
assert resp.form['c%s-test4' % cells[0].get_reference()].tag == 'textarea'
resp.forms[0]['c%s-test4' % cells[0].get_reference()].value = 'Text Area'
resp = resp.form.submit(xhr=True)
assert resp.status_int == 200
assert resp.text.strip().startswith('<p><label')
resp = app.get('/manage/pages/%s/' % page.id)
assert resp.form['c%s-test' % cells[0].get_reference()].value == 'World Hello'
assert resp.form['c%s-test2' % cells[0].get_reference()].checked is True
assert resp.form['c%s-test3' % cells[0].get_reference()].value == 'Hello again'
assert resp.form['c%s-test4' % cells[0].get_reference()].value == 'Text Area'
def test_logout(app, admin_user):
app = login(app)
2015-04-17 14:36:55 +02:00
app.get('/logout/')
assert app.get('/manage/', status=302).location.endswith('/login/?next=/manage/')
def test_asset_management(app, admin_user):
app = login(app)
resp = app.get('/manage/assets/')
assert 'have any asset yet.' in resp.text
# test upload
resp = app.get('/manage/assets/')
resp = resp.click('Upload')
resp.form['upload'] = Upload('test.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit().follow()
# check file is now there
resp = app.get('/manage/assets/')
assert 'have any asset yet.' not in resp.text
# check there is also a thumbnail
thumbnail_filename = re.findall('src="/media/(.*thumb.*)"', resp.text)[0]
thumbnail_path = default_storage.path(thumbnail_filename)
assert os.path.exists(thumbnail_path)
thumbnail_contents = open(thumbnail_path, mode='rb').read()
# check overwriting
resp = resp.click('Overwrite')
resp.form['upload'] = Upload('test.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAgAABAADRWoApgAA\nAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit().follow()
resp.click('test.png')
assert re.findall('src="/media/(.*thumb.*)"', resp.text)[0] == thumbnail_filename
assert os.path.exists(thumbnail_path)
thumbnail_contents_new = open(thumbnail_path, mode='rb').read()
assert thumbnail_contents_new != thumbnail_contents
# test deletion
resp = resp.click('Delete')
assert 'Are you sure you want to delete' in resp.text
resp = resp.form.submit().follow()
assert 'have any asset yet.' in resp.text
2016-07-11 14:38:37 +02:00
def test_asset_management_anchor(app, admin_user):
app = login(app)
resp = app.get('/manage/assets/')
assert 'have any asset yet.' in resp.text
for i in range(25):
filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'cc.png')
pix = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
default_storage.save(filepath, BytesIO(base64.decodestring(pix)))
# test upload
resp = app.get('/manage/assets/')
resp = resp.click('Upload')
resp.form['upload'] = Upload('test.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit()
assert resp.location.endswith('?page=3')
resp = resp.follow()
# overwrite
resp = resp.click(href=re.compile('overwrite.*test.png'))
resp.form['upload'] = Upload('aa.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAgAABAADRWoApgAA\nAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit()
assert resp.location.endswith('?page=3')
resp = resp.follow()
# delete
resp = resp.click(href=re.compile('delete.*test.png'))
resp = resp.form.submit()
resp = resp.follow()
assert 'test.png' not in resp.text
2019-01-14 09:56:50 +01:00
def test_asset_management_search(app, admin_user):
app = login(app)
filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'test.png')
pix = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
default_storage.save(filepath, BytesIO(base64.decodestring(pix)))
assert os.path.exists(default_storage.path(filepath))
filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'test.txt')
default_storage.save(filepath, BytesIO(b'hello world'))
filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'foo.txt')
default_storage.save(filepath, BytesIO(b'foo bar baz'))
resp = app.get('/manage/assets/')
assert resp.text.count('<tr class="asset') == 3
resp.form['q'] = 'test'
resp = resp.form.submit()
assert resp.text.count('<tr class="asset') == 2
2019-01-14 09:56:50 +01:00
def test_asset_slots_management(app, admin_user):
app = login(app)
assert Asset.objects.count() == 0
with override_settings(COMBO_ASSET_SLOTS={'collectivity:banner': {'label': 'Banner'}}):
resp = app.get('/manage/assets/')
assert '>Banner<' in resp.text
assert '>Delete<' not in resp.text
resp = resp.click('Overwrite')
resp.form['upload'] = Upload('test.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAgAABAADRWoApgAA\nAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit()
assert resp.location.endswith('?page=1')
resp = resp.follow()
assert 'test.png' in resp.text
assert '>Delete<' in resp.text
assert Asset.objects.filter(key='collectivity:banner').count() == 1
assert app.get('/assets/collectivity:banner', status=302)['location'].endswith('test.png')
# upload a new version of image
resp = resp.click('Overwrite')
resp.form['upload'] = Upload('test2.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAgAABAADRWoApgAA\nAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit().follow()
assert 'test2.png' in resp.text
assert '<img data-href' in resp.text # thumbnail
assert '>Delete<' in resp.text
assert Asset.objects.filter(key='collectivity:banner').count() == 1
resp = resp.click('Delete')
resp = resp.form.submit()
assert resp.location.endswith('?page=1')
resp = resp.follow()
assert '>Banner<' in resp.text
assert '>Delete<' not in resp.text
assert Asset.objects.filter(key='collectivity:banner').count() == 0
resp = app.get('/assets/collectivity:banner', status=404)
with override_settings(COMBO_ASSET_SLOTS={'collectivity:cgu': {'label': 'CGU', 'asset-type': 'document'}}):
resp = app.get('/manage/assets/')
assert '>CGU<' in resp.text
assert '>Delete<' not in resp.text
resp = resp.click('Overwrite')
resp.form['upload'] = Upload('test.pdf', 'PDF-1.4 ...', 'application.pdf')
resp = resp.form.submit().follow()
assert 'test.pdf' in resp.text
assert '<img data-href' not in resp.text # no thumbnail
assert '>Delete<' in resp.text
assert Asset.objects.filter(key='collectivity:cgu').count() == 1
def test_asset_export_import(app, admin_user):
for path in ('uploads', 'assets', 'cache'):
if os.path.exists(default_storage.path(path)):
shutil.rmtree(default_storage.path(path))
app = login(app)
# upload a file
resp = app.get('/manage/assets/')
resp = resp.click('Upload')
resp.form['upload'] = Upload('test.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit()
resp = app.get('/manage/assets/')
resp = resp.click('Export')
assert resp.content_type == 'application/x-tar'
content = resp.content
for path in ('uploads', 'assets'):
if os.path.exists(default_storage.path(path)):
shutil.rmtree(default_storage.path(path))
resp = app.get('/manage/assets/')
assert 'have any asset yet.' in resp.text
resp = resp.click('Import')
resp.form['assets_file'] = Upload('test.tar', content)
resp = resp.form.submit()
assert sum([len(x[2]) for x in os.walk(default_storage.path(''))]) == 2
resp = resp.follow()
assert 'The assets file has been imported.' in resp.text
# test no overwrite
filename = re.findall('data-href="(.*?)"', resp.text)[0][7:] # strip /media/
with open(default_storage.path(filename), 'w') as fd:
fd.write('test') # 4 bytes
assert os.stat(default_storage.path(filename)).st_size == 4
resp = app.get('/manage/assets/')
resp = resp.click('Import')
resp.form['assets_file'] = Upload('test.tar', content)
resp = resp.form.submit()
resp = resp.follow()
assert 'The assets file has been imported.' in resp.text
assert os.stat(default_storage.path(filename)).st_size == 4
# test overwrite
resp = app.get('/manage/assets/')
resp = resp.click('Import')
resp.form['overwrite'] = True
resp.form['assets_file'] = Upload('test.tar', content)
resp = resp.form.submit()
resp = resp.follow()
assert 'The assets file has been imported.' in resp.text
assert os.stat(default_storage.path(filename)).st_size == 67
# test uploading garbage
for path in ('uploads', 'assets'):
if os.path.exists(default_storage.path(path)):
shutil.rmtree(default_storage.path(path))
resp = app.get('/manage/assets/')
resp = resp.click('Import')
resp.form['assets_file'] = Upload('test.tar', b'garbage')
resp = resp.form.submit()
assert sum([len(x[2]) for x in os.walk(default_storage.path(''))]) == 0
resp = resp.follow()
assert 'The assets file is not valid.' in resp.text
2016-07-11 14:38:37 +02:00
def test_menu_json(app, admin_user):
app.get('/manage/menu.json', status=302)
app = login(app)
resp = app.get('/manage/menu.json')
assert resp.headers['content-type'] == 'application/json'
assert resp.json[0]['label'] == 'Content Management'
resp = app.get('/manage/menu.json?callback=fooBar')
assert resp.headers['content-type'] == 'application/javascript'
assert resp.text.startswith('fooBar([{"')
def test_page_multiple_link_cells(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
for i in range(10):
Page(title='page %d' % i, slug='page%d' % i, template_name='standard').save()
cell = LinkCell(page=page, placeholder='content', order=0)
cell.save()
patched_orig = Page.get_as_reordered_flat_hierarchy
app = login(app)
with mock.patch('combo.data.models.Page.get_as_reordered_flat_hierarchy') as func:
func.return_value = []
resp = app.get('/manage/pages/%s/' % page.id)
assert func.call_count == 1
def test_page_cell_placeholder(app, admin_user):
page = Page(title='One', slug='one', template_name='standard')
page.save()
cell = JsonCell(page=page, placeholder='content', order=0, url='http://example.com')
cell.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
assert re.findall('data-placeholder-key="(.*)">', resp.text) == ['content', 'footer']
# check a placeholder within a cell is included
cell.template_string = '{% load combo %}{% placeholder "foobar" name="Foobar" %}'
cell.save()
resp = app.get('/manage/pages/%s/' % page.id)
assert re.findall('data-placeholder-key="(.*)">', resp.text) == ['content', 'foobar', 'footer']
assert re.findall('<h2>(.*)</h2>', resp.text) == [
'Page - One', 'Content', 'JSON Feed / Foobar', 'Footer']
def test_page_familycell_placeholder(app, admin_user):
page = Page(title='My family', slug='my-family', template_name='standard')
page.save()
cell = FamilyInfosCell(page=page, placeholder='content', order=0)
cell.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
assert re.findall('data-placeholder-key="(.*)">', resp.text) == ['content', "family_unlinked_user", "footer"]
assert re.findall('<h2>(.*)</h2>', resp.text) == [
'Page - My family', 'Content',
'Family Information Cell / Top content for unlinked users', 'Footer']
def test_page_discover_placeholder_with_error_cells(app, admin_user):
page = Page(title='One', slug='one', template_name='standard')
page.save()
cell = JsonCell(page=page, placeholder='content', order=0, url='xx')
cell.template_string = '{% xxx %}'
cell.save()
app = login(app)
with mock.patch('combo.utils.requests.get') as requests_get:
data = {'data': [{'url': 'xxx', 'text': 'xxx'}]}
with pytest.raises(TemplateSyntaxError):
cell.render({})
resp = app.get('/manage/pages/%s/' % page.id)
assert re.findall('data-placeholder-key="(.*)">', resp.text) == ['content', 'footer']
2018-04-01 15:23:01 +02:00
def test_page_versionning(app, admin_user):
Page.objects.all().delete()
PageSnapshot.objects.all()
page = Page(title='One', slug='one')
page.save()
cell1 = TextCell(page=page, placeholder='content', text='Foobar1', order=0)
cell1.save()
cell2 = TextCell(page=page, placeholder='content', text='Foobar2', order=1)
cell2.save()
cell3 = TextCell(page=page, placeholder='content', text='Foobar3', order=1)
cell3.save()
anonymous_app = app
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id, status=200)
# update title
resp = resp.click(href='.*/title')
resp.form['title'].value = 'One Two'
resp = resp.form.submit()
resp = resp.follow()
assert Page.objects.all()[0].title == 'One Two'
assert PageSnapshot.objects.all().count() == 1
# change cell text
resp.forms[0]['c%s-text' % cell1.get_reference()].value = 'Hello world'
resp = resp.forms[0].submit().follow()
assert PageSnapshot.objects.all().count() == 2
# reorder cells
params = []
for i, cell in enumerate([cell3, cell1, cell2]):
params.append(('ph_data_textcell-%s' % cell.id, 'content')) # no placeholder change
params.append(('pos_data_textcell-%s' % cell.id, str(i)))
app.get('/manage/pages/%s/order?%s' % (page.id, urlencode(params)))
2018-04-01 15:23:01 +02:00
assert PageSnapshot.objects.all().count() == 3
resp = resp.click('history')
assert resp.text.index('reordered cells') < resp.text.index('changed cell') < resp.text.index('changed title')
2018-04-01 15:23:01 +02:00
resp2 = resp.click('view', index=1)
assert resp2.text.index('Hello world') < resp2.text.index('Foobar3')
2018-04-01 15:23:01 +02:00
resp2 = resp.click('view', index=0)
assert resp2.text.index('Hello world') > resp2.text.index('Foobar3')
2018-04-01 15:23:01 +02:00
resp2 = resp.click('view', index=2)
assert 'Foobar1' in resp2.text
assert not 'Hello world' in resp2.text
2018-04-01 15:23:01 +02:00
assert Page.objects.all().count() == 1
assert PageSnapshot.objects.filter(page=page)[0].user.username == 'admin'
2018-04-01 15:23:01 +02:00
# check with asynchronous cells
resp = app.get('/manage/pages/%s/add-cell-to-content/data_jsoncell/default/' % page.id)
resp = resp.follow()
resp.forms[3]['cdata_jsoncell-1-template_string'].value = 'A{{json.data.0.text}}B'
resp.forms[3]['cdata_jsoncell-1-url'].value = 'http://example.com'
resp = resp.forms[3].submit().follow()
assert PageSnapshot.objects.all().count() == 5 # add + change
resp.forms[3]['cdata_jsoncell-1-template_string'].value = 'C{{json.data.0.text}}D'
resp = resp.forms[3].submit().follow()
assert PageSnapshot.objects.all().count() == 6
resp.forms[1]['c%s-text' % cell1.get_reference()].value = 'Foo back to 1'
resp = resp.forms[0].submit().follow()
resp = resp.click('history')
assert 'added cell' in resp.text
2018-04-01 15:23:01 +02:00
resp2 = resp.click('view', index=1)
json_cell_url = re.findall(r'/ajax/cell/.*/data_jsoncell-.*/', resp2.text)[0]
2018-04-01 15:23:01 +02:00
with mock.patch('combo.utils.requests.get') as requests_get:
data = {'data': [{'url': 'xxx', 'text': 'xxx'}]}
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
resp3 = app.get(json_cell_url)
assert resp3.text.strip() == 'CxxxD'
2018-04-01 15:23:01 +02:00
# previous version should return AxxxB
resp2 = resp.click('view', index=2)
json_cell_url = re.findall(r'/ajax/cell/.*/data_jsoncell-.*/', resp2.text)[0]
2018-04-01 15:23:01 +02:00
with mock.patch('combo.utils.requests.get') as requests_get:
data = {'data': [{'url': 'xxx', 'text': 'xxx'}]}
requests_get.return_value = mock.Mock(content=json.dumps(data), status_code=200)
resp3 = app.get(json_cell_url)
assert resp3.text.strip() == 'AxxxB'
2018-04-01 15:23:01 +02:00
# check anonymous users can't get to cells from snapshots
app.get('/logout/')
resp3 = app.get(json_cell_url, status=403)
# restore a snapshot
app = login(app)
resp = resp.click('restore', index=6)
resp = resp.form.submit()
resp = resp.follow()
resp2 = resp.click('see online')
assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3')
2018-04-01 15:23:01 +02:00
# clean it up
Page.snapshots.all().delete()
assert Page.objects.count() == 1
assert TextCell.objects.count() == 3
assert JsonCell.objects.count() == 0
def test_django_admin(app, admin_user):
resp = app.get('/admin/')
resp = resp.follow() # -> /admin/login/
resp = resp.follow() # -> /login/
resp.form['username'] = 'admin'
resp.form['password'] = 'admin'
resp = resp.form.submit()
resp = resp.follow() # -> /admin/
assert '/admin/logout/' in resp.text
resp = resp.click(href='/admin/logout/')
resp = resp.follow() # -> /logout/
assert urlparse.urlparse(resp.location).path == '/'