Skip to content
1 change: 1 addition & 0 deletions homeassistant/components/microbees/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["application_credentials"],
"documentation": "https://www.home-assistant.io/integrations/microbees",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["microBeesPy==0.3.5"]
}
1 change: 1 addition & 0 deletions homeassistant/components/mikrotik/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"codeowners": ["@engrbm87"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/mikrotik",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["librouteros"],
"requirements": ["librouteros==3.2.0"]
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/moat/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"config_flow": true,
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/moat",
"integration_type": "device",
"iot_class": "local_push",
"requirements": ["moat-ble==0.1.1"]
}
1 change: 1 addition & 0 deletions homeassistant/components/moehlenhoff_alpha2/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"codeowners": ["@j-a-n"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/moehlenhoff_alpha2",
"integration_type": "hub",
"iot_class": "local_push",
"requirements": ["moehlenhoff-alpha2==1.4.0"]
}
1 change: 1 addition & 0 deletions homeassistant/components/monarch_money/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"codeowners": ["@jeeftor"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/monarchmoney",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["typedmonarchmoney==0.4.4"]
}
1 change: 1 addition & 0 deletions homeassistant/components/monoprice/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"codeowners": ["@etsinko", "@OnFreund"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/monoprice",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["pymonoprice"],
"requirements": ["pymonoprice==0.5"]
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/monzo/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["application_credentials"],
"documentation": "https://www.home-assistant.io/integrations/monzo",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["monzopy==1.5.1"]
}
1 change: 1 addition & 0 deletions homeassistant/components/motioneye/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"config_flow": true,
"dependencies": ["http", "webhook"],
"documentation": "https://www.home-assistant.io/integrations/motioneye",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["motioneye_client"],
"requirements": ["motioneye-client==0.3.14"]
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/roborock/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) ->
show_background=entry.options.get(CONF_SHOW_BACKGROUND, False),
map_scale=MAP_SCALE,
),
mqtt_session_unauthorized_hook=lambda: entry.async_start_reauth(hass),
)
except RoborockInvalidCredentials as err:
raise ConfigEntryAuthFailed(
Expand Down
8 changes: 4 additions & 4 deletions homeassistant/generated/integrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -4075,7 +4075,7 @@
},
"mikrotik": {
"name": "Mikrotik",
"integration_type": "hub",
"integration_type": "device",
"config_flow": true,
"iot_class": "local_polling"
},
Expand Down Expand Up @@ -4110,7 +4110,7 @@
},
"moat": {
"name": "Moat",
"integration_type": "hub",
"integration_type": "device",
"config_flow": true,
"iot_class": "local_push"
},
Expand Down Expand Up @@ -4150,7 +4150,7 @@
},
"monarch_money": {
"name": "Monarch Money",
"integration_type": "hub",
"integration_type": "service",
"config_flow": true,
"iot_class": "cloud_polling"
},
Expand All @@ -4167,7 +4167,7 @@
},
"monzo": {
"name": "Monzo",
"integration_type": "hub",
"integration_type": "service",
"config_flow": true,
"iot_class": "cloud_polling"
},
Expand Down
38 changes: 38 additions & 0 deletions tests/components/roborock/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,44 @@ async def test_reauth_started(
assert flows[0]["step_id"] == "reauth_confirm"


async def test_mqtt_session_unauthorized_hook_called(
hass: HomeAssistant,
mock_roborock_entry: MockConfigEntry,
device_manager: AsyncMock,
) -> None:
"""Test that the mqtt session unauthorized hook is called on unauthorized event."""
device_manager_kwargs = {}

def create_device_manager(*args: Any, **kwargs: Any) -> AsyncMock:
nonlocal device_manager_kwargs
device_manager_kwargs = kwargs
return device_manager

with patch(
"homeassistant.components.roborock.create_device_manager",
side_effect=create_device_manager,
):
await hass.config_entries.async_setup(mock_roborock_entry.entry_id)
await hass.async_block_till_done()
assert mock_roborock_entry.state is ConfigEntryState.LOADED

flows = hass.config_entries.flow.async_progress()
assert not flows

# Simulate an unauthorized event by calling the captured hook
assert device_manager_kwargs
mqtt_session_unauthorized_hook = device_manager_kwargs.get(
"mqtt_session_unauthorized_hook"
)
assert mqtt_session_unauthorized_hook
mqtt_session_unauthorized_hook()

# Verify that reauth flow is started
flows = hass.config_entries.flow.async_progress()
assert len(flows) == 1
assert flows[0]["step_id"] == "reauth_confirm"


@pytest.mark.parametrize("platforms", [[Platform.IMAGE]])
@pytest.mark.parametrize(
("exists", "is_dir", "rmtree_called"),
Expand Down
Loading