diff --git a/cli/pa b/cli/pa index 39810eb..17681bb 100755 --- a/cli/pa +++ b/cli/pa @@ -13,7 +13,7 @@ It was build with typer & click under the hood. app = typer.Typer(help=help) app.add_typer(django.app, name="django", help="Makes Django Girls tutorial projects deployment easy") -app.add_typer(scheduled_task.app, name="scheduled_task", help="Manage scheduled tasks") +app.add_typer(scheduled_task.app, name="scheduled-task", help="Manage scheduled tasks") app.add_typer(webapp.app, name="webapp", help="Everything for web apps") diff --git a/cli/scheduled_task.py b/cli/scheduled_task.py index 24ab7a8..d1471a2 100644 --- a/cli/scheduled_task.py +++ b/cli/scheduled_task.py @@ -1,11 +1,59 @@ import typer +from pythonanywhere.task import Task + app = typer.Typer() @app.command() -def create(): - raise NotImplementedError +def create( + command: str = typer.Option( + ..., "-c", "--command", help="Task's command to be scheduled" + ), + hour: int = typer.Option( + None, + "-h", + "--hour", + min=0, + max=23, + help="Sets the task to be performed daily at HOUR", + ), + minute: int = typer.Option( + ..., + "-m", + "--minute", + min=0, + max=59, + help="Minute on which the task will be executed", + ), + disabled: bool = typer.Option( + False, "-d", "--disabled", help="Creates disabled task (otherwise enabled)" + ), +): + """Create a scheduled task. + + Two categories of tasks are available: daily and hourly. + Both kinds require a command to run and scheduled time. In order to create a + daily task provide hour and minute; to create hourly task provide only minute. + If task is intended to be enabled later add --disabled flag. + + Example: + Create a daily task to be run at 13:15: + + pa scheduled-task create --command "echo foo" --hour 13 --minute 15 + + Create an inactive hourly task to be run 27 minutes past every hour: + + pa scheduled-task create --command "echo bar" --minute 27 --disabled + + Note: + Once task is created its behavior may be altered later on with + `pa scheduled-task update` or deleted with `pa scheduled-task delete` + commands.""" + task = Task.to_be_created( + command=command, hour=hour, minute=minute, disabled=disabled + ) + task.create_schedule() @app.command() diff --git a/tests/test_cli_scheduled_task.py b/tests/test_cli_scheduled_task.py new file mode 100644 index 0000000..56afd9b --- /dev/null +++ b/tests/test_cli_scheduled_task.py @@ -0,0 +1,41 @@ +from unittest.mock import call + +from typer.testing import CliRunner + +from cli.scheduled_task import app + +runner = CliRunner() + + +def test_create_calls_all_stuff_in_right_order(mocker): + mock_task_to_be_created = mocker.patch("cli.scheduled_task.Task.to_be_created") + + runner.invoke( + app, + [ + "create", + "--command", + "echo foo", + "--hour", + 8, + "--minute", + 10, + ], + ) + + assert mock_task_to_be_created.call_args == call( + command="echo foo", hour=8, minute=10, disabled=False + ) + assert mock_task_to_be_created.return_value.method_calls == [call.create_schedule()] + + +def test_create_validates_minutes(): + result = runner.invoke(app, ["create", "-c", "echo foo", "-h", 8, "-m", 66]) + assert "Invalid value" in result.stdout + assert "66 is not in the valid range of 0 to 59" in result.stdout + + +def test_create_validates_hours(): + result = runner.invoke(app, ["create", "-c", "echo foo", "-h", 66, "-m", 1]) + assert "Invalid value" in result.stdout + assert "66 is not in the valid range of 0 to 23" in result.stdout