diff --git a/README.md b/README.md index fb9af00037141916d7ceefaca264bb3c474757e9..ecbd121d02bfe222a0721cadbde5cca842b117b0 100644 --- a/README.md +++ b/README.md @@ -198,4 +198,32 @@ Method send_mail yang ada pada views adalah seperti berikut: self.assertEqual(to_list, ['edith@example.com']) ``` -Pada potongan code di atas terdapat anotasi patch yang digunakan untuk melakuan monkeypatching. Anotasi patch menerima notasi dot dari object yang ingin di monkeypatch. Arti `accounts.views.send_mail` yang ada pada code di atas akan menggantikan `send_mail` yang ada pada views. Karena itu ketika test dijalankan, `send_mail` tidak akan dijalankan, akan tetapi `send_mail_mock` yang akan menggantikannya. \ No newline at end of file +Pada potongan code di atas terdapat anotasi patch yang digunakan untuk melakuan monkeypatching. Anotasi patch menerima notasi dot dari object yang ingin di monkeypatch. Arti `accounts.views.send_mail` yang ada pada code di atas akan menggantikan `send_mail` yang ada pada views. Karena itu ketika test dijalankan, `send_mail` tidak akan dijalankan, akan tetapi `send_mail_mock` yang akan menggantikannya. + + + +## Exercise 9 + +Pada **subbab 18.3**, functional test dibuat sebagaimana sehingga setiap kali test dijalankan test tersebut akan melakukan login email. Model seperti ini tidak optimal karena memakan waktu yang cukup banyak dan juga tidak terlalu diperlukan untuk selalu melakukan login/logout setiap kali menjalankan functional test. Karena itu, pada **subbab 20.1** ini akan dibuat functional test yang dapat mengidentifikasi user sehingga dapat mempunyai user yang sudah logged in. + +Functional test pada subbab 20.1 ini dibuat dengan menggunakan ``session cookies``. + +Pertama, database akan membuat object session dengan objeck user primary key (email user) sebagai ``session_key``. Selanjutnya cookie ditambahkan ke browser (akan disesuaikan dengan session di server). Dengan model seperti ini, server dapat mengenali functional test yang sudah dijalankan sebagai logged in user. Berikut potongan codenya: + +```python + 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 first 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='/', + )) +``` + diff --git a/functional_tests/base.py b/functional_tests/base.py index 0929e71ca0e66fc9c55e4bf812c7cb49e31066d1..45ca4a1661eff94e497246848d6a9ed334c87416 100644 --- a/functional_tests/base.py +++ b/functional_tests/base.py @@ -20,25 +20,74 @@ class FunctionalTest(StaticLiveServerTestCase): def tearDown(self): self.browser.quit() - 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') - rows = table.find_elements_by_tag_name('tr') - self.assertIn(row_text, [row.text for row in rows]) - return - 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 + + @wait 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) + return 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') + # rows = table.find_elements_by_tag_name('tr') + # self.assertIn(row_text, [row.text for row in rows]) + # return + # except (AssertionError, WebDriverException) as e: + # if time.time() - start_time > MAX_WAIT: + # raise e + # time.sleep(0.5) + + # 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_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) + + @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') + self.assertIn(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') + navbar = self.browser.find_element_by_css_selector('.navbar') + self.assertIn(email, navbar.text) + + @wait + def wait_to_be_logged_out(self, email): + self.browser.find_element_by_name('email') + navbar = self.browser.find_element_by_css_selector('.navbar') + self.assertNotIn(email, navbar.text) diff --git a/functional_tests/test_login.py b/functional_tests/test_login.py index a6349ef48c3e60e98476d4a5c21890846147186a..4f98296b109916be033d0b8ffe3830059724668a 100644 --- a/functional_tests/test_login.py +++ b/functional_tests/test_login.py @@ -42,19 +42,29 @@ class LoginTest(FunctionalTest): # 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) + # # 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) + + # # 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') + # ) + # navbar = self.browser.find_element_by_css_selector('.navbar') + # self.assertNotIn(TEST_EMAIL, navbar.text) + + # she is logged in! + self.wait_to_be_logged_in(email=TEST_EMAIL) # 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') - ) - navbar = self.browser.find_element_by_css_selector('.navbar') - self.assertNotIn(TEST_EMAIL, navbar.text) + self.wait_to_be_logged_out(email=TEST_EMAIL) + diff --git a/functional_tests/test_my_lists.py b/functional_tests/test_my_lists.py new file mode 100644 index 0000000000000000000000000000000000000000..6b392f2ae26225681c9d53e40be82df7826c588d --- /dev/null +++ b/functional_tests/test_my_lists.py @@ -0,0 +1,32 @@ +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 +User = get_user_model() + + +class MyListsTest(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 first 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)