emancipated hardcoded form views & html from base.html, apps.dashboard.views, apps.dashboard.tests.test_views; added get_item_input_box() helper method to functional_tests.base & retrofitted the other FTs to utilize it
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils import html
|
from django.utils import html
|
||||||
|
from ..forms import EMPTY_ITEM_ERROR
|
||||||
from ..models import Item, List
|
from ..models import Item, List
|
||||||
import lxml.html
|
import lxml.html
|
||||||
|
|
||||||
@@ -28,17 +29,22 @@ class NewListTest(TestCase):
|
|||||||
new_list = List.objects.get()
|
new_list = List.objects.get()
|
||||||
self.assertRedirects(response, f'/apps/dashboard/{new_list.id}/')
|
self.assertRedirects(response, f'/apps/dashboard/{new_list.id}/')
|
||||||
|
|
||||||
def test_validation_errors_are_sent_back_to_home_page_template(self):
|
# Post invalid input helper
|
||||||
response = self.client.post("/apps/dashboard/newlist", data={"text": ""})
|
def post_invalid_input(self):
|
||||||
|
return self.client.post("/apps/dashboard/newlist", data={"text": ""})
|
||||||
|
|
||||||
|
def test_for_invalid_input_nothing_saved_to_db(self):
|
||||||
|
self.post_invalid_input()
|
||||||
|
self.assertEqual(Item.objects.count(), 0)
|
||||||
|
|
||||||
|
def test_for_invalid_input_renders_list_template(self):
|
||||||
|
response = self.post_invalid_input()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertTemplateUsed(response, "apps/dashboard/home.html")
|
self.assertTemplateUsed(response, "apps/dashboard/home.html")
|
||||||
expected_error = html.escape("You can't have an empty list item")
|
|
||||||
self.assertContains(response, expected_error)
|
|
||||||
|
|
||||||
def test_invalid_list_items_never_save(self):
|
def test_for_invalid_input_shows_error_on_page(self):
|
||||||
self.client.post("/apps/dashboard/newlist", data={"text": ""})
|
response = self.post_invalid_input()
|
||||||
self.assertEqual(List.objects.count(), 0)
|
self.assertContains(response, html.escape(EMPTY_ITEM_ERROR))
|
||||||
self.assertEqual(Item.objects.count(), 0)
|
|
||||||
|
|
||||||
class DashViewTest(TestCase):
|
class DashViewTest(TestCase):
|
||||||
def test_uses_list_template(self):
|
def test_uses_list_template(self):
|
||||||
@@ -94,13 +100,20 @@ class DashViewTest(TestCase):
|
|||||||
|
|
||||||
self.assertRedirects(response, f'/apps/dashboard/{correct_list.id}/')
|
self.assertRedirects(response, f'/apps/dashboard/{correct_list.id}/')
|
||||||
|
|
||||||
def test_validation_errors_end_up_on_lists_page(self):
|
# Post invalid input helper
|
||||||
list_ = List.objects.create()
|
def post_invalid_input(self):
|
||||||
response = self.client.post(
|
mylist = List.objects.create()
|
||||||
f"/apps/dashboard/{list_.id}/",
|
return self.client.post(f"/apps/dashboard/{mylist.id}/", data={"text": ""})
|
||||||
data={"text": ""},
|
|
||||||
)
|
def test_for_invalid_input_nothing_saved_to_db(self):
|
||||||
|
self.post_invalid_input()
|
||||||
|
self.assertEqual(Item.objects.count(), 0)
|
||||||
|
|
||||||
|
def test_for_invalid_input_renders_list_template(self):
|
||||||
|
response = self.post_invalid_input()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertTemplateUsed(response, "apps/dashboard/list.html")
|
self.assertTemplateUsed(response, "apps/dashboard/list.html")
|
||||||
expected_error = html.escape("You can't have an empty list item")
|
|
||||||
self.assertContains(response, expected_error)
|
def test_for_invalid_input_shows_error_on_page(self):
|
||||||
|
response = self.post_invalid_input()
|
||||||
|
self.assertContains(response, html.escape(EMPTY_ITEM_ERROR))
|
||||||
|
|||||||
@@ -4,26 +4,24 @@ from .forms import ItemForm
|
|||||||
from .models import Item, List
|
from .models import Item, List
|
||||||
|
|
||||||
def home_page(request):
|
def home_page(request):
|
||||||
# return render(request, 'apps/dashboard/home.html', {"form": ItemForm()})
|
return render(request, 'apps/dashboard/home.html', {"form": ItemForm()})
|
||||||
return render(request, "apps/dashboard/home.html")
|
|
||||||
|
|
||||||
def new_list(request):
|
def new_list(request):
|
||||||
|
form = ItemForm(data=request.POST)
|
||||||
|
if form.is_valid():
|
||||||
nulist = List.objects.create()
|
nulist = List.objects.create()
|
||||||
item = Item(text=request.POST['text'], list=nulist)
|
Item.objects.create(text=request.POST["text"], list=nulist)
|
||||||
try:
|
|
||||||
item.full_clean()
|
|
||||||
item.save()
|
|
||||||
except ValidationError:
|
|
||||||
nulist.delete()
|
|
||||||
error = "You can't have an empty list item"
|
|
||||||
return render(request, "apps/dashboard/home.html", {"error": error})
|
|
||||||
return redirect(nulist)
|
return redirect(nulist)
|
||||||
|
else:
|
||||||
|
return render(request, "apps/dashboard/home.html", {"form": form})
|
||||||
|
|
||||||
def view_list(request, list_id):
|
def view_list(request, list_id):
|
||||||
our_list = List.objects.get(id=list_id)
|
our_list = List.objects.get(id=list_id)
|
||||||
error = None
|
error = None
|
||||||
|
form = ItemForm()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
form = ItemForm(data=request.POST)
|
||||||
try:
|
try:
|
||||||
item = Item(text=request.POST['text'], list=our_list)
|
item = Item(text=request.POST['text'], list=our_list)
|
||||||
item.full_clean()
|
item.full_clean()
|
||||||
@@ -32,5 +30,5 @@ def view_list(request, list_id):
|
|||||||
except ValidationError:
|
except ValidationError:
|
||||||
error = "You can't have an empty list item"
|
error = "You can't have an empty list item"
|
||||||
|
|
||||||
return render(request, 'apps/dashboard/list.html', {'list': our_list, "error": error})
|
return render(request, 'apps/dashboard/list.html', {'list': our_list, "form": form, "error": error})
|
||||||
|
|
||||||
|
|||||||
@@ -40,3 +40,6 @@ class FunctionalTest(StaticLiveServerTestCase):
|
|||||||
if time.time() - start_time > MAX_WAIT:
|
if time.time() - start_time > MAX_WAIT:
|
||||||
raise
|
raise
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
def get_item_input_box(self):
|
||||||
|
return self.browser.find_element(By.ID, "id-text")
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class LayoutAndStylingTest(FunctionalTest):
|
|||||||
self.browser.set_window_size(1024, 768)
|
self.browser.set_window_size(1024, 768)
|
||||||
# print("Viewport width:", self.browser.execute_script("return window.innerWidth"))
|
# print("Viewport width:", self.browser.execute_script("return window.innerWidth"))
|
||||||
|
|
||||||
inputbox = self.browser.find_element(By.ID, 'id-new-item')
|
inputbox = self.get_item_input_box()
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
inputbox.location['x'] + inputbox.size['width'] / 2,
|
inputbox.location['x'] + inputbox.size['width'] / 2,
|
||||||
512,
|
512,
|
||||||
@@ -20,7 +20,7 @@ class LayoutAndStylingTest(FunctionalTest):
|
|||||||
inputbox.send_keys('testing')
|
inputbox.send_keys('testing')
|
||||||
inputbox.send_keys(Keys.ENTER)
|
inputbox.send_keys(Keys.ENTER)
|
||||||
self.wait_for_row_in_list_table('1. testing')
|
self.wait_for_row_in_list_table('1. testing')
|
||||||
inputbox = self.browser.find_element(By.ID, 'id-new-item')
|
inputbox = self.get_item_input_box()
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
inputbox.location['x'] + inputbox.size['width'] / 2,
|
inputbox.location['x'] + inputbox.size['width'] / 2,
|
||||||
512,
|
512,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from .base import FunctionalTest
|
|||||||
class ItemValidationTest(FunctionalTest):
|
class ItemValidationTest(FunctionalTest):
|
||||||
def test_cannot_add_empty_list_items(self):
|
def test_cannot_add_empty_list_items(self):
|
||||||
self.browser.get(self.live_server_url)
|
self.browser.get(self.live_server_url)
|
||||||
self.browser.find_element(By.ID, "id-new-item").send_keys(Keys.ENTER)
|
self.get_item_input_box().send_keys(Keys.ENTER)
|
||||||
|
|
||||||
self.wait_for(
|
self.wait_for(
|
||||||
lambda: self.assertEqual(
|
lambda: self.assertEqual(
|
||||||
@@ -15,12 +15,12 @@ class ItemValidationTest(FunctionalTest):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.browser.find_element(By.ID, "id-new-item").send_keys("Purchase milk")
|
self.get_item_input_box().send_keys("Purchase milk")
|
||||||
self.browser.find_element(By.ID, "id-new-item").send_keys(Keys.ENTER)
|
self.get_item_input_box().send_keys(Keys.ENTER)
|
||||||
|
|
||||||
self.wait_for_row_in_list_table("1. Purchase milk")
|
self.wait_for_row_in_list_table("1. Purchase milk")
|
||||||
|
|
||||||
self.browser.find_element(By.ID, "id-new-item").send_keys(Keys.ENTER)
|
self.get_item_input_box().send_keys(Keys.ENTER)
|
||||||
|
|
||||||
self.wait_for(
|
self.wait_for(
|
||||||
lambda: self.assertEqual(
|
lambda: self.assertEqual(
|
||||||
@@ -29,6 +29,6 @@ class ItemValidationTest(FunctionalTest):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.browser.find_element(By.ID, 'id-new-item').send_keys("Make tea")
|
self.get_item_input_box().send_keys("Make tea")
|
||||||
self.browser.find_element(By.ID, "id-new-item").send_keys(Keys.ENTER)
|
self.get_item_input_box().send_keys(Keys.ENTER)
|
||||||
self.wait_for_row_in_list_table("2. Make tea")
|
self.wait_for_row_in_list_table("2. Make tea")
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class NewVisitorTest(FunctionalTest):
|
|||||||
header_text = self.browser.find_element(By.TAG_NAME, 'h1').text
|
header_text = self.browser.find_element(By.TAG_NAME, 'h1').text
|
||||||
self.assertIn('Dashboard', header_text)
|
self.assertIn('Dashboard', header_text)
|
||||||
|
|
||||||
inputbox = self.browser.find_element(By.ID, 'id-new-item')
|
inputbox = self.get_item_input_box()
|
||||||
self.assertEqual(inputbox.get_attribute('placeholder'), 'Enter a to-do item')
|
self.assertEqual(inputbox.get_attribute('placeholder'), 'Enter a to-do item')
|
||||||
|
|
||||||
inputbox.send_keys('Buy peacock feathers')
|
inputbox.send_keys('Buy peacock feathers')
|
||||||
@@ -22,7 +22,7 @@ class NewVisitorTest(FunctionalTest):
|
|||||||
inputbox.send_keys(Keys.ENTER)
|
inputbox.send_keys(Keys.ENTER)
|
||||||
self.wait_for_row_in_list_table('1. Buy peacock feathers')
|
self.wait_for_row_in_list_table('1. Buy peacock feathers')
|
||||||
|
|
||||||
inputbox = self.browser.find_element(By.ID, 'id-new-item')
|
inputbox = self.get_item_input_box()
|
||||||
inputbox.send_keys('Use peacock feathers to make a fly')
|
inputbox.send_keys('Use peacock feathers to make a fly')
|
||||||
inputbox.send_keys(Keys.ENTER)
|
inputbox.send_keys(Keys.ENTER)
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ class NewVisitorTest(FunctionalTest):
|
|||||||
|
|
||||||
def test_multiple_users_can_start_lists_at_different_urls(self):
|
def test_multiple_users_can_start_lists_at_different_urls(self):
|
||||||
self.browser.get(self.live_server_url)
|
self.browser.get(self.live_server_url)
|
||||||
inputbox = self.browser.find_element(By.ID, 'id-new-item')
|
inputbox = self.get_item_input_box()
|
||||||
inputbox.send_keys('Buy peacock feathers')
|
inputbox.send_keys('Buy peacock feathers')
|
||||||
inputbox.send_keys(Keys.ENTER)
|
inputbox.send_keys(Keys.ENTER)
|
||||||
self.wait_for_row_in_list_table('1. Buy peacock feathers')
|
self.wait_for_row_in_list_table('1. Buy peacock feathers')
|
||||||
@@ -45,7 +45,7 @@ class NewVisitorTest(FunctionalTest):
|
|||||||
page_text = self.browser.find_element(By.TAG_NAME, 'body').text
|
page_text = self.browser.find_element(By.TAG_NAME, 'body').text
|
||||||
self.assertNotIn('Buy peacock feathers', page_text)
|
self.assertNotIn('Buy peacock feathers', page_text)
|
||||||
|
|
||||||
inputbox = self.browser.find_element(By.ID, 'id-new-item')
|
inputbox = self.get_item_input_box()
|
||||||
inputbox.send_keys('Buy milk')
|
inputbox.send_keys('Buy milk')
|
||||||
inputbox.send_keys(Keys.ENTER)
|
inputbox.send_keys(Keys.ENTER)
|
||||||
self.wait_for_row_in_list_table('1. Buy milk')
|
self.wait_for_row_in_list_table('1. Buy milk')
|
||||||
|
|||||||
@@ -18,19 +18,10 @@
|
|||||||
<h2 class="display-2 mb-2">{% block header_text %}{% endblock header_text %}</h2>
|
<h2 class="display-2 mb-2">{% block header_text %}{% endblock header_text %}</h2>
|
||||||
|
|
||||||
<form method="POST" action="{% block form_action %}{% endblock form_action %}">
|
<form method="POST" action="{% block form_action %}{% endblock form_action %}">
|
||||||
{% if form %}
|
|
||||||
{{ form.text }}
|
{{ form.text }}
|
||||||
{% else %}
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg{% if error %} is-invalid{% endif %}"
|
|
||||||
name="text"
|
|
||||||
id="id-new-item"
|
|
||||||
placeholder="Enter a to-do item"
|
|
||||||
/>
|
|
||||||
{% endif %}
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if error %}
|
{% if form.errors %}
|
||||||
<div class="invalid-feedback">{{ error }}</div>
|
<div class="invalid-feedback">{{ form.errors.text }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user