|
5 | 5 | from typer.testing import CliRunner
|
6 | 6 |
|
7 | 7 | from cli.schedule import app, delete_app
|
| 8 | +from pythonanywhere.scripts_commons import tabulate_formats |
8 | 9 |
|
9 | 10 | runner = CliRunner()
|
10 | 11 |
|
11 | 12 |
|
12 | 13 | @pytest.fixture
|
13 | 14 | def task_list(mocker):
|
| 15 | + username = getpass.getuser() |
| 16 | + specs1 = { |
| 17 | + "can_enable": False, |
| 18 | + "command": "echo foo", |
| 19 | + "enabled": True, |
| 20 | + "expiry": None, |
| 21 | + "extend_url": f"/user/{username}/schedule/task/42/extend", |
| 22 | + "hour": 16, |
| 23 | + "task_id": 42, |
| 24 | + "interval": "daily", |
| 25 | + "logfile": "/user/{username}/files/var/log/tasklog-126708-daily-at-1600-echo_foo.log", |
| 26 | + "minute": 0, |
| 27 | + "printable_time": "16:00", |
| 28 | + "url": f"/api/v0/user/{username}/schedule/42", |
| 29 | + "user": username, |
| 30 | + } |
| 31 | + specs2 = {**specs1} |
| 32 | + specs2.update({"task_id": 43, "enabled": False}) |
14 | 33 | mock_task_list = mocker.patch("cli.schedule.TaskList")
|
15 |
| - mock_task_list.return_value.tasks = [Mock(task_id=1), Mock(task_id=2)] |
| 34 | + mock_task_list.return_value.tasks = [Mock(**specs1), Mock(**specs2)] |
16 | 35 | return mock_task_list
|
17 | 36 |
|
18 |
| - |
19 | 37 | @pytest.fixture
|
20 | 38 | def mock_confirm(mocker):
|
21 | 39 | return mocker.patch("cli.schedule.typer.confirm")
|
@@ -213,3 +231,45 @@ def test_logs_only_value_of_requested_task_spec(self, mocker, task_from_id):
|
213 | 231 | assert task_from_id.call_args == call(42)
|
214 | 232 | assert mock_logger.call_args == call(set_info=True)
|
215 | 233 | assert mock_logger.return_value.info.call_args == call("10:23")
|
| 234 | +@pytest.mark.clischedulelist |
| 235 | +class TestList: |
| 236 | + def test_logs_table_with_correct_headers_and_values(self, mocker, task_list): |
| 237 | + mock_logger = mocker.patch("cli.schedule.get_logger") |
| 238 | + mock_tabulate = mocker.patch("cli.schedule.tabulate") |
| 239 | + |
| 240 | + result = runner.invoke(app, ["list", "--format", "orgtbl"]) |
| 241 | + |
| 242 | + headers = "id", "interval", "at", "status", "command" |
| 243 | + attrs = "task_id", "interval", "printable_time", "enabled", "command" |
| 244 | + table = [[getattr(task, attr) for attr in attrs] for task in task_list.return_value.tasks] |
| 245 | + table = [ |
| 246 | + ["enabled" if spec == True else "disabled" if spec == False else spec for spec in row] |
| 247 | + for row in table |
| 248 | + ] |
| 249 | + assert mock_logger.call_args == call(set_info=True) |
| 250 | + assert task_list.call_count == 1 |
| 251 | + assert mock_tabulate.call_args == call(table, headers, tablefmt="orgtbl") |
| 252 | + assert mock_logger.return_value.info.call_args == call(mock_tabulate.return_value) |
| 253 | + |
| 254 | + def test_snakesays_when_no_scheduled_tasks(self, mocker): |
| 255 | + mock_logger = mocker.patch("cli.schedule.get_logger").return_value |
| 256 | + mock_tabulate = mocker.patch("cli.schedule.tabulate") |
| 257 | + mock_snakesay = mocker.patch("cli.schedule.snakesay") |
| 258 | + mock_tasks = mocker.patch("cli.schedule.TaskList") |
| 259 | + mock_tasks.return_value.tasks = [] |
| 260 | + |
| 261 | + runner.invoke(app, ["list"]) |
| 262 | + |
| 263 | + assert mock_tabulate.call_count == 0 |
| 264 | + assert mock_snakesay.call_args == call("No scheduled tasks") |
| 265 | + assert mock_logger.info.call_args == call(mock_snakesay.return_value) |
| 266 | + |
| 267 | + def test_warns_when_wrong_format_provided(self, mocker, task_list): |
| 268 | + mock_tabulate = mocker.patch("cli.schedule.tabulate") |
| 269 | + wrong_format = "excel" |
| 270 | + |
| 271 | + result = runner.invoke(app, ["list", "--format", "excel"]) |
| 272 | + |
| 273 | + assert mock_tabulate.call_count == 0 |
| 274 | + assert wrong_format not in tabulate_formats |
| 275 | + assert "Table format has to be one of" in result.stdout |
0 commit comments