@@ -310,6 +310,94 @@ async def test_reauth(
310310 assert config_entry .data ["token" ].get ("refresh_token" ) == "mock-refresh-token"
311311
312312
313+ @pytest .mark .usefixtures ("current_request_with_host" )
314+ @pytest .mark .parametrize (
315+ (
316+ "new_email" ,
317+ "expected_abort_reason" ,
318+ "expected_placeholders" ,
319+ "expected_access_token" ,
320+ "expected_setup_calls" ,
321+ ),
322+ [
323+ (TEST_USER_EMAIL , "reconfigure_successful" , None , "updated-access-token" , 1 ),
324+ (
325+ "other.user@domain.com" ,
326+ "wrong_account" ,
327+ {"email" : TEST_USER_EMAIL },
328+ "mock-access-token" ,
329+ 0 ,
330+ ),
331+ ],
332+ ids = ["reconfigure_successful" , "wrong_account" ],
333+ )
334+ async def test_reconfigure (
335+ hass : HomeAssistant ,
336+ hass_client_no_auth : ClientSessionGenerator ,
337+ config_entry : MockConfigEntry ,
338+ aioclient_mock : AiohttpClientMocker ,
339+ mock_api : MagicMock ,
340+ new_email : str ,
341+ expected_abort_reason : str ,
342+ expected_placeholders : dict [str , str ] | None ,
343+ expected_access_token : str ,
344+ expected_setup_calls : int ,
345+ ) -> None :
346+ """Test the reconfiguration flow."""
347+ config_entry .add_to_hass (hass )
348+ result = await config_entry .start_reconfigure_flow (hass )
349+
350+ state = config_entry_oauth2_flow ._encode_jwt (
351+ hass ,
352+ {
353+ "flow_id" : result ["flow_id" ],
354+ "redirect_uri" : "https://example.com/auth/external/callback" ,
355+ },
356+ )
357+ assert result ["url" ] == (
358+ f"{ GOOGLE_AUTH_URI } ?response_type=code&client_id={ CLIENT_ID } "
359+ "&redirect_uri=https://example.com/auth/external/callback"
360+ f"&state={ state } &scope=https://www.googleapis.com/auth/drive.file"
361+ "&access_type=offline&prompt=consent"
362+ )
363+ client = await hass_client_no_auth ()
364+ resp = await client .get (f"/auth/external/callback?code=abcd&state={ state } " )
365+ assert resp .status == 200
366+ assert resp .headers ["content-type" ] == "text/html; charset=utf-8"
367+
368+ # Prepare API responses
369+ mock_api .get_user = AsyncMock (return_value = {"user" : {"emailAddress" : new_email }})
370+ aioclient_mock .post (
371+ GOOGLE_TOKEN_URI ,
372+ json = {
373+ "refresh_token" : "mock-refresh-token" ,
374+ "access_token" : "updated-access-token" ,
375+ "type" : "Bearer" ,
376+ "expires_in" : 60 ,
377+ },
378+ )
379+
380+ with patch (
381+ "homeassistant.components.google_drive.async_setup_entry" , return_value = True
382+ ) as mock_setup :
383+ result = await hass .config_entries .flow .async_configure (result ["flow_id" ])
384+ await hass .async_block_till_done ()
385+
386+ assert len (hass .config_entries .async_entries (DOMAIN )) == 1
387+ assert len (mock_setup .mock_calls ) == expected_setup_calls
388+
389+ assert result .get ("type" ) is FlowResultType .ABORT
390+ assert result .get ("reason" ) == expected_abort_reason
391+ assert result .get ("description_placeholders" ) == expected_placeholders
392+
393+ assert config_entry .unique_id == TEST_USER_EMAIL
394+ assert "token" in config_entry .data
395+
396+ # Verify access token is refreshed
397+ assert config_entry .data ["token" ].get ("access_token" ) == expected_access_token
398+ assert config_entry .data ["token" ].get ("refresh_token" ) == "mock-refresh-token"
399+
400+
313401@pytest .mark .usefixtures ("current_request_with_host" )
314402async def test_already_configured (
315403 hass : HomeAssistant ,
0 commit comments