Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions traffic_control/admin/traffic_sign.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class TrafficSignPlanAdmin(
"value",
"txt",
"source_id",
"source_name",
)
},
),
Expand Down
20 changes: 20 additions & 0 deletions traffic_control/migrations/0090_alter_additionalsignplan_parent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.2.20 on 2025-04-07 10:45

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('traffic_control', '0089_parkingzoneupdateinfo'),
]

operations = [
migrations.AlterField(
model_name='additionalsignplan',
name='parent',
field=models.ForeignKey(default=1, help_text='The traffic sign to which this additional sign is associated.', on_delete=django.db.models.deletion.PROTECT, related_name='additional_signs', to='traffic_control.trafficsignplan', verbose_name='Parent Traffic Sign Plan'),
preserve_default=False,
),
]
4 changes: 2 additions & 2 deletions traffic_control/models/additional_sign.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ class AdditionalSignPlan(UpdatePlanLocationMixin, ReplaceableDevicePlanMixin, Ab
verbose_name=_("Parent Traffic Sign Plan"),
on_delete=models.PROTECT,
related_name="additional_signs",
blank=True,
null=True,
blank=False,
null=False,
help_text=_("The traffic sign to which this additional sign is associated."),
)
mount_plan = models.ForeignKey(
Expand Down
7 changes: 3 additions & 4 deletions traffic_control/static/traffic_control/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14587,7 +14587,6 @@ components:
parent:
type: string
format: uuid
nullable: true
title: Parent Traffic Sign Plan
description: The traffic sign to which this additional sign is associated.
mount_plan:
Expand All @@ -14606,6 +14605,7 @@ components:
- id
- location
- owner
- parent
- updated_at
- updated_by
AdditionalSignPlanInputRequest:
Expand Down Expand Up @@ -14855,7 +14855,6 @@ components:
parent:
type: string
format: uuid
nullable: true
title: Parent Traffic Sign Plan
description: The traffic sign to which this additional sign is associated.
mount_plan:
Expand All @@ -14871,6 +14870,7 @@ components:
required:
- location
- owner
- parent
AdditionalSignPlanOutput:
type: object
properties:
Expand Down Expand Up @@ -15151,7 +15151,6 @@ components:
parent:
type: string
format: uuid
nullable: true
title: Parent Traffic Sign Plan
description: The traffic sign to which this additional sign is associated.
mount_plan:
Expand All @@ -15171,6 +15170,7 @@ components:
- is_replaced
- location
- owner
- parent
- replaced_by
- replaces
- updated_at
Expand Down Expand Up @@ -21271,7 +21271,6 @@ components:
parent:
type: string
format: uuid
nullable: true
title: Parent Traffic Sign Plan
description: The traffic sign to which this additional sign is associated.
mount_plan:
Expand Down
22 changes: 21 additions & 1 deletion traffic_control/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ def get_barrier_plan(
device_type=None,
responsible_entity=None,
replaces=None,
**kwargs,
) -> BarrierPlan:
user = get_user("test_user")
barrier_plan = BarrierPlan.objects.get_or_create(
Expand All @@ -173,6 +174,7 @@ def get_barrier_plan(
responsible_entity=responsible_entity,
created_by=user,
updated_by=user,
**kwargs,
)[0]

if replaces:
Expand Down Expand Up @@ -269,7 +271,7 @@ class Meta:
mount_type = factory.SubFactory(MountTypeFactory)


def get_mount_plan(location="", plan=None, responsible_entity=None, replaces=None) -> MountPlan:
def get_mount_plan(location="", plan=None, responsible_entity=None, replaces=None, **kwargs) -> MountPlan:
user = get_user("test_user")

mount_plan = MountPlan.objects.get_or_create(
Expand All @@ -281,6 +283,7 @@ def get_mount_plan(location="", plan=None, responsible_entity=None, replaces=Non
responsible_entity=responsible_entity,
created_by=user,
updated_by=user,
**kwargs,
)[0]

if replaces:
Expand Down Expand Up @@ -354,6 +357,7 @@ def get_road_marking_plan(
traffic_sign_plan=None,
responsible_entity=None,
replaces=None,
**kwargs,
) -> RoadMarkingPlan:
user = get_user("test_user")

Expand All @@ -373,6 +377,7 @@ def get_road_marking_plan(
traffic_sign_plan=traffic_sign_plan,
created_by=user,
updated_by=user,
**kwargs,
)[0]

if replaces:
Expand Down Expand Up @@ -442,6 +447,7 @@ def get_signpost_plan(
txt=None,
responsible_entity=None,
replaces=None,
**kwargs,
) -> SignpostPlan:
user = get_user("test_user")

Expand All @@ -457,6 +463,7 @@ def get_signpost_plan(
txt=txt,
created_by=user,
updated_by=user,
**kwargs,
)[0]

if replaces:
Expand Down Expand Up @@ -525,6 +532,7 @@ def get_traffic_light_plan(
mount_plan=None,
responsible_entity=None,
replaces=None,
**kwargs,
) -> TrafficLightPlan:
user = get_user("test_user")

Expand All @@ -542,6 +550,7 @@ def get_traffic_light_plan(
responsible_entity=responsible_entity,
created_by=user,
updated_by=user,
**kwargs,
)[0]

if replaces:
Expand Down Expand Up @@ -638,6 +647,7 @@ def get_traffic_sign_plan(
mount_plan=None,
responsible_entity=None,
replaces=None,
**kwargs,
) -> TrafficSignPlan:
user = get_user("test_user")

Expand All @@ -651,6 +661,7 @@ def get_traffic_sign_plan(
mount_plan=mount_plan,
created_by=user,
updated_by=user,
**kwargs,
)[0]
if replaces:
traffic_sign_plan_replace(old=replaces, new=traffic_sign_plan)
Expand Down Expand Up @@ -735,6 +746,15 @@ class Meta:
parent = factory.SubFactory(TrafficSignPlanFactory)


def get_additional_sign_plan_and_replace(**kwargs):
replaces = kwargs.pop("replaces", None)
asp = AdditionalSignPlanFactory(**kwargs)
asp.refresh_from_db()
if replaces:
additional_sign_plan_replace(old=replaces, new=asp)
return asp


def get_additional_sign_plan(
location=test_point_3d,
device_type=None,
Expand Down
20 changes: 10 additions & 10 deletions traffic_control/tests/models/test_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from city_furniture.tests.factories import get_furniture_signpost_plan
from traffic_control.tests.factories import (
get_additional_sign_plan,
AdditionalSignPlanFactory,
get_barrier_plan,
get_mount_plan,
get_plan,
Expand Down Expand Up @@ -46,8 +46,8 @@ def test__plan__get_related_locations():
tlp_2 = get_traffic_light_plan(location=Point(MIN_X + 90.0, MIN_Y + 115.0, 0, srid=settings.SRID), plan=plan)
tsp_1 = get_traffic_sign_plan(location=Point(MIN_X + 55.0, MIN_Y + 5.0, 0.0, srid=settings.SRID), plan=plan)
tsp_2 = get_traffic_sign_plan(location=Point(MIN_X + 95.0, MIN_Y + 110.0, 0.0, srid=settings.SRID), plan=plan)
asp_1 = get_additional_sign_plan(location=Point(MIN_X + 80.0, MIN_Y + 120.0, 0.0, srid=settings.SRID), plan=plan)
asp_2 = get_additional_sign_plan(
asp_1 = AdditionalSignPlanFactory(location=Point(MIN_X + 80.0, MIN_Y + 120.0, 0.0, srid=settings.SRID), plan=plan)
asp_2 = AdditionalSignPlanFactory(
location=Point(MIN_X + 85.0, MIN_Y + 125.0, 0.0, srid=settings.SRID), parent=tsp_2, plan=plan
)
fsp_1 = get_furniture_signpost_plan(
Expand Down Expand Up @@ -101,8 +101,8 @@ def test__plan__derive_location_from_related_plans():
tlp_2 = get_traffic_light_plan(location=Point(MIN_X + 90.0, MIN_Y + 115.0, 0.0, srid=settings.SRID), plan=plan)
tsp_1 = get_traffic_sign_plan(location=Point(MIN_X + 55.0, MIN_Y + 6.0, 0.0, srid=settings.SRID), plan=plan)
tsp_2 = get_traffic_sign_plan(location=Point(MIN_X + 95.0, MIN_Y + 110.0, 0.0, srid=settings.SRID), plan=plan)
asp_1 = get_additional_sign_plan(location=Point(MIN_X + 80.0, MIN_Y + 120.0, 1.0, srid=settings.SRID), plan=plan)
asp_2 = get_additional_sign_plan(
asp_1 = AdditionalSignPlanFactory(location=Point(MIN_X + 80.0, MIN_Y + 120.0, 1.0, srid=settings.SRID), plan=plan)
asp_2 = AdditionalSignPlanFactory(
location=Point(MIN_X + 80.0, MIN_Y + 120.0, 2.0, srid=settings.SRID), parent=tsp_2, plan=plan
)
fsp_1 = get_furniture_signpost_plan(
Expand All @@ -118,7 +118,7 @@ def test__plan__derive_location_from_related_plans():
noise_sp = get_signpost_plan(location=Point(MIN_X + 150.0, MIN_Y + 150.0, 0.4, srid=settings.SRID))
noise_tlp = get_traffic_light_plan(location=Point(MIN_X + 150.0, MIN_Y + 150.0, 0.5, srid=settings.SRID))
noise_tsp = get_traffic_sign_plan(location=Point(MIN_X + 150.0, MIN_Y + 150.0, 0.6, srid=settings.SRID))
noise_asp = get_additional_sign_plan(location=Point(MIN_X + 150.0, MIN_Y + 150.0, 0.7, srid=settings.SRID))
noise_asp = AdditionalSignPlanFactory(location=Point(MIN_X + 150.0, MIN_Y + 150.0, 0.7, srid=settings.SRID))
noise_fsp = get_furniture_signpost_plan(location=Point(MIN_X + 150.0, MIN_Y + 150.0, 0.8, srid=settings.SRID))

plan.refresh_from_db()
Expand Down Expand Up @@ -154,7 +154,7 @@ def test__plan__derive_location_from_related_plans():
@pytest.mark.parametrize(
"factory",
(
get_additional_sign_plan,
AdditionalSignPlanFactory,
get_barrier_plan,
get_furniture_signpost_plan,
get_mount_plan,
Expand Down Expand Up @@ -188,7 +188,7 @@ def test__plan__location_update_on_related_model_save(factory, derive_location:
@pytest.mark.parametrize(
"factory",
(
get_additional_sign_plan,
AdditionalSignPlanFactory,
get_barrier_plan,
get_furniture_signpost_plan,
get_mount_plan,
Expand Down Expand Up @@ -235,7 +235,7 @@ def test__plan__both_plan_locations_update_when_plan_is_changed(factory, derive_
@pytest.mark.parametrize(
"factory",
(
get_additional_sign_plan,
AdditionalSignPlanFactory,
get_barrier_plan,
get_furniture_signpost_plan,
get_mount_plan,
Expand Down Expand Up @@ -271,7 +271,7 @@ def test__plan__location_update_when_plan_is_removed_from_object(factory, derive
@pytest.mark.parametrize(
"factory",
(
get_additional_sign_plan,
AdditionalSignPlanFactory,
get_barrier_plan,
get_furniture_signpost_plan,
get_mount_plan,
Expand Down
10 changes: 5 additions & 5 deletions traffic_control/tests/models/test_traffic_control_device_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

from traffic_control.enums import DeviceTypeTargetModel
from traffic_control.tests.factories import (
AdditionalSignPlanFactory,
AdditionalSignRealFactory,
get_additional_sign_plan,
get_barrier_plan,
get_barrier_real,
get_road_marking_plan,
Expand Down Expand Up @@ -75,7 +75,7 @@
(DeviceTypeTargetModel.TRAFFIC_LIGHT, get_traffic_light_real),
(DeviceTypeTargetModel.TRAFFIC_SIGN, get_traffic_sign_plan),
(DeviceTypeTargetModel.TRAFFIC_SIGN, get_traffic_sign_real),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, get_additional_sign_plan),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, AdditionalSignPlanFactory),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, AdditionalSignRealFactory),
),
)
Expand Down Expand Up @@ -110,7 +110,7 @@ def test__traffic_control_device_type__target_model__restricts_relations(allowed
(DeviceTypeTargetModel.TRAFFIC_LIGHT, get_traffic_light_real),
(DeviceTypeTargetModel.TRAFFIC_SIGN, get_traffic_sign_plan),
(DeviceTypeTargetModel.TRAFFIC_SIGN, get_traffic_sign_real),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, get_additional_sign_plan),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, AdditionalSignPlanFactory),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, AdditionalSignRealFactory),
),
)
Expand Down Expand Up @@ -139,7 +139,7 @@ def test__traffic_control_device_type__target_model__update_is_valid(new_target_
(DeviceTypeTargetModel.TRAFFIC_SIGN, get_traffic_light_real),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, get_traffic_sign_plan),
(DeviceTypeTargetModel.ADDITIONAL_SIGN, get_traffic_sign_real),
(DeviceTypeTargetModel.BARRIER, get_additional_sign_plan),
(DeviceTypeTargetModel.BARRIER, AdditionalSignPlanFactory),
(DeviceTypeTargetModel.BARRIER, AdditionalSignRealFactory),
),
)
Expand Down Expand Up @@ -169,7 +169,7 @@ def test__traffic_control_device_type__target_model__validate_multiple_invalid_r
get_traffic_light_real(device_type=device_type)
get_traffic_sign_plan(device_type=device_type)
get_traffic_sign_real(device_type=device_type)
get_additional_sign_plan(device_type=device_type)
AdditionalSignPlanFactory(device_type=device_type)
AdditionalSignRealFactory(device_type=device_type)

for target_model in DeviceTypeTargetModel:
Expand Down
15 changes: 8 additions & 7 deletions traffic_control/tests/test_additional_sign_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
from traffic_control.enums import DeviceTypeTargetModel, Lifecycle
from traffic_control.models import AdditionalSignPlan, AdditionalSignReal
from traffic_control.tests.factories import (
AdditionalSignPlanFactory,
AdditionalSignRealFactory,
get_additional_sign_plan,
get_owner,
get_traffic_control_device_type,
get_user,
TrafficControlDeviceTypeFactory,
TrafficSignPlanFactory,
TrafficSignRealFactory,
)
from traffic_control.tests.models.test_traffic_control_device_type import content_valid_by_simple_schema, simple_schema
Expand All @@ -35,7 +36,7 @@ def teardown_module():
@pytest.mark.parametrize(
("model", "url_name", "parent_factory"),
(
(AdditionalSignPlan, "additionalsignplan", None),
(AdditionalSignPlan, "additionalsignplan", TrafficSignPlanFactory),
(AdditionalSignReal, "additionalsignreal", TrafficSignRealFactory),
),
ids=("plan", "real"),
Expand Down Expand Up @@ -82,7 +83,7 @@ def test__additional_sign__create_missing_content(client: Client, model, url_nam
@pytest.mark.parametrize(
("model", "factory", "url_name", "parent_factory"),
(
(AdditionalSignPlan, get_additional_sign_plan, "additionalsignplan", None),
(AdditionalSignPlan, AdditionalSignPlanFactory, "additionalsignplan", TrafficSignPlanFactory),
(AdditionalSignReal, AdditionalSignRealFactory, "additionalsignreal", TrafficSignRealFactory),
),
ids=("plan", "real"),
Expand Down Expand Up @@ -141,7 +142,7 @@ def test__additional_sign__update_device_with_content_to_missing_content(
@pytest.mark.parametrize(
("model", "factory", "url_name", "parent_factory"),
(
(AdditionalSignPlan, get_additional_sign_plan, "additionalsignplan", None),
(AdditionalSignPlan, AdditionalSignPlanFactory, "additionalsignplan", TrafficSignPlanFactory),
(AdditionalSignReal, AdditionalSignRealFactory, "additionalsignreal", TrafficSignRealFactory),
),
ids=("plan", "real"),
Expand Down Expand Up @@ -227,7 +228,7 @@ def test__additional_sign__create_dont_accept_content_when_missing_content_is_en
@pytest.mark.parametrize(
("model", "factory", "url_name", "parent_factory"),
(
(AdditionalSignPlan, get_additional_sign_plan, "additionalsignplan", None),
(AdditionalSignPlan, AdditionalSignPlanFactory, "additionalsignplan", TrafficSignPlanFactory),
(AdditionalSignReal, AdditionalSignRealFactory, "additionalsignreal", TrafficSignRealFactory),
),
ids=("plan", "real"),
Expand Down Expand Up @@ -273,7 +274,7 @@ def test__additional_sign__update_dont_accept_content_when_missing_content_is_en
@pytest.mark.parametrize(
"model,factory,url_name,parent_factory",
(
(AdditionalSignPlan, get_additional_sign_plan, "additionalsignplan", None),
(AdditionalSignPlan, AdditionalSignPlanFactory, "additionalsignplan", TrafficSignPlanFactory),
(AdditionalSignReal, AdditionalSignRealFactory, "additionalsignreal", TrafficSignRealFactory),
),
)
Expand Down Expand Up @@ -315,7 +316,7 @@ def test_additional_sign_illegal_location(client: Client, model, factory, url_na
@pytest.mark.parametrize(
"model,url_name,parent_factory",
(
(AdditionalSignPlan, "additionalsignplan", None),
(AdditionalSignPlan, "additionalsignplan", TrafficSignPlanFactory),
(AdditionalSignReal, "additionalsignreal", TrafficSignRealFactory),
),
)
Expand Down
Loading
Loading