diff --git a/pyproject.toml b/pyproject.toml index 218d645d..033cabb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ "uvicorn[standard] >= 0.17.6", "rignore >= 0.5.1", "httpx >= 0.27.0", - "rich-toolkit>=0.20.5", + "rich-toolkit>=0.20.6", "pydantic[email] >= 2.7.4; python_version < '3.13'", "pydantic[email] >= 2.8.0; python_version == '3.13'", "pydantic[email] >= 2.12.0; python_version >= '3.14'", diff --git a/tests/domains/test_cli.py b/tests/domains/test_cli.py index 0e1f5d42..fcb2a16b 100644 --- a/tests/domains/test_cli.py +++ b/tests/domains/test_cli.py @@ -954,7 +954,9 @@ def test_domains_remove_warns_and_confirms( return_value=Response(200, json={"message": "Custom domain deleted"}) ) - with patch("rich_toolkit.container.getchar", side_effect=[Keys.ENTER]): + with patch( + "rich_toolkit.container.getchar", side_effect=[Keys.RIGHT_ARROW, Keys.ENTER] + ): result = runner.invoke( app, ["domains", "remove", domain["name"], "--app-id", APP_ID], @@ -967,6 +969,9 @@ def test_domains_remove_warns_and_confirms( ⚠️ FastAPI Cloud resources for api.example.com will be removed. DNS records at your provider will not be changed. + Remove api.example.com? + ○ Yes ● No + Remove api.example.com? ● Yes ○ No @@ -1023,7 +1028,7 @@ def test_domains_remove_can_be_cancelled( with patch( "rich_toolkit.container.getchar", - side_effect=[Keys.RIGHT_ARROW, Keys.ENTER], + side_effect=[Keys.ENTER], ): result = runner.invoke( app, @@ -1037,9 +1042,6 @@ def test_domains_remove_can_be_cancelled( ⚠️ FastAPI Cloud resources for api.example.com will be removed. DNS records at your provider will not be changed. - Remove api.example.com? - ● Yes ○ No - Remove api.example.com? ○ Yes ● No diff --git a/tests/integrations/resources/test_disconnect.py b/tests/integrations/resources/test_disconnect.py index d5bd15f7..5fe70981 100644 --- a/tests/integrations/resources/test_disconnect.py +++ b/tests/integrations/resources/test_disconnect.py @@ -220,7 +220,7 @@ def test_disconnect_resource_allows_interactive_selection( changing_dir(tmp_path), patch( "rich_toolkit.container.getchar", - side_effect=[Keys.ENTER, Keys.ENTER], + side_effect=[Keys.ENTER, Keys.RIGHT_ARROW, Keys.ENTER], ), ): result = runner.invoke(app, ["integrations", "resources", "disconnect"]) @@ -238,6 +238,9 @@ def test_disconnect_resource_allows_interactive_selection( 💡 The managed environment variables DATABASE_URL, DATABASE_PASSWORD will be removed from the app. The Neon resource itself will not be deleted. + Disconnect production? + ○ Yes ● No + Disconnect production? ● Yes ○ No @@ -264,7 +267,9 @@ def test_disconnect_resource_prompts_for_confirmation_when_id_is_provided( return_value=Response(204) ) - with patch("rich_toolkit.container.getchar", side_effect=[Keys.ENTER]): + with patch( + "rich_toolkit.container.getchar", side_effect=[Keys.RIGHT_ARROW, Keys.ENTER] + ): result = runner.invoke( app, [ @@ -284,6 +289,9 @@ def test_disconnect_resource_prompts_for_confirmation_when_id_is_provided( 💡 Managed environment variables will be removed from the app. The Neon resource itself will not be deleted. + Disconnect production? + ○ Yes ● No + Disconnect production? ● Yes ○ No @@ -304,7 +312,7 @@ def test_disconnect_resource_can_be_cancelled( with patch( "rich_toolkit.container.getchar", - side_effect=[Keys.RIGHT_ARROW, Keys.ENTER], + side_effect=[Keys.ENTER], ): result = runner.invoke( app, @@ -325,9 +333,6 @@ def test_disconnect_resource_can_be_cancelled( 💡 The managed environment variables DATABASE_URL, DATABASE_PASSWORD will be removed from the app. The Neon resource itself will not be deleted. - Disconnect production? - ● Yes ○ No - Disconnect production? ○ Yes ● No diff --git a/tests/test_cli_setup_ci.py b/tests/test_cli_setup_ci.py index c8f4befd..c8eb6556 100644 --- a/tests/test_cli_setup_ci.py +++ b/tests/test_cli_setup_ci.py @@ -728,7 +728,12 @@ def test_overwrites_existing_workflow_when_confirmed( patch("fastapi_cloud_cli.commands.setup_ci._set_github_secret"), patch("rich_toolkit.container.getchar") as mock_getchar, ): - mock_getchar.side_effect = [Keys.ENTER, Keys.ENTER, Keys.ENTER] + mock_getchar.side_effect = [ + Keys.ENTER, + Keys.ENTER, + Keys.RIGHT_ARROW, + Keys.ENTER, + ] result = runner.invoke(app, ["setup-ci"]) assert result.exit_code == 0 @@ -768,7 +773,6 @@ def test_skips_writing_workflow_when_declined( mock_getchar.side_effect = [ Keys.ENTER, Keys.ENTER, - Keys.RIGHT_ARROW, Keys.ENTER, Keys.ENTER, ] @@ -811,7 +815,6 @@ def test_renames_workflow_when_declined_and_new_name_given( mock_getchar.side_effect = [ Keys.ENTER, Keys.ENTER, - Keys.RIGHT_ARROW, Keys.ENTER, *"ci-deploy.yml", Keys.ENTER, diff --git a/tests/test_env_delete.py b/tests/test_env_delete.py index 3c08002d..466ce307 100644 --- a/tests/test_env_delete.py +++ b/tests/test_env_delete.py @@ -160,12 +160,17 @@ def test_shows_message_when_it_deletes( with ( changing_dir(configured_app), - patch("rich_toolkit.container.getchar", side_effect=[Keys.ENTER]), + patch( + "rich_toolkit.container.getchar", side_effect=[Keys.RIGHT_ARROW, Keys.ENTER] + ), ): result = runner.invoke(app, ["env", "delete", "SOME_VAR"]) assert result.exit_code == 0 assert result.output == snapshot("""\ +Delete SOME_VAR? +○ Yes ● No + Delete SOME_VAR? ● Yes ○ No @@ -360,16 +365,13 @@ def test_shows_message_when_deletion_is_cancelled( changing_dir(configured_app), patch( "rich_toolkit.container.getchar", - side_effect=[Keys.RIGHT_ARROW, Keys.ENTER], + side_effect=[Keys.ENTER], ), ): result = runner.invoke(app, ["env", "delete", "SOME_VAR"]) assert result.exit_code == 0 assert result.output == snapshot("""\ -Delete SOME_VAR? -● Yes ○ No - Delete SOME_VAR? ○ Yes ● No diff --git a/uv.lock b/uv.lock index 3ca6cafd..39fc488e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.15'", @@ -382,7 +382,7 @@ requires-dist = [ { name = "pydantic", extras = ["email"], marker = "python_full_version < '3.13'", specifier = ">=2.7.4" }, { name = "pydantic", extras = ["email"], marker = "python_full_version == '3.13.*'", specifier = ">=2.8.0" }, { name = "pydantic", extras = ["email"], marker = "python_full_version >= '3.14'", specifier = ">=2.12.0" }, - { name = "rich-toolkit", specifier = ">=0.20.5" }, + { name = "rich-toolkit", specifier = ">=0.20.6" }, { name = "rignore", specifier = ">=0.5.1" }, { name = "sentry-sdk", specifier = ">=2.20.0" }, { name = "typer", specifier = ">=0.26.1" }, @@ -1209,16 +1209,16 @@ wheels = [ [[package]] name = "rich-toolkit" -version = "0.20.5" +version = "0.20.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/1c/f134352beb393cc17e6241ecf0bf4dd41a6759e2e3971a69a6ad185b87a2/rich_toolkit-0.20.5.tar.gz", hash = "sha256:0c9e1c414ffb0720be26285d472e263d1e704b71d31a7e13274b9996db4969e1", size = 213207, upload-time = "2026-09-08T16:13:12.007Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/fe/e851890b72568a075a3574f760eed9014736b449fe104b16fd05a416c321/rich_toolkit-0.20.6.tar.gz", hash = "sha256:04768f19438df877c6279e6e668ab0d88b5fff5c7ef3ac302838d97f7b03472e", size = 213510, upload-time = "2026-10-08T08:51:01.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/5f/ee8c39750ed9837f54021a8a0eb96f971cd788c1a7d40931867d6d0518bd/rich_toolkit-0.20.5-py3-none-any.whl", hash = "sha256:e21fd616db9c0539d3c50f3433fb1173db95c19d3cbf215615e224182fad6c18", size = 39370, upload-time = "2026-09-08T16:13:10.885Z" }, + { url = "https://files.pythonhosted.org/packages/79/fc/7c296a563a893b0a23a73923ce27965ae15f658dcb58c0bcdd463e1671a2/rich_toolkit-0.20.6-py3-none-any.whl", hash = "sha256:465453ba6f94f99401f59f79fb562827ba5f6b4d4759015d40019f5c67750262", size = 39466, upload-time = "2026-10-08T08:51:00.412Z" }, ] [[package]]