0001-maps-add-layers-8454.patch
combo/apps/maps/__init__.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2015 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import django.apps |
|
18 |
from django.core.urlresolvers import reverse |
|
19 |
from django.utils.translation import ugettext_lazy as _ |
|
20 | ||
21 | ||
22 |
class AppConfig(django.apps.AppConfig): |
|
23 |
name = 'combo.apps.maps' |
|
24 |
verbose_name = _('Maps') |
|
25 | ||
26 |
def get_before_urls(self): |
|
27 |
from . import urls |
|
28 |
return urls.urlpatterns |
|
29 | ||
30 |
def get_extra_manager_actions(self): |
|
31 |
return [{'href': reverse('maps-manager-homepage'), |
|
32 |
'text': _('Maps')}] |
|
33 | ||
34 |
default_app_config = 'combo.apps.maps.AppConfig' |
combo/apps/maps/forms.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2017 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import itertools |
|
18 | ||
19 |
from django import forms |
|
20 | ||
21 |
from .models import MapLayer |
|
22 | ||
23 |
colours = [('%s%s%s' % x, '%s%s%s' % x) for x in itertools.product(('00', '66', '99', 'FF'), repeat=3)] |
|
24 | ||
25 |
class MapLayerForm(forms.ModelForm): |
|
26 |
class Meta: |
|
27 |
model = MapLayer |
|
28 |
fields = '__all__' |
|
29 |
widgets = {'marker_colour': forms.Select(attrs={'class': 'colour-picker'}, |
|
30 |
choices=colours), |
|
31 |
'icon_colour': forms.Select(attrs={'class': 'colour-picker'}, |
|
32 |
choices=colours), |
|
33 |
} |
combo/apps/maps/manager_views.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2017 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.core.urlresolvers import reverse_lazy |
|
18 |
from django.views.generic import (TemplateView, ListView, CreateView, |
|
19 |
UpdateView, DeleteView) |
|
20 | ||
21 |
from .models import MapLayer |
|
22 |
from .forms import MapLayerForm |
|
23 | ||
24 | ||
25 |
class ManagerHomeView(TemplateView): |
|
26 |
template_name = 'maps/manager_home.html' |
|
27 | ||
28 | ||
29 |
class LayersManagerView(ListView): |
|
30 |
model = MapLayer |
|
31 | ||
32 | ||
33 |
class LayerAddView(CreateView): |
|
34 |
model = MapLayer |
|
35 |
form_class = MapLayerForm |
|
36 |
success_url = reverse_lazy('maps-manager-layers-list') |
|
37 | ||
38 | ||
39 |
class LayerEditView(UpdateView): |
|
40 |
model = MapLayer |
|
41 |
form_class = MapLayerForm |
|
42 |
success_url = reverse_lazy('maps-manager-layers-list') |
|
43 | ||
44 | ||
45 |
class LayerDeleteView(DeleteView): |
|
46 |
model = MapLayer |
|
47 |
success_url = reverse_lazy('maps-manager-layers-list') |
combo/apps/maps/migrations/0001_initial.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import migrations, models |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
] |
|
11 | ||
12 |
operations = [ |
|
13 |
migrations.CreateModel( |
|
14 |
name='MapLayer', |
|
15 |
fields=[ |
|
16 |
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
17 |
('label', models.CharField(max_length=128, verbose_name='Label')), |
|
18 |
('geojson_url', models.URLField(verbose_name='Geojson URL')), |
|
19 |
('marker_colour', models.CharField(default=b'0000FF', max_length=6, verbose_name='Marker color')), |
|
20 |
('icon', models.CharField(help_text='FontAwesome style name', max_length=32, null=True, verbose_name='Marker icon', blank=True)), |
|
21 |
('icon_colour', models.CharField(default=b'FFFFFF', max_length=6, verbose_name='Icon colour')), |
|
22 |
], |
|
23 |
), |
|
24 |
] |
combo/apps/maps/models.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2017 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 | ||
18 |
from django.db import models |
|
19 |
from django.utils.translation import ugettext_lazy as _ |
|
20 | ||
21 |
from combo.utils import requests |
|
22 | ||
23 | ||
24 |
class MapLayer(models.Model): |
|
25 |
label = models.CharField(_('Label'), max_length=128) |
|
26 |
geojson_url = models.URLField(_('Geojson URL')) |
|
27 |
marker_colour = models.CharField(_('Marker color'), max_length=6, default='0000FF') |
|
28 |
icon = models.CharField(_('Marker icon'), max_length=32, blank=True, null=True, |
|
29 |
help_text=_('FontAwesome style name')) |
|
30 |
icon_colour = models.CharField(_('Icon colour'), max_length=6, default='FFFFFF') |
|
31 | ||
32 |
def __unicode__(self): |
|
33 |
return self.label |
|
34 | ||
35 |
def get_geojson(self): |
|
36 |
response = requests.get(self.geojson_url, |
|
37 |
remote_service='auto', |
|
38 |
headers={'accept': 'application/json'}) |
|
39 |
if not response.ok: |
|
40 |
return [] |
|
41 |
features = response.json() |
|
42 |
for feature in features: |
|
43 |
feature['display_fields'] = feature['properties'].copy() |
|
44 |
feature['properties']['colour'] = '#%s' % self.marker_colour |
|
45 |
feature['properties']['icon_colour'] = '#%s' % self.icon_colour |
|
46 |
feature['properties']['label'] = self.label |
|
47 |
feature['properties']['icon'] = self.icon |
|
48 |
return features |
combo/apps/maps/templates/maps/manager_base.html | ||
---|---|---|
1 |
{% extends "combo/manager_base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
<h2>{% trans 'Maps' %}</h2> |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block breadcrumb %} |
|
9 |
{{ block.super }} |
|
10 |
<a href="{% url 'maps-manager-homepage' %}">{% trans 'Maps' %}</a> |
|
11 |
{% endblock %} |
combo/apps/maps/templates/maps/manager_home.html | ||
---|---|---|
1 |
{% extends "maps/manager_base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block content %} |
|
5 |
<ul class="apps"> |
|
6 |
<li><a class="button" href="{% url 'maps-manager-layers-list' %}">{% trans 'Layers' %}</a></li> |
|
7 |
</ul> |
|
8 |
{% endblock %} |
combo/apps/maps/templates/maps/maplayer_confirm_delete.html | ||
---|---|---|
1 |
{% extends "combo/manager_base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
<h2>{{ view.model.get_verbose_name }}</h2> |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block content %} |
|
9 |
<form method="post"> |
|
10 |
{% csrf_token %} |
|
11 |
{% blocktrans %}Are you sure you want to delete this?{% endblocktrans %} |
|
12 |
<div class="buttons"> |
|
13 |
<button class="delete-button">{% trans 'Delete' %}</button> |
|
14 |
<a class="cancel" href="{% url 'maps-manager-layers-list' %}">{% trans 'Cancel' %}</a> |
|
15 |
</div> |
|
16 |
</form> |
|
17 |
{% endblock %} |
combo/apps/maps/templates/maps/maplayer_form.html | ||
---|---|---|
1 |
{% extends "maps/maplayer_list.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
{% if object.id %} |
|
6 |
<h2>{% trans "Edit Layer" %}</h2> |
|
7 |
{% else %} |
|
8 |
<h2>{% trans "New Layer" %}</h2> |
|
9 |
{% endif %} |
|
10 |
{% endblock %} |
|
11 | ||
12 |
{% block breadcrumb %} |
|
13 |
{{ block.super }} |
|
14 |
<a href="{% url 'maps-manager-homepage' %}">{% trans 'Layers' %}</a> |
|
15 |
{% endblock %} |
|
16 | ||
17 |
{% block content %} |
|
18 | ||
19 |
<form method="post" enctype="multipart/form-data"> |
|
20 |
{% csrf_token %} |
|
21 |
{{ form.as_p }} |
|
22 |
<div class="buttons"> |
|
23 |
<button class="submit-button">{% trans "Save" %}</button> |
|
24 |
<a class="cancel" href="{% url 'maps-manager-layers-list' %}">{% trans 'Cancel' %}</a> |
|
25 |
{% if object.id %} |
|
26 |
<a class="delete" rel="popup" href="{% url 'maps-manager-layer-delete' pk=object.id %}">{% trans 'Delete' %}</a> |
|
27 |
{% endif %} |
|
28 |
</div> |
|
29 |
</form> |
|
30 |
{% endblock %} |
combo/apps/maps/templates/maps/maplayer_list.html | ||
---|---|---|
1 |
{% extends "maps/manager_base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block breadcrumb %} |
|
5 |
{{ block.super }} |
|
6 |
<a href="{% url 'maps-manager-homepage' %}">{% trans 'Layers' %}</a> |
|
7 |
{% endblock %} |
|
8 | ||
9 |
{% block appbar %} |
|
10 |
<h2>{% trans 'Layers' %}</h2> |
|
11 |
<a rel="popup" href="{% url 'maps-manager-layer-add' %}">{% trans 'New' %}</a> |
|
12 |
{% endblock %} |
|
13 | ||
14 |
{% block content %} |
|
15 | ||
16 |
{% if object_list %} |
|
17 |
<div class="objects-list"> |
|
18 |
{% for layer in object_list %} |
|
19 |
<div> |
|
20 |
<a href="{% url 'maps-manager-layer-edit' pk=layer.id %}">{{ layer.label }} |
|
21 |
</a> |
|
22 |
</div> |
|
23 |
{% endfor %} |
|
24 |
</div> |
|
25 |
{% else %} |
|
26 |
<div class="big-msg-info"> |
|
27 |
{% blocktrans %} |
|
28 |
This site doesn't have any layer yet. Click on the "New" button in the top |
|
29 |
right of the page to add a first one. |
|
30 |
{% endblocktrans %} |
|
31 |
</div> |
|
32 |
{% endif %} |
|
33 |
{% endblock %} |
combo/apps/maps/urls.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2017 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.conf.urls import url, include |
|
18 | ||
19 |
from combo.urls_utils import decorated_includes, manager_required |
|
20 | ||
21 |
from .manager_views import (ManagerHomeView, LayersManagerView, LayerAddView, |
|
22 |
LayerEditView, LayerDeleteView) |
|
23 | ||
24 |
maps_manager_urls = [ |
|
25 |
url('^$', ManagerHomeView.as_view(), name='maps-manager-homepage'), |
|
26 |
url('^layers/$', LayersManagerView.as_view(), name='maps-manager-layers-list'), |
|
27 |
url('^layers/add/$', LayerAddView.as_view(), name='maps-manager-layer-add'), |
|
28 |
url('^layers/(?P<pk>\w+)/edit$', LayerEditView.as_view(), |
|
29 |
name='maps-manager-layer-edit'), |
|
30 |
url('^layers/(?P<pk>\w+)/edit/$', LayerEditView.as_view(), |
|
31 |
name='maps-manager-layer-edit'), |
|
32 |
url('^layers/(?P<pk>\w+)/delete/$', LayerDeleteView.as_view(), |
|
33 |
name='maps-manager-layer-delete'), |
|
34 |
] |
|
35 | ||
36 |
urlpatterns = [ |
|
37 |
url(r'^manage/maps/', decorated_includes(manager_required, |
|
38 |
include(maps_manager_urls))), |
|
39 |
] |
combo/manager/static/css/combo.manager.css | ||
---|---|---|
301 | 301 |
font-size: 80%; |
302 | 302 |
opacity: 0.5; |
303 | 303 |
} |
304 | ||
305 |
/* colour picker styles */ |
|
306 | ||
307 |
#jquery-colour-picker { |
|
308 |
background: #fafafa; |
|
309 |
width: 250px; |
|
310 |
padding: 10px 5px; |
|
311 |
border-radius: 5px; |
|
312 |
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3); |
|
313 |
z-index: 2000; |
|
314 |
} |
|
315 | ||
316 |
#jquery-colour-picker ul { |
|
317 |
margin: 0; |
|
318 |
padding: 0; |
|
319 |
list-style-type: none; |
|
320 |
} |
|
321 | ||
322 |
#jquery-colour-picker li { |
|
323 |
float: left; |
|
324 |
margin: 0 5px 5px 0; |
|
325 |
} |
|
326 | ||
327 |
#jquery-colour-picker li a { |
|
328 |
display: block; |
|
329 |
width: 13px; |
|
330 |
height: 13px; |
|
331 |
text-decoration: none; |
|
332 |
text-indent: -10000px; |
|
333 |
outline: 0; |
|
334 |
border: 1px solid #aaa; |
|
335 |
} |
combo/manager/static/js/combo.manager.js | ||
---|---|---|
224 | 224 |
window.location = $(this).parent('div').find('option:selected').data('add-url'); |
225 | 225 |
return false; |
226 | 226 |
}); |
227 | ||
228 |
$(document).on('gadjo:dialog-loaded', function(e, dialog) { |
|
229 |
if (jQuery.fn.colourPicker !== undefined) { |
|
230 |
jQuery('select.colour-picker').colourPicker({title: ''}); |
|
231 |
} |
|
232 |
}); |
|
227 | 233 |
}); |
combo/manager/templates/combo/manager_base.html | ||
---|---|---|
30 | 30 |
<script src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script> |
31 | 31 |
<script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script> |
32 | 32 |
<script src="{% static "js/combo.manager.js" %}"></script> |
33 |
<script src="{% static "xstatic/jquery.colourpicker.js" %}"></script> |
|
33 | 34 |
{% endblock %} |
combo/settings.py | ||
---|---|---|
75 | 75 |
'combo.apps.notifications', |
76 | 76 |
'combo.apps.search', |
77 | 77 |
'combo.apps.usersearch', |
78 |
'combo.apps.maps', |
|
78 | 79 |
'haystack', |
79 | 80 |
'xstatic.pkg.chartnew_js', |
81 |
'xstatic.pkg.font_awesome', |
|
82 |
'xstatic.pkg.jquery_colourpicker', |
|
80 | 83 |
) |
81 | 84 | |
82 | 85 |
INSTALLED_APPS = plugins.register_plugins_apps(INSTALLED_APPS) |
debian/control | ||
---|---|---|
16 | 16 |
python-feedparser, |
17 | 17 |
python-django-cmsplugin-blurp, |
18 | 18 |
python-xstatic-chartnew-js, |
19 |
python-xstatic-font-awesome, |
|
20 |
python-xstatic-jquery-colourpicker, |
|
19 | 21 |
python-eopayment (>= 1.9), |
20 | 22 |
python-django-haystack (>= 2.4.0) |
21 | 23 |
Recommends: python-django-mellon, python-whoosh |
requirements.txt | ||
---|---|---|
6 | 6 |
django-jsonfield |
7 | 7 |
requests |
8 | 8 |
XStatic-ChartNew.js |
9 |
XStatic-Font-Awesome |
|
10 |
Xstatic-Jquery-Colourpicker |
|
9 | 11 |
eopayment>=1.13 |
10 | 12 |
python-dateutil |
11 | 13 |
djangorestframework>=3.3, <3.4 |
setup.py | ||
---|---|---|
111 | 111 |
'django-jsonfield', |
112 | 112 |
'requests', |
113 | 113 |
'XStatic-ChartNew.js', |
114 |
'XStatic-Font-Awesome', |
|
115 |
'XStatic-Jquery-Colourpicker', |
|
114 | 116 |
'eopayment>=1.13', |
115 | 117 |
'python-dateutil', |
116 | 118 |
'djangorestframework>=3.3, <3.4', |
tests/test_maps_manager.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | ||
3 |
import pytest |
|
4 |
import mock |
|
5 | ||
6 |
from django.contrib.auth.models import User |
|
7 | ||
8 |
from combo.apps.maps.models import MapLayer |
|
9 | ||
10 |
pytestmark = pytest.mark.django_db |
|
11 | ||
12 |
@pytest.fixture |
|
13 |
def admin_user(): |
|
14 |
try: |
|
15 |
user = User.objects.get(username='admin') |
|
16 |
except User.DoesNotExist: |
|
17 |
user = User.objects.create_superuser('admin', email=None, password='admin') |
|
18 |
return user |
|
19 | ||
20 |
def login(app, username='admin', password='admin'): |
|
21 |
login_page = app.get('/login/') |
|
22 |
login_form = login_page.forms[0] |
|
23 |
login_form['username'] = username |
|
24 |
login_form['password'] = password |
|
25 |
resp = login_form.submit() |
|
26 |
assert resp.status_int == 302 |
|
27 |
return app |
|
28 | ||
29 |
def test_access(app, admin_user): |
|
30 |
app = login(app) |
|
31 |
resp = app.get('/manage/', status=200) |
|
32 |
assert '/manage/maps/' in resp.body |
|
33 | ||
34 |
def test_add_layer(app, admin_user): |
|
35 |
MapLayer.objects.all().delete() |
|
36 |
app = login(app) |
|
37 |
resp = app.get('/manage/maps/layers/', status=200) |
|
38 |
resp = resp.click('New') |
|
39 |
assert 'xstatic/jquery.colourpicker.js' in resp.content |
|
40 |
resp.forms[0]['label'] = 'Test' |
|
41 |
resp.forms[0]['geojson_url'] = 'http://example.net/geojson' |
|
42 |
assert resp.form['marker_colour'].value == '0000FF' |
|
43 |
resp.forms[0]['marker_colour'] = 'FFFFFF' |
|
44 |
resp.forms[0]['icon'] = 'fa-bicycle' |
|
45 |
assert resp.form['icon_colour'].value == 'FFFFFF' |
|
46 |
resp.form['icon_colour'] = '000000' |
|
47 |
resp = resp.forms[0].submit() |
|
48 |
assert resp.location == 'http://testserver/manage/maps/layers/' |
|
49 |
assert MapLayer.objects.count() == 1 |
|
50 |
layer = MapLayer.objects.get() |
|
51 |
assert layer.label == 'Test' |
|
52 | ||
53 |
def test_edit_layer(app, admin_user): |
|
54 |
test_add_layer(app, admin_user) |
|
55 |
app = login(app) |
|
56 |
resp = app.get('/manage/maps/layers/', status=200) |
|
57 |
resp = resp.click('Test') |
|
58 |
resp.forms[0]['geojson_url'] = 'http://example.net/new_geojson' |
|
59 |
resp = resp.forms[0].submit() |
|
60 |
assert resp.location == 'http://testserver/manage/maps/layers/' |
|
61 |
assert MapLayer.objects.count() == 1 |
|
62 |
layer = MapLayer.objects.get() |
|
63 |
assert layer.geojson_url == 'http://example.net/new_geojson' |
|
64 | ||
65 |
def test_delete_layer(app, admin_user): |
|
66 |
test_add_layer(app, admin_user) |
|
67 |
app = login(app) |
|
68 |
resp = app.get('/manage/maps/layers/', status=200) |
|
69 |
resp = resp.click('Test') |
|
70 |
resp = resp.click('Delete') |
|
71 |
assert 'Are you sure you want to delete this?' in resp.body |
|
72 |
resp = resp.forms[0].submit() |
|
73 |
assert resp.location == 'http://testserver/manage/maps/layers/' |
|
74 |
assert MapLayer.objects.count() == 0 |
|
75 | ||
76 |
@mock.patch('combo.apps.maps.models.requests.get') |
|
77 |
def test_download_geojson(mock_request, app, admin_user): |
|
78 |
test_add_layer(app, admin_user) |
|
79 |
layer = MapLayer.objects.get() |
|
80 |
mocked_response = mock.Mock() |
|
81 |
mocked_response.json.return_value = [{'type': 'Feature', |
|
82 |
'geometry': {'type': 'Point', |
|
83 |
'coordinates': [2.3233688436448574, 48.83369263315934]}, |
|
84 |
'properties': {'property': 'property value'}}] |
|
85 |
mocked_response.ok.return_value = True |
|
86 |
mock_request.return_value = mocked_response |
|
87 |
geojson = layer.get_geojson() |
|
88 |
assert len(geojson) > 0 |
|
89 |
for item in geojson: |
|
90 |
assert item['type'] == 'Feature' |
|
91 |
assert item['geometry']['type'] == 'Point' |
|
92 |
assert item['geometry']['coordinates'] == [2.3233688436448574, 48.83369263315934] |
|
93 |
assert item['display_fields'] == {'property': 'property value'} |
|
94 |
assert item['properties']['icon'] == 'fa-bicycle' |
|
95 |
assert item['properties']['label'] == 'Test' |
|
96 |
assert item['properties']['colour'] == '#FFFFFF' |
|
97 |
assert item['properties']['icon_colour'] == '#000000' |
|
0 |
- |