Fakultas Ilmu Komputer UI

Commit 7e0f8d2a authored by LUTHFI DZAKY SAIFUDDIN's avatar LUTHFI DZAKY SAIFUDDIN
Browse files

Merge branch 'take_home_programming' into 'master'

Take home programming

See merge request !18
parents f696194d 27885cca
Pipeline #27504 passed with stages
in 9 minutes and 6 seconds
......@@ -11,7 +11,8 @@ UnitTest:
- pip3 install -r requirements.txt
when: on_success
script:
- python3 manage.py test lists accounts
- coverage run --source=lists,accounts manage.py test lists accounts
- coverage report -m
Deployment:
image: ruby:2.4
......
......@@ -41,9 +41,15 @@ class FunctionalTest(StaticLiveServerTestCase):
@wait
def wait_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')
rows = table.find_elements_by_tag_name('td')
self.assertIn(row_text, [row.text for row in rows])
@wait
def wait_for_delete_item_in_list_table(self, row_text):
table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('td')
self.assertNotIn(row_text, [row.text for row in rows])
@wait
def wait_to_be_logged_in(self, email):
self.browser.find_element_by_link_text('Log out')
......@@ -55,3 +61,9 @@ class FunctionalTest(StaticLiveServerTestCase):
self.browser.find_element_by_name('email')
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertNotIn(email, navbar.text)
@wait
def wait_for_head_table(self, row_text):
table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('th')
self.assertIn(row_text, [row.text for row in rows])
from .base import FunctionalTest
class ContentTest(FunctionalTest):
def test_header_and_footer(self):
self.browser.get(self.live_server_url)
header = self.browser.find_element_by_tag_name('header')
self.assertIn("Luthfi Dzaky Saifuddin", header.text)
footer = self.browser.find_element_by_tag_name('footer')
self.assertIn("Luthfi Dzaky Saifuddin", footer.text)
\ No newline at end of file
from selenium.webdriver.common.keys import Keys
from .base import FunctionalTest
class DeleteItemTest(FunctionalTest):
def test_item_delete(self):
self.browser.get(self.live_server_url)
inputbox = self.browser.find_element_by_id('id_new_item')
self.assertEqual(
inputbox.get_attribute('placeholder'),
'Enter a to-do item'
)
inputbox.send_keys('An Item')
inputbox.send_keys(Keys.ENTER)
deletebutton = self.browser.find_elements_by_class_name('delete-item')
deletebutton[0].click()
self.wait_for_delete_item_in_list_table('1: An Item')
......@@ -19,6 +19,10 @@ class ItemValidationTest(FunctionalTest):
# She tries again with some text for the item, which now works
self.browser.find_element_by_id('id_new_item').send_keys('Buy milk')
self.browser.find_element_by_id('id_new_item').send_keys(Keys.ENTER)
# She tries to know the detail of to do
self.wait_for_head_table("My To Do List")
self.wait_for_head_table("Created Date")
self.wait_for_row_in_list_table('1: Buy milk')
# Perversely, she now decides to submit a second blank list item
......
# Generated by Django 2.2.5 on 2019-12-21 14:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lists', '0008_add_data'),
]
operations = [
migrations.AddField(
model_name='item',
name='created_date',
field=models.TextField(default='21/12/2019 14:03:11'),
),
]
......@@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.db import models
from django.urls import reverse
from datetime import datetime
class List(models.Model):
def get_absolute_url(self):
......@@ -12,6 +13,7 @@ class Item(models.Model):
text = models.TextField(default='')
list = models.ForeignKey(List, default=None, on_delete=models.CASCADE)
slug = models.SlugField(blank=True)
created_date = models.TextField(default=datetime.now().strftime("%d %m %Y %H:%M:%S"))
class Meta:
ordering = ('id',)
......
......@@ -13,6 +13,8 @@
</head>
<body>
<header>Header: Luthfi Dzaky Saifuddin</header>
<div class="card" id="card-luthfi">
<img src="https://assets.gitlab-static.net/uploads/-/system/user/avatar/1572360/avatar.png?width=90" alt="Luthfi"
style="width:100%">
......@@ -104,5 +106,6 @@
</div>
<footer>Footer: Luthfi Dzaky Saifuddin</footer>
</body>
</html>
\ No newline at end of file
......@@ -5,10 +5,21 @@
{% block form_action %}{% url 'view_list' list.id %}{% endblock %}
{% block table %}
<table id="id_list_table" class="table">
<tr><th>My To Do List</th></tr>
{% for item in list.item_set.all %}
<tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr>
{% endfor %}
</table>
<table id="id_list_table" class="table">
<tr>
<th>My To Do List</th>
<th>Created Date</th>
<th></th>
</tr>
{% for item in list.item_set.all %}
<tr>
<td>{{ forloop.counter }}: {{ item.text }}</td>
<td>{{ item.created_date }}</td>
<td><a href="{% url 'delete_item' list.id item.id %}" class="delete-item">
<div data-id="{{ data.id }}">&#10006</div>
</a>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
\ No newline at end of file
......@@ -27,8 +27,10 @@ class ListAndItemModelsTest(TestCase):
first_saved_item = saved_items[0]
second_saved_item = saved_items[1]
self.assertEqual(first_saved_item.text, 'The first (ever) list item')
self.assertNotEquals(first_saved_item.created_date, '')
self.assertEqual(first_saved_item.list, list_)
self.assertEqual(second_saved_item.text, 'Item the second')
self.assertNotEquals(second_saved_item.created_date, '')
self.assertEqual(second_saved_item.list, list_)
def test_cannot_save_empty_list_items(self):
......
......@@ -123,6 +123,51 @@ class NewListTest(TestCase):
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()
correct_list = List.objects.create()
self.client.post(
f'/lists/{correct_list.id}/add_item',
data={'item_text': 'A new item for an existing list'}
)
self.assertEqual(Item.objects.count(), 1)
new_item = Item.objects.first()
self.assertEqual(new_item.text, 'A new item for an existing list')
self.assertEqual(new_item.list, correct_list)
def test_redirects_to_list_view(self):
other_list = List.objects.create()
correct_list = List.objects.create()
response = self.client.post(
f'/lists/{correct_list.id}/add_item',
data={'item_text': 'A new item for an existing list'}
)
self.assertRedirects(response, f'/lists/{correct_list.id}/')
class DeleteItemTest(TestCase):
def test_function_delete_item(self):
_list = List.objects.create()
self.client.post(
f'/lists/{_list.id}/add_item',
data={'item_text': 'A new item for an existing list'}
)
self.assertEqual(Item.objects.count(), 1)
new_item = Item.objects.first()
self.client.post(
f'/lists/{_list.id}/delete_item/{new_item.id}'
)
self.assertEqual(Item.objects.count(), 0)
class TodoMessageTest(TestCase):
def test_function_message_is_zero(self):
......
......@@ -18,5 +18,7 @@ from lists import views
urlpatterns = [
url(r'^new$', views.new_list, name='new_list'),
url(r'^(\d+)/$', views.view_list, name='view_list')
url(r'^(\d+)/$', views.view_list, name='view_list'),
url(r'^(\d+)/add_item$', views.add_item, name='add_item'),
url(r'^(\d+)/delete_item/(\d+)$', views.delete_item, name='delete_item'),
]
......@@ -38,6 +38,12 @@ def add_item(request, list_id):
Item.objects.create(text=request.POST['item_text'], list=list_)
return redirect(f'/lists/{list_.id}/')
def delete_item(request, list_id, item_id):
item = Item.objects.get(id=item_id)
item.delete()
list_ = List.objects.get(id=list_id)
return redirect(f'/lists/{list_.id}/')
def message_todo(list_):
if (list_.item_set.count() == 0):
return "yey, waktunya berlibur"
......
......@@ -20,4 +20,5 @@ MutPy==0.6.0
pydot==1.4.1
pyparsing==2.4.2
PyYAML==5.1.2
termcolor==1.1.0
\ No newline at end of file
termcolor==1.1.0
coverage==5.0
\ No newline at end of file
......@@ -125,7 +125,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Jakarta'
USE_I18N = True
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment