From 73132ed330ab56db029e9340eee9be2257030ac4 Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 25 Sep 2019 22:41:08 +0700 Subject: [PATCH 1/3] FT refactor as its own small, atomic change: --- functional_tests.py | 25 ++++++++++++++++++------- lists/templates/home.html | 8 +++++++- lists/tests.py | 26 ++++++++++++-------------- lists/views.py | 4 +++- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/functional_tests.py b/functional_tests.py index f370240..bafd537 100644 --- a/functional_tests.py +++ b/functional_tests.py @@ -11,6 +11,11 @@ class NewVisitorTest(unittest.TestCase): def tearDown(self): self.browser.quit() + def check_for_row_in_list_table(self, row_text): + table = self.browser.find_element_by_id('id_list_table') + rows = table.find_elements_by_tag_name('tr') + self.assertIn(row_text, [row.text for row in rows]) + def test_can_start_a_list_and_retrieve_it_later(self): self.browser.get('http://localhost:8000') @@ -32,17 +37,23 @@ class NewVisitorTest(unittest.TestCase): # When she hits enter, the page updates, and now the page lists # "1: Buy peacock feathers" as an item in a to-do list table inputbox.send_keys(Keys.ENTER) + self.check_for_row_in_list_table('1: Buy peacock feathers') - table = self.browser.find_element_by_id('id_list_table') - rows = table.find_elements_by_tag_name('tr') - self.assertTrue( - - any(row.text == '1: Buy peacock feathers' for row in rows), - "New to-do item did not appear in table" - ) # There is still a text box inviting her to add another item. She # enters "Use peacock feathers to make a fly" (Edith is very # methodical) + inputbox = self.browser.find_element_by_id('id_new_item') + inputbox.send_keys('Use peacock feathers to make a fly') + inputbox.send_keys(Keys.ENTER) + + # The page updates again, and now shows both items on her list + self.check_for_row_in_list_table('1: Buy peacock feathers') + self.check_for_row_in_list_table('2: Use peacock feathers to make a fly') + + + # Edith wonders whether the site will remember her list. Then she sees + # that the site has generated a unique URL for her -- there is some + # explanatory text to that effect. self.fail('Finish the test!') #h = self.browser.page_source diff --git a/lists/templates/home.html b/lists/templates/home.html index 5474b01..1190734 100644 --- a/lists/templates/home.html +++ b/lists/templates/home.html @@ -4,7 +4,13 @@

Your To-Do list

- +
+ {% csrf_token %} + + +
+ +
1: {{ new_item_text }}
diff --git a/lists/tests.py b/lists/tests.py index b02f54c..230ebb7 100644 --- a/lists/tests.py +++ b/lists/tests.py @@ -9,7 +9,7 @@ class HomePageTest(TestCase): def test_root_url_resolves_to_home_page_view(self): found = resolve('/') self.assertEqual(found.func, home_page) - +#"" %csrf_string def test_home_page_returns_correct_html(self): request = HttpRequest() # response = home_page(request) # @@ -19,17 +19,15 @@ class HomePageTest(TestCase): #self.assertTrue(response.content.startswith(b'')) # #self.assertTrue(response.content.strip().endswith(b'')) # - #def test_home_page_returns_correct_html(self): - # request = HttpRequest() # - # response = home_page(request) # - # self.assertTrue(response.content.startswith(b'')) # - # self.assertIn(b'Rumah', response.content) # - # self.assertIn(b'

Jordan Muhammad Andrianda

', response.content) # - # self.assertIn(b'

1506722765

', response.content) # - # self.assertTrue(response.content.endswith(b'')) # - - -# class SmokeTest(TestCase): -# def test_bad_maths(self): -# self.assertEqual(1 + 1, 3) + def test_home_page_can_save_a_POST_request(self): + request = HttpRequest() + request.method = 'POST' + request.POST['item_text'] = 'A new list item' + response = home_page(request) + self.assertIn('A new list item', response.content.decode()) + expected_html = render_to_string( + 'home.html', + {'new_item_text': 'A new list item'} + ) + self.assertEqual(response.content.decode(), expected_html) diff --git a/lists/views.py b/lists/views.py index 8410f5b..e273a0a 100644 --- a/lists/views.py +++ b/lists/views.py @@ -3,4 +3,6 @@ from django.http import HttpResponse def home_page(request): #return HttpResponse('Rumah

Jordan Muhammad Andrianda

1506722765

') - return render(request,'home.html') + return render(request,'home.html', { + 'new_item_text': request.POST.get('item_text', ''), + }) -- GitLab From 29e3e1a6ca2ed4801fd3439adfe1aa032afbba66 Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 25 Sep 2019 22:49:42 +0700 Subject: [PATCH 2/3] Model for list Items and associated migration --- lists/migrations/0001_initial.py | 20 ++++++++++++++++++++ lists/migrations/0002_item_text.py | 18 ++++++++++++++++++ lists/models.py | 2 ++ lists/templates/home.html | 2 +- lists/tests.py | 18 ++++++++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 lists/migrations/0001_initial.py create mode 100644 lists/migrations/0002_item_text.py diff --git a/lists/migrations/0001_initial.py b/lists/migrations/0001_initial.py new file mode 100644 index 0000000..ac2a792 --- /dev/null +++ b/lists/migrations/0001_initial.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.5 on 2019-09-25 15:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Item', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + ] diff --git a/lists/migrations/0002_item_text.py b/lists/migrations/0002_item_text.py new file mode 100644 index 0000000..468321c --- /dev/null +++ b/lists/migrations/0002_item_text.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.5 on 2019-09-25 15:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lists', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='item', + name='text', + field=models.TextField(default=''), + ), + ] diff --git a/lists/models.py b/lists/models.py index 71a8362..59abf09 100644 --- a/lists/models.py +++ b/lists/models.py @@ -1,3 +1,5 @@ from django.db import models # Create your models here. +class Item(models.Model): + text = models.TextField(default='') diff --git a/lists/templates/home.html b/lists/templates/home.html index 1190734..57a26aa 100644 --- a/lists/templates/home.html +++ b/lists/templates/home.html @@ -5,7 +5,7 @@

Your To-Do list

- {% csrf_token %} +
diff --git a/lists/tests.py b/lists/tests.py index 230ebb7..a5702bb 100644 --- a/lists/tests.py +++ b/lists/tests.py @@ -2,6 +2,7 @@ from django.test import TestCase from django.urls import resolve from django.http import HttpRequest from lists.views import home_page +from lists.models import Item from django.template.loader import render_to_string # Create your tests here. @@ -31,3 +32,20 @@ class HomePageTest(TestCase): {'new_item_text': 'A new list item'} ) self.assertEqual(response.content.decode(), expected_html) +class ItemModelTest(TestCase): + def test_saving_and_retrieving_items(self): + first_item = Item() + first_item.text = 'The first (ever) list item' + first_item.save() + + second_item = Item() + second_item.text = 'Item the second' + second_item.save() + + saved_items = Item.objects.all() + self.assertEqual(saved_items.count(), 2) + + first_saved_item = saved_items[0] + second_saved_item = saved_items[1] + self.assertEqual(first_saved_item.text, 'The first (ever) list item') + self.assertEqual(second_saved_item.text, 'Item the second') -- GitLab From 1d3f179caa89b70ca7dde3e1519a22d48a2602c2 Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 25 Sep 2019 23:13:57 +0700 Subject: [PATCH 3/3] Redirect after POST, and show all items in template --- lists/templates/home.html | 6 ++++-- lists/tests.py | 40 +++++++++++++++++++++++++++++++++------ lists/views.py | 17 +++++++++++------ 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/lists/templates/home.html b/lists/templates/home.html index 57a26aa..e6b05e3 100644 --- a/lists/templates/home.html +++ b/lists/templates/home.html @@ -5,12 +5,14 @@

Your To-Do list

- + {% csrf_token %}
- + {% for item in items %} + + {% endfor %}
1: {{ new_item_text }}
{{ forloop.counter }}: {{ item.text }}
diff --git a/lists/tests.py b/lists/tests.py index a5702bb..91610b7 100644 --- a/lists/tests.py +++ b/lists/tests.py @@ -3,8 +3,11 @@ from django.urls import resolve from django.http import HttpRequest from lists.views import home_page from lists.models import Item + from django.template.loader import render_to_string + + # Create your tests here. class HomePageTest(TestCase): def test_root_url_resolves_to_home_page_view(self): @@ -25,13 +28,38 @@ class HomePageTest(TestCase): request = HttpRequest() request.method = 'POST' request.POST['item_text'] = 'A new list item' + + response = home_page(request) + + self.assertEqual(Item.objects.count(), 1) + new_item = Item.objects.first() + self.assertEqual(new_item.text, 'A new list item') + + def test_home_page_redirects_after_POST(self): + request = HttpRequest() + request.method = 'POST' + request.POST['item_text'] = 'A new list item' response = home_page(request) - self.assertIn('A new list item', response.content.decode()) - expected_html = render_to_string( - 'home.html', - {'new_item_text': 'A new list item'} - ) - self.assertEqual(response.content.decode(), expected_html) + + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], '/') + + + def test_home_page_only_saves_items_when_necessary(self): + request = HttpRequest() + home_page(request) + self.assertEqual(Item.objects.count(), 0) + + def test_home_page_displays_all_list_items(self): + Item.objects.create(text='itemey 1') + Item.objects.create(text='itemey 2') + + request = HttpRequest() + response = home_page(request) + + self.assertIn('itemey 1', response.content.decode()) + self.assertIn('itemey 2', response.content.decode()) + class ItemModelTest(TestCase): def test_saving_and_retrieving_items(self): first_item = Item() diff --git a/lists/views.py b/lists/views.py index e273a0a..ff38975 100644 --- a/lists/views.py +++ b/lists/views.py @@ -1,8 +1,13 @@ -from django.shortcuts import render -from django.http import HttpResponse +from django.shortcuts import redirect, render +from lists.models import Item -def home_page(request): +#def home_page(request): #return HttpResponse('Rumah

Jordan Muhammad Andrianda

1506722765

') - return render(request,'home.html', { - 'new_item_text': request.POST.get('item_text', ''), - }) + +def home_page(request): + if request.method == 'POST': + Item.objects.create(text=request.POST['item_text']) + return redirect('/') + items = Item.objects.all() + return render(request, 'home.html', {'items': items}) + -- GitLab