Compare commits
3 Commits
b3db6643b9
...
1a8da002cf
Author | SHA1 | Date | |
---|---|---|---|
1a8da002cf | |||
c828d04f05 | |||
f919fe30fa |
@ -14,7 +14,7 @@
|
|||||||
<article class="LP-TextSection">
|
<article class="LP-TextSection">
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
{% include 'partials/osm_map.html' with config=map_config %}
|
{% include 'partials/osm_map.html' with config=mapping_config %}
|
||||||
<div class="LP-PlaceGrid">
|
<div class="LP-PlaceGrid">
|
||||||
<h1 class="LP-Headline LP-Headline">Explore the latest locations</h1>
|
<h1 class="LP-Headline LP-Headline">Explore the latest locations</h1>
|
||||||
<ul class="LP-PlaceGrid__Grid">
|
<ul class="LP-PlaceGrid__Grid">
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
var vectorSource = new ol.source.Vector({
|
var vectorSource = new ol.source.Vector({
|
||||||
features: [
|
features: [
|
||||||
{% for point in config.point_list %}
|
{% for point in config.all_points %}
|
||||||
new ol.Feature({
|
new ol.Feature({
|
||||||
geometry: new ol.geom.Point(
|
geometry: new ol.geom.Point(
|
||||||
ol.proj.fromLonLat([{{point.longitude}},{{point.latitude}}])
|
ol.proj.fromLonLat([{{point.longitude}},{{point.latitude}}])
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
<section class="LP-Section">
|
<section class="LP-Section">
|
||||||
<h1 class="LP-Headline">Map-Links</h1>
|
<h1 class="LP-Headline">Map-Links</h1>
|
||||||
{% include 'partials/osm_map.html' with config=map_config%}
|
{% include 'partials/osm_map.html' with config=mapping_config%}
|
||||||
<div class="LP-LinkList">
|
<div class="LP-LinkList">
|
||||||
<ul class="LP-LinkList__Container">
|
<ul class="LP-LinkList__Container">
|
||||||
<li class="LP-LinkList__Item"><a target="_blank" href="https://www.google.com/maps?q={{place.latitude}},{{place.longitude}}" class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
|
<li class="LP-LinkList__Item"><a target="_blank" href="https://www.google.com/maps?q={{place.latitude}},{{place.longitude}}" class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
|
|
||||||
{% include 'partials/osm_map.html' with config=map_config %}
|
{% include 'partials/osm_map.html' with config=mapping_config %}
|
||||||
<div class="LP-PlaceList">
|
<div class="LP-PlaceList">
|
||||||
<h1 class="LP-Headline">Listing our places</h1>
|
<h1 class="LP-Headline">Listing our places</h1>
|
||||||
<ul class="LP-PlaceList__List">
|
<ul class="LP-PlaceList__List">
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from lostplaces_app.models import Taggable, MapablePoint
|
||||||
|
|
||||||
|
from taggit.models import Tag
|
||||||
|
|
||||||
class ViewTestCase(TestCase):
|
class ViewTestCase(TestCase):
|
||||||
'''
|
'''
|
||||||
This is a mixni for testing views. It provides functionality to
|
This is a mixni for testing views. It provides functionality to
|
||||||
@ -105,4 +109,116 @@ class ViewTestCase(TestCase):
|
|||||||
self.assertHttpCode(response, 404)
|
self.assertHttpCode(response, 404)
|
||||||
|
|
||||||
def assertHttpMethodNotAllowed(self, response):
|
def assertHttpMethodNotAllowed(self, response):
|
||||||
self.assertHttpCode(response, 405)
|
self.assertHttpCode(response, 405)
|
||||||
|
|
||||||
|
class TaggableViewTestCaseMixin:
|
||||||
|
|
||||||
|
def assertTaggableContext(self, context):
|
||||||
|
self.assertTrue(
|
||||||
|
'all_tags' in context,
|
||||||
|
msg='Expecting the context for taggable to contain an \'all_tags\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
for tag in context['all_tags']:
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(tag, Tag),
|
||||||
|
msg='Expecting all entries to be an instance of %s, got %s' % (
|
||||||
|
str(Tag),
|
||||||
|
str(type(tag))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'submit_form' in context,
|
||||||
|
msg='Expecting the context for taggable to contain \'submit_form\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'tagged_item' in context,
|
||||||
|
msg='Expecting the context for taggable to contain \'tagged_item\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(context['tagged_item'], Taggable),
|
||||||
|
msg='Expecting the tagged_item to be an instance of %s' % (
|
||||||
|
str(Taggable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'submit_url_name' in context,
|
||||||
|
msg='Expecting the context for taggable to contain \'submit_url_name\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
type(context['submit_url_name']) == str,
|
||||||
|
msg='Expecting submit_url_name to be of type string'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'delete_url_name' in context,
|
||||||
|
msg='Expecting the context for taggable to contain \'delete_url_name\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
type(context['delete_url_name']) == str,
|
||||||
|
msg='Expecting delete_url_name to be of type string'
|
||||||
|
)
|
||||||
|
|
||||||
|
class MapablePointViewTestCaseMixin:
|
||||||
|
|
||||||
|
def assertMapablePointContext(self, context):
|
||||||
|
self.assertTrue(
|
||||||
|
'all_points' in context,
|
||||||
|
msg='Expecting the context for mapable point to contain \'all_points\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
for point in context['all_points']:
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(point, MapablePoint),
|
||||||
|
msg='Expecting all entries to be an instance of %s, got %s' % (
|
||||||
|
str(MapablePoint),
|
||||||
|
str(type(point))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'map_center' in context,
|
||||||
|
msg='Expecting the context for mapable point to contain \'map_center\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'latitude' in context['map_center'],
|
||||||
|
msg='Expecting the map center to contain an \'latitude\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(context['map_center']['latitude'], float) or isinstance(context['map_center']['latitude'], int),
|
||||||
|
msg='Expecting the latitude of the map center to be numeric, type %s given' % (
|
||||||
|
str(type(context['map_center']['latitude']))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
-90 <= context['map_center']['latitude'] <= 90,
|
||||||
|
msg='Expecting the latitude of map center to be in the range of -90 and 90'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'longitude' in context['map_center'],
|
||||||
|
msg='Expecting the map center to contain an \'longitude\' attribute'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(context['map_center']['longitude'], float) or isinstance(context['map_center']['longitude'], int),
|
||||||
|
msg='Expecting the longitude of the map center to be numeric, type %s given' % (
|
||||||
|
str(type(context['map_center']['longitude']))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
-180 <= context['map_center']['longitude'] <= 180,
|
||||||
|
msg='Expecting the longitude of map center to be in the range of -180 and 180'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
@ -1,27 +1,33 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from lostplaces_app.models import Place
|
from lostplaces_app.models import Place
|
||||||
from lostplaces_app.views import (
|
from lostplaces_app.views import (
|
||||||
PlaceCreateView,
|
PlaceCreateView,
|
||||||
PlaceListView
|
PlaceListView,
|
||||||
|
PlaceDetailView
|
||||||
)
|
)
|
||||||
from lostplaces_app.forms import PlaceImageCreateForm, PlaceForm
|
from lostplaces_app.forms import PlaceImageCreateForm, PlaceForm
|
||||||
from lostplaces_app.tests.views import ViewTestCase
|
from lostplaces_app.tests.views import (
|
||||||
|
ViewTestCase,
|
||||||
|
TaggableViewTestCaseMixin,
|
||||||
|
MapablePointViewTestCaseMixin
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestPlaceCreateView(ViewTestCase):
|
class TestPlaceCreateView(ViewTestCase):
|
||||||
view = PlaceCreateView
|
view = PlaceCreateView
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
user = User.objects.create_user(
|
user = User.objects.create_user(
|
||||||
username='testpeter',
|
username='testpeter',
|
||||||
password='Develop123'
|
password='Develop123'
|
||||||
)
|
)
|
||||||
|
|
||||||
place = Place.objects.create(
|
place = Place.objects.create(
|
||||||
name='Im a place',
|
name='Im a place',
|
||||||
submitted_when=datetime.datetime.now(),
|
submitted_when=datetime.datetime.now(),
|
||||||
@ -33,27 +39,28 @@ class TestPlaceCreateView(ViewTestCase):
|
|||||||
)
|
)
|
||||||
place.tags.add('I a tag', 'testlocation')
|
place.tags.add('I a tag', 'testlocation')
|
||||||
place.save()
|
place.save()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
|
||||||
def test_has_forms(self):
|
def test_has_forms(self):
|
||||||
self.client.login(username='testpeter', password='Develop123')
|
self.client.login(username='testpeter', password='Develop123')
|
||||||
response = self.client.get(reverse_lazy('place_create'))
|
response = self.client.get(reverse('place_create'))
|
||||||
|
|
||||||
self.assertHasForm(response, 'place_image_form', PlaceImageCreateForm)
|
self.assertHasForm(response, 'place_image_form', PlaceImageCreateForm)
|
||||||
self.assertHasForm(response, 'place_form', PlaceForm)
|
self.assertHasForm(response, 'place_form', PlaceForm)
|
||||||
|
|
||||||
|
|
||||||
class TestPlaceListView(ViewTestCase):
|
class TestPlaceListView(ViewTestCase):
|
||||||
view = PlaceListView
|
view = PlaceListView
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
user = User.objects.create_user(
|
user = User.objects.create_user(
|
||||||
username='testpeter',
|
username='testpeter',
|
||||||
password='Develop123'
|
password='Develop123'
|
||||||
)
|
)
|
||||||
|
|
||||||
place = Place.objects.create(
|
place = Place.objects.create(
|
||||||
name='Im a place',
|
name='Im a place',
|
||||||
submitted_when=datetime.datetime.now(),
|
submitted_when=datetime.datetime.now(),
|
||||||
@ -65,18 +72,55 @@ class TestPlaceListView(ViewTestCase):
|
|||||||
)
|
)
|
||||||
place.tags.add('I a tag', 'testlocation')
|
place.tags.add('I a tag', 'testlocation')
|
||||||
place.save()
|
place.save()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
|
||||||
def test_list_view(self):
|
def test_list_view(self):
|
||||||
self.client.login(username='testpeter', password='Develop123')
|
self.client.login(username='testpeter', password='Develop123')
|
||||||
response = self.client.get(reverse_lazy('place_list'))
|
response = self.client.get(reverse('place_list'))
|
||||||
|
|
||||||
self.assertContext(response, 'map_config')
|
self.assertContext(response, 'mapping_config')
|
||||||
|
|
||||||
def test_test(self):
|
|
||||||
response = self.client.get(reverse_lazy('place_list'))
|
class PlaceDetailViewTestCase(TaggableViewTestCaseMixin, MapablePointViewTestCaseMixin, ViewTestCase):
|
||||||
print(response['location'])
|
view = PlaceDetailView
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
user = User.objects.create_user(
|
||||||
|
username='testpeter',
|
||||||
|
password='Develop123'
|
||||||
|
)
|
||||||
|
|
||||||
|
place = Place.objects.create(
|
||||||
|
name='Im a place',
|
||||||
|
submitted_when=datetime.datetime.now(),
|
||||||
|
submitted_by=user.explorer,
|
||||||
|
location='Testtown',
|
||||||
|
latitude=50.5,
|
||||||
|
longitude=7.0,
|
||||||
|
description='This is just a test, do not worry'
|
||||||
|
)
|
||||||
|
place.tags.add('I a tag', 'testlocation')
|
||||||
|
place.save()
|
||||||
|
|
||||||
|
def test_context(self):
|
||||||
|
self.client.login(username='testpeter', password='Develop123')
|
||||||
|
response = self.client.get(reverse('place_detail', kwargs={'pk': 1}))
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'tagging_config' in response.context,
|
||||||
|
msg='Expecting the context of %s to have an \'tagging_config\'' % (
|
||||||
|
str(self.view)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertTaggableContext(response.context['tagging_config'])
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
'mapping_config' in response.context,
|
||||||
|
msg='Expecting the context of %s to have an \'mapping_config\'' % (
|
||||||
|
str(self.view)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertMapablePointContext(response.context['mapping_config'])
|
||||||
|
@ -23,8 +23,8 @@ class PlaceListView(IsAuthenticatedMixin, ListView):
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['map_config'] = {
|
context['mapping_config'] = {
|
||||||
'point_list': context['place_list'],
|
'all_points': context['place_list'],
|
||||||
'map_center': Place.average_latlon(context['place_list'])
|
'map_center': Place.average_latlon(context['place_list'])
|
||||||
}
|
}
|
||||||
return context
|
return context
|
||||||
@ -34,8 +34,8 @@ class PlaceDetailView(IsAuthenticatedMixin, View):
|
|||||||
place = Place.objects.get(pk=pk)
|
place = Place.objects.get(pk=pk)
|
||||||
context = {
|
context = {
|
||||||
'place': place,
|
'place': place,
|
||||||
'map_config': {
|
'mapping_config': {
|
||||||
'point_list': [ place ],
|
'all_points': [ place ],
|
||||||
'map_center': {'latitude': place.latitude, 'longitude': place.longitude},
|
'map_center': {'latitude': place.latitude, 'longitude': place.longitude},
|
||||||
},
|
},
|
||||||
'tagging_config': {
|
'tagging_config': {
|
||||||
@ -90,23 +90,19 @@ class PlaceCreateView(IsAuthenticatedMixin, View):
|
|||||||
submitter=submitter
|
submitter=submitter
|
||||||
)
|
)
|
||||||
|
|
||||||
kwargs_to_pass = {
|
|
||||||
'pk': place.pk
|
|
||||||
}
|
|
||||||
|
|
||||||
messages.success(
|
messages.success(
|
||||||
self.request, 'Successfully created place.')
|
self.request,
|
||||||
return redirect(reverse_lazy('place_detail', kwargs=kwargs_to_pass))
|
'Successfully created place.'
|
||||||
|
)
|
||||||
|
return redirect(reverse_lazy('place_detail', kwargs={'pk': place.pk}))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
context = {
|
|
||||||
'form': form_place
|
|
||||||
}
|
|
||||||
|
|
||||||
# Usually the browser should have checked the form before sending.
|
# Usually the browser should have checked the form before sending.
|
||||||
messages.error(
|
messages.error(
|
||||||
self.request, 'Please fill in all required fields.')
|
self.request,
|
||||||
return render(request, 'place/place_create.html', context)
|
'Please fill in all required fields.'
|
||||||
|
)
|
||||||
|
return render(request, 'place/place_create.html', context={'form': form_place})
|
||||||
|
|
||||||
def _apply_multipart_image_upload(self, files, place, submitter):
|
def _apply_multipart_image_upload(self, files, place, submitter):
|
||||||
for image in files:
|
for image in files:
|
||||||
|
@ -28,8 +28,8 @@ class HomeView(IsAuthenticatedMixin, View):
|
|||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
place_list = Place.objects.all().order_by('-submitted_when')[:10]
|
place_list = Place.objects.all().order_by('-submitted_when')[:10]
|
||||||
context = {
|
context = {
|
||||||
'place_list': place_list,
|
'all_points': place_list,
|
||||||
'map_config': {
|
'mapping_config': {
|
||||||
'point_list': place_list,
|
'point_list': place_list,
|
||||||
'map_center': Place.average_latlon(place_list)
|
'map_center': Place.average_latlon(place_list)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user