Fakultas Ilmu Komputer UI

Commit b74535cc authored by Fannyah Dita Cahya's avatar Fannyah Dita Cahya
Browse files

Merge branch 'take_home_programming' into 'master'

Take home programming

See merge request !28
parents 1fc9f9f9 e9aef9c4
Pipeline #27385 passed with stages
in 8 minutes and 6 seconds
......@@ -8,3 +8,8 @@ functional_tests/__pycache__/
__pycache__/
/static
.vscode
.coverage
.coverage.*
coverage.xml
accounts/tests/__pycache__/*
lists/tests/__pycache__/*
......@@ -14,7 +14,7 @@ lists:
- python3 manage.py migrate
- python3 manage.py collectstatic --no-input
script:
- python3 manage.py test lists
- python manage.py test lists
accounts:
image: python:3.7.0
......@@ -28,7 +28,7 @@ accounts:
- python3 manage.py migrate
- python3 manage.py collectstatic --no-input
script:
- python3 manage.py test accounts
- python manage.py test accounts
functional_test:
image: python:3.7.0
......@@ -48,4 +48,5 @@ functional_test:
- python3 manage.py migrate
- python3 manage.py collectstatic --no-input
script:
- python3 manage.py test functional_tests
- coverage run --source=lists,accounts,functional_tests manage.py test functional_tests lists accounts
- coverage report -m
......@@ -3,6 +3,11 @@
Fannyah Dita Cahya - 1606918414 - PMPL A
link heroku : https://pmpl-fannyahdita.herokuapp.com/
[![pipeline status](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606918414-practice/badges/take_home_programming/pipeline.svg)](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606918414-practice/commits/take_home_programming)
[![coverage report](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606918414-practice/badges/take_home_programming/coverage.svg)](https://gitlab.cs.ui.ac.id/pmpl/practice-collection/2019/1606918414-practice/commits/take_home_programming)
# EXERCISE-3
Pada bagian ini akan dijelaskan bagaimana proses isolation test pada aplikasi yang telah dibuat
......
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<mask id="a">
<rect width="99" height="20" rx="3" fill="#fff"/>
</mask>
<g mask="url(#a)">
<path fill="#555" d="M0 0h63v20H0z"/>
<path fill="#97CA00" d="M63 0h36v20H63z"/>
<path fill="url(#b)" d="M0 0h99v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
<text x="31.5" y="14">coverage</text>
<text x="80" y="15" fill="#010101" fill-opacity=".3">94%</text>
<text x="80" y="14">94%</text>
</g>
</svg>
......@@ -45,7 +45,8 @@ class FunctionalTest(StaticLiveServerTestCase):
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])
for row in rows :
self.assertIn(row_text, row.text)
@wait
def wait_to_be_logged_in(self, email):
......
......@@ -3,6 +3,15 @@ from .base import FunctionalTest
class LayoutAndStylingTest(FunctionalTest):
def test_name_in_header_and_footer(self):
self.browser.get(self.live_server_url)
header = self.browser.find_element_by_id('header_text').text
footer = self.browser.find_element_by_id('footer_text').text
self.assertIn('Fannyah Dita Cahya', header)
self.assertIn('Fannyah Dita Cahya', footer)
def test_layout_and_styling(self):
# Edith goes to the home page
self.browser.get(self.live_server_url)
......
......@@ -30,9 +30,3 @@ class ItemValidationTest(FunctionalTest):
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')
......@@ -19,7 +19,7 @@ class NewVisitorTest(FunctionalTest):
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
self.wait_for_row_in_list_table('1: Buy peacock feathers')
self.wait_for_row_in_list_table('Buy peacock feathers')
def test_comment_with_less_than_five_todolist(self):
self.browser.get(self.live_server_url)
......@@ -47,7 +47,7 @@ class NewVisitorTest(FunctionalTest):
inputbox = self.browser.find_element_by_id('id_new_item')
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
self.wait_for_row_in_list_table('1: Buy peacock feathers')
self.wait_for_row_in_list_table('Buy peacock feathers')
# She notices that her list has a unique URL
edith_list_url = self.browser.current_url
......
# Generated by Django 2.2.5 on 2019-12-21 02:12
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('lists', '0003_unique_together'),
]
operations = [
migrations.AddField(
model_name='item',
name='date',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]
from django.db import models
from django.utils import timezone
class List(models.Model):
pass
......@@ -6,6 +7,7 @@ class List(models.Model):
class Item(models.Model):
text = models.TextField(default='')
list = models.ForeignKey(List, default=None, on_delete=models.CASCADE)
date = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ('id',)
......
......@@ -3,7 +3,7 @@
}
body {
background-color: #f5f5f5;
background-color: #a84db8;
}
#name {
color: #df6357;
......
......@@ -3,12 +3,22 @@
}
body {
background-color: #f5f5f5;
background-color: #eddde6;
width: 100%;
max-width: 100%;
padding: 0;
display:flex;
flex-direction:column;
}
#name {
color: #df6357;
}
h1 {
margin-top: 20px;
text-align: center;
top: 50%;
}
h2 {
margin-top: 20px;
}
......@@ -29,6 +39,36 @@ tr {
td {
margin-top: 10px;
text-align: center;
text-align: left;
font-size: 22px;
}
#date {
text-align: right;
font-size: 16px;
}
.navbar{
padding-left: 100px;
padding-right: 100px;
padding-bottom: 0;
padding-top: 10px;
background-color: #cfcfcf;
}
#header_text, .navbar-brand {
margin-bottom: 20px;
text-align: center;
font-size: 20px;
font-weight: bold;
}
.footer {
background-color: #cfcfcf;
margin-top: auto;
}
#footer_text {
text-align: center;
font-weight: bold;
}
\ No newline at end of file
......@@ -17,24 +17,28 @@
<!-- ​<link href="/static/base.css" rel="stylesheet"> -->
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<a class="navbar-brand" href="/">Superlists</a>
<p id="header_text">Fannyah Dita Cahya</p>
{% 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" placeholder="Enter email to log in"/>
{% csrf_token %}
</form>
{% endif %}
</div>
</nav>
<div class="container">
<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>
{% endif %}
</div>
</nav>
{% if messages %}
<div class="row">
......@@ -54,7 +58,7 @@
<div class="row">
<div class="col-md-12 col-md-offset-3">
<div class="text-center">
<h1> Hello! I'm Fannyah Dita </h1>
<h1> Hello!</h1>
<h1>{% block header_text %}{% endblock %}</h1>
<form method="POST" action="{% block form_action %}{% endblock %}">
<input name="item_text" id="id_new_item" class="form-control input-lg" placeholder="Enter a to-do item" />
......@@ -75,5 +79,8 @@
</div>
</div>
</div>
<div class="footer">
<p id="footer_text">Fannyah Dita Cahya © 2019</p>
</div>
</body>
</html>
......@@ -7,7 +7,10 @@
{% block table %}
<table id="id_list_table" class="table">
{% for item in list.item_set.all %}
<tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr>
<tr>
<td>{{ forloop.counter }}: {{ item.text }}</td>
<td id="date">{{ item.date }}</td>
</tr>
{% endfor %}
</table>
<h3 id="comment">{{ comment }}</h3>
......
......@@ -3,23 +3,13 @@ from lists.models import Item, List
from django.core.exceptions import ValidationError
# Create your views here.
def home_page(request):
def home_page(request, error=''):
return render(request, 'index.html', {'error': error})
items = Item.objects.all()
if len(items) >= 5:
comment = "Oh tidak"
elif len(items) >= 1:
comment = "Sibuk tapi santai"
else:
comment = "Yey, waktunya berlibur"
return render(request, 'index.html', {'items': items, 'comment':comment})
def view_list(request, list_id):
def view_list(request, list_id, error=''):
list_ = List.objects.get(id=list_id)
items = Item.objects.all()
items = Item.objects.filter(list=list_)
if len(items) >= 5:
comment = "Oh tidak"
elif len(items) >= 1:
......@@ -27,47 +17,22 @@ def view_list(request, list_id):
else:
comment = "Yey, waktunya berlibur"
#MUTANT:
# if len(items) > 5:
# comment = "Oh tidak"
# elif len(items) >= 1:
# comment = "Sibuk tapi santai"
# else:
# comment = "Yey, waktunya berlibur"
# if len(items) >= 5:
# comment = "Oh tidak"
# elif len(items) > 1:
# comment = "Sibuk tapi santai"
# else:
# comment = "Yey, waktunya berlibur"
return render(request, 'list.html', {'comment':comment, 'items':items, 'list':list_})
return render(request, 'list.html', {'list': list_, 'items': items, 'comment': comment, 'error': error})
def new_list(request):
list_ = List.objects.create()
item = Item(text=request.POST['item_text'], list=list_)
try:
item.full_clean()
item.save()
except ValidationError:
list_.delete()
if (len(request.POST['item_text']) == 0):
error = "You can't have an empty list item"
return render(request, 'index.html', {"error": error})
return redirect('view_list', list_.id)
return home_page(request, error)
list_ = List.objects.create()
Item.objects.create(text=request.POST['item_text'], list=list_)
return redirect(f'/lists/{list_.id}/')
def add_item(request, list_id):
if (len(request.POST['item_text']) == 0):
error = "You can't have an empty list item"
return view_list(request, list_id, error)
list_ = List.objects.get(id=list_id)
error = None
Item.objects.create(text=request.POST['item_text'], list=list_)
return redirect(f'/lists/{list_.id}/')
if request.method == 'POST':
try:
item = Item(text=request.POST['item_text'], list=list_)
item.full_clean()
item.save()
return redirect(f'/lists/{list_.id}/')
except ValidationError:
error = "You can't have an empty list item"
return render(request, 'list.html', {'list': list_, 'error': error})
\ No newline at end of file
......@@ -10,3 +10,4 @@ whitenoise==4.1.3
django_compressor==2.3
django-libsass==0.7
django-mutpy==0.1.2
coverage==4.4.1
\ No newline at end of file
......@@ -145,7 +145,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Jakarta'
USE_I18N = True
......
Markdown is supported
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