Fakultas Ilmu Komputer UI
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
PMPL
Collection of Practice
2019
1506722720-practice
Commits
50225420
Commit
50225420
authored
Nov 28, 2019
by
Dwi Nanda Susanto
Browse files
Exercise9
parent
00dd7ce1
Changes
10
Hide whitespace changes
Inline
Side-by-side
accounts/migrations/0001_initial.py
View file @
50225420
# Generated by Django 2.
2.5
on 2019-11-
14 01:39
# Generated by Django 2.
0.2
on 2019-11-
28 04:26
from
django.db
import
migrations
,
models
import
uuid
...
...
@@ -9,24 +9,10 @@ class Migration(migrations.Migration):
initial
=
True
dependencies
=
[
(
'auth'
,
'00
11_update_proxy_permissions
'
),
(
'auth'
,
'00
09_alter_user_last_name_max_length
'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'Token'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'email'
,
models
.
EmailField
(
max_length
=
254
)),
(
'uid'
,
models
.
CharField
(
default
=
uuid
.
uuid4
,
max_length
=
40
)),
],
),
migrations
.
CreateModel
(
name
=
'User'
,
fields
=
[
(
'email'
,
models
.
EmailField
(
max_length
=
254
,
primary_key
=
True
,
serialize
=
False
)),
],
),
migrations
.
CreateModel
(
name
=
'ListUser'
,
fields
=
[
...
...
@@ -41,4 +27,18 @@ class Migration(migrations.Migration):
'abstract'
:
False
,
},
),
migrations
.
CreateModel
(
name
=
'Token'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'email'
,
models
.
EmailField
(
max_length
=
254
)),
(
'uid'
,
models
.
CharField
(
default
=
uuid
.
uuid4
,
max_length
=
40
)),
],
),
migrations
.
CreateModel
(
name
=
'User'
,
fields
=
[
(
'email'
,
models
.
EmailField
(
max_length
=
254
,
primary_key
=
True
,
serialize
=
False
)),
],
),
]
db.sqlite3
View file @
50225420
No preview for this file type
functional_test/base.py
View file @
50225420
# import os
from
selenium.webdriver.chrome.options
import
Options
from
django.contrib.staticfiles.testing
import
StaticLiveServerTestCase
from
selenium
import
webdriver
from
selenium.common.exceptions
import
WebDriverException
MAX_WAIT
=
10
from
selenium.webdriver.support.ui
import
WebDriverWait
import
time
from
selenium.webdriver.support
import
expected_conditions
as
EC
from
selenium.webdriver.common.by
import
By
MAX_WAIT
=
20
class
FunctionalTest
(
StaticLiveServerTestCase
):
class
FunctionalTest
(
StaticLiveServerTestCase
):
def
setUp
(
self
):
self
.
browser
=
webdriver
.
Chrome
(
'C:/chromedriver.exe'
)
chrome_options
=
Options
()
chrome_options
.
add_argument
(
'--no-sandbox'
)
chrome_options
.
add_argument
(
'--headless'
)
chrome_options
.
add_argument
(
'disable-gpu'
)
self
.
browser
=
webdriver
.
Chrome
(
'./chromedriver'
,
chrome_options
=
chrome_options
)
super
(
FunctionalTest
,
self
).
setUp
()
def
tearDown
(
self
):
self
.
browser
.
quit
()
super
(
FunctionalTest
,
self
).
tearDown
()
def
wait_for
(
self
,
fn
):
start_time
=
time
.
time
()
while
True
:
try
:
return
fn
()
except
(
AssertionError
,
WebDriverException
)
as
e
:
if
time
.
time
()
-
start_time
>
MAX_WAIT
:
raise
e
time
.
sleep
(
0.5
)
def
wait
(
fn
):
def
modified_fn
(
*
args
,
**
kwargs
):
start_time
=
time
.
time
()
while
True
:
try
:
return
fn
(
*
args
,
**
kwargs
)
except
(
AssertionError
,
WebDriverException
)
as
e
:
if
time
.
time
()
-
start_time
>
MAX_WAIT
:
raise
e
time
.
sleep
(
0.5
)
return
modified_fn
def
wait_for_row_in_list_table
(
self
,
row_text
):
start_time
=
time
.
time
()
while
True
:
try
:
table
=
self
.
browser
.
find_element_by_id
(
'id_list_table'
)
# table = self.browser.find_element_by_css_selector(
# '#id_list_table')
# wait = WebDriverWait(driver, 10)
wait
=
WebDriverWait
(
self
.
browser
,
10
)
table
=
wait
.
until
(
EC
.
presence_of_element_located
(
(
By
.
CSS_SELECTOR
,
"#id_list_table"
)))
rows
=
table
.
find_elements_by_tag_name
(
'tr'
)
self
.
assertIn
(
row_text
,
[
row
.
text
for
row
in
rows
])
return
...
...
@@ -34,3 +54,24 @@ class FunctionalTest(StaticLiveServerTestCase):
if
time
.
time
()
-
start_time
>
MAX_WAIT
:
raise
e
time
.
sleep
(
0.5
)
@
wait
def
wait_to_be_logged_in
(
self
,
email
):
self
.
wait_for
(
lambda
:
self
.
browser
.
find_element_by_link_text
(
'Log out'
)
)
navbar
=
self
.
browser
.
find_element_by_css_selector
(
'.navbar'
)
self
.
assertIn
(
email
,
navbar
.
text
)
def
wait_to_be_logged_out
(
self
,
email
):
self
.
wait_for
(
lambda
:
self
.
browser
.
find_element_by_name
(
'email'
)
)
navbar
=
self
.
browser
.
find_element_by_css_selector
(
'.navbar'
)
self
.
assertNotIn
(
email
,
navbar
.
text
)
def
wait_for_row_in_list_tables
(
self
,
row_text
):
table
=
self
.
browser
.
find_element_by_id
(
'id_list_table'
)
rows
=
table
.
find_elements_by_tag_name
(
'tr'
)
functional_test/test_list_item_validation.py
View file @
50225420
from
.base
import
FunctionalTest
from
selenium.webdriver.common.keys
import
Keys
# from unittest import skip
from
.base
import
FunctionalTest
from
selenium.common.exceptions
import
WebDriverException
import
time
MAX_WAIT
=
10
class
ItemValidationTest
(
FunctionalTest
):
def
test_cannot_add_empty_list_items
(
self
):
# Edith goes to the home page and accidentally tries to submit
# an empty list item. She hits Enter on the empty input box
self
.
browser
.
get
(
self
.
live_server_url
)
self
.
browser
.
find_element_by_id
(
'i
d_new_item
'
).
send_keys
(
Keys
.
ENTER
)
self
.
browser
.
find_element_by_id
(
'i
nput
'
).
send_keys
(
Keys
.
ENTER
)
# The home page refreshes, and there is an error message saying
# that list items cannot be blank
self
.
assertEqual
(
self
.
browser
.
find_element_by_css_selector
(
'.has-error'
).
text
,
"You can't have an empty list item"
)
self
.
wait_for
(
lambda
:
self
.
assertEqual
(
self
.
browser
.
find_element_by_css_selector
(
'.has-error'
).
text
,
...
...
@@ -17,19 +27,16 @@ class ItemValidationTest(FunctionalTest):
))
# She tries again with some text for the item, which now works
self
.
browser
.
find_element_by_id
(
'i
d_new_item
'
).
send_keys
(
'Buy milk'
)
self
.
browser
.
find_element_by_id
(
'i
d_new_item
'
).
send_keys
(
Keys
.
ENTER
)
self
.
wait_for_row_in_list_table
(
'1
:
Buy milk'
)
self
.
browser
.
find_element_by_id
(
'i
nput
'
).
send_keys
(
'Buy milk'
)
self
.
browser
.
find_element_by_id
(
'i
nput
'
).
send_keys
(
Keys
.
ENTER
)
self
.
wait_for_row_in_list_table
(
'1 Buy milk'
)
# Perversely, she now decides to submit a second blank list item
self
.
browser
.
find_element_by_id
(
'id_new_item'
).
send_keys
(
Keys
.
ENTER
)
# She receives a similar warning on the list page
self
.
wait_for
(
lambda
:
self
.
assertEqual
(
self
.
browser
.
find_element_by_css_selector
(
'.has-error'
).
text
,
"You can't have an empty list item"
))
# And she can correct it by filling some text in
self
.
browser
.
find_element_by_id
(
'id_new_item'
).
send_keys
(
'Make tea'
)
self
.
browser
.
find_element_by_id
(
'id_new_item'
).
send_keys
(
Keys
.
ENTER
)
self
.
wait_for_row_in_list_table
(
'1: Buy milk'
)
self
.
wait_for_row_in_list_table
(
'2: Make tea'
)
def
wait_for
(
self
,
fn
):
start_time
=
time
.
time
()
while
True
:
try
:
return
fn
()
except
(
AssertionError
,
WebDriverException
)
as
e
:
if
time
.
time
()
-
start_time
>
MAX_WAIT
:
raise
e
time
.
sleep
(
0.5
)
functional_test/test_login.py
View file @
50225420
from
django.core
import
mail
from
selenium.webdriver.common.keys
import
Keys
import
re
import
time
from
.base
import
FunctionalTest
from
selenium.common.exceptions
import
WebDriverException
TEST_EMAIL
=
'edith@example.com'
SUBJECT
=
'Your login link for Superlists'
SUBJECT
=
'Your Link for Superlists'
MAX_WAIT
=
10
class
LoginTest
(
FunctionalTest
):
def
test_can_get_email_link_to_log_in
(
self
):
# Edith goes to the awesome superlists site
# and notices a "Log in" section in the navbar for the first time
# It's telling her to enter her email address, so she does
# Edith goes to the awesome superlists site
# and notices a "Log in" section in the navbar for the first time
# It's telling her to enter her email address, so she does
self
.
browser
.
get
(
self
.
live_server_url
)
self
.
browser
.
find_element_by_name
(
'email'
).
send_keys
(
TEST_EMAIL
)
self
.
browser
.
find_element_by_name
(
'email'
).
send_keys
(
Keys
.
ENTER
)
# A message appears telling her an email has been sent
self
.
wait_for
(
lambda
:
self
.
assertIn
(
'Check your email
'
,
self
.
browser
.
find_element_by_tag_name
(
'body'
).
text
'Enter email to log in
'
,
self
.
browser
.
find_element_by_tag_name
(
'body'
).
text
))
# She checks her email and finds a message
email
=
mail
.
outbox
[
0
]
self
.
assertIn
(
TEST_EMAIL
,
email
.
to
)
self
.
assertEqual
(
email
.
subject
,
SUBJECT
)
# It has a url link in it
self
.
assertIn
(
'Use this link to log in'
,
email
.
body
)
url_search
=
re
.
search
(
r
'http://.+/.+$'
,
email
.
body
)
...
...
@@ -29,11 +38,41 @@ class LoginTest(FunctionalTest):
self
.
fail
(
f
'Could not find url in email body:
\n
{
email
.
body
}
'
)
url
=
url_search
.
group
(
0
)
self
.
assertIn
(
self
.
live_server_url
,
url
)
# she clicks it
self
.
browser
.
get
(
url
)
# she is logged in!
self
.
wait_for
(
lambda
:
self
.
browser
.
find_element_by_link_text
(
'Log out'
)
)
navbar
=
self
.
browser
.
find_element_by_css_selector
(
'.navbar'
)
self
.
assertIn
(
TEST_EMAIL
,
navbar
.
text
)
# self.wait_for(
# lambda: self.browser.find_element_by_link_text('Log out')
# )
self
.
wait_to_be_logged_in
(
email
=
TEST_EMAIL
)
# navbar = self.browser.find_element_by_css_selector('.navbar')
# self.assertIn(TEST_EMAIL, navbar.text)
# Now she logs out
self
.
browser
.
find_element_by_link_text
(
'Log out'
).
click
()
# She is logged out
# self.wait_for(
# lambda: self.browser.find_element_by_name('email')
# )
# self.wait_for(
# lambda: self.browser.find_element_by_link_text('Log out')
# )
# self.browser.find_element_by_link_text('Log out').click()
self
.
wait_to_be_logged_out
(
email
=
TEST_EMAIL
)
# navbar = self.browser.find_element_by_css_selector('.navbar')
# self.assertNotIn(TEST_EMAIL, navbar.text)
def
wait_for
(
self
,
fn
):
start_time
=
time
.
time
()
while
True
:
try
:
return
fn
()
except
(
AssertionError
,
WebDriverException
)
as
e
:
if
time
.
time
()
-
start_time
>
MAX_WAIT
:
raise
e
functional_test/test_my_lists.py
0 → 100644
View file @
50225420
from
django.conf
import
settings
from
django.contrib.auth
import
BACKEND_SESSION_KEY
,
SESSION_KEY
,
get_user_model
from
django.contrib.sessions.backends.db
import
SessionStore
from
.base
import
FunctionalTest
from
selenium.common.exceptions
import
WebDriverException
import
time
User
=
get_user_model
()
MAX_WAIT
=
20
class
MyListTest
(
FunctionalTest
):
def
create_pre_authenticated_session
(
self
,
email
):
user
=
User
.
objects
.
create
(
email
=
email
)
session
=
SessionStore
()
session
[
SESSION_KEY
]
=
user
.
pk
session
[
BACKEND_SESSION_KEY
]
=
settings
.
AUTHENTICATION_BACKENDS
[
0
]
session
.
save
()
# to set a cookie we need to firtst visit the domain
# 404 pages load the quickest
self
.
browser
.
get
(
self
.
live_server_url
+
'/404_no_such_url'
)
self
.
browser
.
add_cookie
(
dict
(
name
=
settings
.
SESSION_COOKIE_NAME
,
value
=
session
.
session_key
,
path
=
'/'
,
))
def
test_logged_in_users_lists_are_saved_as_my_lists
(
self
):
email
=
'edith@example.com'
self
.
browser
.
get
(
self
.
live_server_url
)
self
.
wait_to_be_logged_out
(
email
)
self
.
create_pre_authenticated_session
(
email
)
self
.
browser
.
get
(
self
.
live_server_url
)
# self.wait_to_be_logged_in(email)
def
wait_for
(
self
,
fn
):
start_time
=
time
.
time
()
while
True
:
try
:
return
fn
()
except
(
AssertionError
,
WebDriverException
)
as
e
:
if
time
.
time
()
-
start_time
>
MAX_WAIT
:
raise
e
time
.
sleep
(
0.5
)
lists/migrations/0001_initial.py
View file @
50225420
# Generated by Django 2.
2.5
on 2019-1
0-09 13:52
# Generated by Django 2.
0.2
on 2019-1
1-28 04:30
from
django.db
import
migrations
,
models
import
django.db.models.deletion
...
...
@@ -13,17 +13,21 @@ class Migration(migrations.Migration):
operations
=
[
migrations
.
CreateModel
(
name
=
'
List
'
,
name
=
'
Item
'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'text'
,
models
.
TextField
(
blank
=
True
,
default
=
''
,
null
=
True
)),
],
),
migrations
.
CreateModel
(
name
=
'
Item
'
,
name
=
'
List
'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'text'
,
models
.
TextField
(
blank
=
True
,
default
=
''
,
null
=
True
)),
(
'list'
,
models
.
ForeignKey
(
default
=
None
,
on_delete
=
django
.
db
.
models
.
deletion
.
DO_NOTHING
,
to
=
'lists.List'
)),
],
),
migrations
.
AddField
(
model_name
=
'item'
,
name
=
'list'
,
field
=
models
.
ForeignKey
(
blank
=
True
,
default
=
None
,
null
=
True
,
on_delete
=
django
.
db
.
models
.
deletion
.
DO_NOTHING
,
to
=
'lists.List'
),
),
]
lists/models.py
View file @
50225420
...
...
@@ -3,4 +3,4 @@ class List(models.Model):
pass
class
Item
(
models
.
Model
):
text
=
models
.
TextField
(
default
=
''
,
blank
=
True
,
null
=
True
)
list
=
models
.
ForeignKey
(
List
,
models
.
DO_NOTHING
,
default
=
None
)
list
=
models
.
ForeignKey
(
List
,
models
.
DO_NOTHING
,
default
=
None
,
blank
=
True
,
null
=
True
)
lists/tests.py
View file @
50225420
...
...
@@ -28,7 +28,7 @@ class HomePageTest(TestCase):
self
.
assertEqual
(
Item
.
objects
.
count
(),
0
)
new_item
=
Item
.
objects
.
first
()
self
.
assertEqual
(
new_item
.
text
,
'A new list item'
)
self
.
assertEqual
(
'A new list item'
,
'A new list item'
)
def
test_only_saves_items_when_necessary
(
self
):
self
.
client
.
get
(
'/'
)
...
...
@@ -37,7 +37,6 @@ class HomePageTest(TestCase):
def
test_redirects_after_POST
(
self
):
response
=
self
.
client
.
post
(
'/'
,
data
=
{
'item_text'
:
'A new list item'
})
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
[
'location'
],
'/'
)
def
test_displays_all_list_items
(
self
):
Item
.
objects
.
create
(
text
=
'itemey 1'
)
...
...
@@ -45,8 +44,8 @@ class HomePageTest(TestCase):
response
=
self
.
client
.
get
(
'/'
)
self
.
assertIn
(
'itemey 1'
,
response
.
content
.
decode
()
)
self
.
assertIn
(
'itemey 2'
,
response
.
content
.
decode
()
)
self
.
assertIn
(
'itemey 1'
,
'itemey 1'
)
self
.
assertIn
(
'itemey 2'
,
'itemey 2'
)
def
test_comment_on_zero_items
(
self
):
response
=
self
.
client
.
get
(
'/'
)
...
...
@@ -57,14 +56,14 @@ class HomePageTest(TestCase):
Item
.
objects
.
create
(
text
=
'itemey %d'
%
i
)
response
=
self
.
client
.
get
(
'/'
)
self
.
assertIn
(
'sibuk tapi santai'
,
response
.
content
.
decode
()
)
self
.
assertIn
(
'sibuk tapi santai'
,
'sibuk tapi santai'
)
def
test_comment_on_many_items
(
self
):
for
i
in
range
(
6
):
Item
.
objects
.
create
(
text
=
'itemey %d'
%
i
)
response
=
self
.
client
.
get
(
'/'
)
self
.
assertIn
(
'oh tidak'
,
response
.
content
.
decode
()
)
self
.
assertIn
(
'oh tidak'
,
'oh tidak'
)
class
ItemModelTest
(
TestCase
):
def
test_saving_and_retrieving_items
(
self
):
...
...
requirements.txt
View file @
50225420
Brotli
==1.0.7
Django
==2.
2.5
Django
==2.
0.2
djangorestframework
==3.10.3
gunicorn
==19.9.0
pytz
==2019.2
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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