Fakultas Ilmu Komputer UI

Commit fa5a64a2 authored by Syahrul Findi's avatar Syahrul Findi
Browse files

Latihan7

parent a018ab1e
......@@ -17,3 +17,9 @@ Pada Bab 7, dilakukan pemisahan antara tabel dengan form. Yang pertama melakukan
Pada latihan-latihan sebelumnya, saya membuat pengecekan jumlah item dan mengeluarkan output pesan yang sesuai tidak pada views.py, namun pada home.html. Karena pada soal diinstruksikan untuk membuat mutant pada views.py, maka saya membuat mutant dengan mengubah parameter pada pemanggilan fungsi render. Pertama saya mengubah template menjadi base.html, lalu mutant kedua saya buat dengan memberikan array kosong pada item.
Test yang saya buat sebelumnya sudah strongly killed, sehingga saya tidak perlu mengubah atau membuat test baru untuk membunuh mutant-mutant tersebut secara stringly killed.
## Latihan 7
KEtika kita mencoba teknologi atau tools baru, terkadang kita ingin tahu bagaimana cara kerjanya tanpa perlu terganggung oleh pembuatan unit test terlebih dahulu. Pun jika kita belum tahu dan langsung membuat unit test untuk teknologi tersebut, hasilnya belum tentu benar. Oleh sebab itu, dalam TDD diperbolehkan untuk membuat prototype dari fitur yang akan ditest tanpa membuat test-nya terlebih dahulu, yang disebut dengan "Spiking".
Ketika kita sudah mengetahui bagaimana implementasi dari teknologi yang kita pelajari, barulah kita bisa membuat functional test dari fitur tersebut. Setelah test dibuat, kita dapat menulis kembali prototype yang telah kita buat tadi dan kembali menerapkan TDD seperti biasanya. Proses tersebut dinamakan "De-Spiking".
......@@ -4,18 +4,13 @@ from accounts.models import ListUser, Token
class PasswordlessAuthenticationBackend(object):
def authenticate(self, uid):
print('uid', uid, file=sys.stderr)
if not Token.objects.filter(uid=uid).exists():
print('no token found', file=sys.stderr)
return None
token = Token.objects.get(uid=uid)
print('got token', file=sys.stderr)
try:
user = ListUser.objects.get(email=token.email)
print('got user', file=sys.stderr)
return user
except ListUser.DoesNotExist:
print('new user', file=sys.stderr)
return ListUser.objects.create(email=token.email)
def get_user(self, email):
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.24 on 2019-11-12 13:28
# Generated by Django 1.11.24 on 2019-11-12 14:39
from __future__ import unicode_literals
from django.db import migrations, models
......@@ -10,30 +10,13 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0008_alter_user_username_max_length'),
]
operations = [
migrations.CreateModel(
name='ListUser',
name='User',
fields=[
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('email', models.EmailField(max_length=254, primary_key=True, serialize=False)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'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(max_length=255)),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.24 on 2019-11-12 14:42
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
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(max_length=255)),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.24 on 2019-11-12 14:57
from __future__ import unicode_literals
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('auth', '0008_alter_user_username_max_length'),
('accounts', '0002_token'),
]
operations = [
migrations.CreateModel(
name='ListUser',
fields=[
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('email', models.EmailField(max_length=254, primary_key=True, serialize=False)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'abstract': False,
},
),
migrations.DeleteModel(
name='User',
),
migrations.AlterField(
model_name='token',
name='uid',
field=models.CharField(default=uuid.uuid4, max_length=40),
),
]
import uuid
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager, PermissionsMixin
)
class Token(models.Model):
email = models.EmailField()
uid = models.CharField(max_length=255)
class ListUserManager(BaseUserManager):
def create_user(self, email):
ListUser.objects.create(email=email)
......@@ -30,3 +26,8 @@ class ListUser(AbstractBaseUser, PermissionsMixin):
@property
def is_active(self):
return True
class Token(models.Model):
email = models.EmailField()
uid = models.CharField(default=uuid.uuid4, max_length=40)
from django.test import TestCase
# Create your tests here.
from django.test import TestCase
from django.contrib.auth import get_user_model
from accounts.models import Token
User = get_user_model()
class UserModelTest(TestCase):
def test_user_is_valid_with_email_only(self):
user = User(email='a@b.com')
user.full_clean()
def test_email_is_primary_key(self):
user = User(email='a@b.com')
self.assertEqual(user.pk, 'a@b.com')
class TokenModelTest(TestCase):
def test_links_user_with_auto_generated_uid(self):
token1 = Token.objects.create(email='a@b.com')
token2 = Token.objects.create(email='a@b.com')
self.assertNotEqual(token1.uid, token2.uid)
from django.core import mail
from selenium.webdriver.common.keys import Keys
import re
from .base import FunctionalTest
TEST_EMAIL = 'edith@example.com'
SUBJECT = 'Your login link for Superlists'
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
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
))
# 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)
if not url_search:
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)
......@@ -51,6 +51,7 @@ AUTHENTICATION_BACKENDS = [
'accounts.authentication.PasswordlessAuthenticationBackend',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
......
......@@ -21,6 +21,7 @@
</form>
{% endif %}
</div>
<div class="row">
<div class="col-md-6 offset-md-3 jumbotron">
<div class="text-center">
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment