Repository: home-assistant/core
File: homeassistant/components/calendar/__init__.py (Python)

Code before:

    _alarm_unsubs: list[CALLBACK_TYPE] | None = None

    _attr_color: RGBColor | None = None

    @property
    def color(self) -> RGBColor | None:
        """Return the color of the calendar entity as RGBColor."""
        return self._attr_color

    @property
    def event(self) -> CalendarEvent | None:
        """Return the next upcoming event."""
        raise NotImplementedError

    @final
    @property
    def state_attributes(self) -> dict[str, Any] | None:
        """Return the entity state attributes."""
        color_hex_val = (
            f"#{color_rgb_to_hex(*self._attr_color)}" if self._attr_color else None
        )
        if (event := self.event) is None:
            if color_hex_val is None:
                return None
            return {"color": color_hex_val}

        attrs = {
            "message": event.summary,
            "all_day": event.all_day,
            "start_time": event.start_datetime_local.strftime(DATE_STR_FORMAT),
            "end_time": event.end_datetime_local.strftime(DATE_STR_FORMAT),
            "location": event.location or "",
            "description": event.description or "",
        }

        if color_hex_val is not None:
            attrs["color"] = color_hex_val

        return attrs

    @final
    @property
    def state(self) -> str:
        """Return the state of the calendar event."""
        if (event := self.event) is None:
            return STATE_OFF

        now = dt_util.now()

        if event.start_datetime_local <= now < event.end_datetime_local:

Review comment (suggestion):
Please add a test for a case where there is no upcoming event but the calendar has a color.

You may just want to add another MockCalendarEntity to the list of entities to exercise this case. You can also pass a color in the constructor instead of changing the attributes in the middle of the test.

Code after:
    _attr_initial_color: str | None = None

    @property
    def initial_color(self) -> str | None:
        """Return the initial color for the calendar entity."""
        return self._attr_initial_color

    def get_initial_entity_options(self) -> er.EntityOptionsType | None:
        """Return initial entity options."""
        if self.initial_color is None:
            return None

        # Validate that it's a valid hex color string with # prefix
        try:
            validated_color = cv.color_hex(self.initial_color)
        except vol.Invalid:
            return None

        return {DOMAIN: {"color": validated_color}}

    @property
    def event(self) -> CalendarEvent | None:
        """Return the next upcoming event."""
        raise NotImplementedError

    @final
    @property
    def state_attributes(self) -> dict[str, Any] | None:
        """Return the entity state attributes."""
        if (event := self.event) is None:
            return None

        return {
            "message": event.summary,
            "all_day": event.all_day,
            "start_time": event.start_datetime_local.strftime(DATE_STR_FORMAT),
            "end_time": event.end_datetime_local.strftime(DATE_STR_FORMAT),
            "location": event.location or "",
            "description": event.description or "",
        }

    @final
    @property
    def state(self) -> str:
        """Return the state of the calendar event."""
        if (event := self.event) is None:
            return STATE_OFF

        now = dt_util.now()

        if event.start_datetime_local <= now < event.end_datetime_local: