#!/usr/bin/env python3 # -*- coding: utf-8 -*- import datetime import lxml.etree import shutil from io import StringIO import os import json import sys test_path = os.path.abspath(__file__) test_dir_path = os.path.dirname(test_path) + os.sep from django.contrib.auth.models import User, Group from django.contrib.gis.geos import GEOSGeometry from django.conf import settings from django.core import mail from django.core.files import File from django.core.management import call_command from django.core.urlresolvers import reverse from django.template import Context from django.test import TestCase from chimere.models import Area, Icon, Importer, Category, SubCategory, \ Marker, Route, News, SubCategoryUserLimit, Polygon, PropertyModel from chimere.forms import MarkerForm, AreaAdminForm, notifySubmission from chimere.templatetags.chimere_tags import display_news from chimere.utils import ShapefileManager def copy_file_to_media(source): dest = os.path.join(settings.MEDIA_ROOT, source.split(os.sep)[-1]) shutil.copy(source, dest) return File(open(dest, 'rb')) def areas_setup(): area_1 = Area.objects.create( name='area 1', urn='area-1', order=1, available=True, upper_left_corner='SRID=4326;POINT(-4.907753 48.507656)', lower_right_corner='SRID=4326;POINT(-4.049447 48.279688)', default=True ) area_2 = Area.objects.create( name='area 2', urn='area-2', order=2, available=True, upper_left_corner='SRID=4326;POINT(-3 47.5)', lower_right_corner='SRID=4326;POINT(-2.5 47)', ) area_3 = Area.objects.create( name='area 3', urn='area-3', order=3, available=True, upper_left_corner='SRID=4326;POINT(-1.5 1.5)', lower_right_corner='SRID=4326;POINT(1.5 -1.5)') return [area_1, area_2, area_3] def properties_setup(): properties = [] properties.append( PropertyModel.objects.create(name="Property 1", slug='prop-1', order=10, available=True, mandatory=False) ) properties.append( PropertyModel.objects.create(name="Property 2", slug='prop-2', order=20, available=True, mandatory=False) ) return properties def subcategory_setup(): category = Category.objects.create( name='Main category', available=True, order=1, description='') if not os.path.exists(settings.MEDIA_ROOT): os.makedirs(settings.MEDIA_ROOT) media_root = settings.MEDIA_ROOT if not media_root.endswith(os.sep): media_root += os.sep shutil.copyfile(test_dir_path + "static/chimere/img/marker.png", settings.MEDIA_ROOT + "marker.png") icon = Icon.objects.create(name='Default icon', image='marker.png', height=25, width=21) subcategory_1 = SubCategory.objects.create( category=category, name='Subcategory 1', available=True, icon=icon, order=1, item_type='M',) subcategory_2 = SubCategory.objects.create( category=category, name='Subcategory 2', available=True, icon=icon, order=1, item_type='M',) subcategory_3 = SubCategory.objects.create( category=category, name='Subcategory 3', available=True, icon=icon, order=1, item_type='M',) subcategory_4 = SubCategory.objects.create( category=category, name='Subcategory 4', available=True, icon=icon, order=1, item_type='M',) subcategory_5 = SubCategory.objects.create( category=category, name='Subcategory 5', available=True, icon=icon, order=1, item_type='M',) return [subcategory_1, subcategory_2, subcategory_3, subcategory_4, subcategory_5] def marker_setup(sub_categories=[]): if not sub_categories: sub_categories = subcategory_setup() current_date = datetime.datetime.now() markers = [] marker_1 = Marker.objects.create(name="Marker 1", status='A', point='SRID=4326;POINT(-4.5 48.4)', available_date=current_date) marker_1.categories.add(sub_categories[0]) markers.append(marker_1) marker_2 = Marker.objects.create(name="Marker 2", status='A', point='SRID=4326;POINT(-3.5 48.4)', is_front_page=True, available_date=current_date, start_date=current_date) marker_2.categories.add(sub_categories[1]) markers.append(marker_2) marker_3 = Marker.objects.create( name="Marker 3", status='A', point='SRID=4326;POINT(-4.5 48.45)', is_front_page=True, available_date=current_date - datetime.timedelta(days=60), start_date=current_date - datetime.timedelta(days=60), end_date=current_date - datetime.timedelta(days=30)) marker_3.categories.add(sub_categories[1]) markers.append(marker_3) return markers def route_setup(sub_categories=[]): if not sub_categories: sub_categories = subcategory_setup() # current_date = datetime.datetime.now() routes = [] route_1 = Route.objects.create( name="Route 1", status='A', route='SRID=4326;LINESTRING(-1 1, 1 -1)') route_1.categories.add(sub_categories[0]) routes.append(route_1) route_2 = Route.objects.create( name="Route 2", status='A', route='SRID=4326;LINESTRING(0 0, 2 2)') route_2.categories.add(sub_categories[1]) routes.append(route_2) return routes class ImporterTest: def test_get(self): nb_by_cat = {} for importer, awaited_nb in self.marker_importers: nb, nb_updated, res = importer.manager.get() if awaited_nb is None: continue self.assertEqual( nb, awaited_nb, msg=u"{}: get test failed - got {} when {} was awaited - {}" .format(str(self.__class__), nb, awaited_nb, res)) self.assertEqual(nb_updated, 0) for cat in importer.categories.all(): if cat not in nb_by_cat: nb_by_cat[cat] = 0 nb_by_cat[cat] += nb for cat in nb_by_cat: nb = Marker.objects.filter(categories__pk=cat.pk).count() + \ Route.objects.filter(categories__pk=cat.pk).count() + \ Polygon.objects.filter(categories__pk=cat.pk).count() self.assertEqual( nb_by_cat[cat], nb, msg=u"{} - category association test failed: {}/{}".format( str(cat), nb, nb_by_cat[cat])) # update for importer, awaited_nb in self.marker_importers: importer.overwrite = True importer.save() nb, nb_updated, res = importer.manager.get() if awaited_nb is None: continue self.assertEqual( nb, 0, msg=u"{}: update test failed - new items have been add" .format(str(self.__class__))) # TODO: v3 - retablir overwrite """ # manage overwrite for importer, awaited_nb in self.marker_importers: if not awaited_nb: continue # mimic the modification of one item for cls in (Marker, Route): items = cls.objects.filter( categories=importer.categories.all()[0]).order_by( '-pk').all() if items.count(): item = items.all()[0] item.import_version = 99999 # fake version number item.save() # as when the import_version it is considered as an import # modification force the modification flag item.modified_since_import = True item.save() importer.overwrite = False importer.save() nb, nb_updated, res = importer.manager.get() if awaited_nb is None: continue self.assertEqual( nb, 1, msg=u"%s: overwrite test failed" % str(self.__class__))""" class KMLImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() importer1 = Importer.objects.create( importer_type='KML', source=test_dir_path + 'tests/sample.kml', filtr="Category 1") importer1.categories.add(subcategories[0]) importer2 = Importer.objects.create( importer_type='KML', source=test_dir_path + 'tests/sample.kml', filtr="Subcategory 1") importer2.categories.add(subcategories[1]) importer3 = Importer.objects.create( importer_type='KML', source=test_path + 'tests/sample.kml', filtr="Subcategory 3") importer3.categories.add(subcategories[2]) importer4 = Importer.objects.create( importer_type='KML', source=test_dir_path + 'tests/sample.kml.zip', zipped=True, default_description="Default description") importer4.categories.add(subcategories[3]) importer5 = Importer.objects.create( importer_type='KML', source=test_dir_path + 'tests/sample-no-folder.kml', zipped=False, default_description="Default description") importer5.categories.add(subcategories[4]) self.marker_importers = [ (importer1, 1), (importer2, 3), (importer3, 0), (importer4, 4), (importer5, 3)] def test_defaultdescription(self): Marker.objects.all().delete() importer = self.marker_importers[-1][0] importer.overwrite = True importer.save() importer.manager.get() last_marker = Marker.objects.order_by('-pk').all()[0] self.assertEqual(last_marker.description, importer.default_description) # don't overwrite description on update new_desc = u"Description set by an user" last_marker.description = new_desc last_marker.save() importer.manager.get() last_marker = Marker.objects.order_by('-pk').all()[0] self.assertEqual(last_marker.description, new_desc) class ShapefileImporterTest(TestCase, ImporterTest): def setUp(self): self.subcategories = subcategory_setup() importer = Importer.objects.create( importer_type='SHP', source=test_dir_path + 'tests/sample_nodes.shp.zip', zipped=True) importer.categories.add(self.subcategories[0]) importer2 = Importer.objects.create( importer_type='SHP', source=test_dir_path + 'tests/sample_ways.shp.zip', zipped=True) importer2.categories.add(self.subcategories[1]) self.marker_importers = [(importer, 29), (importer2, 5)] self.markers = marker_setup() def test_export(self): filename, zip_stream = ShapefileManager.export(Marker.objects.all()) class OSMImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() marker_setup() importer1 = Importer.objects.create( importer_type='OSM', source=test_dir_path + 'tests/sample_nodes.osm') importer1.categories.add(subcategories[0]) importer2 = Importer.objects.create( importer_type='OSM', source=test_dir_path + 'tests/sample_ways.osm') importer2.categories.add(subcategories[1]) importer3 = Importer.objects.create( importer_type='OSM', source='http://open.mapquestapi.com/xapi/api/0.6/way' '[highway=motorway]' '[bbox=2.0393839939136975,48.68908639634696,' '2.3140421970277316,48.790972349390415]') self.marker_importers = [(importer1, 19), (importer2, 8), (importer3, None)] class GeoRSSImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() importer1 = Importer.objects.create( importer_type='RSS', source=test_dir_path + 'tests/georss_simple.xml') importer1.categories.add(subcategories[0]) importer2 = Importer.objects.create( importer_type='RSS', source=test_dir_path + 'tests/eqs7day-M5.xml') importer2.categories.add(subcategories[1]) self.marker_importers = [(importer1, 2), (importer2, 32)] class HtmlXsltImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() xslt1 = copy_file_to_media( test_dir_path + 'tests/villiers-le-bacle.xslt') xslt2 = copy_file_to_media( test_dir_path + 'tests/villiers-le-bacle-detail.xslt') importer1 = Importer.objects.create( importer_type='XSLT', source='http://www.chymeres.net/test/ville-villierslebacle.fr/', source_file=xslt1, source_file_alt=xslt2, default_localisation='SRID=4326;POINT(-4.5 48.4)',) importer1.categories.add(subcategories[0]) self.marker_importers = [(importer1, 7)] class XmlXsltImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() xslt1 = copy_file_to_media( test_dir_path + 'tests/magny-xml.xslt') importer1 = Importer.objects.create( importer_type='XXLT', source='http://www.chymeres.net/test/magny.xml', source_file=xslt1, default_localisation='SRID=4326;POINT(-4.5 48.4)',) importer1.categories.add(subcategories[0]) self.marker_importers = [(importer1, 10)] class JsonImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() jsonfile = copy_file_to_media( test_dir_path + 'tests/test.json') importer1 = Importer.objects.create( importer_type='JSON', source_file=jsonfile, filtr='{"title":"name", "id_agenda":"id", ' '"content":"description", "date_start_evt":"start_date", ' '"date_end_evt":"end_date"}', default_localisation='SRID=4326;POINT(-4.5 48.4)',) importer1.categories.add(subcategories[0]) jsonfile = copy_file_to_media( test_dir_path + 'tests/events.json') importer2 = Importer.objects.create( importer_type='JSON', source_file=jsonfile, filtr='events{"title":{"fr":"name"}, "uid":"id", ' '"image":"external_image",' '"html":{"fr":"description"},' '"timings":{"start":"start_date"}, ' '"timings":{"end":"end_date"}, ' '"latitude":"lat", ' '"longitude":"lon"' '}', default_localisation='SRID=4326;POINT(-4.5 48.4)',) importer2.categories.add(subcategories[0]) self.marker_importers = [(importer1, 5), (importer2, 20)] class IcalImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() icsfile = copy_file_to_media(test_dir_path + 'tests/test.ics') importer1 = Importer.objects.create( importer_type='ICAL', source_file=icsfile,) importer1.categories.add(subcategories[0]) self.marker_importers = [(importer1, 1), ] class FeedsTest(TestCase): def setUp(self): self.areas = areas_setup() self.markers = marker_setup() def test_rss(self): # global url = reverse('chimere:feeds-global') response = self.client.get(url) self.assertEqual(200, response.status_code) doc = lxml.etree.fromstring(response.content) self.assertEqual(int(doc.xpath('count(//item)')), len(self.markers)) url = reverse('chimere:feeds-areaid', args=('', self.areas[0].pk)) response = self.client.get(url) self.assertEqual(200, response.status_code) doc = lxml.etree.fromstring(response.content) self.assertEqual(int(doc.xpath('count(//item)')), 2) class MainUITest(TestCase): fixtures = [settings.ROOT_PATH + 'chimere/fixtures/initial_data.json'] def setUp(self): self.areas = areas_setup() self.subcategories = subcategory_setup() self.markers = marker_setup() def test_pages(self): url = reverse(settings.MAIN_INDEX) response = self.client.get(url) self.assertEqual(200, response.status_code) url = reverse('chimere:edit') response = self.client.get(url) self.assertRedirects(response, "/{}/edit-marker/".format( Area.objects.get(default=True).urn)) url_editmarker = reverse('chimere:editmarker') response = self.client.get(url_editmarker) self.assertEqual(200, response.status_code) url = reverse('chimere:editroute') response = self.client.get(url) self.assertEqual(200, response.status_code) url = reverse('chimere:editpolygon') response = self.client.get(url) self.assertEqual(200, response.status_code) class AdministratorsTest(TestCase): def setUp(self): self.areas = areas_setup() self.subcategories = subcategory_setup() self.markers = marker_setup(self.subcategories) self.adminuser = User.objects.create_superuser( 'admin', 'admin@test.com', 'pass') self.moderation_user = User.objects.create_user( 'mod_1', 'mod1@test.com', 'pass') self.moderation_user.is_staff = True self.moderation_user.save() self.moderation_user2 = User.objects.create_user( 'mod_2', 'mod2@test.com', 'pass') self.moderation_user2.is_staff = True self.moderation_user2.save() SubCategoryUserLimit.objects.create( subcategory=self.subcategories[0], user=self.moderation_user2) for g in Group.objects.all(): g.user_set.add(self.moderation_user) g.user_set.add(self.moderation_user2) class AdminTest(AdministratorsTest): def test_actions(self): self.client.login(username='admin', password='pass') q_markers = Marker.objects.filter(pk__in=[m.pk for m in self.markers]) # disable self.client.post( '/admin/chimere/marker/', data={'action': ['disable'], '_selected_action': [str(m.pk) for m in self.markers], }) self.assertEqual(q_markers.count(), q_markers.filter(status='D').count()) # validate self.client.post('/admin/chimere/marker/', data={'action': ['validate'], '_selected_action': [str(m.pk) for m in self.markers] }) self.assertEqual(q_markers.count(), q_markers.filter(status='A').count()) def test_moderation_action_filter(self): m_ok = self.markers[0] m_nok = self.markers[2] self.client.login(username='mod_1', password='pass') response = self.client.get('/admin/chimere/marker/') self.assertTrue(str(self.subcategories[1]) in str(response.content)) response = self.client.get('/admin/chimere/marker/{}/change/'.format( m_ok.pk)) self.assertEqual(200, response.status_code) self.assertTrue(str(self.subcategories[1]) in str(response.content)) response = self.client.get( '/admin/chimere/marker/{}/change/'.format(m_nok.pk)) self.assertEqual(200, response.status_code) self.client.logout() self.client.login(username='mod_2', password='pass') response = self.client.get('/admin/chimere/marker/') self.assertFalse(str(self.subcategories[1]) in str(response.content)) response = self.client.get('/admin/chimere/marker/{}/change/'.format( m_ok.pk)) self.assertEqual(200, response.status_code) # functionality currently disabled # self.assertFalse(str(self.subcategories[1]) in response.content) response = self.client.get( '/admin/chimere/marker/{}/change/'.format(m_nok.pk)) self.assertRedirects(response, '/admin/') class NotifyTest(AdministratorsTest): def test_notify_email(self): # OK for all: two moderators and superuser m1 = self.markers[0] notifySubmission('dont-care-about-uri-for-tests', m1) out = mail.outbox.pop() self.assertEqual(sorted(out.to), sorted([self.adminuser.email, self.moderation_user.email, self.moderation_user2.email])) # not in the area for both moderators m2 = self.markers[1] notifySubmission('dont-care-about-uri-for-tests', m2) out = mail.outbox.pop() self.assertEqual(out.to, [self.adminuser.email]) # not a category followed by moderator2 m3 = self.markers[2] notifySubmission('dont-care-about-uri-for-tests', m3) out = mail.outbox.pop() self.assertEqual(sorted(out.to), sorted([self.adminuser.email, self.moderation_user.email])) self.assertEqual(len(out.to), 2) class MarkerFormTest(TestCase): def setUp(self): self.subcategories = subcategory_setup() def test_marker_creation(self): current_date = datetime.datetime.now() # end_date before start_date data = {'name': "Marker 1", 'status': 'A', 'available_date': current_date, 'point': 'SRID=4326;POINT(-4.5 48.4)', 'start_date': current_date, 'end_date': current_date - datetime.timedelta(1), 'categories': [self.subcategories[0].pk]} form = MarkerForm(data) self.assertEqual(form.is_valid(), False) class AreaTest(TestCase): def setUp(self): self.areas = areas_setup() def test_area_availability(self): area_1 = self.areas[0] area_1.available = False area_1.default = False area_1.save() area_2 = self.areas[1] area_2.default = True area_2.save() response = self.client.get('/%s/' % area_1.urn) self.assertNotIn( str(area_1.upper_left_corner.y), str(response.content), msg="A non-available area shouln't be reached" ) class AreaAdminFormTest(TestCase): def setUp(self): self.areas = areas_setup() def test_area_default(self): area_1, area_2 = self.areas[0], self.areas[1] area_1.default = True area_1.save() area_2.default = True area_2.save() area_1 = Area.objects.get(urn=area_1.urn) self.assertEqual(area_1.default, False) def test_area_creation(self): base_data = { 'name': u'New test', 'order': 3, 'available': True, 'urn': 'area-new', 'upper_left_lat': 48.5, 'upper_left_lon': -5, 'lower_right_lat': 48, 'lower_right_lon': -4, 'upper_left_corner': 'SRID=4326;POINT(0 0)', 'lower_right_corner': 'SRID=4326;POINT(0 0)'} # order already given data = base_data.copy() data['order'] = self.areas[0].order form = AreaAdminForm(data) self.assertEqual(form.is_valid(), False) # update an already existing area data = base_data.copy() data['order'] = self.areas[0].order form = AreaAdminForm(data, instance=self.areas[0]) self.assertEqual(form.is_valid(), True) # empty area data = base_data.copy() data.update({'upper_left_lat': 0, 'upper_left_lon': 0, 'lower_right_lat': 0, 'lower_right_lon': 0}) form = AreaAdminForm(data) self.assertEqual(form.is_valid(), False) class DynamicCategoryTest(TestCase): def setUp(self): self.areas = areas_setup() subcategories = subcategory_setup() self.markers = marker_setup(subcategories) self.routes = route_setup(subcategories) def test_dynamic_evaluation(self): cats = self.areas[0].getCategories(status='A', filter_available=True) self.assertEqual(len(cats), 1) cats = self.areas[2].getCategories(status='A', filter_available=True) self.assertEqual(len(cats), 2) def test_get_all_categories(self): url = reverse('chimere:get_all_categories') response = self.client.get(url) self.assertEqual(200, response.status_code) cats = json.loads(str(response.content, 'utf-8'))['categories'] # the default area is get: only one category in this area self.assertEqual(len(cats), 1) class NewsTest(TestCase): def setUp(self): self.areas = areas_setup() self.markers = marker_setup() current_date = datetime.datetime.now() Marker.objects.create( name="Marker 4", status='A', point='SRID=4326;POINT(-4.5 48.45)', available_date=current_date - datetime.timedelta(days=90), start_date=current_date - datetime.timedelta(days=90), end_date=None) self.news = [] self.news.append(News.objects.create(is_front_page=True, title=u"Test news 1", available=True, date=datetime.date.today())) self.news.append(News.objects.create(is_front_page=True, title=u"Test news 2", available=False, date=datetime.date.today())) def test_news_display(self): context = display_news(Context({})) self.assertEqual(len(context['news_lst']), 2) context = display_news(Context({'area_name': 'area-2'})) self.assertEqual(len(context['news_lst']), 1) class RapprochementTest(TestCase): def setUp(self): self.areas = areas_setup() self.subcategories = subcategory_setup() self.markers = marker_setup(self.subcategories) self.routes = route_setup(self.subcategories) self.adminuser = User.objects.create_superuser( 'admin', 'admin@test.com', 'pass') self.client.login(username='admin', password='pass') def test_managed_modified_markers(self): ref_marker = self.markers[0] new_vals = {'name': "Marker 1 - modified", 'point': GEOSGeometry('SRID=4326;POINT(-4 48)')} values = {'status': 'M', 'ref_item': ref_marker} values.update(new_vals) modified_marker = Marker.objects.create(**values) modified_marker.categories.add(ref_marker.categories.all()[0]) self.client.post( '/admin/chimere/marker/', data={'action': ['managed_modified'], 'index': 0, 'rapprochement': 1, 'name': 1, 'point': 1, '_selected_action': [str(ref_marker.pk)]}) ref_marker = Marker.objects.get(pk=ref_marker.pk) self.assertEqual(Marker.objects.filter(ref_item=ref_marker, status='M').count(), 0) for k in new_vals: self.assertEqual(getattr(ref_marker, k), new_vals[k]) def test_managed_modified_imported_markers(self): ref_marker = self.markers[0] new_vals = {'name': "Marker 1 - modified", 'point': GEOSGeometry('SRID=4326;POINT(-4 48)')} values = {'status': 'I', 'ref_item': ref_marker, 'import_version': 42} values.update(new_vals) modified_marker = Marker.objects.create(**values) self.assertNotEqual(ref_marker.import_version, modified_marker.import_version) modified_marker.categories.add(ref_marker.categories.all()[0]) self.client.post('/admin/chimere/marker/', data={'action': ['managed_modified'], 'index': 0, 'rapprochement': 1, 'name': 1, 'point': 1, '_selected_action': [str(ref_marker.pk)] }) ref_marker = Marker.objects.get(pk=ref_marker.pk) self.assertEqual(Marker.objects.filter(ref_item=ref_marker, status='I').count(), 0) for k in list(new_vals.keys()) + ['import_version']: self.assertEqual(getattr(ref_marker, k), values[k]) def test_managed_modified_routes(self): ref_route = self.routes[0] new_vals = {'name': "Route 1 - modified", 'route': GEOSGeometry('SRID=4326;LINESTRING(1 1,2 2)')} values = {'status': 'M', 'ref_item': ref_route} values.update(new_vals) modified_route = Route.objects.create(**values) modified_route.categories.add(self.subcategories[1]) self.client.post('/admin/chimere/route/', data={'action': ['managed_modified'], 'index': 0, 'rapprochement': 1, 'name': 1, 'route': 1, 'categories': 1, '_selected_action': [str(ref_route.pk)] }) ref_route = Route.objects.get(pk=ref_route.pk) self.assertEqual(Route.objects.filter(ref_item=ref_route, status='M').count(), 0) self.assertEqual(ref_route.name, new_vals['name']) self.assertEqual(ref_route.route.wkt, new_vals['route'].wkt) self.assertEqual(ref_route.categories.all()[0], self.subcategories[1]) class RouteTest(TestCase): def setUp(self): self.subcategories = subcategory_setup() class V3ToV2Test(TestCase): def setUp(self): self.areas = areas_setup() self.markers = marker_setup() self.routes = route_setup() properties_setup() self.markers[0].setProperty('prop-1', 'myproperty') def test_markers(self): sysout = sys.stdout sys.stdout = StringIO() call_command('v3_to_v2_markers') vals = sys.stdout.getvalue() values = json.loads(vals) markers = [k for k in values if k['model'] == 'chimere.marker'] self.assertEqual(len(markers), len(self.markers)) self.assertNotIn('weight', markers[0]['fields']) self.assertNotIn('normalised_weight', markers[0]['fields']) self.assertEqual(values[-1]['fields']['value'], 'myproperty') self.assertNotIn('polygon', markers[-1]['fields']) self.assertNotIn('route', markers[-1]['fields']) sys.stdout = sysout def test_routes(self): sysout = sys.stdout sys.stdout = StringIO() call_command('v3_to_v2_routes') vals = sys.stdout.getvalue() routes = [k for k in json.loads(vals) if k['model'] == 'chimere.route'] self.assertEqual(len(routes), len(self.routes)) self.assertNotIn('weight', routes[0]['fields']) self.assertNotIn('normalised_weight', routes[0]['fields']) self.assertNotIn('color', routes[0]['fields']) sys.stdout = sysout