Skip to content

Commit 29bff0f

Browse files
committed
PA-752: Checking domain name already exists when creating a website. by Nina & Sam
1 parent d1b6c04 commit 29bff0f

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

pythonanywhere_core/website.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import os
12
import getpass
3+
from snakesay import snakesay
4+
from textwrap import dedent
25

36
from pythonanywhere_core.base import call_api, get_api_endpoint
4-
from pythonanywhere_core.exceptions import PythonAnywhereApiException
5-
7+
from pythonanywhere_core.exceptions import SanityException, PythonAnywhereApiException
68

79

810
class Website:
@@ -27,6 +29,35 @@ def __init__(self) -> None:
2729
self.websites_base_url = get_api_endpoint(username=getpass.getuser(), flavor="websites")
2830
self.domains_base_url = get_api_endpoint(username=getpass.getuser(), flavor="domains")
2931

32+
def sanity_check(self, domain_name: str, nuke: bool = False) -> None:
33+
"""Check that we have a token, and that we don't already have a webapp for this domain"""
34+
print(snakesay("Running API sanity checks"))
35+
token = os.environ.get("API_TOKEN")
36+
if not token:
37+
raise SanityException(
38+
dedent(
39+
"""
40+
Could not find your API token.
41+
You may need to create it on the Accounts page?
42+
You will also need to close this console and open a new one once you've done that.
43+
"""
44+
)
45+
)
46+
47+
if nuke:
48+
return
49+
50+
response = call_api(
51+
f"{self.websites_base_url}{domain_name}/",
52+
"get"
53+
)
54+
55+
if response.status_code == 200:
56+
raise SanityException(
57+
f"You already have a webapp for {domain_name}.\n\nUse the --nuke option if you want to replace it."
58+
)
59+
60+
3061
def create(self, domain_name: str, command: str) -> dict:
3162
"""Creates new website with ``domain_name`` and ``command``.
3263

tests/test_website.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pythonanywhere_core.base import get_api_endpoint
88
from pythonanywhere_core.exceptions import PythonAnywhereApiException
99
from pythonanywhere_core.website import Website
10+
from pythonanywhere_core.exceptions import SanityException, PythonAnywhereApiException
1011

1112

1213
pytestmark = pytest.mark.usefixtures("api_token")
@@ -159,3 +160,31 @@ def test_raises_if_ssl_info_does_not_return_200(api_responses, domain_name, doma
159160

160161
assert "GET SSL details via API failed, got" in str(e.value)
161162
assert "nope" in str(e.value)
163+
164+
165+
def test_website_sanity_check_domain_already_exists(api_responses, websites_base_url, website_info, domain_name):
166+
api_responses.add(
167+
responses.GET,
168+
url=f"{websites_base_url}{domain_name}/",
169+
status=200,
170+
body=json.dumps(website_info)
171+
)
172+
173+
with pytest.raises(SanityException) as e:
174+
Website().sanity_check(domain_name=domain_name, nuke=False)
175+
176+
177+
def test_website_sanity_check_can_be_bypassed_with_nuke_option(api_responses, websites_base_url, website_info, domain_name):
178+
# Test that the sanity check does not raise an exception
179+
Website().sanity_check(domain_name=domain_name, nuke=True)
180+
181+
182+
def test_website_sanity_check_tests_api_token_present(api_responses, websites_base_url, website_info, domain_name):
183+
import os
184+
del os.environ["API_TOKEN"]
185+
186+
# Test that the sanity check does not raise an exception
187+
with pytest.raises(SanityException) as e:
188+
Website().sanity_check(domain_name=domain_name, nuke=False)
189+
190+
assert "Could not find your API token" in str(e.value)

0 commit comments

Comments
 (0)