diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0db29f6dbbb3d9c1c74e6c2f8967fde29a80e83a..bae327b5e468fa7c6eba70c077fb760a5f4d8df8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,6 +13,7 @@ Test:
     - python3 manage.py makemigrations
     - python3 manage.py migrate
     - python3 manage.py test lists
+    - python3 manage.py test accounts
   tags:
     - test
 
diff --git a/README.md b/README.md
index 5c70546b07c27fb8f43ef055192e230a6d2b6497..27775ce51186d7115511d0ddb7fe651f863d6552 100644
--- a/README.md
+++ b/README.md
@@ -148,4 +148,32 @@ Pada saat membuat suatu test case, terkadang kita ingin melakukan test terhadap
 
 Saat melakukan mocking secara manual, kita menggantikan fungsi yang akan ditest dengan mock yang kita buat sendiri. Teknik ini dinamakan monkeypatching, dimana kita memodifikasi fungsi agar sesuai dengan alur program dengan data-data yang bersifat local (hanya berjalan saat test). Melakukan mocking manual harus dilakukan sebelum fungsi yang ingin di test dipanggil, agar fungsi original dapat diganti terlebih dahulu dengan mock yang dibuat.
 
-Berbeda dengan mocking manual, saat melakukan mocking dengan library kita tidak perlu melakukan setup mock sendiri, dikarenakan sudah ada library yang menyediakan dan mempersiapkan mock tersebut, sehingga kita hanya mengatur return value apa dan bagaimana mock tersebut berjalan. Salah satu library mock adalah unittest.mock dan unittest.patch yang terdapat pada Python 3.3.
\ No newline at end of file
+Berbeda dengan mocking manual, saat melakukan mocking dengan library kita tidak perlu melakukan setup mock sendiri, dikarenakan sudah ada library yang menyediakan dan mempersiapkan mock tersebut, sehingga kita hanya mengatur return value apa dan bagaimana mock tersebut berjalan. Salah satu library mock adalah unittest.mock dan unittest.patch yang terdapat pada Python 3.3.
+
+## Alasan Mocking Menyebabkan Tightly Coupled
+
+Penggunaan mocking memang sangat membantu dalam melakukan testing fungsi yang menggunakan eksternal framework. Namun, penggunaan mock bisa menyebabkan Tightly Coupled to Implementation. Hal ini disebabkan karena saat membuat mock up kita harus mengatur dan menyesuaikan mock yang dibuat dengan implementasi yang ada pada business logic (dalam hal ini views.py atau file lain yang berisi logic program). Sementara itu, mungkin saja framework yang digunakan memiliki lebih dari satu cara implementasi dengan output yang sama, sehingga mungkin program memberikan output yang sama dengan implementasi berbeda namun mocking test nya menjadi rusak. Contohnya pada implementasi mocking yang dibuat adalah sebagai berikut:
+
+(accounts/tests/test_view.py)
+```bash
+@patch('accounts.views.messages')
+    def test_adds_success_message_with_mocks(self, mock_messages, mock_auth):
+        response = self.client.post('/accounts/send_login_email', data={
+            'email': 'edith@example.com'
+        })
+
+        expected = "Check your email, we've sent you a link you can use to log in."
+        self.assertEqual(
+            mock_messages.success.call_args,
+            call(response.wsgi_request, expected),
+        )
+```
+Pada mock tersebut, kita melakukan mocking pada implementasi messages.success. Namun, framework Django mengizinkan implementasi penggunaan message yang lain untuk message.success dengan menggunakan message.add_message(...). Contohnya adalah sebagai berikut:
+```bash
+messages.add_message(
+        request,
+        messages.SUCCESS,
+        "Check your email, we've sent you a link you can use to log in."
+    )
+```
+Kedua implementasi tersebut, yaitu penggunaan message_success atau message.add_message akan memberikan output yang sama. Namun, dikarenakan mock yang dibuat terikat dengan message.success, maka mock yang dibuat akan rusak jika kita menggunakan implementasi message.add_message, sehingga mocking tersebut sangat bergantung pada bagaimana kita melakukan implementasi program tersebut (tightly coupled with the implementation).
\ No newline at end of file
diff --git a/accounts/models.py b/accounts/models.py
index 0bfe88f02ae39a3147518cd56d564b454571ccc0..158791187874eeaf197474a9d4cf27616da83e4f 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -1,5 +1,8 @@
-from django.db import models
 import uuid
+from django.contrib import auth
+from django.db import models
+
+auth.signals.user_logged_in.disconnect(auth.models.update_last_login)
 
 class User(models.Model):
     email = models.EmailField(primary_key=True)
diff --git a/accounts/tests/test_models.py b/accounts/tests/test_models.py
index ec6655238954b4eac1bb55dff9ba0ca0e1e11b0a..83bac645f534a514cce0b7d2917809c6f495a929 100644
--- a/accounts/tests/test_models.py
+++ b/accounts/tests/test_models.py
@@ -1,8 +1,7 @@
 from django.test import TestCase
-from django.contrib.auth import get_user_model
+from django.contrib import auth
 from accounts.models import Token
-
-User = get_user_model()
+User = auth.get_user_model()
 
 
 class UserModelTest(TestCase):
@@ -15,6 +14,12 @@ class UserModelTest(TestCase):
         user = User(email='a@b.com')
         self.assertEqual(user.pk, 'a@b.com')
 
+    def test_no_problem_with_auth_login(self):
+        user = User.objects.create(email='edith@example.com')
+        user.backend = ''
+        request = self.client.request().wsgi_request
+        auth.login(request, user)  # should not raise
+
 class TokenModelTest(TestCase):
 
     def test_links_user_with_auto_generated_uid(self):
diff --git a/accounts/tests/test_views.py b/accounts/tests/test_views.py
index fd5dfe6ffb1dc59ca9744cd0f82c4bccd2949474..d9fb074760e8cf82ad2afca351f7fc1db17f6167 100644
--- a/accounts/tests/test_views.py
+++ b/accounts/tests/test_views.py
@@ -93,5 +93,17 @@ class LoginViewTest(TestCase):
         self.client.get('/accounts/login?token=abcd123')
         self.assertEqual(mock_auth.login.called, False)
 
+    @patch('accounts.views.messages')
+    def test_adds_success_message_with_mocks(self, mock_messages, mock_auth):
+        response = self.client.post('/accounts/send_login_email', data={
+            'email': 'edith@example.com'
+        })
+
+        expected = "Check your email, we've sent you a link you can use to log in."
+        self.assertEqual(
+            mock_messages.success.call_args,
+            call(response.wsgi_request, expected),
+        )
+
 
     
\ No newline at end of file
diff --git a/accounts/urls.py b/accounts/urls.py
index 0dd223f5a349506f9eec3294f8e4e689eee776c1..2e1a498681d3576f2bed4538c7d6c7806ed7678f 100644
--- a/accounts/urls.py
+++ b/accounts/urls.py
@@ -1,7 +1,9 @@
 from django.conf.urls import url
 from accounts import views
+from django.contrib.auth import logout
 
 urlpatterns = [
     url(r'^send_login_email$', views.send_login_email, name='send_login_email'),
-    url(r'^login$', views.login, name='login'), 
+    url(r'^login$', views.login, name='login'),
+    url(r'^logout$', logout, {'next_page': '/'}, name='logout'),
 ]
\ No newline at end of file
diff --git a/functional_tests/test_login.py b/functional_tests/test_login.py
index 902647ec34268b2d0378efb1bfe1c7f1ad74f4f2..476440fed69b61bf80d43ad1ebb2535e6099f428 100644
--- a/functional_tests/test_login.py
+++ b/functional_tests/test_login.py
@@ -45,4 +45,14 @@ class LoginTest(FunctionalTest):
             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) """
\ No newline at end of file
+        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) """
\ No newline at end of file
diff --git a/lists/templates/base.html b/lists/templates/base.html
index afb885e8a225ac34391a71e375b4e72e4ebc17ff..b2ddb67352402e7ebace89549333665597207161 100644
--- a/lists/templates/base.html
+++ b/lists/templates/base.html
@@ -14,15 +14,24 @@
 <body>
     ​<div class="container">
 
-        <nav class="navbar navbar-default" role="navigation">
-            <div class="container-fluid">
-                <a class="navbar-brand" href="/">Superlists</a>
-                <form class="navbar-form navbar-right" method="POST" action="{% url 'send_login_email' %}">
+    <nav class="navbar navbar-default" role="navigation">
+        <div class="container-fluid">
+            <a class="navbar-brand" href="/">Superlists</a>
+            {% if user.email %}
+            <ul class="nav navbar-nav navbar-right">
+                <li class="navbar-text">Logged in as {{ user.email }}</li>
+                <li><a href="{% url 'logout' %}">Log out</a></li>
+            </ul>
+            {% else %}
+            <form class="navbar-form navbar-right"
+                    method="POST"
+                    action="{% url 'send_login_email' %}">
                 <span>Enter email to log in:</span>
                 <input class="form-control" name="email" type="text" />
                 {% csrf_token %}
-                </form>
-            </div>
+            </form>
+            {% endif %}
+        </div>
         </nav>
 
         {% if messages %}
diff --git a/superlists/settings.py b/superlists/settings.py
index 12a4006185508becbaf5a7150cb5b9fd8023ec48..9e96734f735acf1a24c54d611ebcbda3a866b0e0 100644
--- a/superlists/settings.py
+++ b/superlists/settings.py
@@ -32,7 +32,7 @@ DEBUG = True
 ALLOWED_HOSTS = ['*']
 
 EMAIL_HOST = 'smtp.gmail.com'
-EMAIL_HOST_USER = 'ilhamperuzzi'
+EMAIL_HOST_USER = 'ilhamperuzzi@gmail.com'
 EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_PASSWORD')
 EMAIL_PORT = 587
 EMAIL_USE_TLS = True