Skip to content

Commit

Permalink
Add search day-care funconallity to dog-owner homepage.
Browse files Browse the repository at this point in the history
The dog-owner user can search for day-care that relevant for him.
If the user didnt search for day-care he will see all Day-Cares in the application.

Signed-off-by: tamirmatok <[email protected]>
  • Loading branch information
tamirmatok authored and ErezCohenn committed May 12, 2022
1 parent e815468 commit aeab256
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 23 deletions.
31 changes: 31 additions & 0 deletions daycare/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django import forms
from .models import DayCare, Area
from django.db.models import Max, Min


class DayCareSearchForm(forms.Form):
min_price = DayCare.objects.all().aggregate(Min('price_per_day')).get('price_per_day__min')
max_price = DayCare.objects.all().aggregate(Max('price_per_day')).get('price_per_day__max')
start_date = forms.DateField(required=True, label=' Start date',
widget=forms.widgets.DateInput(attrs={'class': 'form-control', 'type': 'date'}))
end_date = forms.DateField(required=True, label=' End date',
widget=forms.widgets.DateInput(attrs={'class': 'form-control', 'type': 'date'}))

area = forms.ChoiceField(required=False, label='Area',
choices=(Area.choices + [('', 'All'), ]), initial="")
city = forms.CharField(required=False, label='City')
name = forms.CharField(required=False, label='Day care name')
price_per_day = forms.ChoiceField(required=False, label='Max price',
choices=((str(x), x) for x in range(min_price, max_price + 11, 10)),
initial=str(max_price))

def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get("start_date")
end_date = cleaned_data.get("end_date")

if start_date and end_date:
if end_date < start_date:
self._errors['end_date'] = self.error_class(["End date should be greater!"])

return cleaned_data
3 changes: 2 additions & 1 deletion dogowner/templates/dogowner/dog_owner_homepage.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ <h5 class="card-title">{{ daycare.name }}</h5>
</div>
</div>
</div>
{% endblock %}

{% endblock %}
23 changes: 22 additions & 1 deletion dogowner/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from daycare.models import DayCare
from daycare.forms import DayCareSearchForm
from orders.models import Order


@login_required()
def dog_owner_home(request):
form = DayCareSearchForm(request.POST or None)
day_care_queryset = DayCare.objects.all()
context = {
'daycares': DayCare.objects.all(),
'day_care_queryset': day_care_queryset,
'form': form
}
if request.method == 'POST':
if form.is_valid():
filter_day_cares = DayCare.objects.filter(area__startswith=form['area'].value(),
city__icontains=form['city'].value(),
name__icontains=form['name'].value(),
price_per_day__lte=form['price_per_day'].value())

available_day_cares = Order.get_all_day_cares_available_on_dates(form['start_date'].value(),
form['end_date'].value())
day_care_queryset = filter_day_cares.intersection(available_day_cares)

context = {
'day_care_queryset': day_care_queryset,
'form': form
}

return render(request, 'dogowner/dog_owner_homepage.html', context)
82 changes: 81 additions & 1 deletion main/tests.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest
from orders.models import Order
from dogowner.models import DogOwner
from daycare.models import DayCare
from orders.models import Order


@pytest.mark.django_db
Expand All @@ -18,6 +19,24 @@ def test_enter_login_page(self, client):
response = client.get('/login/')
assert response.status_code == 200

def test_valid_login_dog_owner_user_info(self, client, create_dog_owner_user):
previous_logged_user = client.get('/').wsgi_request.user
form = {'username': 'dogOwnerUser01',
'password': 'password123',
}

response = client.post('/login/', form, follow=True)
current_log_user = response.wsgi_request.user
assert current_log_user == create_dog_owner_user.user
assert previous_logged_user != current_log_user

def test_invalid_login_dog_owner_user_info(self, client):
form = {'username': "[email protected]",
'password': "incorrect",
}
response = client.post('/login/', form, follow=True)
assert response.wsgi_request.user.is_anonymous

def test_valid_login_daycare_user_info(self, client, create_daycare_user, daycare_data):
previous_logged_user = client.get('/').wsgi_request.user
form = {'username': pytest.DAYCARE_USERNAME,
Expand Down Expand Up @@ -73,6 +92,67 @@ def test_unlogged_user_access_to_homepage(self, client):
assert response.status_code == 302
assert response['Location'] == '/login/?next=/homepage/'


@pytest.mark.django_db
class TestDogOwnerHomePageView:
def test_dog_owner_present_all_day_cares_at_entrypoint(self, client, create_dog_owner_user):
client.force_login(user=create_dog_owner_user.user)
response = client.get("/homepage/")
day_care_queryset = response.context['day_care_queryset']
assert set(day_care_queryset) == set(DayCare.objects.all())

def test_search_daycare_present_only_available_daycares_on_specific_dates(self, client, create_dog_owner_user):
test_day_care = DayCare.create(username='testuser', email='[email protected]', password='test_password',
name='name', description='test description', price_per_day=100,
capacity=1, area='CENTER', city='tel aviv', address='address')
client.force_login(user=create_dog_owner_user.user)
search_form = {'area': "",
'city': "",
'price_per_day': 100,
'name': "",
'start_date': "2022-05-03",
'end_date': "2022-05-08",
}
response = client.post('/homepage/', search_form, follow=True)
day_care_queryset = response.context['day_care_queryset']
assert test_day_care in day_care_queryset
Order.create(dog_owner_id=DogOwner.objects.get(id=1), daycare_id=test_day_care,
start_date="2022-05-02", end_date="2022-08-02", price_per_day=100).approve_order()
response = client.post('/homepage/', search_form, follow=True)
assert test_day_care not in response.context['day_care_queryset']

def test_successful_dog_owner_search_for_day_care(self, client, create_dog_owner_user):
client.force_login(user=create_dog_owner_user.user)
search_form = {'area': "C",
'city': "tel aviv",
'price_per_day': 800,
'name': "",
'start_date': "2022-05-03",
'end_date': "2022-05-08",
}
response = client.post('/homepage/', search_form, follow=True)
day_care_queryset = response.context['day_care_queryset']
available_day_cares = Order.get_all_day_cares_available_on_dates("2022-05-03", "2022-05-08")
filters_day_cares = DayCare.objects.filter(area__startswith='C',
city__icontains="tel aviv",
price_per_day__lte=800)
assert set(day_care_queryset) == set(available_day_cares.intersection(filters_day_cares))

def test_search_for_day_care_with_start_date_greater_than_end_date_show_error_and_present_all_daycares(
self, client, create_dog_owner_user):
client.force_login(user=create_dog_owner_user.user)
search_form = {'area': "C",
'city': "tel aviv",
'price_per_day': 800,
'name': "",
'start_date': "2022-05-03",
'end_date': "2022-05-01",
}
response = client.post('/homepage/', search_form, follow=True)
day_care_queryset = response.context['day_care_queryset']
assert set(day_care_queryset) == set(DayCare.objects.all())
assert response.context['form']._errors['end_date']

def test_dog_owner_homepage_is_visible_for_dog_owner(self, client, create_dog_owner_user):
client.force_login(user=create_dog_owner_user.user)
response = client.get("/homepage/")
Expand Down
59 changes: 39 additions & 20 deletions static/CSS/dog_owner_homepage.css
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
.cards
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-left: 50px;
justify-content: center;
align-items: center;
float:left;
margin: 0 0 0 5em;
position:relative;
width:100%;
}

.row
{
height: 30rem;
width: 120rem;
margin-left: 200px;
#searchResult {
font-weight:bold;
position: relative;
left: 6.3em;
top:30px;
}

.card
{
width: 18.5%;
width: 330px;
height: 30rem;
margin: 60px 60px 0 60px;
max-width: 100%;
}

.card-body
{
display: flex;
flex-direction: column;
float:left;
margin: 60px 20px 0 20px;
}

.card-body .btn
Expand All @@ -39,3 +31,30 @@
{
height: 200px;
}

#searchBoxArea {
background-color:#dcdcdc;
left:5em;
top: 5.2em;
max-width:100%;
padding: 2em 2em 2em 2em;
}

#searchBoxArea span {
font-weight:bold;
font-size:18px;
color:#3e3e3e;
padding: 5px 0 1em 0;
float:left;
}

#searchBoxArea input[type="submit"] {
background-color:#3e3e3e;
border: 0;
border-radius:12px;
color:#FFF;
}

#searchBoxArea input[type="submit"]:hover {
background-color:#1e1e1e;
}

0 comments on commit aeab256

Please sign in to comment.