not getting the same precise error message, but perhaps the intent is the same?; anyway, updated views & some FTs, base.html for more dynamic error handling (tho incomplete)
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db.utils import IntegrityError
|
||||
from django.test import TestCase
|
||||
from ..models import Item, List
|
||||
|
||||
@@ -29,3 +31,14 @@ class ListAndItemModelsTest(TestCase):
|
||||
self.assertEqual(second_saved_item.text, "A sequel somehow better than the first")
|
||||
self.assertEqual(second_saved_item.list, mylist)
|
||||
|
||||
def test_cannot_save_null_list_items(self):
|
||||
mylist = List.objects.create()
|
||||
item = Item(list=mylist, text=None)
|
||||
with self.assertRaises(IntegrityError):
|
||||
item.save()
|
||||
|
||||
def test_cannot_save_empty_list_items(self):
|
||||
mylist = List.objects.create()
|
||||
item = Item(list=mylist, text="")
|
||||
with self.assertRaises(ValidationError):
|
||||
item.full_clean()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.test import TestCase
|
||||
from django.utils import html
|
||||
from ..models import Item, List
|
||||
import lxml.html
|
||||
|
||||
@@ -56,6 +57,18 @@ class NewListTest(TestCase):
|
||||
new_list = List.objects.get()
|
||||
self.assertRedirects(response, f'/apps/dashboard/{new_list.id}/')
|
||||
|
||||
def test_validation_errors_are_sent_back_to_home_page_template(self):
|
||||
response = self.client.post("/apps/dashboard/newlist", data={"item_text": ""})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
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):
|
||||
self.client.post("/apps/dashboard/newlist", data={"item_text": ""})
|
||||
self.assertEqual(List.objects.count(), 0)
|
||||
self.assertEqual(Item.objects.count(), 0)
|
||||
|
||||
class NewItemTest(TestCase):
|
||||
def test_can_save_a_POST_request_to_an_existing_list(self):
|
||||
other_list = List.objects.create()
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.shortcuts import redirect, render
|
||||
from .models import Item, List
|
||||
|
||||
def home_page(request):
|
||||
return render(request, 'apps/dashboard/home.html')
|
||||
|
||||
def new_list(request):
|
||||
nulist = List.objects.create()
|
||||
item = Item(text=request.POST['item_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(f'/apps/dashboard/{nulist.id}/')
|
||||
|
||||
def view_list(request, list_id):
|
||||
our_list = List.objects.get(id=list_id)
|
||||
return render(request, 'apps/dashboard/list.html', {'list': our_list})
|
||||
|
||||
def new_list(request):
|
||||
nulist = List.objects.create()
|
||||
Item.objects.create(text=request.POST['item_text'], list=nulist)
|
||||
return redirect(f'/apps/dashboard/{nulist.id}/')
|
||||
|
||||
def add_item(request, list_id):
|
||||
our_list = List.objects.get(id=list_id)
|
||||
Item.objects.create(text=request.POST['item_text'], list=our_list)
|
||||
|
||||
@@ -18,6 +18,16 @@ class FunctionalTest(StaticLiveServerTestCase):
|
||||
def tearDown(self):
|
||||
self.browser.quit()
|
||||
|
||||
def wait_for(self, fn):
|
||||
start_time = time.time()
|
||||
while True:
|
||||
try:
|
||||
return fn()
|
||||
except (AssertionError, WebDriverException):
|
||||
if time.time() - start_time > MAX_WAIT:
|
||||
raise
|
||||
time.sleep(0.5)
|
||||
|
||||
def wait_for_row_in_list_table(self, row_text):
|
||||
start_time = time.time()
|
||||
while True:
|
||||
@@ -30,13 +40,3 @@ class FunctionalTest(StaticLiveServerTestCase):
|
||||
if time.time() - start_time > MAX_WAIT:
|
||||
raise
|
||||
time.sleep(0.5)
|
||||
|
||||
def wait_for(self, fn):
|
||||
start_time = time.time()
|
||||
while True:
|
||||
try:
|
||||
return fn()
|
||||
except (AssertionError, WebDriverException):
|
||||
if time.time() - start_time > MAX_WAIT:
|
||||
raise
|
||||
time.sleep(0.5)
|
||||
@@ -31,5 +31,3 @@ class ItemValidationTest(FunctionalTest):
|
||||
self.browser.find_element(By.ID, 'id-new-item').send_keys("Make tea")
|
||||
self.browser.find_element(By.ID, "id-new-item").send_keys(Keys.ENTER)
|
||||
self.wait_for_row_in_list_table("2. Make tea")
|
||||
|
||||
self.fail("finish the fight!")
|
||||
|
||||
@@ -14,16 +14,20 @@
|
||||
<div class="container">
|
||||
<div class="row justify-content-center p-5 bg-body-tertiary rounded-3">
|
||||
<div class="col-lg-6 text-center">
|
||||
<h1 class="display-1 mb-4">Dashboard | {% block header_text %}{% endblock header_text %}</h1>
|
||||
<h1 class="display-1 mb-4">Dashboard</h1>
|
||||
<h2 class="display-2 mb-2">{% block header_text %}{% endblock header_text %}</h2>
|
||||
|
||||
<form method="POST" action="{% block form_action %}{% endblock form_action %}">
|
||||
<input
|
||||
name="item_text"
|
||||
id="id-new-item"
|
||||
class="form-control form-control-lg"
|
||||
class="form-control form-control-lg {% if error %}is-valid{% endif %}"
|
||||
placeholder="Enter a to-do item"
|
||||
/>
|
||||
{% csrf_token %}
|
||||
{% if error %}
|
||||
<div class="invalid-feedback">{{ error }}</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user