class Meta:
model = Report
- fields = ["title", "description", "email", "category"]
+ fields = ["title", "description", "email", "category","latitude", "longitude"]
# Location
# NOTE: Latitude is between -90 and 90°, while Longitude is between -180 and 180°
# Therefore the latitude field is slightly smaller
+ # TODO: Restrict geocoordinates to the values above (or even smaller)
longitude = models.DecimalField(max_digits=9, decimal_places=6)
latitude = models.DecimalField(max_digits=8, decimal_places=6)
return str(self.title)
-# TODO: Location
-
# TODO: Image
getsubcats(this);
}
select.name = "category";
+ select.required = true;
// Create the new options
var option = document.createElement("option");
// Add change listener to the input-elements
lat_element.addEventListener("change", () => {
- marker.setLatLng([lat_element.value, lng_element.value])
- .addTo(map);
+ marker.setLatLng([lat_element.value, lng_element.value])
+ .addTo(map);
});
lng_element.addEventListener("change", () => {
- marker.setLatLng([lat_element.value, lng_element.value])
- .addTo(map);
+ marker.setLatLng([lat_element.value, lng_element.value])
+ .addTo(map);
});
* The precirsion is accorcding to https://en.wikipedia.org/wiki/Decimal_degrees
*/
function onMapClick(e, decimal_precision = 6) {
- marker.setLatLng(e.latlng).addTo(map);
+ marker.setLatLng(e.latlng).addTo(map);
- lat_element.value = e.latlng.lat.toFixed(decimal_precision);
- lng_element.value = e.latlng.lng.toFixed(decimal_precision);
+ lat_element.value = e.latlng.lat.toFixed(decimal_precision);
+ lng_element.value = e.latlng.lng.toFixed(decimal_precision);
}
+
+map.on("click", onMapClick);
</div>
<div class="detail">
<!-- TODO better URLS -->
-<a href="/georeport">Cancel</a>
+<a href="{% url 'georeport:index' %}">Cancel</a>
</div>
{% endblock %}
<p id="p-lng" data-lng="{{ report.longitude }}">Longitude: {{ report.longitude }}</p>
<p>Status: {{ report.get_state_display }} </p>
<p>Kategorie: {{ report.category }} </p>
- <a href="{% url 'index' %}">Back</a>
+ <a href="{% url 'georeport:index' %}">Back</a>
<script src="{% static 'georeport/addMarker.js' %}"></script>
<!-- <img src="{{report.image.url}}" alt="Kein Bild vorhanden" scale=0.25>-->
{% for img in report.images.all %}
<!-- List with published reports -->
{% for report in report_list %}
{% if report.published %}
- <li><a href="{{ report.id }}">{{ report.title }}</a></li>
+ <li><a href="{% url 'georeport:report' report.id%}">{{ report.title }}</a></li>
<script>
let marker{{report.id}} = L.marker([{{report.latitude}},{{report.longitude}}]);
marker{{report.id}}.addTo(map);
<h2>Categories</h2>
<ul>
{% for category in category_list %}
- <li><a href="category/{{ category.id }}">{{ category.name }}</a></li>
+ <li><a href="{% url 'georeport:category' category.id %}">{{ category.name }}</a></li>
{% endfor %}
</ul>
</div>
--- /dev/null
+from django import template
+
+register = template.Library()
+
+
+def key(value, arg):
+ return value[arg]
+
+
+register.filter("key", key)
class ReportTestCase(TestCase):
- def setUp(self):
- Category.objects.create(name="Cat1") # type:ignore Attribute object is unknown
- Report.objects.create( # type:ignore Attribute object is unknown
- title="Test",
- email="test@test.de",
- category=Category.objects.first(), # type:ignore Attribute object is unknown
- latitude=0,
- longitude=0,
- )
-
- def test_unpulished_as_default(self):
- report = Report.objects.get(title="Test") # type:ignore Attribute object is unknown
- self.assertEqual(report.published, False)
+ @classmethod
+ def setUpTestData(cls):
+ cls.cat = Category.objects.create(name="Cat1") # type:ignore Attribute object is unknown
+ def test_create_report_get(self):
+ """
+ Test the create report view if get is called
+ """
+ url = reverse("georeport:create")
+ response = self.client.get(url)
-# TODO: Test latlng
+ # Test create view
+ self.assertEqual(response.status_code, 200) # type:ignore Attribute status_code unknown
+ self.assertTemplateUsed(response, "georeport/create.html")
+ # Check if category is in context of request
+ self.assertIn(self.cat.id, response.context) # type:ignore
+ def test_create_report_post(self):
+ """
+ Test create_report_view with a post call
+ """
+ # Testcase setup
+ post_data = {
+ "title": "Test",
+ "description": "description",
+ "category": self.cat.id,
+ "email": "test@example.de",
+ "longitude": 8.741698,
+ "latitude": 51.715841,
+ }
+ url = reverse("georeport:create")
+ response = self.client.post(url, post_data)
+
+ # check response
+ self.assertEqual(response.status_code, 302) # type: ignore
+ self.assertEqual(response.url, reverse("georeport:index")) # type:ignore
+
+ report = Report.objects.get(pk=1, title=post_data["title"]) # type: ignore
+ self.assertEqual(report.description, post_data["description"])
+ self.assertEqual(report.category.id, post_data["category"])
+ self.assertEqual(report.email, post_data["email"])
+ self.assertEqual(float(report.latitude), float(post_data["latitude"]))
+ self.assertEqual(float(report.longitude), float(post_data["longitude"]))
+ self.assertFalse(report.published)
+ self.assertEqual(report.state, 0)
+
+ def test_detail_view(self):
+ self.assertTrue(True)
+ url = reverse("georeport:report", kwargs={"id": 1})
+ # Test report not existsing
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 404) # type:ignore
+ report = Report.objects.create( # type:ignore
+ title="Test",
+ category=self.cat,
+ email="test@pinpoint.de",
+ longitude=8.741698,
+ latitude=51.715841,
+ )
+ # Test unpulished report
+ self.assertFalse(report.published)
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 403) # type:ignore
-# TODO: Test get_categories
+ report.published = True
+ report.save()
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200) # type: ignore
+ self.assertContains(response, f"Title: {report.title}", status_code=200)
+ self.assertTemplateUsed(response, "georeport/detail.html")
+ # TODO: test if response contains title
-class CategoryViewTests(TestCase):
+class GetCategoryViewTests(TestCase):
@classmethod
def setUpTestData(cls):
"""
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, HttpResponseForbidden, JsonResponse
-from django.shortcuts import get_object_or_404, render
+from django.shortcuts import get_object_or_404, render, redirect
from django.views.decorators.http import require_GET, require_safe, require_http_methods
-
from .models import Category, Report
from .forms import ReportForm
return JsonResponse(data)
-# TODO: Category-Detail
-
-
@require_safe
def category_detail_view(request, id) -> HttpResponse:
"""
if user in group.user_set.all():
allowed = True
+ # If User is allowd to view the category provice it, otherwise rise 403- PermissionDenied
if allowed:
return render(request, "georeport/category.html", context={"categroy": cat})
# TODO: Report-List
-# TODO: Create-Report
@require_http_methods(["GET", "POST"])
report["description"] = post["description"]
report["category"] = post["category"]
report["email"] = post["email"]
-
- reportform = ReportForm(report)
-
- # TODO: Location
+ report["longitude"] = post["longitude"]
+ report["latitude"] = post["latitude"]
+ reportForm = ReportForm(report)
+ # TODO: Check if category is a leaf
+ # NOTE: Currently not implemented, since it is assumed, that
+ # reports are created with the website, and there every category-selection is required
+ if reportForm.is_valid():
+ reportForm.save()
+
+ # TODO: Send confirmation-Mails
+ return redirect("georeport:index")
return render(
request,
"""
Returns the detail-view page of a single report
"""
- report = get_object_or_404(Report, pd=id)
+ report = get_object_or_404(Report, pk=id)
if report.published:
return render(request, "georeport/detail.html", context={"report": report})
+ raise PermissionDenied
+
# TODO: Finish Link