diff --git a/README.md b/README.md index 34e7bf65fbb98ccdda0e7129ca19aab09104de1b..16d6dc6febeff77328bf1e4bfb7432ba099242a4 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,18 @@ # 1606821886-practice Herokuapp : https://pmpl-farah.herokuapp.com/ +master + [](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606821886-practice/commits/master) [](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606821886-practice/commits/master) +uas-take-home branch + +[](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606821886-practice/commits/uas-take-home) + +[](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606821886-practice/commits/uas-take-home) + ## Table of Contents - Exercise 3 : @@ -24,6 +32,9 @@ Herokuapp : https://pmpl-farah.herokuapp.com/ - Mocks Can Leave You Tightly Coupled - Exercise 9 : - Perbedaan implementasi functional test fitur login +- Exercise 10 : + - Migrasi data + - Populate data ## Exercise 3 **Proses test isolation** diff --git a/functional_tests/test_layout_and_styling.py b/functional_tests/test_layout_and_styling.py index 97c06d5550de9651a53d9d20deb1956fadaeaf17..adc8e6efa6cfa829075970d755a8a4f0f40ad6c8 100644 --- a/functional_tests/test_layout_and_styling.py +++ b/functional_tests/test_layout_and_styling.py @@ -1,8 +1,20 @@ from .base import FunctionalTest from selenium.webdriver.common.keys import Keys +from lists.models import Item +import pytz + class LayoutAndStylingTest(FunctionalTest): + def test_name_in_header_and_footer(self): + self.browser.get(self.live_server_url) + + header = self.browser.find_element_by_id('header').text + footer = self.browser.find_element_by_id('footer').text + + self.assertIn('Farah Alhaniy', header) + self.assertIn('Farah Alhaniy', footer) + def test_layout_and_styling(self): # Edith goes to the home page self.browser.get(self.live_server_url) @@ -19,7 +31,20 @@ class LayoutAndStylingTest(FunctionalTest): # centered there too inputbox.send_keys('testing') inputbox.send_keys(Keys.ENTER) - self.wait_for_row_in_list_table('1: testing') + + data = Item.objects.all() + date1 = '' + for item in data: + if (item.text=='testing'): + date = item.created_at + tz = pytz.timezone('Asia/Jakarta') + date = date.astimezone(tz) + if ((int(date.strftime("%H"))) <= 11) : + date1 = str(date.strftime("%b. %d, %Y, %-I:%M a.m.")) + else : + date1 = str(date.strftime("%b. %d, %Y, %-I:%M p.m.")) + + self.wait_for_row_in_list_table('1: testing '+date1) inputbox = self.browser.find_element_by_id('id_new_item') self.assertAlmostEqual( inputbox.location['x'] + inputbox.size['width'] / 2, diff --git a/functional_tests/test_simple_list_creation.py b/functional_tests/test_simple_list_creation.py index 3b01a3212cd5e810742040db8cd4cc09460fade0..9cefc8c5960ce950eec9c4e8132378292c8593fd 100644 --- a/functional_tests/test_simple_list_creation.py +++ b/functional_tests/test_simple_list_creation.py @@ -2,8 +2,8 @@ from .base import FunctionalTest from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options - - +from lists.models import Item +import pytz class NewVisitorTest(FunctionalTest): @@ -13,7 +13,7 @@ class NewVisitorTest(FunctionalTest): url = self.live_server_url self.browser.get(url) - self.assertIn('Homepage - Farah Alhaniy', self.browser.title) + self.assertIn('To-Do List - Farah Alhaniy', self.browser.title) # She notices the page title and header mention to-do lists # self.assertIn('To-Do', self.browser.title) @@ -34,7 +34,20 @@ class NewVisitorTest(FunctionalTest): # 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.wait_for_row_in_list_table('1: Buy peacock feathers') + + data = Item.objects.all() + date1 = '' + for item in data: + if (item.text=='Buy peacock feathers'): + date = item.created_at + tz = pytz.timezone('Asia/Jakarta') + date = date.astimezone(tz) + if ((int(date.strftime("%H"))) <= 11) : + date1 = str(date.strftime("%b. %d, %Y, %-I:%M a.m.")) + else : + date1 = str(date.strftime("%b. %d, %Y, %-I:%M p.m.")) + + self.wait_for_row_in_list_table('1: Buy peacock feathers '+date1) # There is still a text box inviting her to add another item. She # enters "Use peacock feathers to make a fly" (Edith is very @@ -43,9 +56,21 @@ class NewVisitorTest(FunctionalTest): inputbox.send_keys('Use peacock feathers to make a fly') inputbox.send_keys(Keys.ENTER) + data = Item.objects.all() + date2 = '' + for item in data: + if (item.text=='Use peacock feathers to make a fly'): + date = item.created_at + tz = pytz.timezone('Asia/Jakarta') + date = date.astimezone(tz) + if ((int(date.strftime("%H"))) <= 11) : + date2 = str(date.strftime("%b. %d, %Y, %-I:%M a.m.")) + else : + date2 = str(date.strftime("%b. %d, %Y, %-I:%M p.m.")) + # The page updates again, and now shows both items on her list - self.wait_for_row_in_list_table('2: Use peacock feathers to make a fly') - self.wait_for_row_in_list_table('1: Buy peacock feathers') + self.wait_for_row_in_list_table('2: Use peacock feathers to make a fly '+date2) + self.wait_for_row_in_list_table('1: Buy peacock feathers '+date1) # 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 @@ -61,7 +86,20 @@ class NewVisitorTest(FunctionalTest): inputbox = self.browser.find_element_by_id('id_new_item') inputbox.send_keys('Buy peacock feathers') inputbox.send_keys(Keys.ENTER) - self.wait_for_row_in_list_table('1: Buy peacock feathers') + + data = Item.objects.all() + date1 = '' + for item in data: + if (item.text=='Buy peacock feathers'): + date = item.created_at + tz = pytz.timezone('Asia/Jakarta') + date = date.astimezone(tz) + if ((int(date.strftime("%H"))) <= 11) : + date1 = str(date.strftime("%b. %d, %Y, %-I:%M a.m.")) + else : + date1 = str(date.strftime("%b. %d, %Y, %-I:%M p.m.")) + + self.wait_for_row_in_list_table('1: Buy peacock feathers '+date1) # She notices that her list has a unique URL edith_list_url = self.browser.current_url @@ -91,7 +129,20 @@ class NewVisitorTest(FunctionalTest): inputbox = self.browser.find_element_by_id('id_new_item') inputbox.send_keys('Buy milk') inputbox.send_keys(Keys.ENTER) - self.wait_for_row_in_list_table('1: Buy milk') + + data = Item.objects.all() + date2 = '' + for item in data: + if (item.text=='Buy milk'): + date = item.created_at + tz = pytz.timezone('Asia/Jakarta') + date = date.astimezone(tz) + if ((int(date.strftime("%H"))) <= 11) : + date2 = str(date.strftime("%b. %d, %Y, %-I:%M a.m.")) + else : + date2 = str(date.strftime("%b. %d, %Y, %-I:%M p.m.")) + + self.wait_for_row_in_list_table('1: Buy milk '+date2) # Francis gets his own unique URL francis_list_url = self.browser.current_url diff --git a/lists/migrations/0007_item_created_at.py b/lists/migrations/0007_item_created_at.py new file mode 100644 index 0000000000000000000000000000000000000000..9e45cb27c04f80e0b84ba83a95ae63f56d8fcbf6 --- /dev/null +++ b/lists/migrations/0007_item_created_at.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.5 on 2019-12-23 12:44 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('lists', '0006_unique_together'), + ] + + operations = [ + migrations.AddField( + model_name='item', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + preserve_default=False, + ), + ] diff --git a/lists/models.py b/lists/models.py index 6d91b4db7e19bd8245670ec396286bae1c41f3d6..76837dcfb214b10d1761c309210bb3000fad2fcb 100644 --- a/lists/models.py +++ b/lists/models.py @@ -6,6 +6,7 @@ class List(models.Model): class Item(models.Model): text = models.TextField(default='') list = models.ForeignKey(List, default=None, on_delete=models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ('id',) diff --git a/lists/templates/base.html b/lists/templates/base.html index afae2d8596f09339f5ac9186de3234a981fe232f..328d4681a468b0a3faa1337eba1dc86079cc6d16 100644 --- a/lists/templates/base.html +++ b/lists/templates/base.html @@ -5,7 +5,7 @@ <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>Homepage - Farah Alhaniy</title> + <title>To-Do List - Farah Alhaniy</title> <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="/static/base.css" rel="stylesheet"> </head> @@ -14,8 +14,8 @@ <div class="container"> <nav class="navbar navbar-default" role="navigation"> - <div class="container-fluid"> - <a class="navbar-brand" href="/">Superlists</a> + <div class="container-fluid" id=header> + <a class="navbar-brand" href="/">Superlists by Farah Alhaniy</a> {% if user.email %} <ul class="nav navbar-nav navbar-right"> <li class="navbar-text">Logged in as {{ user.email }}</li> @@ -51,7 +51,6 @@ <div class="col-md-6 col-md-offset-3 jumbotron"> <div class="text-center"> <h1 id="name">Hi!</h1> - <h2 id="npm">I'm Farah, a CompSci student</h1> <h1>{% block header_text %}{% endblock %}</h1> <form method="POST" action="{% block form_action %}{% endblock %}"> <input name="item_text" id="id_new_item" @@ -71,6 +70,8 @@ </div> </div> + <div class="footer text-center" id="footer" style="bottom: 0; width: 100%;"> + <p>Made with <i class="fa fa-heart" aria-hidden="true" style="color:#E90606"></i> by Farah Alhaniy - 1606821886</p> </body> diff --git a/lists/templates/list.html b/lists/templates/list.html index 37be8fe081abe92214a711046c79de6b0c180497..3ea5932776378fadcd63f8165bb54e8dd92a5a9f 100644 --- a/lists/templates/list.html +++ b/lists/templates/list.html @@ -5,11 +5,14 @@ {% block form_action %}/lists/{{ list.id }}/add_item{% endblock %} {% block table %} + <p id="comment">{{ comment }}</p> <table id="id_list_table" class="table"> {% for item in list.item_set.all %} - <tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr> + <tr> + <td>{{ forloop.counter }}: {{ item.text }}</td> + <td class="text-muted" align="right">{{ item.created_at }}</td> + </tr> {% endfor %} - </table> - <h3 id="comment">{{ comment }}</h3> + </table>\ </body> {% endblock %} \ No newline at end of file diff --git a/lists/tests/test_views.py b/lists/tests/test_views.py index 0189e90726cd934e3a857978267b95cb6a3b0b5a..50787128e73981ec2d8d360b214969c2699c95e7 100644 --- a/lists/tests/test_views.py +++ b/lists/tests/test_views.py @@ -84,10 +84,10 @@ class HomePageTest(TestCase): html = response.content.decode('utf8') expected_greeting = 'Hi!' - expected_name = 'Farah' + # expected_name = 'Farah' self.assertIn(expected_greeting, html) - self.assertIn(expected_name, html) + # self.assertIn(expected_name, html) def test_only_saves_items_when_necessary(self): self.client.get('/') @@ -102,7 +102,7 @@ class HomePageTest(TestCase): response = self.client.get('/') html = response.content.decode('utf8') self.assertTrue(html.startswith('<!DOCTYPE html>')) - self.assertIn('<title>Homepage - Farah Alhaniy</title>', html) + self.assertIn('<title>To-Do List - Farah Alhaniy</title>', html) self.assertTrue(html.strip().endswith('</html>')) self.assertTemplateUsed(response, 'home.html') diff --git a/superlists/settings.py b/superlists/settings.py index 48b4be439352daad64b1c66906596cb2ace7d59f..1c984f30282c1382a78f8198e973691e9312c076 100644 --- a/superlists/settings.py +++ b/superlists/settings.py @@ -119,7 +119,7 @@ AUTH_PASSWORD_VALIDATORS = [ LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Asia/Jakarta' USE_I18N = True