combo/tests/test_manager.py

460 lines
18 KiB
Python

import base64
import os
import StringIO
import urllib
from django.core.files.storage import default_storage
from django.conf import settings
from django.contrib.auth.models import User
import pytest
from webtest import TestApp
from webtest import Upload
from combo.wsgi import application
from combo.data.models import Page, CellBase, TextCell, LinkCell
from combo.apps.search.models import SearchCell
pytestmark = pytest.mark.django_db
@pytest.fixture
def admin_user():
try:
user = User.objects.get(username='admin')
except User.DoesNotExist:
user = User.objects.create_superuser('admin', email=None, password='admin')
return user
def login(app, username='admin', password='admin'):
login_page = app.get('/login/')
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):
# connect while not being logged in
assert app.get('/manage/', status=302).location == 'http://localhost:80/login/?next=/manage/'
def test_access(app, admin_user):
app = login(app)
resp = app.get('/manage/', status=200)
assert 'Pages' in resp.body
assert "This site doesn't have any page yet." in resp.body
def test_add_page(app, admin_user):
app = login(app)
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 == 'http://localhost:80/manage/pages/1/'
assert Page.objects.get(slug='index').title == 'Home'
assert Page.objects.get(slug='index').template_name == 'standard' # first one was taken
def test_add_second_page(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one')
page.save()
app = login(app)
resp = app.get('/manage/', status=200)
resp = resp.click('New')
# assert there's no defaul title for the second page
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'
# 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.body
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_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.body
assert Page.objects.get(id=page.id).slug == 'two2'
def test_delete_page(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('delete')
assert '<button class="delete-button">Delete</button>' in resp.body
resp = resp.forms[0].submit()
assert resp.location == 'http://localhost:80/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.body
assert 'Delete only this page' in resp.body
assert 'Delete this page and all subpages' in resp.body
resp.form['choice'].value = 'delete-one'
resp = resp.forms[0].submit()
assert resp.location == 'http://localhost:80/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.body
assert 'Delete only this page' in resp.body
assert 'Delete this page and all subpages' in resp.body
resp.form['choice'].value = 'delete-all'
resp = resp.forms[0].submit()
assert resp.location == 'http://localhost:80/manage/'
assert Page.objects.count() == 0
def test_export_page(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('export')
assert resp.headers['content-type'] == 'application/json'
assert resp.json.get('fields').get('slug') == 'one'
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'
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 == 'http://localhost:80/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.body
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 == 'http://localhost:80/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'
resp = app.get('/manage/pages/%s/' % page.id)
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.body
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.body.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()
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):
delattr(settings, 'COMBO_SEARCH_SERVICES')
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
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-restricted_to_unlogged' % cell.id].checked is False
assert resp.form['cdata_textcell-%s-public' % cell.id].checked is False
resp.form['cdata_textcell-%s-public' % cell.id].checked = True
resp = resp.form.submit('submit')
assert TextCell.objects.get(id=cell.id).public is False
resp = app.get('/manage/pages/%s/' % page.id)
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id)
assert resp.form['cdata_textcell-%s-restricted_to_unlogged' % cell.id].checked is False
assert resp.form['cdata_textcell-%s-public' % cell.id].checked is True
resp.form['cdata_textcell-%s-public' % cell.id].checked = False
resp.form['cdata_textcell-%s-restricted_to_unlogged' % cell.id].checked = True
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
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)
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, urllib.urlencode(params)))
assert resp.status_code == 206
for i, cell in enumerate(cells):
assert TextCell.objects.get(id=cell.id).order == new_order[i]
def test_logout(app, admin_user):
app = login(app)
app.get('/logout/')
assert app.get('/manage/', status=302).location == 'http://localhost:80/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.body
filepath = os.path.join(settings.CKEDITOR_UPLOAD_PATH, 'test.png')
pix = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
default_storage.save(filepath, StringIO.StringIO(base64.decodestring(pix)))
assert os.path.exists(default_storage.path(filepath))
resp = app.get('/manage/assets/')
assert 'have any asset yet.' not in resp.body
app.get('/manage/assets/delete?img_orig=%s' % filepath, status=204)
assert not os.path.exists(default_storage.path(filepath))
app.get('/manage/assets/delete?img_orig=/foo.png', status=403)
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.content.startswith('fooBar([{"')