Skip to content

Commit b6f285a

Browse files
committed
Clean up paths code. Add more tests for startunicorn.
1 parent 4cf4b27 commit b6f285a

File tree

2 files changed

+190
-15
lines changed

2 files changed

+190
-15
lines changed

django_unicorn/management/commands/startunicorn.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
2+
import webbrowser
23
from pathlib import Path
3-
from webbrowser import open
44

55
from django.conf import settings
66
from django.core.management.base import BaseCommand, CommandError
@@ -45,11 +45,16 @@ def handle(self, *args, **options):
4545
# Fallback to the current directory
4646
base_path = os.getcwd()
4747

48+
base_path = Path(base_path)
49+
50+
if "app_name" not in options:
51+
raise CommandError("An application name is required.")
52+
4853
if "component_names" not in options:
49-
raise CommandError("Pass in at least one component name.")
54+
raise CommandError("At least one component name is required.")
5055

5156
app_name = options["app_name"]
52-
app_directory = Path(base_path) / Path(app_name)
57+
app_directory = base_path / app_name
5358

5459
is_app_directory_correct = input(
5560
f"\nUse '{app_directory}' for the app directory? [Y/n] "
@@ -64,10 +69,11 @@ def handle(self, *args, **options):
6469
if not app_directory.exists():
6570
is_new_app = True
6671
app_directory.mkdir()
67-
(app_directory / Path("__init__.py")).touch(exist_ok=True)
72+
73+
(app_directory / "__init__.py").touch(exist_ok=True)
6874

6975
# Create component
70-
component_base_path = app_directory / Path("components")
76+
component_base_path = app_directory / "components"
7177

7278
if not component_base_path.exists():
7379
component_base_path.mkdir()
@@ -78,15 +84,13 @@ def handle(self, *args, **options):
7884

7985
is_first_component = True
8086

81-
(component_base_path / Path("__init__.py")).touch(exist_ok=True)
87+
(component_base_path / "__init__.py").touch(exist_ok=True)
8288

8389
for component_name in options["component_names"]:
8490
snake_case_component_name = convert_to_snake_case(component_name)
8591
pascal_case_component_name = convert_to_pascal_case(component_name)
8692

87-
component_path = component_base_path / Path(
88-
f"{snake_case_component_name}.py"
89-
)
93+
component_path = component_base_path / f"{snake_case_component_name}.py"
9094

9195
if component_path.exists():
9296
self.stdout.write(
@@ -103,15 +107,15 @@ def handle(self, *args, **options):
103107
self.stdout.write(self.style.SUCCESS(f"Created {component_path}."))
104108

105109
# Create template
106-
template_base_path = app_directory / Path("templates") / Path("unicorn")
110+
template_base_path = app_directory / "templates" / "unicorn"
107111

108112
if not template_base_path.exists():
109-
if not (app_directory / Path("templates")).exists():
110-
(app_directory / Path("templates")).mkdir()
113+
if not (app_directory / "templates").exists():
114+
(app_directory / "templates").mkdir()
111115

112116
template_base_path.mkdir()
113117

114-
template_path = template_base_path / Path(f"{component_name}.html")
118+
template_path = template_base_path / f"{component_name}.html"
115119

116120
if template_path.exists():
117121
self.stdout.write(
@@ -156,15 +160,17 @@ def handle(self, *args, **options):
156160
"""
157161
)
158162

159-
open("https://github.com/adamghill/django-unicorn", new=2)
163+
webbrowser.open(
164+
"https://github.com/adamghill/django-unicorn", new=2
165+
)
160166
else:
161167
self.stdout.write(
162168
self.style.ERROR(
163169
"That's a bummer, but I understand. I hope you will star it for me later!"
164170
)
165171
)
166172

167-
if is_new_app or app_name not in settings.INSTALLED_APPS:
173+
if is_new_app:
168174
self.stdout.write(
169175
self.style.WARNING(
170176
f'\nMake sure to add `"{app_name}",` to your INSTALLED_APPS list in your settings file if necessary.'

tests/management/commands/startunicorn/test_handle.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import io
12
import os
23

34
from django.core.management.base import CommandError
@@ -17,3 +18,171 @@ def test_handle_no_args(settings):
1718

1819
with pytest.raises(CommandError):
1920
Command().handle()
21+
22+
23+
def test_handle_new_app(settings, tmp_path, monkeypatch, capsys):
24+
settings.BASE_DIR = tmp_path
25+
26+
# Reply "y" then "n"
27+
monkeypatch.setattr("sys.stdin", io.StringIO("y\nn\n"))
28+
29+
app_name = "test123"
30+
component_names = ["hello-world"]
31+
Command().handle(app_name=app_name, component_names=component_names)
32+
33+
assert (tmp_path / f"{app_name}/components/__init__.py").exists()
34+
assert (tmp_path / f"{app_name}/components/hello_world.py").exists()
35+
assert (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
36+
37+
captured = capsys.readouterr()
38+
assert "Starring the GitHub repo " in captured.out
39+
assert f'Make sure to add `"{app_name}",` to your' in captured.out
40+
41+
42+
def test_handle_existing_app(settings, tmp_path, monkeypatch, capsys):
43+
settings.BASE_DIR = tmp_path
44+
45+
app_name = "test123"
46+
(tmp_path / app_name).mkdir()
47+
48+
# Reply "y" then "n"
49+
monkeypatch.setattr("sys.stdin", io.StringIO("y\nn\n"))
50+
51+
component_names = ["hello-world"]
52+
Command().handle(app_name=app_name, component_names=component_names)
53+
54+
assert (tmp_path / f"{app_name}/components/__init__.py").exists()
55+
assert (tmp_path / f"{app_name}/components/hello_world.py").exists()
56+
assert (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
57+
58+
captured = capsys.readouterr()
59+
assert "Starring the GitHub repo " in captured.out
60+
assert "That's a bummer" in captured.out
61+
assert "Make sure to add " not in captured.out
62+
63+
64+
def test_handle_existing_component(settings, tmp_path, monkeypatch, capsys):
65+
settings.BASE_DIR = tmp_path
66+
67+
app_name = "test123"
68+
(tmp_path / app_name).mkdir()
69+
(tmp_path / app_name / "components").mkdir()
70+
71+
# Reply "y"
72+
monkeypatch.setattr("sys.stdin", io.StringIO("y\n"))
73+
74+
component_names = ["hello-world"]
75+
Command().handle(app_name=app_name, component_names=component_names)
76+
77+
assert (tmp_path / f"{app_name}/components/__init__.py").exists()
78+
assert (tmp_path / f"{app_name}/components/hello_world.py").exists()
79+
assert (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
80+
81+
captured = capsys.readouterr()
82+
assert "Starring the GitHub repo " not in captured.out
83+
assert "Make sure to add " not in captured.out
84+
85+
86+
def test_handle_existing_templates(settings, tmp_path, monkeypatch, capsys):
87+
settings.BASE_DIR = tmp_path
88+
89+
app_name = "test123"
90+
(tmp_path / app_name).mkdir()
91+
(tmp_path / app_name / "components").mkdir()
92+
(tmp_path / app_name / "templates").mkdir()
93+
94+
# Reply "y"
95+
monkeypatch.setattr("sys.stdin", io.StringIO("y\n"))
96+
97+
component_names = ["hello-world"]
98+
Command().handle(app_name=app_name, component_names=component_names)
99+
100+
assert (tmp_path / f"{app_name}/components/__init__.py").exists()
101+
assert (tmp_path / f"{app_name}/components/hello_world.py").exists()
102+
assert (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
103+
104+
captured = capsys.readouterr()
105+
assert "Starring the GitHub repo " not in captured.out
106+
assert "Make sure to add " not in captured.out
107+
108+
109+
def test_handle_existing_unicorn_templates(settings, tmp_path, monkeypatch, capsys):
110+
settings.BASE_DIR = tmp_path
111+
112+
app_name = "test123"
113+
(tmp_path / app_name).mkdir()
114+
(tmp_path / app_name / "components").mkdir()
115+
(tmp_path / app_name / "templates").mkdir()
116+
(tmp_path / app_name / "templates" / "unicorn").mkdir()
117+
118+
# Reply "y"
119+
monkeypatch.setattr("sys.stdin", io.StringIO("y\n"))
120+
121+
component_names = ["hello-world"]
122+
Command().handle(app_name=app_name, component_names=component_names)
123+
124+
assert (tmp_path / f"{app_name}/components/__init__.py").exists()
125+
assert (tmp_path / f"{app_name}/components/hello_world.py").exists()
126+
assert (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
127+
128+
captured = capsys.readouterr()
129+
assert "Starring the GitHub repo " not in captured.out
130+
assert "Make sure to add " not in captured.out
131+
132+
133+
def test_handle_reply_no(settings, tmp_path, monkeypatch, capsys):
134+
settings.BASE_DIR = tmp_path
135+
136+
# Reply "n"
137+
monkeypatch.setattr("sys.stdin", io.StringIO("n\n"))
138+
139+
app_name = "test123"
140+
component_names = ["hello-world"]
141+
Command().handle(app_name=app_name, component_names=component_names)
142+
143+
assert not (tmp_path / f"{app_name}/components/__init__.py").exists()
144+
assert not (tmp_path / f"{app_name}/components/hello_world.py").exists()
145+
assert not (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
146+
147+
captured = capsys.readouterr()
148+
assert "Make sure to add " not in captured.out
149+
150+
# Reply "no"
151+
monkeypatch.setattr("sys.stdin", io.StringIO("no\n"))
152+
153+
Command().handle(app_name=app_name, component_names=component_names)
154+
155+
assert not (tmp_path / f"{app_name}/components/__init__.py").exists()
156+
assert not (tmp_path / f"{app_name}/components/hello_world.py").exists()
157+
assert not (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
158+
159+
captured = capsys.readouterr()
160+
assert "Make sure to add " not in captured.out
161+
162+
163+
def test_handle_reply_yes_star(settings, tmp_path, monkeypatch, capsys):
164+
settings.BASE_DIR = tmp_path
165+
166+
# Reply "y" then "y"
167+
monkeypatch.setattr("sys.stdin", io.StringIO("y\ny\n"))
168+
169+
# Patch opening a webbrowser
170+
def webbrowser_open(url, **kwargs):
171+
assert url == "https://github.com/adamghill/django-unicorn"
172+
173+
monkeypatch.setattr("webbrowser.open", webbrowser_open)
174+
175+
app_name = "test123"
176+
component_names = ["hello-world"]
177+
178+
Command().handle(app_name=app_name, component_names=component_names)
179+
180+
assert (tmp_path / f"{app_name}/components/__init__.py").exists()
181+
assert (tmp_path / f"{app_name}/components/hello_world.py").exists()
182+
assert (tmp_path / f"{app_name}/templates/unicorn/hello-world.html").exists()
183+
184+
captured = capsys.readouterr()
185+
assert "Starring the GitHub repo " in captured.out
186+
assert "That's a bummer" not in captured.out
187+
assert "Thank you for helping spread the" in captured.out
188+
assert f'Make sure to add `"{app_name}",` to your' in captured.out

0 commit comments

Comments
 (0)