| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- """Regression tests: parsers must not raise IndexError on short mfr_data (#494)."""
- from __future__ import annotations
- import pytest
- from switchbot.adv_parsers.contact import process_wocontact
- from switchbot.adv_parsers.leak import process_leak
- from switchbot.adv_parsers.presence_sensor import process_presence_sensor
- @pytest.mark.parametrize(
- "mfr_data",
- [b"", b"\x00", b"\x00\x01", b"\x00" * 8],
- )
- def test_process_leak_short_mfr_returns_empty(mfr_data: bytes) -> None:
- """Leak parser must not crash when mfr_data is shorter than 9 bytes."""
- data = b"&\x00N"
- assert process_leak(data, mfr_data) == {}
- @pytest.mark.parametrize(
- "mfr_data",
- [b"", b"\x00" * 6, b"\x00" * 11],
- )
- def test_process_presence_sensor_short_mfr_returns_empty(mfr_data: bytes) -> None:
- """Presence sensor parser must not crash when mfr_data is shorter than 12 bytes."""
- assert process_presence_sensor(None, mfr_data) == {}
- def test_process_presence_sensor_none_mfr_returns_empty() -> None:
- assert process_presence_sensor(None, None) == {}
- @pytest.mark.parametrize(
- ("data", "mfr_data"),
- [
- (None, b""),
- (None, b"\x00" * 12),
- (b"", None),
- (b"\x00" * 8, None),
- (b"\x00", b"\x00" * 12),
- (b"\x00" * 8, b"\x00" * 12),
- ],
- )
- def test_process_wocontact_short_payloads_return_empty(
- data: bytes | None, mfr_data: bytes | None
- ) -> None:
- """Contact parser must not crash when neither payload is long enough."""
- assert process_wocontact(data, mfr_data) == {}
- def test_process_wocontact_uses_mfr_when_data_short() -> None:
- """Long mfr_data lets the parser succeed even with short service data."""
- # mfr_data byte 7 = 0xF0 -> motion+light+contact_open+contact_timeout all True
- mfr_data = b"\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x02"
- result = process_wocontact(None, mfr_data)
- assert result["motion_detected"] is True
- assert result["contact_open"] is True
- assert result["contact_timeout"] is True
- assert result["is_light"] is True
- assert result["button_count"] == 2
- assert result["battery"] is None
- assert result["tested"] is None
- def test_process_wocontact_uses_data_when_mfr_missing() -> None:
- """Long service data lets the parser succeed without mfr_data."""
- data = b"d@d\x05\x00u\x00\xf8\x12"
- result = process_wocontact(data, None)
- assert result["battery"] == 100
- assert result["motion_detected"] is True
- assert result["contact_open"] is True
- assert result["contact_timeout"] is True
- assert result["is_light"] is True
- assert result["button_count"] == 2
|