from django.test import TestCase from django.utils import html from unittest import skip from ..forms import ( DUPLICATE_ITEM_ERROR, EMPTY_ITEM_ERROR, ) from ..models import Item, List import lxml.html class HomePageTest(TestCase): def test_uses_home_template(self): response = self.client.get('/') self.assertTemplateUsed(response, 'apps/dashboard/home.html') def test_renders_input_form(self): response = self.client.get('/') parsed = lxml.html.fromstring(response.content) forms = parsed.cssselect('form[method=POST]') self.assertIn("/apps/dashboard/new_list", [form.get("action") for form in forms]) [form] = [form for form in forms if form.get("action") == "/apps/dashboard/new_list"] inputs = form.cssselect("input") self.assertIn("text", [input.get("name") for input in inputs]) class NewListTest(TestCase): def test_can_save_a_POST_request(self): self. client.post("/apps/dashboard/new_list", data={"text": "A new list item"}) self.assertEqual(Item.objects.count(), 1) new_item = Item.objects.get() self.assertEqual(new_item.text, "A new list item") def test_redirects_after_POST(self): response = self.client.post("/apps/dashboard/new_list", data={"text": "A new list item"}) new_list = List.objects.get() self.assertRedirects(response, f"/apps/dashboard/{new_list.id}/") # Post invalid input helper def post_invalid_input(self): return self.client.post("/apps/dashboard/new_list", 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.assertTemplateUsed(response, "apps/dashboard/home.html") def test_for_invalid_input_shows_error_on_page(self): response = self.post_invalid_input() self.assertContains(response, html.escape(EMPTY_ITEM_ERROR)) class ListViewTest(TestCase): def test_uses_list_template(self): mylist = List.objects.create() response = self.client.get(f"/apps/dashboard/{mylist.id}/") self.assertTemplateUsed(response, "apps/dashboard/list.html") def test_renders_input_form(self): mylist = List.objects.create() url = f"/apps/dashboard/{mylist.id}/" response = self.client.get(url) parsed = lxml.html.fromstring(response.content) forms = parsed.cssselect("form[method=POST]") self.assertIn(url, [form.get("action") for form in forms]) [form] = [form for form in forms if form.get("action") == url] inputs = form.cssselect("input") self.assertIn("text", [input.get("name") for input in inputs]) def test_displays_only_items_for_that_list(self): # Given/Arrange correct_list = List.objects.create() Item.objects.create(text="itemey 1", list=correct_list) Item.objects.create(text="itemey 2", list=correct_list) other_list = List.objects.create() Item.objects.create(text="other list item", list=other_list) # When/Act response = self.client.get(f"/apps/dashboard/{correct_list.id}/") # Then/Assert self.assertContains(response, "itemey 1") self.assertContains(response, "itemey 2") self.assertNotContains(response, "other list item") def test_can_save_a_POST_request_to_an_existing_list(self): other_list = List.objects.create() correct_list = List.objects.create() self.client.post( f"/apps/dashboard/{correct_list.id}/", data={"text": "A new item for an existing list"}, ) self.assertEqual(Item.objects.count(), 1) new_item = Item.objects.get() self.assertEqual(new_item.text, "A new item for an existing list") self.assertEqual(new_item.list, correct_list) def test_POST_redirects_to_list_view(self): other_list = List.objects.create() correct_list = List.objects.create() response = self.client.post( f"/apps/dashboard/{correct_list.id}/", data={"text": "A new item for an existing list"}, ) self.assertRedirects(response, f"/apps/dashboard/{correct_list.id}/") # Post invalid input helper def post_invalid_input(self): mylist = List.objects.create() return self.client.post(f"/apps/dashboard/{mylist.id}/", 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.assertTemplateUsed(response, "apps/dashboard/list.html") def test_for_invalid_input_shows_error_on_page(self): response = self.post_invalid_input() self.assertContains(response, html.escape(EMPTY_ITEM_ERROR)) def test_for_invalid_input_sets_is_invalid_class(self): response = self.post_invalid_input() parsed = lxml.html.fromstring(response.content) [input] = parsed.cssselect("input[name=text]") self.assertIn("is-invalid", set(input.classes)) def test_duplicate_item_validation_errors_end_up_on_lists_page(self): list1 = List.objects.create() Item.objects.create(list=list1, text="lorem ipsum") response = self.client.post( f"/apps/dashboard/{list1.id}/", data={"text": "lorem ipsum"}, ) expected_error = html.escape(DUPLICATE_ITEM_ERROR) self.assertContains(response, expected_error) self.assertTemplateUsed(response, "apps/dashboard/list.html") self.assertEqual(Item.objects.all().count(), 1)