44from rest_framework .test import APIClient
55
66from trails .models import POI , Trail
7+ from transit .models import Stop
78from tenancy .services import get_or_create_default_island
89
910
@@ -24,6 +25,14 @@ def setUp(self):
2425 name = 'Alpha Trail' ,
2526 difficulty = 'easy' ,
2627 distance_km = 3.2 ,
28+ shape = 'circular' ,
29+ duration_min = 90 ,
30+ description_en = 'Alpha EN' ,
31+ description_pt = 'Alpha PT' ,
32+ gpx_url = 'https://example.test/a.gpx' ,
33+ start_lat = 37.78 ,
34+ start_lon = - 25.50 ,
35+ waypoints = [{'name' : 'Start' , 'lat' : 37.78 , 'lng' : - 25.50 }],
2736 geojson = {'type' : 'LineString' , 'coordinates' : [[- 25.5 , 37.78 ], [- 25.49 , 37.79 ]]},
2837 )
2938 self .trail_b = Trail .objects .create (
@@ -32,6 +41,8 @@ def setUp(self):
3241 name = 'Beta Trail' ,
3342 difficulty = 'hard' ,
3443 distance_km = 8.0 ,
44+ shape = 'linear' ,
45+ duration_min = 240 ,
3546 geojson = {'type' : 'LineString' , 'coordinates' : [[- 25.51 , 37.77 ], [- 25.48 , 37.80 ]]},
3647 )
3748 self .poi = POI .objects .create (
@@ -42,6 +53,13 @@ def setUp(self):
4253 latitude = 37.78 ,
4354 longitude = - 25.50 ,
4455 )
56+ Stop .objects .create (
57+ island = self .island ,
58+ name = 'Ponta Delgada' ,
59+ cleaned_name = 'ponta delgada' ,
60+ latitude = 37.781 ,
61+ longitude = - 25.501 ,
62+ )
4563
4664 def test_list_trails_ordered_by_name (self ):
4765 response = self .client .get ('/api/v3/trails/' , ** self .headers )
@@ -60,13 +78,38 @@ def test_list_trails_difficulty_filter(self):
6078 self .assertEqual (len (trails ), 1 )
6179 self .assertEqual (trails [0 ]['id' ], self .trail_b .id )
6280
63- def test_detail_includes_geojson (self ):
81+ def test_list_trails_shape_and_length_filters (self ):
82+ response = self .client .get ('/api/v3/trails/?shape=circular&max_length=5' , ** self .headers )
83+ self .assertEqual (response .status_code , 200 )
84+ trails = response .json ()['trails' ]
85+ self .assertEqual (len (trails ), 1 )
86+ self .assertEqual (trails [0 ]['id' ], self .trail_a .id )
87+ self .assertEqual (trails [0 ]['shape' ], 'circular' )
88+ self .assertEqual (trails [0 ]['durationMin' ], 90 )
89+
90+ def test_list_trails_invalid_length_returns_400 (self ):
91+ response = self .client .get ('/api/v3/trails/?min_length=abc' , ** self .headers )
92+ self .assertEqual (response .status_code , 400 )
93+
94+ def test_detail_includes_enriched_fields (self ):
6495 response = self .client .get (f'/api/v3/trails/{ self .trail_a .id } ' , ** self .headers )
6596 self .assertEqual (response .status_code , 200 )
6697 body = response .json ()
6798 self .assertEqual (body ['geojson' ]['type' ], 'LineString' )
6899 self .assertEqual (body ['stages' ], [])
69100 self .assertIn ('attribution' , body )
101+ self .assertEqual (body ['descriptionEn' ], 'Alpha EN' )
102+ self .assertEqual (body ['descriptionPt' ], 'Alpha PT' )
103+ self .assertEqual (body ['gpxUrl' ], 'https://example.test/a.gpx' )
104+ self .assertEqual (body ['startLat' ], 37.78 )
105+ self .assertEqual (len (body ['waypoints' ]), 1 )
106+ self .assertEqual (body ['nearestStop' ]['name' ], 'Ponta Delgada' )
107+
108+ def test_detail_includes_geojson (self ):
109+ response = self .client .get (f'/api/v3/trails/{ self .trail_a .id } ' , ** self .headers )
110+ self .assertEqual (response .status_code , 200 )
111+ body = response .json ()
112+ self .assertEqual (body ['geojson' ]['type' ], 'LineString' )
70113
71114 def test_detail_not_found (self ):
72115 response = self .client .get ('/api/v3/trails/99999' , ** self .headers )
0 commit comments