from django.test import TestCase, Client from django.contrib.auth.models import User from django.contrib.gis.geos import Polygon, MultiPolygon from django.urls import reverse from django.utils import timezone from assets.models import ParkingLocation, ParkingSpot, AssetInspection, ParkingSpotInspection from common.models import Thematic, UserConfig, UserThematics class ParkingSpotAndInspectionTest(TestCase): def setUp(self): self.user = User.objects.create_user(username="inspector_user", password="password123") self.client = Client() # Create thematic and user thematic permissions self.thematic, _ = Thematic.objects.get_or_create( code="parking", defaults={ "name_fr": "Stationnement & Mobilité", "name_nl": "Parkeren & Mobiliteit" } ) self.user_config = UserConfig.objects.create(user=self.user) UserThematics.objects.create( user_config=self.user_config, thematic=self.thematic, can_view_assets=True ) self.client.force_login(self.user) poly = Polygon(((648000, 670000), (648010, 670000), (648010, 670010), (648000, 670010), (648000, 670000)), srid=3812) multi_poly = MultiPolygon(poly, srid=3812) self.parking_loc = ParkingLocation.objects.create( code="PARK-LOC-01", name_fr="Zone vélo Grand Place", geom=multi_poly ) self.spot = ParkingSpot.objects.create( code="SPOT-VELO-01", name_fr="Stationnement vélo Grand Place", location=self.parking_loc, spot_type="bicycle", standard_stand_count=3, cargo_stand_count=2, stand_type="mixed", has_scooter_drop_zone=True, scooter_capacity=10, geom=poly ) def test_parking_spot_creation_and_stand_counts(self): self.assertEqual(self.spot.standard_stand_count, 3) self.assertEqual(self.spot.cargo_stand_count, 2) self.assertEqual(self.spot.total_stand_count, 5) self.assertTrue(self.spot.has_scooter_drop_zone) self.assertTrue(self.spot.is_compliant) self.assertEqual(self.spot.inspection_status, "unknown") self.assertIsNotNone(self.spot.geojson) def test_parking_spot_inspection_updates_asset(self): inspection = ParkingSpotInspection.objects.create( asset=self.spot, inspector=self.user, inspection_date=timezone.now(), result_status="updated", verified_standard_stand_count=4, verified_cargo_stand_count=3, verified_has_scooter_drop_zone=True, verified_marking_quality="good", apply_changes_to_asset=True, notes="Ajout récent de 1 arceau classique et 1 arceau cargo" ) self.spot.refresh_from_db() self.assertEqual(self.spot.standard_stand_count, 4) self.assertEqual(self.spot.cargo_stand_count, 3) self.assertEqual(self.spot.total_stand_count, 7) self.assertEqual(self.spot.validation_status, "validated") self.assertEqual(self.spot.inspection_status, "updated") self.assertIsNotNone(self.spot.last_inspection_date) self.assertTrue(self.spot.is_compliant) def test_generic_asset_inspection_non_compliance(self): inspection = AssetInspection.objects.create( asset=self.spot, inspector=self.user, inspection_date=timezone.now(), result_status="non_compliant", notes="Arceau cargo tordu suite à un choc de livraison", apply_changes_to_asset=True ) self.spot.refresh_from_db() self.assertFalse(self.spot.is_compliant) self.assertEqual(self.spot.inspection_status, "non_compliant") self.assertEqual(self.spot.non_compliance_reason, "Arceau cargo tordu suite à un choc de livraison") def test_parking_assets_geojson_view(self): url = reverse('assets:parking_assets_geojson') response = self.client.get(url) self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data.get("type"), "FeatureCollection") features = data.get("features", []) self.assertEqual(len(features), 1) feat = features[0] self.assertEqual(feat["properties"]["code"], "SPOT-VELO-01") self.assertEqual(feat["properties"]["standard_stand_count"], 3) self.assertEqual(feat["properties"]["cargo_stand_count"], 2) self.assertEqual(feat["properties"]["total_stand_count"], 5) self.assertTrue(feat["properties"]["has_scooter_drop_zone"]) def test_parking_assets_autocomplete_view(self): url = reverse('assets:parking_autocomplete_assets') response = self.client.get(url, {'q': 'Grand Place'}) self.assertEqual(response.status_code, 200) data = response.json() results = data.get("results", []) self.assertEqual(len(results), 1) self.assertEqual(results[0]["code"], "SPOT-VELO-01") def test_parking_thematic_config(self): from assets.views.core import build_thematic_config config = build_thematic_config([self.thematic]) self.assertIn("parking", config) self.assertEqual(config["parking"]["assets_geojson_url"], reverse("assets:parking_assets_geojson")) self.assertEqual(config["parking"]["locations_geojson_url"], reverse("assets:parking_locations_geojson"))