Skip to content

Commit d256e2c

Browse files
committed
add cli tests
1 parent c63351f commit d256e2c

File tree

6 files changed

+635
-2
lines changed

6 files changed

+635
-2
lines changed

pixi.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/cli/__init__.py

Whitespace-only changes.

tests/cli/commands/__init__.py

Whitespace-only changes.
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
import unittest
2+
from unittest.mock import patch, MagicMock
3+
from pathlib import Path
4+
from types import SimpleNamespace
5+
from typer.testing import CliRunner
6+
7+
from gaiaflow.constants import DEFAULT_IMAGE_NAME, BaseAction, \
8+
ExtendedAction
9+
from gaiaflow.cli.commands.minikube import app as prod_app
10+
from gaiaflow.cli.commands.minikube import load_imports
11+
12+
class TestGaiaflowProdCLI(unittest.TestCase):
13+
def setUp(self):
14+
self.runner = CliRunner()
15+
self.test_project_path = Path("/test/project")
16+
self.test_gaiaflow_path = Path("/tmp/gaiaflow/test")
17+
18+
self.mock_imports = SimpleNamespace(
19+
BaseAction=BaseAction,
20+
ExtendedAction=ExtendedAction,
21+
MinikubeManager=MagicMock(),
22+
create_gaiaflow_context_path=MagicMock(
23+
return_value=(self.test_gaiaflow_path, self.test_project_path)
24+
),
25+
gaiaflow_path_exists_in_state=MagicMock(return_value=True),
26+
parse_key_value_pairs=MagicMock(return_value={"key1": "value1", "key2": "value2"}),
27+
)
28+
29+
@patch('gaiaflow.cli.commands.minikube.load_imports')
30+
def test_start_command(self, mock_load_imports):
31+
mock_load_imports.return_value = self.mock_imports
32+
33+
result = self.runner.invoke(prod_app, [
34+
"start",
35+
"--path", str(self.test_project_path),
36+
"--force-new"
37+
])
38+
39+
self.assertEqual(result.exit_code, 0)
40+
41+
self.mock_imports.create_gaiaflow_context_path.assert_called_once_with(
42+
self.test_project_path
43+
)
44+
self.mock_imports.gaiaflow_path_exists_in_state.assert_called_once_with(
45+
self.test_gaiaflow_path, True
46+
)
47+
48+
self.mock_imports.MinikubeManager.run.assert_called_once_with(
49+
gaiaflow_path=self.test_gaiaflow_path,
50+
user_project_path=self.test_project_path,
51+
action=BaseAction.START,
52+
force_new=True,
53+
)
54+
55+
@patch('gaiaflow.cli.commands.minikube.load_imports')
56+
def test_start_command_exits_when_project_not_exists(self, mock_load_imports):
57+
mock_load_imports.return_value = self.mock_imports
58+
self.mock_imports.gaiaflow_path_exists_in_state.return_value = False
59+
60+
result = self.runner.invoke(prod_app, [
61+
"start",
62+
"--path", str(self.test_project_path)
63+
])
64+
65+
self.assertEqual(result.exit_code, 0)
66+
self.assertIn("Please create a project with Gaiaflow", result.output)
67+
68+
self.mock_imports.MinikubeManager.run.assert_not_called()
69+
70+
@patch('gaiaflow.cli.commands.minikube.load_imports')
71+
def test_stop_command(self, mock_load_imports):
72+
mock_load_imports.return_value = self.mock_imports
73+
74+
result = self.runner.invoke(prod_app, [
75+
"stop",
76+
"--path", str(self.test_project_path)
77+
])
78+
79+
self.assertEqual(result.exit_code, 0)
80+
81+
self.mock_imports.MinikubeManager.run.assert_called_once_with(
82+
gaiaflow_path=self.test_gaiaflow_path,
83+
user_project_path=self.test_project_path,
84+
action=BaseAction.STOP,
85+
)
86+
87+
@patch('gaiaflow.cli.commands.minikube.load_imports')
88+
def test_restart_command(self, mock_load_imports):
89+
mock_load_imports.return_value = self.mock_imports
90+
91+
result = self.runner.invoke(prod_app, [
92+
"restart",
93+
"--path", str(self.test_project_path),
94+
"--force-new"
95+
])
96+
97+
self.assertEqual(result.exit_code, 0)
98+
99+
self.mock_imports.MinikubeManager.run.assert_called_once_with(
100+
gaiaflow_path=self.test_gaiaflow_path,
101+
user_project_path=self.test_project_path,
102+
action=BaseAction.RESTART,
103+
)
104+
105+
@patch('gaiaflow.cli.commands.minikube.load_imports')
106+
def test_dockerize_command(self, mock_load_imports):
107+
mock_load_imports.return_value = self.mock_imports
108+
109+
result = self.runner.invoke(prod_app, [
110+
"dockerize",
111+
"--path", str(self.test_project_path),
112+
"--image-name", "my-custom-image"
113+
])
114+
115+
self.assertEqual(result.exit_code, 0)
116+
117+
self.mock_imports.MinikubeManager.run.assert_called_once_with(
118+
gaiaflow_path=self.test_gaiaflow_path,
119+
user_project_path=self.test_project_path,
120+
action=ExtendedAction.DOCKERIZE,
121+
local=False,
122+
image_name="my-custom-image"
123+
)
124+
125+
@patch('gaiaflow.cli.commands.minikube.load_imports')
126+
def test_dockerize_command_with_default_image_name(self, mock_load_imports):
127+
mock_load_imports.return_value = self.mock_imports
128+
129+
result = self.runner.invoke(prod_app, [
130+
"dockerize",
131+
"--path", str(self.test_project_path)
132+
])
133+
134+
self.assertEqual(result.exit_code, 0)
135+
136+
self.mock_imports.MinikubeManager.run.assert_called_once()
137+
call_args = self.mock_imports.MinikubeManager.run.call_args
138+
self.assertEqual(call_args.kwargs['image_name'], DEFAULT_IMAGE_NAME)
139+
140+
@patch('gaiaflow.cli.commands.minikube.load_imports')
141+
def test_create_config_command(self, mock_load_imports):
142+
mock_load_imports.return_value = self.mock_imports
143+
144+
result = self.runner.invoke(prod_app, [
145+
"create-config",
146+
"--path", str(self.test_project_path)
147+
])
148+
149+
self.assertEqual(result.exit_code, 0)
150+
151+
self.mock_imports.MinikubeManager.run.assert_called_once_with(
152+
gaiaflow_path=self.test_gaiaflow_path,
153+
user_project_path=self.test_project_path,
154+
action=ExtendedAction.CREATE_CONFIG,
155+
)
156+
157+
@patch('gaiaflow.cli.commands.minikube.load_imports')
158+
def test_create_secret_command(self, mock_load_imports):
159+
mock_load_imports.return_value = self.mock_imports
160+
161+
result = self.runner.invoke(prod_app, [
162+
"create-secret",
163+
"--path", str(self.test_project_path),
164+
"--name", "my-secret",
165+
"--data", "key1=value1",
166+
"--data", "key2=value2"
167+
])
168+
169+
self.assertEqual(result.exit_code, 0)
170+
171+
self.mock_imports.parse_key_value_pairs.assert_called_once_with(
172+
["key1=value1", "key2=value2"]
173+
)
174+
175+
self.mock_imports.MinikubeManager.run.assert_called_once_with(
176+
gaiaflow_path=self.test_gaiaflow_path,
177+
user_project_path=self.test_project_path,
178+
action=ExtendedAction.CREATE_SECRET,
179+
secret_name="my-secret",
180+
secret_data={"key1": "value1", "key2": "value2"},
181+
)
182+
183+
@patch('gaiaflow.cli.commands.minikube.load_imports')
184+
def test_cleanup_command(self, mock_load_imports):
185+
mock_load_imports.return_value = self.mock_imports
186+
187+
result = self.runner.invoke(prod_app, [
188+
"cleanup",
189+
"--path", str(self.test_project_path)
190+
])
191+
192+
self.assertEqual(result.exit_code, 0)
193+
194+
self.mock_imports.MinikubeManager.run.assert_called_once_with(
195+
gaiaflow_path=self.test_gaiaflow_path,
196+
user_project_path=self.test_project_path,
197+
action="cleanup",
198+
)
199+
200+
@patch('gaiaflow.cli.commands.minikube.load_imports')
201+
def test_all_commands_handle_missing_project_gracefully(self, mock_load_imports):
202+
mock_load_imports.return_value = self.mock_imports
203+
self.mock_imports.gaiaflow_path_exists_in_state.return_value = False
204+
205+
commands_and_args = [
206+
["start", "--path", str(self.test_project_path)],
207+
["stop", "--path", str(self.test_project_path)],
208+
["restart", "--path", str(self.test_project_path)],
209+
["dockerize", "--path", str(self.test_project_path)],
210+
["create-config", "--path", str(self.test_project_path)],
211+
["create-secret", "--path", str(self.test_project_path),
212+
"--name", "test", "--data", "key=value"],
213+
["cleanup", "--path", str(self.test_project_path)],
214+
]
215+
216+
for command_args in commands_and_args:
217+
with self.subTest(command=command_args[0]):
218+
self.mock_imports.MinikubeManager.run.reset_mock()
219+
220+
result = self.runner.invoke(prod_app, command_args)
221+
222+
self.assertEqual(result.exit_code, 0)
223+
self.assertIn("Please create a project with Gaiaflow", result.output)
224+
225+
self.mock_imports.MinikubeManager.run.assert_not_called()
226+
227+
def test_load_imports_function(self):
228+
imports = load_imports()
229+
230+
expected_attributes = [
231+
'BaseAction', 'ExtendedAction', 'MinikubeManager',
232+
'create_gaiaflow_context_path', 'gaiaflow_path_exists_in_state',
233+
'parse_key_value_pairs'
234+
]
235+
236+
for attr in expected_attributes:
237+
with self.subTest(attribute=attr):
238+
self.assertTrue(hasattr(imports, attr),
239+
f"Missing attribute: {attr}")
240+
241+
@patch('gaiaflow.cli.commands.minikube.load_imports')
242+
def test_action_objects_comparison(self, mock_load_imports):
243+
mock_load_imports.return_value = self.mock_imports
244+
245+
result = self.runner.invoke(prod_app, [
246+
"start",
247+
"--path", str(self.test_project_path)
248+
])
249+
250+
self.assertEqual(result.exit_code, 0)
251+
252+
call_args = self.mock_imports.MinikubeManager.run.call_args
253+
passed_action = call_args.kwargs['action']
254+
255+
self.assertEqual(passed_action, BaseAction.START)
256+
self.assertEqual(passed_action.name, "start")

0 commit comments

Comments
 (0)