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 django.test import TestCase
|
||||||
from ..models import Item, List
|
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.text, "A sequel somehow better than the first")
|
||||||
self.assertEqual(second_saved_item.list, mylist)
|
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.test import TestCase
|
||||||
|
from django.utils import html
|
||||||
from ..models import Item, List
|
from ..models import Item, List
|
||||||
import lxml.html
|
import lxml.html
|
||||||
|
|
||||||
@@ -56,6 +57,18 @@ 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):
|
||||||
|
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):
|
class NewItemTest(TestCase):
|
||||||
def test_can_save_a_POST_request_to_an_existing_list(self):
|
def test_can_save_a_POST_request_to_an_existing_list(self):
|
||||||
other_list = List.objects.create()
|
other_list = List.objects.create()
|
||||||
|
|||||||
@@ -1,18 +1,26 @@
|
|||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
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')
|
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):
|
def view_list(request, list_id):
|
||||||
our_list = List.objects.get(id=list_id)
|
our_list = List.objects.get(id=list_id)
|
||||||
return render(request, 'apps/dashboard/list.html', {'list': our_list})
|
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):
|
def add_item(request, list_id):
|
||||||
our_list = List.objects.get(id=list_id)
|
our_list = List.objects.get(id=list_id)
|
||||||
Item.objects.create(text=request.POST['item_text'], list=our_list)
|
Item.objects.create(text=request.POST['item_text'], list=our_list)
|
||||||
|
|||||||
@@ -18,6 +18,16 @@ class FunctionalTest(StaticLiveServerTestCase):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.browser.quit()
|
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):
|
def wait_for_row_in_list_table(self, row_text):
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
while True:
|
while True:
|
||||||
@@ -30,13 +40,3 @@ 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 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("Make tea")
|
||||||
self.browser.find_element(By.ID, "id-new-item").send_keys(Keys.ENTER)
|
self.browser.find_element(By.ID, "id-new-item").send_keys(Keys.ENTER)
|
||||||
self.wait_for_row_in_list_table("2. Make tea")
|
self.wait_for_row_in_list_table("2. Make tea")
|
||||||
|
|
||||||
self.fail("finish the fight!")
|
|
||||||
|
|||||||
@@ -14,16 +14,20 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center p-5 bg-body-tertiary rounded-3">
|
<div class="row justify-content-center p-5 bg-body-tertiary rounded-3">
|
||||||
<div class="col-lg-6 text-center">
|
<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 %}">
|
<form method="POST" action="{% block form_action %}{% endblock form_action %}">
|
||||||
<input
|
<input
|
||||||
name="item_text"
|
name="item_text"
|
||||||
id="id-new-item"
|
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"
|
placeholder="Enter a to-do item"
|
||||||
/>
|
/>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
{% if error %}
|
||||||
|
<div class="invalid-feedback">{{ error }}</div>
|
||||||
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user