From 3335f9450f371c982d29e7314bf36000f7e9eff1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Valentin=20Grou=C3=A8s?= <valentin.groues@uni.lu>
Date: Tue, 21 Mar 2017 14:43:41 +0100
Subject: [PATCH]  #70 allow subject edit in appointment edit view

---
 smash/web/templates/appointments/edit.html | 94 +++++++++++-----------
 smash/web/tests/functions.py               | 12 ++-
 smash/web/tests/test_view_appointments.py  | 66 ++++++++++-----
 smash/web/tests/test_view_functions.py     |  5 +-
 smash/web/tests/test_view_kit_request.py   |  1 -
 smash/web/views.py                         | 30 ++++---
 6 files changed, 121 insertions(+), 87 deletions(-)

diff --git a/smash/web/templates/appointments/edit.html b/smash/web/templates/appointments/edit.html
index eb50e3b8..24c4c735 100644
--- a/smash/web/templates/appointments/edit.html
+++ b/smash/web/templates/appointments/edit.html
@@ -35,55 +35,51 @@
 
             <form method="post" action="" class="form-horizontal">
                 {% csrf_token %}
+                <fieldset>
+                    <div class="box-header with-border">
+                        <h3 class="box-title">Appointment's details</h3>
+                    </div>
+                    <div class="box-body">
+                        {% for field in form %}
+                            <div class="col-md-6 form-group  {% if field.errors %}has-error{% endif %}  {% if field|is_checkbox %}multi-checkboxes{% endif %}">
+                                <label for="{# TODO #}" class="col-sm-4 control-label">
+                                    {{ field.label }}
+                                </label>
+
+                                <div class="col-sm-8">
+                                    {{ field|add_class:'form-control' }}
+                                </div>
 
-                <div class="box-body">
-                    {% for field in form %}
-                        <div class="col-md-6 form-group  {% if field.errors %}has-error{% endif %} {% if field|is_checkbox %}multi-checkboxes{% endif %}">
+                                {% if field.errors %}
+                                    <span class="help-block">
+                  {{ field.errors }}
+                </span>
+                                {% endif %}
+                            </div>
+                        {% endfor %}
+                        <div class="col-md-6 form-group">
                             <label for="{# TODO #}" class="col-sm-4 control-label">
-                                {{ field.label }}
+                                Status:
                             </label>
-                            <div class="col-sm-8">
-                                {{ field|add_class:'form-control' }}
+                            <div class="btn-group-vertical col-sm-8">
+                                <label class="btn btn-primary">{{ appointment.status }}</label>
+                                <a href="{% url 'web.views.appointment_mark' id 'finished' %}"
+                                   class="btn btn-warning btn-block">Mark as finished</a>
+                                <a href="{% url 'web.views.appointment_mark' id 'cancelled' %}"
+                                   class="btn btn-warning btn-block">Mark as cancelled</a>
+                                <a href="{% url 'web.views.appointment_mark' id 'no_show' %}"
+                                   class="btn btn-warning btn-block">Mark as no show</a>
                             </div>
-
-                            {% if field.errors %}
-                                <span class="help-block">
-              {{ field.errors }}
-            </span>
-                            {% endif %}
-                        </div>
-                    {% endfor %}
-                    <div class="col-md-6 form-group">
-                        <label for="{# TODO #}" class="col-sm-4 control-label">
-                            Status:
-                        </label>
-                        <div class="btn-group-vertical col-sm-8">
-                            <label class="btn btn-primary">{{ appointment.status }}</label>
-                            <a href="{% url 'web.views.appointment_mark' id 'finished' %}"
-                               class="btn btn-warning btn-block">Mark as finished</a>
-                            <a href="{% url 'web.views.appointment_mark' id 'cancelled' %}"
-                               class="btn btn-warning btn-block">Mark as cancelled</a>
-                            <a href="{% url 'web.views.appointment_mark' id 'no_show' %}"
-                               class="btn btn-warning btn-block">Mark as no show</a>
                         </div>
-                    </div>
-                </div><!-- /.box-body -->
+                    </div><!-- /.box-body -->
 
-                <div class="box-footer">
-                    <div class="col-sm-6">
-                        <button type="submit" class="btn btn-block btn-success">Save</button>
-                    </div>
-                    <div class="col-sm-6">
-                        <a href="{% url 'web.views.appointments' %}" class="btn btn-block btn-default"
-                           onclick="history.back()">Cancel</a>
-                    </div>
-                </div><!-- /.box-footer -->
 
-                <div class="box-header with-border">
-                    <h3 class="box-title">Subject's details</h3>
-                </div>
+                </fieldset>
+                <fieldset>
+                    <div class="box-header with-border">
+                        <h3 class="box-title">Subject's details</h3>
+                    </div>
 
-                <form class="form-horizontal">
                     <div class="box-body">
                         {% for field in subject_form %}
                             <div class="col-md-6 form-group  {% if field.errors %}has-error{% endif %}">
@@ -92,7 +88,7 @@
                                 </label>
 
                                 <div class="col-sm-8">
-                                    {{ field|disable|add_class:'form-control' }}
+                                    {{ field|add_class:'form-control' }}
                                 </div>
 
                                 {% if field.errors %}
@@ -105,13 +101,15 @@
                     </div><!-- /.box-body -->
 
                     <div class="box-footer">
-                        <a href="{% url 'web.views.subject_edit' appointment.visit.subject.id %}" type="button"
-                           class="btn btn-block btn-default">Edit subject</a>
-                        <a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default"
-                           onclick="history.back()">Back</a>
+                        <div class="col-sm-6">
+                            <button type="submit" class="btn btn-block btn-success">Save</button>
+                        </div>
+                        <div class="col-sm-6">
+                            <a href="{% url 'web.views.appointments' %}" class="btn btn-block btn-default"
+                               onclick="history.back()">Cancel</a>
+                        </div>
                     </div><!-- /.box-footer -->
-                </form>
-
+                </fieldset>
             </form>
         </div>
     {% endblock %}
diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py
index 728bf683..3b5f1a3e 100644
--- a/smash/web/tests/functions.py
+++ b/smash/web/tests/functions.py
@@ -32,7 +32,9 @@ def create_subject():
         last_name="Gawron",
         default_location=get_test_location(),
         sex=Subject.SEX_CHOICES_MALE,
-        type=Subject.SUBJECT_TYPE_CHOICES_CONTROL)
+        type=Subject.SUBJECT_TYPE_CHOICES_CONTROL,
+        screening_number="piotr's number",
+        country="france")
 
 
 def create_user():
@@ -45,13 +47,17 @@ def create_user():
     return user
 
 
-def create_worker(user=None):
-    return Worker.objects.create(
+def create_worker(user=None, with_test_location=False):
+    worker = Worker.objects.create(
         first_name='piotr',
         last_name="gawron",
         email='jacob@bla',
         user=user,
     )
+    if with_test_location:
+        worker.locations = [get_test_location()]
+        worker.save()
+    return worker
 
 
 def create_visit(subject=None):
diff --git a/smash/web/tests/test_view_appointments.py b/smash/web/tests/test_view_appointments.py
index 22cd13d3..e92bb096 100644
--- a/smash/web/tests/test_view_appointments.py
+++ b/smash/web/tests/test_view_appointments.py
@@ -1,41 +1,70 @@
+import datetime
+
 from django.contrib.auth.models import User
-from django.test import TestCase, RequestFactory
+from django.test import Client
+from django.test import TestCase
 from django.urls import reverse
 
-from functions import create_subject, create_visit, create_appointment
-from web.models import Appointment
-from web.views import appointments, appointment_mark
+from functions import create_subject, create_visit, create_appointment, create_worker
+from web.forms import AppointmentEditForm, SubjectEditForm
+from web.models import Appointment, Subject
 
 
 class AppointmentsViewTests(TestCase):
     def setUp(self):
-        # Every test needs access to the request factory.
-        self.factory = RequestFactory()
+        self.client = Client()
+        username = 'piotr'
+        password = 'top_secret'
         self.user = User.objects.create_user(
-            username='piotr', email='jacob@bla', password='top_secret')
+            username=username, email='jacob@bla', password=password)
+        self.client.login(username=username, password=password)
 
     def test_appointments_list_request(self):
-        request = self.factory.get(reverse('web.views.appointments'))
-        request.user = self.user
-        response = appointments(request)
+        response = self.client.get(reverse('web.views.appointments'))
         self.assertEqual(response.status_code, 200)
 
+    def test_appointments_edit(self):
+        subject = create_subject()
+        visit = create_visit(subject)
+        appointment = create_appointment(visit, when=datetime.datetime.now())
+        create_worker(self.user, True)
+        new_comment = 'new comment'
+        new_last_name = "new last name"
+        form_appointment = AppointmentEditForm(user=self.user, instance=appointment, prefix="appointment")
+        form_subject = SubjectEditForm(instance=subject, prefix="subject")
+        form_data = {}
+        for key, value in form_appointment.initial.items():
+            if value is not None:
+                form_data['appointment-{}'.format(key)] = value
+        for key, value in form_subject.initial.items():
+            if value is not None:
+                form_data['subject-{}'.format(key)] = value
+        form_data["appointment-comment"] = new_comment
+        form_data["subject-last_name"] = new_last_name
+        response = self.client.post(
+            reverse('web.views.appointment_edit', kwargs={'id': appointment.id}), data=form_data)
+        self.assertEqual(response.status_code, 302)
+        updated_appointment = Appointment.objects.filter(id=appointment.id)[0]
+        updated_subject = Subject.objects.filter(id=subject.id)[0]
+        self.assertEqual(new_comment, updated_appointment.comment)
+        self.assertEqual(new_last_name, updated_subject.last_name)
+
     def test_mark_as_finished(self):
         subject = create_subject()
         visit = create_visit(subject)
         appointment = create_appointment(visit)
-        request = self.factory.get(reverse('web.views.appointment_mark', args=[appointment.id, 'finished']))
-        request.user = self.user
-        response = appointment_mark(request, appointment.id, 'finished')
+        response = self.client.get(
+            reverse('web.views.appointment_mark', kwargs={'id': appointment.id, 'as_what': 'finished'}))
         self.assertEqual(response.status_code, 302)
+        update_appointment = Appointment.objects.filter(id=appointment.id)[0]
+        self.assertEqual(update_appointment.status, Appointment.APPOINTMENT_STATUS_FINISHED)
 
     def test_mark_as_cancelled(self):
         subject = create_subject()
         visit = create_visit(subject)
         appointment = create_appointment(visit)
-        request = self.factory.get(reverse('web.views.appointment_mark', args=[appointment.id, 'cancelled']))
-        request.user = self.user
-        response = appointment_mark(request, appointment.id, 'cancelled')
+        response = self.client.get(
+            reverse('web.views.appointment_mark', kwargs={'id': appointment.id, 'as_what': 'cancelled'}))
         self.assertEqual(response.status_code, 302)
         update_appointment = Appointment.objects.filter(id=appointment.id)[0]
         self.assertEqual(update_appointment.status, Appointment.APPOINTMENT_STATUS_CANCELLED)
@@ -44,9 +73,8 @@ class AppointmentsViewTests(TestCase):
         subject = create_subject()
         visit = create_visit(subject)
         appointment = create_appointment(visit)
-        request = self.factory.get(reverse('web.views.appointment_mark', args=[appointment.id, 'no_show']))
-        request.user = self.user
-        response = appointment_mark(request, appointment.id, 'no_show')
+        response = self.client.get(
+            reverse('web.views.appointment_mark', kwargs={'id': appointment.id, 'as_what': 'no_show'}))
         self.assertEqual(response.status_code, 302)
         update_appointment = Appointment.objects.filter(id=appointment.id)[0]
         self.assertEqual(update_appointment.status, Appointment.APPOINTMENT_STATUS_NO_SHOW)
diff --git a/smash/web/tests/test_view_functions.py b/smash/web/tests/test_view_functions.py
index 88410ae3..b43d3c33 100644
--- a/smash/web/tests/test_view_functions.py
+++ b/smash/web/tests/test_view_functions.py
@@ -1,7 +1,6 @@
 from django.test import TestCase
 
 from functions import create_location, create_user, create_worker, get_test_location
-from web.models import Location
 from web.views import get_filter_locations
 
 
@@ -13,12 +12,12 @@ class ViewFunctionsTests(TestCase):
     def test_locations_for_user(self):
         user = create_user()
 
-        self.assertEquals(Location.objects.all().count(), len(get_filter_locations(user)))
+        self.assertEquals(1, len(get_filter_locations(user)))
 
     def test_locations_for_worker(self):
         worker = create_worker()
 
-        self.assertEquals(Location.objects.all().count(), len(get_filter_locations(worker)))
+        self.assertEquals(1, len(get_filter_locations(worker)))
 
     def test_locations_for_worker_with_location(self):
         worker = create_worker()
diff --git a/smash/web/tests/test_view_kit_request.py b/smash/web/tests/test_view_kit_request.py
index d07bd8c6..19883898 100644
--- a/smash/web/tests/test_view_kit_request.py
+++ b/smash/web/tests/test_view_kit_request.py
@@ -68,7 +68,6 @@ class ViewFunctionsTests(TestCase):
         appointment = create_appointment()
         appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
         appointment.appointment_types.add(appointment_type)
-        appointment.location = create_location("other_loc")
         appointment.save()
 
         request = self.factory.get(reverse('web.views.kit_requests'))
diff --git a/smash/web/views.py b/smash/web/views.py
index 3197798b..a18ece4b 100644
--- a/smash/web/views.py
+++ b/smash/web/views.py
@@ -707,26 +707,29 @@ def appointment_add(request, id):
 def appointment_edit(request, id):
     the_appointment = get_object_or_404(Appointment, id=id)
     if request.method == 'POST':
-        form = AppointmentEditForm(request.POST,
-                                   request.FILES,
-                                   instance=the_appointment,
-                                   user=request.user
-                                   )
-        if form.is_valid():
-            form.save()
-
-            data = form.cleaned_data
+        appointment_form = AppointmentEditForm(request.POST,
+                                               request.FILES,
+                                               instance=the_appointment,
+                                               user=request.user,
+                                               prefix="appointment")
+        subject_form = SubjectEditForm(request.POST, instance=the_appointment.visit.subject, prefix="subject")
+
+        if appointment_form.is_valid() and subject_form.is_valid():
+            appointment_form.save()
+            subject_form.save()
+
+            data = appointment_form.cleaned_data
             vis = data['visit']
             get_object_or_404(Visit, id=vis.id)
 
             return redirect(appointments)
     else:
-        form = AppointmentEditForm(instance=the_appointment, user=request.user)
+        appointment_form = AppointmentEditForm(instance=the_appointment, user=request.user, prefix="appointment")
 
-    subject_form = SubjectDetailForm(instance=the_appointment.visit.subject)
+        subject_form = SubjectEditForm(instance=the_appointment.visit.subject, prefix="subject")
 
     return wrap_response(request, 'appointments/edit.html', {
-        'form': form,
+        'form': appointment_form,
         'subject_form': subject_form,
         'id': id,
         'appointment': the_appointment
@@ -867,6 +870,7 @@ def kit_requests_send_mail(request, start_date, end_date=None):
     return wrap_response(request, 'equipment_and_rooms/kit_requests_send_mail.html',
                          get_kit_requests_data(request, start_date, end_date))
 
+
 def statistics(request):
     statistics_manager = StatisticsManager()
     visit_choices = [("-1", "all")]
@@ -888,4 +892,4 @@ def statistics(request):
     return wrap_response(request, 'statistics/index.html', {
         'form': form,
         'monthly_statistics': monthly_statistics
-    })
\ No newline at end of file
+    })
-- 
GitLab