Fakultas Ilmu Komputer UI
Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
PMPL
Collection of Practice
2019
1606889830-practice
Commits
7e0f8d2a
Commit
7e0f8d2a
authored
Dec 21, 2019
by
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
Changes
15
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
7e0f8d2a
...
...
@@ -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
...
...
functional_tests/base.py
View file @
7e0f8d2a
...
...
@@ -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
(
't
r
'
)
rows
=
table
.
find_elements_by_tag_name
(
't
d
'
)
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
])
functional_tests/test_content.py
0 → 100644
View file @
7e0f8d2a
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
functional_tests/test_delete_item.py
0 → 100644
View file @
7e0f8d2a
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'
)
functional_tests/test_list_item_validation.py
View file @
7e0f8d2a
...
...
@@ -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
...
...
lists/migrations/0009_item_created_date.py
0 → 100644
View file @
7e0f8d2a
# 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'
),
),
]
lists/models.py
View file @
7e0f8d2a
...
...
@@ -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'
,)
...
...
lists/templates/base.html
View file @
7e0f8d2a
...
...
@@ -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
lists/templates/list.html
View file @
7e0f8d2a
...
...
@@ -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
lists/tests/test_models.py
View file @
7e0f8d2a
...
...
@@ -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
):
...
...
lists/tests/test_views.py
View file @
7e0f8d2a
...
...
@@ -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
):
...
...
lists/urls.py
View file @
7e0f8d2a
...
...
@@ -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'
),
]
lists/views.py
View file @
7e0f8d2a
...
...
@@ -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"
...
...
requirements.txt
View file @
7e0f8d2a
...
...
@@ -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
superlists/settings.py
View file @
7e0f8d2a
...
...
@@ -125,7 +125,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE
=
'en-us'
TIME_ZONE
=
'
UTC
'
TIME_ZONE
=
'
Asia/Jakarta
'
USE_I18N
=
True
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment