Add Radeln ohne Alter ride-coordination demo (Django + HTMX + Leaflet)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
steffen1971 2026-06-20 21:20:17 +02:00
commit 5d967c68b5
40 changed files with 2040 additions and 0 deletions

0
rides/tests/__init__.py Normal file
View file

View file

@ -0,0 +1,53 @@
from django.contrib.auth.models import User
from django.test import TestCase
from django.utils import timezone
from rides.models import Fahrgast, Profile, Ride, RideStatus, Role
class RideLifecycleTests(TestCase):
def setUp(self):
self.pilot = User.objects.create_user("pilot")
Profile.objects.create(user=self.pilot, role=Role.PILOT)
self.fahrgast = Fahrgast.objects.create(name="Frau M.")
self.ride = Ride.objects.create(
fahrgast=self.fahrgast,
scheduled_at=timezone.now(),
pickup_label="A",
pickup_lat=49.25,
pickup_lng=6.96,
dest_label="B",
dest_lat=49.23,
dest_lng=6.99,
)
def test_claim_sets_pilot_and_status(self):
self.ride.claim(self.pilot)
self.assertEqual(self.ride.status, RideStatus.CLAIMED)
self.assertEqual(self.ride.assigned_pilot, self.pilot)
def test_cannot_finish_unclaimed_ride(self):
with self.assertRaises(ValueError):
self.ride.mark_done()
def test_claim_then_done(self):
self.ride.claim(self.pilot)
self.ride.mark_done()
self.assertEqual(self.ride.status, RideStatus.DONE)
def test_cannot_claim_done_ride(self):
self.ride.claim(self.pilot)
self.ride.mark_done()
with self.assertRaises(ValueError):
self.ride.claim(self.pilot)
def test_cannot_cancel_done_ride(self):
self.ride.claim(self.pilot)
self.ride.mark_done()
with self.assertRaises(ValueError):
self.ride.cancel()
def test_open_for_pilots_excludes_claimed(self):
self.assertIn(self.ride, Ride.objects.open_for_pilots())
self.ride.claim(self.pilot)
self.assertNotIn(self.ride, Ride.objects.open_for_pilots())

View file

@ -0,0 +1,65 @@
from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from rides.models import Fahrgast, Profile, Ride, RideStatus, Role
SECRET = "PFLEGEHINWEIS-GEHEIM-XYZ"
class VisibilityTests(TestCase):
def setUp(self):
self.pilot_a = User.objects.create_user("pilot_a", first_name="Anton")
self.pilot_b = User.objects.create_user("pilot_b", first_name="Berta")
Profile.objects.create(user=self.pilot_a, role=Role.PILOT)
Profile.objects.create(user=self.pilot_b, role=Role.PILOT)
self.fahrgast = Fahrgast.objects.create(name="Herr K.", mobility_notes=SECRET)
self.ride = Ride.objects.create(
fahrgast=self.fahrgast,
scheduled_at=timezone.now(),
assigned_pilot=self.pilot_a,
status=RideStatus.CLAIMED,
pickup_label="A",
pickup_lat=49.25,
pickup_lng=6.96,
dest_label="B",
dest_lat=49.23,
dest_lng=6.99,
)
def test_foreign_pilot_cannot_view_assigned_ride(self):
self.client.force_login(self.pilot_b)
resp = self.client.get(reverse("ride_detail", args=[self.ride.pk]))
self.assertEqual(resp.status_code, 403)
def test_foreign_pilot_never_sees_notes(self):
self.client.force_login(self.pilot_b)
resp = self.client.get(reverse("ride_detail", args=[self.ride.pk]))
self.assertNotContains(resp, SECRET, status_code=403)
def test_assigned_pilot_sees_notes(self):
self.client.force_login(self.pilot_a)
resp = self.client.get(reverse("ride_detail", args=[self.ride.pk]))
self.assertContains(resp, SECRET)
def test_open_ride_visible_to_any_pilot(self):
self.ride.assigned_pilot = None
self.ride.status = RideStatus.REQUESTED
self.ride.save()
self.client.force_login(self.pilot_b)
resp = self.client.get(reverse("ride_detail", args=[self.ride.pk]))
self.assertEqual(resp.status_code, 200)
def test_geojson_respects_visibility(self):
# Eine fremde, vergebene Fahrt darf NICHT in der Karten-API eines
# anderen Piloten auftauchen (HIGH-Finding aus dem Code-Review).
self.ride.pickup_label = "GEHEIM-ABHOLORT"
self.ride.save()
self.client.force_login(self.pilot_b)
resp = self.client.get(reverse("rides_geojson"))
self.assertNotContains(resp, "GEHEIM-ABHOLORT")
# die zugeteilte Pilot:in sieht sie sehr wohl
self.client.force_login(self.pilot_a)
resp = self.client.get(reverse("rides_geojson"))
self.assertContains(resp, "GEHEIM-ABHOLORT")