Compare commits

...

3 Commits

Author SHA1 Message Date
1a8da002cf Formatting 2020-09-13 20:39:32 +02:00
c828d04f05 Mixins for testing abstract model/partials in views 2020-09-13 20:27:05 +02:00
f919fe30fa Renaming map config 2020-09-13 20:15:49 +02:00
8 changed files with 203 additions and 47 deletions

View File

@ -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">

View File

@ -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}}])

View File

@ -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>

View File

@ -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">

View File

@ -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'
)

View File

@ -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'])

View File

@ -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:

View File

@ -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)
} }