Skip to content

Commit

Permalink
#5 django start subcommand.
Browse files Browse the repository at this point in the history
  • Loading branch information
filiplajszczak authored and caseneuve committed Mar 13, 2021
1 parent c33d8df commit 750b417
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 13 deletions.
46 changes: 44 additions & 2 deletions cli/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,47 @@ def autoconfigure(


@app.command()
def start():
raise NotImplementedError
def start(
domain_name: str = typer.Option(
"your-username.pythonanywhere.com",
"-d",
"--domain",
help="Domain name, eg www.mydomain.com",
),
django_version: str = typer.Option(
"latest",
"-j",
"--django_version",
help="Django version, eg '3.1.2'",
),
python_version: str = typer.Option(
"3.6",
"-p",
"--python_version",
help="Python version, eg '3.8'",
),
nuke: bool = typer.Option(
False,
help="*Irrevocably* delete any existing web app config on this domain. Irrevocably.",
),
):
"""
Create a new Django webapp with a virtualenv. Defaults to
your free domain, the latest version of Django and Python 3.6
"""
domain = ensure_domain(domain_name)
project = DjangoProject(domain, python_version)
project.sanity_checks(nuke=nuke)
project.create_virtualenv(django_version, nuke=nuke)
project.run_startproject(nuke=nuke)
project.find_django_files()
project.update_settings_file()
project.run_collectstatic()
project.create_webapp(nuke=nuke)
project.add_static_file_mappings()

project.update_wsgi_file()

project.webapp.reload()

typer.echo(snakesay(f"All done! Your site is now live at https://{domain}"))
168 changes: 157 additions & 11 deletions tests/test_cli_django.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import subprocess
import time
from platform import python_version
from unittest.mock import Mock, call
from unittest.mock import call

import pytest
import requests
Expand All @@ -13,10 +13,27 @@
runner = CliRunner()


def test_autoconfigure_calls_all_stuff_in_right_order(mocker):
mock_project = mocker.patch("cli.django.DjangoProject")
mocker.patch("cli.webapp.ensure_domain", Mock(side_effect=lambda x: x))
@pytest.fixture
def mock_django_project(mocker):
return mocker.patch("cli.django.DjangoProject")


@pytest.fixture
def mock_update_wsgi_file(mocker):
return mocker.patch("cli.django.DjangoProject.update_wsgi_file")


@pytest.fixture
def mock_call_api(mocker):
return mocker.patch("pythonanywhere.api.webapp.call_api")


@pytest.fixture
def running_python_version():
return ".".join(python_version().split(".")[:2])


def test_autoconfigure_calls_all_stuff_in_right_order(mock_django_project):
result = runner.invoke(
app,
[
Expand All @@ -29,9 +46,8 @@ def test_autoconfigure_calls_all_stuff_in_right_order(mocker):
"--nuke",
],
)
print(result.stdout)
mock_project.assert_called_once_with("www.domain.com", "python.version")
assert mock_project.return_value.method_calls == [
mock_django_project.assert_called_once_with("www.domain.com", "python.version")
assert mock_django_project.return_value.method_calls == [
call.sanity_checks(nuke=True),
call.download_repo("repo.url", nuke=True),
call.create_virtualenv(nuke=True),
Expand All @@ -52,12 +68,16 @@ def test_autoconfigure_calls_all_stuff_in_right_order(mocker):

@pytest.mark.slowtest
def test_autoconfigure_actually_works_against_example_repo(
mocker, fake_home, virtualenvs_folder, api_token, process_killer
mocker,
mock_call_api,
mock_update_wsgi_file,
fake_home,
virtualenvs_folder,
api_token,
process_killer,
running_python_version,
):
mocker.patch("cli.django.DjangoProject.update_wsgi_file")
mocker.patch("cli.django.DjangoProject.start_bash")
mocker.patch("pythonanywhere.api.webapp.call_api")
running_python_version = ".".join(python_version().split(".")[:2])
repo = "https://github.com/pythonanywhere/example-django-project.git"
domain = "mydomain.com"

Expand Down Expand Up @@ -108,3 +128,129 @@ def test_autoconfigure_actually_works_against_example_repo(
time.sleep(2)
response = requests.get("http://localhost:8000/", headers={"HOST": "mydomain.com"})
assert "Hello from an example django project" in response.text


def test_start_calls_all_stuff_in_right_order(mock_django_project):
result = runner.invoke(
app,
[
"start",
"-d",
"www.domain.com",
"-j",
"django.version",
"-p",
"python.version",
"--nuke",
],
)

assert mock_django_project.call_args == call("www.domain.com", "python.version")
assert mock_django_project.return_value.method_calls == [
call.sanity_checks(nuke=True),
call.create_virtualenv("django.version", nuke=True),
call.run_startproject(nuke=True),
call.find_django_files(),
call.update_settings_file(),
call.run_collectstatic(),
call.create_webapp(nuke=True),
call.add_static_file_mappings(),
call.update_wsgi_file(),
call.webapp.reload(),
]
assert (
f"All done! Your site is now live at https://www.domain.com" in result.stdout
)


@pytest.mark.slowtest
def test_start_actually_creates_django_project_in_virtualenv_with_hacked_settings_and_static_files(
mock_call_api,
mock_update_wsgi_file,
fake_home,
virtualenvs_folder,
api_token,
running_python_version,
):
runner.invoke(
app,
[
"start",
"-d",
"mydomain.com",
"-j",
"2.2.12",
"-p",
running_python_version,
],
)

django_version = (
subprocess.check_output(
[
str(virtualenvs_folder / "mydomain.com/bin/python"),
"-c" "import django; print(django.get_version())",
]
)
.decode()
.strip()
)
assert django_version == "2.2.12"

with (fake_home / "mydomain.com/mysite/settings.py").open() as f:
lines = f.read().split("\n")
assert "MEDIA_ROOT = os.path.join(BASE_DIR, 'media')" in lines
assert "ALLOWED_HOSTS = ['mydomain.com']" in lines

assert "base.css" in os.listdir(str(fake_home / "mydomain.com/static/admin/css"))


@pytest.mark.slowtest
def test_nuke_option_lets_you_run_twice(
mock_call_api,
mock_update_wsgi_file,
fake_home,
virtualenvs_folder,
api_token,
running_python_version,
):
old_django_version = "2.2.12"
new_django_version = "3.0.6"

runner.invoke(
app,
[
"start",
"-d",
"mydomain.com",
"-j",
old_django_version,
"-p",
running_python_version,
],
)
runner.invoke(
app,
[
"start",
"-d",
"mydomain.com",
"-j",
new_django_version,
"-p",
running_python_version,
"--nuke",
],
)

django_version = (
subprocess.check_output(
[
str(virtualenvs_folder / "mydomain.com/bin/python"),
"-c" "import django; print(django.get_version())",
]
)
.decode()
.strip()
)
assert django_version == new_django_version

0 comments on commit 750b417

Please sign in to comment.