Coverage for tests/test_env_get.py: 100%
74 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-11-09 00:25 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-11-09 00:25 +0000
1import json 1abcdefg
2from unittest.mock import patch 1abcdefg
4import pytest 1abcdefg
5import respx 1abcdefg
6from httpx import Response 1abcdefg
7from inline_snapshot import snapshot 1abcdefg
9from fastapi_cloud_cli.cli import cloud_app as app 1abcdefg
10from tests.conftest import ConfiguredApp 1abcdefg
11from tests.utils import Keys, SnapshotCliRunner, changing_dir 1abcdefg
13runner = SnapshotCliRunner() 1abcdefg
16def test_shows_a_message_if_not_logged_in(logged_out_cli: None) -> None: 1abcdefg
17 result = runner.invoke(app, ["env", "get", "LOG_LEVEL"]) 1#$%'()*
19 assert result.exit_code == 1 1#$%'()*
20 assert "No credentials found." in result.output 1#$%'()*
23@pytest.mark.respx 1abcdefg
24def test_shows_message_if_no_environment_variables( 1abcdefg
25 logged_in_cli: None, respx_mock: respx.MockRouter, configured_app: ConfiguredApp
26) -> None:
27 respx_mock.get(f"/apps/{configured_app.app_id}/environment-variables/").mock( 1JKLMNOP
28 return_value=Response(200, json={"data": []})
29 )
31 with changing_dir(configured_app.path): 1JKLMNOP
32 result = runner.invoke(app, ["env", "get"]) 1JKLMNOP
34 assert result.exit_code == 0 1JKLMNOP
35 assert result.output == snapshot("""\ 1JKLMNOP
36environment variables
38No environment variables found.\
39""")
42@pytest.mark.respx 1abcdefg
43def test_gets_environment_variable_in_human_output_with_environment_variables_tag( 1abcdefg
44 logged_in_cli: None, respx_mock: respx.MockRouter
45) -> None:
46 app_id = "00000000-0000-4000-8000-000000000002" 1QRSTUVW
47 respx_mock.get(f"/apps/{app_id}/environment-variables/").mock( 1QRSTUVW
48 return_value=Response(
49 200,
50 json={
51 "data": [
52 {
53 "name": "LOG_LEVEL",
54 "value": "info",
55 "is_secret": False,
56 }
57 ]
58 },
59 )
60 )
62 result = runner.invoke(app, ["env", "get", "LOG_LEVEL", "--app-id", app_id]) 1QRSTUVW
64 assert result.exit_code == 0 1QRSTUVW
65 assert result.output == snapshot("""\ 1QRSTUVW
66environment variables
68name: LOG_LEVEL
69value: info\
70""")
73@pytest.mark.respx 1abcdefg
74def test_gets_secret_environment_variable_in_human_output( 1abcdefg
75 logged_in_cli: None, respx_mock: respx.MockRouter
76) -> None:
77 app_id = "00000000-0000-4000-8000-000000000002" 1XYZ0123
78 respx_mock.get(f"/apps/{app_id}/environment-variables/").mock( 1XYZ0123
79 return_value=Response(
80 200,
81 json={
82 "data": [
83 {
84 "name": "DATABASE_URL",
85 "is_secret": True,
86 }
87 ]
88 },
89 )
90 )
92 result = runner.invoke(app, ["env", "get", "DATABASE_URL", "--app-id", app_id]) 1XYZ0123
94 assert result.exit_code == 0 1XYZ0123
95 assert result.output == snapshot("""\ 1XYZ0123
96environment variables
98name: DATABASE_URL
99value: [secret]\
100""")
103@pytest.mark.respx 1abcdefg
104def test_get_prompts_for_environment_variable_name( 1abcdefg
105 logged_in_cli: None, respx_mock: respx.MockRouter
106) -> None:
107 app_id = "00000000-0000-4000-8000-000000000002" 1vwxyzAB
108 respx_mock.get(f"/apps/{app_id}/environment-variables/").mock( 1vwxyzAB
109 return_value=Response(
110 200,
111 json={
112 "data": [
113 {
114 "name": "DEMO",
115 "value": "VALUE",
116 "is_secret": False,
117 },
118 {
119 "name": "OTHER",
120 "value": "ignored",
121 "is_secret": False,
122 },
123 ]
124 },
125 )
126 )
128 with patch("rich_toolkit.container.getchar", side_effect=[Keys.ENTER]): 1vwxyzAB
129 result = runner.invoke(app, ["env", "get", "--app-id", app_id]) 1vwxyzAB
131 assert result.exit_code == 0 1vwxyzAB
132 assert result.output == snapshot("""\ 1vwxyzAB
133environment variables
135Select the environment variable to get:
136● DEMO
137○ OTHER
139Select the environment variable to get: DEMO
141name: DEMO
142value: VALUE\
143""")
146def test_get_json_returns_missing_required_input_without_name( 1abcdefg
147 logged_in_cli: None,
148) -> None:
149 result = runner.invoke( 1456789!
150 app,
151 [
152 "env",
153 "get",
154 "--app-id",
155 "00000000-0000-4000-8000-000000000002",
156 "--json",
157 ],
158 )
160 assert result.exit_code == 1 1456789!
161 assert json.loads(result.stdout) == { 1456789!
162 "error": {
163 "code": "missing_required_input",
164 "message": "Environment variable name is required.",
165 "hint": "Pass NAME to choose an environment variable.",
166 }
167 }
168 assert result.stderr == "" 1456789!
171@pytest.mark.respx 1abcdefg
172def test_gets_secret_environment_variable_as_json( 1abcdefg
173 logged_in_cli: None, respx_mock: respx.MockRouter
174) -> None:
175 app_id = "00000000-0000-4000-8000-000000000002" 1hijklmn
176 variable = { 1hijklmn
177 "name": "DATABASE_URL",
178 "is_secret": True,
179 "updated_at": "2026-05-22T10:00:00Z",
180 }
181 respx_mock.get(f"/apps/{app_id}/environment-variables/").mock( 1hijklmn
182 return_value=Response(200, json={"data": [variable]})
183 )
185 result = runner.invoke( 1hijklmn
186 app, ["env", "get", "DATABASE_URL", "--app-id", app_id, "--json"]
187 )
189 assert result.exit_code == 0 1hijklmn
190 assert json.loads(result.stdout) == { 1hijklmn
191 "data": {
192 "app_id": app_id,
193 "variable": {
194 "name": "DATABASE_URL",
195 "value": None,
196 "is_secret": True,
197 "updated_at": "2026-05-22T10:00:00Z",
198 },
199 }
200 }
201 assert result.stderr == "" 1hijklmn
204@pytest.mark.respx 1abcdefg
205def test_gets_non_secret_environment_variable_as_json( 1abcdefg
206 logged_in_cli: None, respx_mock: respx.MockRouter
207) -> None:
208 app_id = "00000000-0000-4000-8000-000000000002" 1opqrstu
209 variable = { 1opqrstu
210 "name": "LOG_LEVEL",
211 "value": "info",
212 "is_secret": False,
213 "updated_at": "2026-05-22T10:00:00Z",
214 }
215 respx_mock.get(f"/apps/{app_id}/environment-variables/").mock( 1opqrstu
216 return_value=Response(200, json={"data": [variable]})
217 )
219 result = runner.invoke( 1opqrstu
220 app, ["env", "get", "LOG_LEVEL", "--app-id", app_id, "--json"]
221 )
223 assert result.exit_code == 0 1opqrstu
224 assert json.loads(result.stdout) == { 1opqrstu
225 "data": {
226 "app_id": app_id,
227 "variable": variable,
228 }
229 }
230 assert result.stderr == "" 1opqrstu
233@pytest.mark.respx 1abcdefg
234def test_get_environment_variable_json_returns_not_found( 1abcdefg
235 logged_in_cli: None, respx_mock: respx.MockRouter
236) -> None:
237 app_id = "00000000-0000-4000-8000-000000000002" 1CDEFGHI
238 respx_mock.get(f"/apps/{app_id}/environment-variables/").mock( 1CDEFGHI
239 return_value=Response(
240 200,
241 json={
242 "data": [
243 {
244 "name": "LOG_LEVEL",
245 "value": "info",
246 "is_secret": False,
247 }
248 ]
249 },
250 )
251 )
253 result = runner.invoke( 1CDEFGHI
254 app, ["env", "get", "DATABASE_URL", "--app-id", app_id, "--json"]
255 )
257 assert result.exit_code == 1 1CDEFGHI
258 assert json.loads(result.stdout) == { 1CDEFGHI
259 "error": {
260 "code": "not_found",
261 "message": "Environment variable DATABASE_URL not found.",
262 "hint": "Run `fastapi cloud env list` to see available variables.",
263 }
264 }
265 assert result.stderr == "" 1CDEFGHI