Skip to content

Commit 47c5ea9

Browse files
th3w1zard1pre-commit-ci[bot]basnijholt
authored
Add test_supported_features and fix the problem introduced in #565 (#575)
* Update test_switch.py * Update test_switch.py * test is now done. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix the test only. test is backwards compatible with the old method. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix _supported_to_attributes everything works now. * pre-commit fixes cannot fix the `function too complex` problem. * ignore test_switch.py in `pre-commit-config.yaml` * Add ignore C901 to test_supported_features * remove commented out code --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Bas Nijholt <[email protected]> Co-authored-by: Bas Nijholt <[email protected]>
1 parent adf0d0c commit 47c5ea9

File tree

2 files changed

+100
-15
lines changed

2 files changed

+100
-15
lines changed

custom_components/adaptive_lighting/switch.py

+17-14
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,13 @@
155155
)
156156

157157
_SUPPORT_OPTS = {
158-
"brightness": SUPPORT_BRIGHTNESS,
159-
"color_temp": SUPPORT_COLOR_TEMP,
160-
"color": SUPPORT_COLOR,
161-
"transition": SUPPORT_TRANSITION,
158+
COLOR_MODE_BRIGHTNESS: SUPPORT_BRIGHTNESS,
159+
COLOR_MODE_COLOR_TEMP: SUPPORT_COLOR_TEMP,
160+
CONST_COLOR: SUPPORT_COLOR,
161+
ATTR_TRANSITION: SUPPORT_TRANSITION,
162162
}
163163

164+
164165
VALID_COLOR_MODES = {
165166
COLOR_MODE_BRIGHTNESS: ATTR_BRIGHTNESS,
166167
COLOR_MODE_COLOR_TEMP: ATTR_COLOR_TEMP_KELVIN,
@@ -642,16 +643,18 @@ def _expand_light_groups(hass: HomeAssistant, lights: list[str]) -> list[str]:
642643
def _supported_to_attributes(supported):
643644
supported_attributes = {}
644645
supports_colors = False
645-
for mode, attr in VALID_COLOR_MODES.items():
646-
if mode not in supported:
647-
continue
648-
supported_attributes[attr] = True
649-
if (
650-
not supports_colors
651-
and mode != COLOR_MODE_BRIGHTNESS
652-
and mode != COLOR_MODE_COLOR_TEMP
653-
):
654-
supports_colors = True
646+
for mode in supported:
647+
attr = VALID_COLOR_MODES.get(mode)
648+
if attr:
649+
supported_attributes[attr] = True
650+
if attr in COLOR_ATTRS:
651+
supports_colors = True
652+
# ATTR_SUPPORTED_FEATURES only
653+
elif mode in _SUPPORT_OPTS:
654+
supported_attributes[mode] = True
655+
if CONST_COLOR in supported_attributes:
656+
supports_colors = True
657+
supported_attributes.pop(CONST_COLOR)
655658
return supported_attributes, supports_colors
656659

657660

tests/test_switch.py

+83-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import asyncio
44
from copy import deepcopy
55
import datetime
6+
import itertools
67
import logging
78
from random import randint
8-
from unittest.mock import patch
9+
from unittest.mock import MagicMock, patch
910

1011
from homeassistant.components.adaptive_lighting.const import (
1112
ADAPT_BRIGHTNESS_SWITCH,
@@ -25,6 +26,7 @@
2526
CONF_TRANSITION,
2627
CONF_TURN_ON_LIGHTS,
2728
CONF_USE_DEFAULTS,
29+
CONST_COLOR,
2830
DEFAULT_MAX_BRIGHTNESS,
2931
DEFAULT_NAME,
3032
DEFAULT_SLEEP_BRIGHTNESS,
@@ -37,7 +39,10 @@
3739
UNDO_UPDATE_LISTENER,
3840
)
3941
from homeassistant.components.adaptive_lighting.switch import (
42+
_SUPPORT_OPTS,
43+
VALID_COLOR_MODES,
4044
_attributes_have_changed,
45+
_supported_features,
4146
color_difference_redmean,
4247
create_context,
4348
is_our_context,
@@ -47,9 +52,13 @@
4752
ATTR_BRIGHTNESS,
4853
ATTR_BRIGHTNESS_PCT,
4954
ATTR_COLOR_TEMP_KELVIN,
55+
ATTR_MAX_COLOR_TEMP_KELVIN,
56+
ATTR_MIN_COLOR_TEMP_KELVIN,
5057
ATTR_RGB_COLOR,
58+
ATTR_SUPPORTED_COLOR_MODES,
5159
ATTR_TRANSITION,
5260
ATTR_XY_COLOR,
61+
COLOR_MODE_BRIGHTNESS,
5362
)
5463
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
5564
from homeassistant.components.light import SERVICE_TURN_OFF
@@ -515,6 +524,79 @@ async def test_turn_on_off_listener_not_tracking_untracked_lights(hass):
515524
assert light not in switch.turn_on_off_listener.lights
516525

517526

527+
def test_supported_features(hass): # noqa: C901
528+
"""Test the supported features of a light."""
529+
530+
possible_legacy_features = {}
531+
MAX_COMBINATIONS = 4 # maximum number of elements that can be combined
532+
for i in range(1, min(MAX_COMBINATIONS, len(_SUPPORT_OPTS)) + 1):
533+
for combination in itertools.combinations(_SUPPORT_OPTS.keys(), i):
534+
key = "_".join(combination)
535+
value = [v for k, v in _SUPPORT_OPTS.items() if k in combination]
536+
possible_legacy_features[key] = value
537+
538+
possible_color_modes = {}
539+
for i in range(1, len(VALID_COLOR_MODES) + 1):
540+
for combination in itertools.combinations(VALID_COLOR_MODES.keys(), i):
541+
key = "_".join(combination)
542+
value = [v for k, v in VALID_COLOR_MODES.items() if k in combination]
543+
possible_color_modes[key] = value
544+
545+
# create a mock HomeAssistant object
546+
hass = MagicMock()
547+
548+
# iterate over possible legacy features
549+
for feature_key, feature_values in possible_legacy_features.items():
550+
# _LOGGER.debug(feature_values)
551+
# set the attributes of the mock state object to the possible legacy feature values
552+
state_attrs = {ATTR_SUPPORTED_FEATURES: sum(feature_values)}
553+
hass.states.get.return_value.attributes = state_attrs
554+
555+
# iterate over possible color modes
556+
for mode_key, mode_values in possible_color_modes.items():
557+
# _LOGGER.debug(mode_values)
558+
# set the attributes of the mock state object to the possible color mode values
559+
state_attrs[ATTR_SUPPORTED_COLOR_MODES] = set(mode_values)
560+
hass.states.get.return_value.attributes = state_attrs
561+
562+
# Handle both the new and the old _supported_features.
563+
result = _supported_features(hass, ENTITY_LIGHT)
564+
supported, supports_colors = (
565+
result if isinstance(result, tuple) else (result, None)
566+
)
567+
expected_supported = {} if supports_colors is not None else set()
568+
for mode, attr in VALID_COLOR_MODES.items():
569+
if mode in mode_values:
570+
if supports_colors is None:
571+
expected_supported.add(mode)
572+
else:
573+
expected_supported[attr] = True
574+
if supports_colors is True:
575+
expected_supported[COLOR_MODE_BRIGHTNESS] = True
576+
for opt, value in _SUPPORT_OPTS.items():
577+
if value in feature_values:
578+
if supports_colors is None:
579+
expected_supported.add(opt)
580+
else:
581+
if supports_colors is True:
582+
expected_supported[COLOR_MODE_BRIGHTNESS] = True
583+
if opt in VALID_COLOR_MODES:
584+
expected_supported[VALID_COLOR_MODES[opt]] = True
585+
elif opt != CONST_COLOR:
586+
expected_supported[opt] = True
587+
if ATTR_MIN_COLOR_TEMP_KELVIN in supported:
588+
supported.pop(ATTR_MIN_COLOR_TEMP_KELVIN)
589+
if ATTR_MAX_COLOR_TEMP_KELVIN in supported:
590+
supported.pop(ATTR_MAX_COLOR_TEMP_KELVIN)
591+
assert supported == expected_supported, (
592+
f"\nExpected supported: {expected_supported}\n"
593+
f"Actual supported: {supported}\n"
594+
f"feature_values: {feature_values}\n"
595+
f"mode_values: {mode_values}\n"
596+
f"supports_colors: {supports_colors}\n"
597+
)
598+
599+
518600
@pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES)
519601
async def test_manual_control(hass):
520602
"""Test the 'manual control' tracking."""

0 commit comments

Comments
 (0)