combo/tests/test_import_export.py

200 lines
6.2 KiB
Python

from cStringIO import StringIO
import datetime
import json
import os
import shutil
import sys
import tempfile
import pytest
from django.contrib.auth.models import Group
from django.core.files import File
from django.core.management import call_command
from combo.apps.assets.models import Asset
from combo.apps.maps.models import MapLayer, Map
from combo.data.models import Page, TextCell
from combo.data.utils import export_site, import_site, MissingGroups
pytestmark = pytest.mark.django_db
@pytest.fixture
def some_data():
page = Page(title='One', slug='one')
page.save()
page = Page(title='Two', slug='two')
page.save()
page = Page(title='Three', slug='three')
page.save()
cell = TextCell(page=page, order=0, text='hello world', placeholder='content')
cell.save()
@pytest.fixture
def some_map_layers():
MapLayer(label='Foo', slug='foo', geojson_url='http://example.net/foo/').save()
MapLayer(label='Bar', slug='bar', geojson_url='http://example.net/bar/').save()
@pytest.fixture
def some_assets():
Asset(key='banner', asset=File(StringIO('test'), 'test.png')).save()
Asset(key='favicon', asset=File(StringIO('test2'), 'test2.png')).save()
def get_output_of_command(command, *args, **kwargs):
old_stdout = sys.stdout
output = sys.stdout = StringIO()
call_command(command, *args, **kwargs)
sys.stdout = old_stdout
return output.getvalue()
def test_import_export(app, some_data):
output = get_output_of_command('export_site')
assert len(json.loads(output)['pages']) == 3
import_site(data={}, clean=True)
assert Page.objects.all().count() == 0
assert TextCell.objects.all().count() == 0
empty_output = get_output_of_command('export_site')
assert len(json.loads(empty_output)['pages']) == 0
Page(title='test', slug='test').save()
old_stdin = sys.stdin
sys.stdin = StringIO(json.dumps({}))
assert Page.objects.count() == 1
try:
call_command('import_site', '-', clean=True)
finally:
sys.stdin = old_stdin
assert Page.objects.count() == 0
with tempfile.NamedTemporaryFile() as f:
f.write(output)
f.flush()
call_command('import_site', f.name)
assert Page.objects.count() == 3
assert TextCell.objects.all().count() == 1
import_site(data={}, if_empty=True)
assert Page.objects.count() == 3
assert TextCell.objects.all().count() == 1
import_site(data=[], clean=True)
tempdir = tempfile.mkdtemp('chrono-test')
empty_output = get_output_of_command('export_site', output=os.path.join(tempdir, 't.json'))
assert os.path.exists(os.path.join(tempdir, 't.json'))
shutil.rmtree(tempdir)
def test_backward_compatibility_import(app, some_data):
old_export = Page.export_all_for_json()
Page.objects.all().delete()
import_site(data=old_export)
assert Page.objects.count() == 3
def test_import_export_map_layers(app, some_map_layers):
output = get_output_of_command('export_site')
assert len(json.loads(output)['map-layers']) == 2
import_site(data={}, clean=True)
assert MapLayer.objects.all().count() == 0
empty_output = get_output_of_command('export_site')
assert len(json.loads(empty_output)['map-layers']) == 0
MapLayer(label='Baz', slug='baz', geojson_url='http://example.net/baz/').save()
old_stdin = sys.stdin
sys.stdin = StringIO(json.dumps({}))
assert MapLayer.objects.count() == 1
try:
call_command('import_site', '-', clean=True)
finally:
sys.stdin = old_stdin
assert MapLayer.objects.count() == 0
with tempfile.NamedTemporaryFile() as f:
f.write(output)
f.flush()
call_command('import_site', f.name)
assert MapLayer.objects.count() == 2
import_site(data={}, if_empty=True)
assert MapLayer.objects.count() == 2
def test_import_export_map_cells(app, some_data, some_map_layers):
page = Page.objects.get(slug='one')
cell = Map(page=page, order=0, placeholder='content')
cell.save()
cell.layers.add(MapLayer.objects.get(slug='foo'))
cell.save()
site_export = get_output_of_command('export_site')
import_site(data={}, clean=True)
assert Map.objects.count() == 0
import_site(data=json.loads(site_export), clean=True)
assert Map.objects.count() == 1
assert Map.objects.all()[0].layers.all()[0].slug == 'foo'
def test_group_restrictions_import_export(app, some_data):
group = Group(name='A Group')
group.save()
page = Page.objects.get(slug='one')
page.groups = [group]
page.save()
cell = TextCell.objects.get(order=0)
cell.groups = [group]
cell.save()
output = get_output_of_command('export_site')
assert len(json.loads(output)['pages']) == 3
import_site(data={}, clean=True)
assert Page.objects.all().count() == 0
assert TextCell.objects.all().count() == 0
Group.objects.all().delete()
with pytest.raises(MissingGroups) as excinfo:
import_site(json.loads(output), clean=True)
assert excinfo.value.names == ['A Group']
group = Group(name='A Group')
group.save()
import_site(json.loads(output), clean=True)
assert Page.objects.all().count() == 3
assert TextCell.objects.all().count() == 1
page = Page.objects.get(slug='one')
assert [x.name for x in page.groups.all()] == ['A Group']
cell = TextCell.objects.get(order=0)
assert [x.name for x in cell.groups.all()] == ['A Group']
def test_import_export_assets(app, some_assets):
output = get_output_of_command('export_site')
assert len(json.loads(output)['assets']) == 2
import_site(data={}, clean=True)
assert Asset.objects.all().count() == 0
empty_output = get_output_of_command('export_site')
assert len(json.loads(empty_output)['assets']) == 0
Asset(key='footer', asset=File(StringIO('test3'), 'test3.png')).save()
old_stdin = sys.stdin
sys.stdin = StringIO(json.dumps({}))
assert Asset.objects.count() == 1
try:
call_command('import_site', '-', clean=True)
finally:
sys.stdin = old_stdin
assert Asset.objects.count() == 0
with tempfile.NamedTemporaryFile() as f:
f.write(output)
f.flush()
call_command('import_site', f.name)
assert Asset.objects.count() == 2
import_site(data={}, if_empty=True)
assert Asset.objects.count() == 2