From 7c2b6d6dc00819efe708039f2a12253e298aa4ec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 13 Aug 2026 13:37:13 +0000 Subject: [PATCH 1/4] Initial plan From dbb23b760e03dd777779cd0f253d6ece46a24fa8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 13 Aug 2026 13:48:02 +0000 Subject: [PATCH 2/4] fix: align junction filtering with new intersection fields Co-authored-by: ziv17 <28224696+ziv17@users.noreply.github.com> --- anyway/widgets/widget_utils.py | 12 +++++- tests/test_infographics_utils.py | 17 +++++---- tests/test_involved_query.py | 65 ++++++++++++++++++++------------ 3 files changed, 59 insertions(+), 35 deletions(-) diff --git a/anyway/widgets/widget_utils.py b/anyway/widgets/widget_utils.py index 80d7f21ba..c1f6c5106 100644 --- a/anyway/widgets/widget_utils.py +++ b/anyway/widgets/widget_utils.py @@ -95,7 +95,15 @@ def get_expression_for_road_segment_location_fields(filters, table_obj): def get_expression_for_segment_junctions(segment_id: int, table_obj): sg = SegmentJunctions.get_instance() junctions = sg.get_segment_junctions(segment_id) - return getattr(table_obj, "non_urban_intersection").in_(junctions) + if hasattr(table_obj, "non_urban_intersection"): + field = getattr(table_obj, "non_urban_intersection") + elif hasattr(table_obj, "intersection"): + field = getattr(table_obj, "intersection") + else: + raise AttributeError( + f"{table_obj}: has neither 'non_urban_intersection' nor 'intersection'" + ) + return field.in_(junctions) def get_filter_expression(table_obj, field_name, value): @@ -229,7 +237,7 @@ def get_injured_filters(location_info: dict): new_filters[new_filter_name] = curr_value new_filters.pop(curr_filter) - new_filters["injury_severity"] = [1, 2, 3] + new_filters["injury_severity"] = InjurySeverity.codes() return new_filters diff --git a/tests/test_infographics_utils.py b/tests/test_infographics_utils.py index adfdbc128..eb89f8689 100644 --- a/tests/test_infographics_utils.py +++ b/tests/test_infographics_utils.py @@ -20,14 +20,14 @@ class TestInfographicsUtilsCase(unittest.TestCase): item1 = { "2019": { - 1: 0, - 2: 3, - 3: 22 + AccidentSeverity.FATAL.value: 0, + AccidentSeverity.SEVERE.value: 3, + AccidentSeverity.LIGHT.value: 22 }, "2020": { - 1: 1, - 2: 1, - 3: 22 + AccidentSeverity.FATAL.value: 1, + AccidentSeverity.SEVERE.value: 1, + AccidentSeverity.LIGHT.value: 22 } } items1_res = [ @@ -118,9 +118,10 @@ def test_get_filter_expression(self): @patch("anyway.widgets.widget_utils.SegmentJunctions") def test_get_expression_for_segment_junctions(self, sg): sg.get_instance.return_value = sg - sg.get_segment_junctions.return_value = [] + sg.get_segment_junctions.return_value = [1, 2] actual = get_expression_for_segment_junctions(17, AccidentMarkerView) - self.assertEqual('1 != 1', str(actual.expression), "1") + self.assertEqual("markers_hebrew.intersection", str(actual.left), "1") + self.assertIn(" IN ", str(actual), "2") def test_add_resolution_location_accuracy_filter(self): f = {"1": 1} diff --git a/tests/test_involved_query.py b/tests/test_involved_query.py index 5816fa7a9..7e1439fda 100644 --- a/tests/test_involved_query.py +++ b/tests/test_involved_query.py @@ -5,23 +5,37 @@ class TestInvolvedQuery(unittest.TestCase): involved_result = { - 'accident_timestamp': '2014-03-23 00:00', - 'accident_type_hebrew': 'פגיעה בהולך רגל', 'accident_year': 2014, - 'accident_yishuv_name': 'תל אביב - יפו', 'day_in_week_hebrew': 'ראשון', - 'day_night_hebrew': 'לילה', 'location_accuracy_hebrew': 'עיגון מדויק', - 'multi_lane_hebrew': None, 'one_lane_hebrew': 'חד סיטרי', 'road1': None, - 'road2': None, 'road_segment_name': None, - 'road_type_hebrew': 'עירונית לא בצומת', 'road_width_hebrew': 'עד 5 מטר', - 'speed_limit_hebrew': 'עד 50 קמ"ש', - 'street2_hebrew': None, 'vehicles': 'רכב נוסעים פרטי', - 'latitude': '32.0701379776572', 'longitude': '34.7978130577587', - '_id': 24, 'age_group_hebrew': '70-74', - 'injured_type_hebrew': 'הולך רגל', 'injured_type_short_hebrew': 'הולך רגל', - 'injury_severity_hebrew': 'פצוע קשה', 'population_type_hebrew': 'יהודים', - 'vehicle_vehicle_type_hebrew': 'הולך רגל', 'sex_hebrew': 'נקבה', - 'TEST-vehicle_type': None, 'TEST-injured_type': 1, - 'vehicle_type_short_hebrew': None - } + "accident_timestamp": "2019-04-16 01:45", + "accident_type_hebrew": "פגיעה בהולך רגל", + "accident_year": 2019, + "accident_yishuv_name": "תל אביב - יפו", + "day_in_week_hebrew": "שלישי", + "day_night_hebrew": "לילה ", + "location_accuracy_hebrew": "עיגון מדויק", + "multi_lane_hebrew": "מיפרדה בנויה ללא גדר בטיחות", + "one_lane_hebrew": "לאידוע", + "road1": None, + "road2": None, + "road_segment_name": None, + "road_type_hebrew": "עירונית לא בצומת", + "road_width_hebrew": None, + "speed_limit_hebrew": 'עד 50 קמ"ש', + "street2_hebrew": None, + "vehicles": "אופניים חשמליים", + "latitude": "32.0559627551410", + "longitude": "34.7708950471885", + "_id": 3, + "age_group_hebrew": "70-74", + "injured_type_hebrew": "הולך רגל", + "injured_type_short_hebrew": "הולך רגל", + "injury_severity_hebrew": "פצוע קשה", + "population_type_hebrew": "יהודים", + "vehicle_vehicle_type_hebrew": "הולך רגל", + "sex_hebrew": "נקבה", + "TEST-vehicle_type": None, + "TEST-injured_type": 1, + "vehicle_type_short_hebrew": None, + } def test_vehicle_type_bit_2_heb(self): f = InvolvedQuery.vehicle_type_bit_2_heb @@ -33,7 +47,7 @@ def test_vehicle_type_bit_2_heb(self): self.assertEqual(f(1 << 0), "") self.assertEqual(f(1 << 26), "") self.assertEqual(f((1 << 1) | (1 << 2)), "רכב נוסעים פרטי, טרנזיט") - self.assertEqual(f((1 << 21) | (1 << 25)), "קורקינט חשמלי, משאית") + self.assertEqual(f((1 << 34) | (1 << 4)), "משאית, קורקינט חשמלי") def test_dictify_double_group_by(self): data = [ @@ -52,29 +66,30 @@ def test_dictify_double_group_by(self): def test_e2e(self): test_client = flask_app.test_client() - actual = test_client.get("/involved?sy=2014&ey=2014&sex=2&age=15&injt=1" - "&sev=2&st=2551") + actual = test_client.get( + "/involved?sy=2019&ey=2019&sex=2&age=15&injt=1&sev=1194&st=2215" + ) self.assertEqual("200 OK", actual.status, "3") self.maxDiff = None res = actual.json["data"][0] - self.assertEqual(2551, res["street1"]) + self.assertEqual(2215, res["street1"]) self.assertIsNone(res["street2"]) res.pop("street1_hebrew") res.pop("street1") res.pop("street2") self.assertEqual(self.involved_result, res, "4") - actual = test_client.get("/involved/groupby?sy=2014&ey=2014&gb=year&gb2=lca&city=5000,1&sort=d") + actual = test_client.get("/involved/groupby?sy=2019&ey=2019&gb=year&gb2=lca&city=5000,1&sort=d") self.assertEqual("200 OK", actual.status, "5") self.assertTrue(len(actual.json) > 0, "9") - actual = test_client.get("/involved/groupby?sy=2014&ey=2014&city=5000,1&gb=vcl&lim=15&sort=d") + actual = test_client.get("/involved/groupby?sy=2019&ey=2019&city=5000,1&gb=vcl&lim=15&sort=d") self.assertEqual("200 OK", actual.status, "7") self.assertTrue(len(actual.json) > 0, "9") - actual = test_client.get("/involved/groupby?sy=2014&ey=2014&city=5000,1&gb=cpop&sort=a") + actual = test_client.get("/involved/groupby?sy=2019&ey=2019&city=5000,1&gb=cpop&sort=a") self.assertEqual("200 OK", actual.status, "10") self.assertTrue(len(actual.json) > 0, "12") actual = test_client.get( - "/involved/groupby?sy=2014&ey=2014&city=5000,1&sev=1&st=1&rd=1" \ + "/involved/groupby?sy=2019&ey=2019&city=5000,1&sev=1&st=1&rd=1" \ "&rds=1&sex=1&age=1&pt=1&dn=1&mn=1&acc=1&selfacc=1&rt=1&sp=1&rw=1" \ "&ml=1&ol=1&lca=1" \ "&gb=cpop&gb2=injt&sort=a&lim=1") From 4d1d9c3ccbad19bac665adb849335864f18702d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 13 Aug 2026 13:49:55 +0000 Subject: [PATCH 3/4] test: cover intersection-based road segment filtering Co-authored-by: ziv17 <28224696+ziv17@users.noreply.github.com> --- anyway/widgets/widget_utils.py | 6 ++---- tests/test_infographics_utils.py | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/anyway/widgets/widget_utils.py b/anyway/widgets/widget_utils.py index c1f6c5106..28279b0be 100644 --- a/anyway/widgets/widget_utils.py +++ b/anyway/widgets/widget_utils.py @@ -8,7 +8,7 @@ # noinspection PyProtectedMember from flask_babel import _ -from sqlalchemy import func, distinct, between, or_, and_ +from sqlalchemy import func, distinct, between, or_, and_, false from anyway.app_and_db import db from anyway.backend_constants import BE_CONST, LabeledCode, InjurySeverity @@ -100,9 +100,7 @@ def get_expression_for_segment_junctions(segment_id: int, table_obj): elif hasattr(table_obj, "intersection"): field = getattr(table_obj, "intersection") else: - raise AttributeError( - f"{table_obj}: has neither 'non_urban_intersection' nor 'intersection'" - ) + return false() return field.in_(junctions) diff --git a/tests/test_infographics_utils.py b/tests/test_infographics_utils.py index eb89f8689..ed50997a6 100644 --- a/tests/test_infographics_utils.py +++ b/tests/test_infographics_utils.py @@ -122,6 +122,7 @@ def test_get_expression_for_segment_junctions(self, sg): actual = get_expression_for_segment_junctions(17, AccidentMarkerView) self.assertEqual("markers_hebrew.intersection", str(actual.left), "1") self.assertIn(" IN ", str(actual), "2") + self.assertEqual("false", str(get_expression_for_segment_junctions(17, InvolvedMarkerView)), "3") def test_add_resolution_location_accuracy_filter(self): f = {"1": 1} From 8291c96bfb4045021c534866f10c584a427e2e80 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 13 Aug 2026 13:51:51 +0000 Subject: [PATCH 4/4] fix: guard empty road segment junction filters Co-authored-by: ziv17 <28224696+ziv17@users.noreply.github.com> --- anyway/widgets/widget_utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/anyway/widgets/widget_utils.py b/anyway/widgets/widget_utils.py index 28279b0be..ae3c0556c 100644 --- a/anyway/widgets/widget_utils.py +++ b/anyway/widgets/widget_utils.py @@ -95,6 +95,8 @@ def get_expression_for_road_segment_location_fields(filters, table_obj): def get_expression_for_segment_junctions(segment_id: int, table_obj): sg = SegmentJunctions.get_instance() junctions = sg.get_segment_junctions(segment_id) + if not junctions: + return false() if hasattr(table_obj, "non_urban_intersection"): field = getattr(table_obj, "non_urban_intersection") elif hasattr(table_obj, "intersection"):