diff --git a/README.md b/README.md index 21d258eb2756bced04319345e79f4be53a33cc48..b5fd8244607b78f7b922a5f0b3ddfef7a3d0e905 100644 --- a/README.md +++ b/README.md @@ -29,3 +29,7 @@ Ketika kita sudah mengetahui bagaimana implementasi dari teknologi yang kita pel Manual mocking adalah implementasi mock dengan cara membuat sendiri method mock dari sebuah method yang mengembalikan nilai yang kita inginkan. Sedangkan jika kita menggunakan mock library, mock method dari method yang kita inginkan akan dibuatkan oleh library tersebut, kita hanya tinggal mengatur behavior dari mock tersebut. Mocking dilakukan pada sebuah method yang dipanggil saat sebuah method dijalankan pada sebuah test. Artinya dalam implementasi method tersebut, setiap pemanggilannya akan bergantung pada method yang dibuat mocknya. Sebuah class/method yang memiliki ketergantungan tinggi dengan class/method lainnya disebut tightly coupled. Misalnya pada source code, setiap pemanggilan method GET untuk url login akan memanggil method auth pada accounts.views. Oleh sebab itu dapat disimpulkan bahwa method login tightly coupled dengan method auth. + +## Latihan 9 + +Pada section 18, funstional test dilakukan dengan melalui proses login terlebih dahulu, sehingga akan memakan banyak waktu. Sedangkan pada section 20, functional test dilakukan dengan memanfaatkan session dari login sebelumnya, sehingga untuk melakukan setiap functional test tidak perlu melalui proses login lagi. diff --git a/accounts/tests/test_views.py b/accounts/tests/test_views.py index 269bf2d6d290c3877df02146e6f153acf7d1b8c3..e6d36efe3fc41141173e80c7071f4ff8b9580776 100644 --- a/accounts/tests/test_views.py +++ b/accounts/tests/test_views.py @@ -49,7 +49,7 @@ class SendLoginEmailViewTest(TestCase): 'email': 'edith@example.com' }) token = Token.objects.first() - expected_url = f'http://testserver/accounts/login?token={token.uid}' + expected_url = 'http://testserver/accounts/login?token=%s' % token.uid (subject, body, from_email, to_list), kwargs = mock_send_mail.call_args self.assertIn(expected_url, body) diff --git a/functional_tests/base.py b/functional_tests/base.py index 624cfd34391ca9a4f047e1437ba8ae97e66472d5..b95f0fbac148bee9c888051c7e942a27ddd4341c 100644 --- a/functional_tests/base.py +++ b/functional_tests/base.py @@ -5,6 +5,18 @@ import time MAX_WAIT = 10 +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 class FunctionalTest(StaticLiveServerTestCase): def setUp(self): @@ -13,25 +25,25 @@ class FunctionalTest(StaticLiveServerTestCase): def tearDown(self): self.browser.quit() + @wait 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) + 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_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() + + @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 e6fc93c594870cf0e2bcaddb8d4eb6188ab873f5..9260fadd03be315c6aecdd61895107ac2a266c1a 100644 --- a/functional_tests/test_login.py +++ b/functional_tests/test_login.py @@ -39,24 +39,10 @@ class LoginTest(FunctionalTest): 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') - ) - navbar = self.browser.find_element_by_css_selector('.navbar') - self.assertIn(TEST_EMAIL, navbar.text) + 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..ae372f736a1a4d085989b4b43fad8dc4f0118426 --- /dev/null +++ b/functional_tests/test_my_lists.py @@ -0,0 +1,31 @@ +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) + # Edith is a logged-in user + self.create_pre_authenticated_session(email) + self.browser.get(self.live_server_url) + self.wait_to_be_logged_in(email) \ No newline at end of file