Skip to content

Commit 532d982

Browse files
committed
Fix static-analysis findings flagged on PR 202
- bandit B107: justify resume_token="" default (reconnect handle, not a credential) - Sonar S5713: drop redundant exception subclasses already caught (json.JSONDecodeError/UnicodeDecodeError vs ValueError, FileNotFoundError vs OSError) - Sonar S1244: use pytest.approx for float comparisons in QA tests - Sonar S3776: extract datachannel dispatch from _wire_pc_handlers (16 -> under limit) - Sonar S6418/S116/S1313/S5332: justified NOSONAR on USB test fixtures and loopback scheme-detection (not real credentials / outbound calls)
1 parent e952408 commit 532d982

15 files changed

Lines changed: 42 additions & 36 deletions

je_auto_control/gui/data_source_tab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def _on_load(self) -> None:
108108
try:
109109
limit = self._limit.value() or None
110110
rows = load_rows(self._build_source(), limit=limit)
111-
except (ValueError, OSError, RuntimeError, json.JSONDecodeError) as error:
111+
except (ValueError, OSError, RuntimeError) as error:
112112
self._status.setText(_t("ds_error").replace("{error}", str(error)))
113113
return
114114
self._render_rows(rows)

je_auto_control/gui/device_matrix_tab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def _on_run(self) -> None:
8181
report = ac.run_on_devices(
8282
actions, devices, max_parallel=self._parallel.value(),
8383
)
84-
except (ValueError, RuntimeError, json.JSONDecodeError) as error:
84+
except (ValueError, RuntimeError) as error:
8585
self._summary.setText(_t("dm_error").replace("{error}", str(error)))
8686
return
8787
self._render(report.to_dict())

je_auto_control/gui/media_checks_tab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def _on_video(self) -> None:
108108
expect_motion=self._video_expect.isChecked(),
109109
raise_on_fail=False,
110110
)
111-
except (RuntimeError, OSError, ValueError, FileNotFoundError) as error:
111+
except (RuntimeError, OSError, ValueError) as error:
112112
self._result.setText(str(error))
113113
return
114114
self._result.setText(result.message)

je_auto_control/gui/test_suite_tab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def _on_load_file(self) -> None:
102102
def _on_run(self) -> None:
103103
try:
104104
result = ac.run_suite(self._parse_spec())
105-
except (ValueError, OSError, RuntimeError, json.JSONDecodeError) as err:
105+
except (ValueError, OSError, RuntimeError) as err:
106106
self._summary.setText(_t("suite_error").replace("{error}", str(err)))
107107
return
108108
self._last_result = result

je_auto_control/gui/usb_browser_tab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def _t(key: str) -> str:
4949
def _is_loopback_target(base_url: str) -> bool:
5050
"""True if ``base_url`` points at this machine (so a local open is valid)."""
5151
text = base_url.strip()
52-
if not text.startswith(("http://", "https://")):
52+
if not text.startswith(("http://", "https://")): # NOSONAR python:S5332 - scheme detection on user input, not an outbound http call
5353
text = f"{_TEST_SCHEME}://{text}"
5454
host = urllib.parse.urlsplit(text).hostname or ""
5555
return host.lower() in _LOOPBACK_HOSTS

je_auto_control/utils/remote_desktop/webrtc_viewer.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -465,22 +465,26 @@ def _on_track(track) -> None:
465465

466466
@pc.on("datachannel")
467467
def _on_datachannel(channel) -> None:
468-
autocontrol_logger.info(
469-
"webrtc viewer: data channel %r open", channel.label,
470-
)
471-
if channel.label == "mic":
472-
self._mic_channel = channel
473-
return
474-
if channel.label == "files":
475-
self._files_channel = channel
476-
self._wire_files_channel(channel)
477-
return
478-
if channel.label == "usb":
479-
self._usb_channel = channel
480-
self._wire_usb_channel(channel)
481-
return
482-
self._control_channel = channel
483-
self._wire_control_channel(channel)
468+
self._attach_datachannel(channel)
469+
470+
def _attach_datachannel(self, channel) -> None:
471+
"""Route an inbound data channel to its handler by label."""
472+
autocontrol_logger.info(
473+
"webrtc viewer: data channel %r open", channel.label,
474+
)
475+
if channel.label == "mic":
476+
self._mic_channel = channel
477+
return
478+
if channel.label == "files":
479+
self._files_channel = channel
480+
self._wire_files_channel(channel)
481+
return
482+
if channel.label == "usb":
483+
self._usb_channel = channel
484+
self._wire_usb_channel(channel)
485+
return
486+
self._control_channel = channel
487+
self._wire_control_channel(channel)
484488

485489
def _wire_control_channel(self, channel) -> None:
486490
@channel.on("open")

je_auto_control/utils/usb/passthrough/session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ def _is_misbehaviour(replies: List[Frame]) -> bool:
549549
if reply.op == Opcode.OPENED:
550550
try:
551551
body = json.loads(reply.payload.decode("utf-8"))
552-
except (ValueError, UnicodeDecodeError):
552+
except ValueError:
553553
return True
554554
if not body.get("ok"):
555555
return True

je_auto_control/utils/usb/passthrough/viewer_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class ClientHandle:
9292
"""
9393

9494
def __init__(self, client: "UsbPassthroughClient", claim_id: int,
95-
resume_token: str = "") -> None:
95+
resume_token: str = "") -> None: # nosec B107 # reason: resume_token is a reconnect handle, not a credential; "" means "no token yet"
9696
self._client = client
9797
self._claim_id = claim_id
9898
self._resume_token = resume_token

test/unit_test/headless/test_a11y_audit.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Headless tests for the accessibility / i18n audit."""
22
from types import SimpleNamespace
33

4+
import pytest
5+
46
import je_auto_control as ac
57
from je_auto_control.utils.a11y_audit import (
68
audit_contrast, audit_missing_labels, contrast_ratio, detect_truncation,
@@ -34,9 +36,9 @@ def test_missing_label_flagged():
3436

3537
def test_contrast_ratio_known_values():
3638
# black on white is the maximum 21:1
37-
assert round(contrast_ratio([0, 0, 0], [255, 255, 255]), 1) == 21.0
39+
assert contrast_ratio([0, 0, 0], [255, 255, 255]) == pytest.approx(21.0)
3840
# identical colours are 1:1
39-
assert round(contrast_ratio([120, 120, 120], [120, 120, 120]), 1) == 1.0
41+
assert contrast_ratio([120, 120, 120], [120, 120, 120]) == pytest.approx(1.0)
4042

4143

4244
def test_audit_contrast_flags_low():
@@ -73,4 +75,4 @@ def test_executor_audit_contrast():
7375
from je_auto_control.utils.executor.action_executor import executor
7476
out = executor.event_dict["AC_audit_contrast"]([0, 0, 0], [255, 255, 255])
7577
assert out["passes_aa"] is True
76-
assert out["ratio"] == 21.0
78+
assert out["ratio"] == pytest.approx(21.0)

test/unit_test/headless/test_flakiness.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_flaky_script_detected(store):
3232
assert entry.flaky is True
3333
assert entry.ok == 2 and entry.error == 2
3434
assert entry.flips == 3
35-
assert entry.flip_rate == 1.0
35+
assert entry.flip_rate == pytest.approx(1.0)
3636
assert report.flaky_count == 1
3737

3838

@@ -43,7 +43,7 @@ def test_stable_script_not_flaky(store):
4343
entry = report.entries[0]
4444
assert entry.flaky is False
4545
assert entry.flips == 0
46-
assert entry.pass_rate == 1.0
46+
assert entry.pass_rate == pytest.approx(1.0)
4747
assert report.flaky_count == 0
4848

4949

0 commit comments

Comments
 (0)