def test_call_list_viewset(self):

        # instantiate client
        client = Client()
        client.login(username=settings.MQTT['USERNAME'],
                     password=settings.MQTT['PASSWORD'])

        response = client.get('/en/api/call/', follow=True)
        self.assertEquals(response.status_code, 200)

        result = JSONParser().parse(BytesIO(response.content))
        answer = CallSerializer(Call.objects.all(), many=True).data
        self.assertCountEqual(result, answer)

        # test_call_list_viewset_one_entry

        c1 = Call.objects.create(details='nani', updated_by=self.u1)

        response = client.get('/en/api/call/', follow=True)
        self.assertEquals(response.status_code, 200)

        result = JSONParser().parse(BytesIO(response.content))
        answer = CallSerializer(Call.objects.all(), many=True).data
        self.assertCountEqual(result, answer)

        # test_call_list_viewset_two_entries:

        c2 = Call.objects.create(details='suhmuh', updated_by=self.u1)

        response = client.get('/en/api/call/', follow=True)
        self.assertEquals(response.status_code, 200)

        result = JSONParser().parse(BytesIO(response.content))
        answer = CallSerializer(Call.objects.all(), many=True).data
        self.assertCountEqual(result, answer)

        # logout
        client.logout()

        # login as testuser2
        client.login(username='******', password='******')

        response = client.get('/en/api/call/', follow=True)
        self.assertEquals(response.status_code, 200)

        result = JSONParser().parse(BytesIO(response.content))
        answer = CallSerializer([], many=True).data
        self.maxDiff = None
        self.assertCountEqual(result, answer)

        # add ambulances to calls, can only read a3
        AmbulanceCall.objects.create(call=c1,
                                     ambulance=self.a3,
                                     updated_by=self.u1)
        AmbulanceCall.objects.create(call=c2,
                                     ambulance=self.a2,
                                     updated_by=self.u1)

        response = client.get('/en/api/call/', follow=True)
        self.assertEquals(response.status_code, 200)

        result = JSONParser().parse(BytesIO(response.content))
        answer = CallSerializer([c1], many=True).data
        self.assertCountEqual(result, answer)

        # add second ambulance to call
        AmbulanceCall.objects.create(call=c1,
                                     ambulance=self.a1,
                                     updated_by=self.u1)

        response = client.get('/en/api/call/', follow=True)
        self.assertEquals(response.status_code, 200)

        result = JSONParser().parse(BytesIO(response.content))
        answer = CallSerializer([c1], many=True).data
        logger.debug(result)
        logger.debug(answer)
        self.assertEqual(len(result), 1)
        self.assertCountEqual(result, answer)

        # logout
        client.logout()
Beispiel #2
0
 def publish_call(self, call, qos=2, retain=False):
     # otherwise, publish call data
     self.publish_topic('call/{}/data'.format(call.id),
                        CallSerializer(call),
                        qos=qos,
                        retain=retain)
    def test_call_viewset_update(self):

        # Pending Call with Ambulancecall_Set will create ambulancecalls
        call = {
            'status':
            CallStatus.P.name,
            'priority':
            CallPriority.B.name,
            'sms_notifications': [],
            'ambulancecall_set': [{
                'ambulance_id':
                self.a1.id,
                'waypoint_set': [{
                    'order': 0,
                    'location': {
                        'type': LocationType.i.name,
                        'number': '123',
                        'street': 'some street'
                    }
                }, {
                    'order': 1,
                    'status': WaypointStatus.D.name,
                    'location': {
                        'type': LocationType.w.name,
                        'location': {
                            'longitude': -110.54,
                            'latitude': 35.75
                        }
                    }
                }]
            }, {
                'ambulance_id':
                self.a2.id,
                'waypoint_set': [{
                    'order': 0,
                    'location': {
                        'type': LocationType.i.name,
                        'number': '321',
                        'street': 'another street'
                    }
                }]
            }],
            'patient_set': [{
                'name': 'Jose',
                'age': 3
            }, {
                'name': 'Maria',
                'age': 10
            }]
        }
        serializer = CallSerializer(data=call)
        serializer.is_valid()
        call = serializer.save(updated_by=self.u1)
        self.assertNotEqual(call.pending_at, None)
        self.assertEqual(call.started_at, None)
        self.assertEqual(call.ended_at, None)

        # instantiate client
        client = Client()
        client.login(username=settings.MQTT['USERNAME'],
                     password=settings.MQTT['PASSWORD'])

        # post call data
        data = {'status': CallStatus.S.name, 'priority': CallPriority.D.name}
        response = client.post('/en/api/call/{}/'.format(call.id),
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 405)

        # partial update call data
        response = client.patch('/en/api/call/{}/'.format(call.id),
                                data,
                                content_type='application/json')
        logger.debug(response.content)
        self.assertEqual(response.status_code, 200)

        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)
        self.assertEqual(call.priority, CallPriority.D.name)
        self.assertNotEqual(call.pending_at, None)
        self.assertNotEqual(call.started_at, None)
        self.assertEqual(call.ended_at, None)
        started_at = call.started_at

        # partial update patient set
        patient_set = PatientSerializer(call.patient_set.all(), many=True).data
        patient_set[0]['age'] = 5
        patient_set[1]['age'] = 12
        logger.debug(patient_set)

        data = {'patient_set': patient_set}
        response = client.patch('/en/api/call/{}/'.format(call.id),
                                data,
                                content_type='application/json')
        self.assertEqual(response.status_code, 200)

        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)
        self.assertEqual(call.priority, CallPriority.D.name)
        self.assertCountEqual(
            patient_set,
            PatientSerializer(call.patient_set.all(), many=True).data)
        self.assertEqual(call.started_at, started_at)

        # partial update patient set with addition
        patient_set = PatientSerializer(call.patient_set.all(), many=True).data
        patient_set.append({'name': 'someone', 'age': 14})
        logger.debug(patient_set)

        data = {'patient_set': patient_set}
        response = client.patch('/en/api/call/{}/'.format(call.id),
                                data,
                                content_type='application/json')
        self.assertEqual(response.status_code, 200)

        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)
        self.assertEqual(call.priority, CallPriority.D.name)
        self.assertEqual(
            len(patient_set),
            len(PatientSerializer(call.patient_set.all(), many=True).data))
        self.assertEqual(call.started_at, started_at)

        # partial update patient set with addition and removal
        patient_set = PatientSerializer(call.patient_set.all(), many=True).data
        del patient_set[0]
        patient_set.append({'name': 'someone else', 'age': 17})

        data = {'patient_set': patient_set}
        response = client.patch('/en/api/call/{}/'.format(call.id),
                                data,
                                content_type='application/json')
        self.assertEqual(response.status_code, 200)

        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)
        self.assertEqual(call.priority, CallPriority.D.name)
        self.assertEqual(
            len(patient_set),
            len(PatientSerializer(call.patient_set.all(), many=True).data))
        self.assertEqual(call.started_at, started_at)

        # partial update patient set with addition with null age
        patient_set = PatientSerializer(call.patient_set.all(), many=True).data
        patient_set.append({'name': 'someone else else'})

        data = {'patient_set': patient_set}
        response = client.patch('/en/api/call/{}/'.format(call.id),
                                data,
                                content_type='application/json')
        self.assertEqual(response.status_code, 200)

        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)
        self.assertEqual(call.priority, CallPriority.D.name)
        self.assertEqual(
            len(patient_set),
            len(PatientSerializer(call.patient_set.all(), many=True).data))
        self.assertEqual(call.started_at, started_at)

        # partial update patient remove all patients
        patient_set = []

        data = {'patient_set': patient_set}
        response = client.patch('/en/api/call/{}/'.format(call.id),
                                data,
                                content_type='application/json')
        self.assertEqual(response.status_code, 200)

        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)
        self.assertEqual(call.priority, CallPriority.D.name)
        self.assertEqual(
            len(patient_set),
            len(PatientSerializer(call.patient_set.all(), many=True).data))
        self.assertEqual(call.started_at, started_at)

        # logout
        client.logout()
    def test_call_create_viewset(self):

        # instantiate client
        client = Client()
        client.login(username=settings.MQTT['USERNAME'],
                     password=settings.MQTT['PASSWORD'])

        data = {
            'status':
            CallStatus.P.name,
            'priority':
            CallPriority.B.name,
            'sms_notifications': [],
            'ambulancecall_set': [{
                'ambulance_id':
                self.a1.id,
                'waypoint_set': [{
                    'order': 0,
                    'location': {
                        'type': LocationType.i.name,
                        'number': '123',
                        'street': 'some street'
                    }
                }, {
                    'order': 1,
                    'status': WaypointStatus.D.name,
                    'location': {
                        'type': LocationType.w.name,
                        'location': {
                            'longitude': -110.54,
                            'latitude': 35.75
                        }
                    }
                }]
            }, {
                'ambulance_id':
                self.a2.id,
                'waypoint_set': [{
                    'order': 0,
                    'location': {
                        'type': LocationType.i.name,
                        'number': '321',
                        'street': 'another street'
                    }
                }]
            }],
            'patient_set': [{
                'name': 'Jose',
                'age': 3
            }, {
                'name': 'Maria',
                'age': 10
            }]
        }
        response = client.post('/en/api/call/',
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 201)

        c1 = Call.objects.get(status=CallStatus.P.name)

        # add notes
        data = {'comment': 'some comment'}
        response = client.post('/en/api/call/{}/note/'.format(c1.id),
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 201)

        data = {'comment': 'another comment'}
        response = client.post('/en/api/call/{}/note/'.format(c1.id),
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 201)

        # serialize
        serializer = CallSerializer(c1)

        expected_patient_set = PatientSerializer(
            Patient.objects.filter(call_id=c1.id), many=True).data
        expected_ambulancecall_set = AmbulanceCallSerializer(
            AmbulanceCall.objects.filter(call_id=c1.id), many=True).data
        expected_callnote_set = CallNoteSerializer(
            CallNote.objects.filter(call_id=c1.id), many=True).data

        self.assertEqual(len(expected_patient_set), 2)
        self.assertEqual(len(expected_callnote_set), 2)
        self.assertEqual(
            len(expected_ambulancecall_set[0]['waypoint_set']) +
            len(expected_ambulancecall_set[1]['waypoint_set']), 3)

        expected = {
            'id': c1.id,
            'status': c1.status,
            'details': c1.details,
            'priority': c1.priority,
            'priority_code': c1.priority_code,
            'radio_code': c1.radio_code,
            'created_at': date2iso(c1.created_at),
            'pending_at': date2iso(c1.pending_at),
            'started_at': date2iso(c1.started_at),
            'ended_at': date2iso(c1.ended_at),
            'comment': c1.comment,
            'updated_by': c1.updated_by.id,
            'updated_on': date2iso(c1.updated_on),
            'sms_notifications': [],
            'ambulancecall_set': expected_ambulancecall_set,
            'patient_set': expected_patient_set,
            'callnote_set': expected_callnote_set
        }

        result = serializer.data
        self.assertCountEqual(result['ambulancecall_set'],
                              expected['ambulancecall_set'])
        self.assertCountEqual(result['patient_set'], expected['patient_set'])
        self.assertCountEqual(result['callnote_set'], expected['callnote_set'])
        expected['ambulancecall_set'] = []
        result['ambulancecall_set'] = []
        expected['patient_set'] = []
        result['patient_set'] = []
        expected['callnote_set'] = []
        result['callnote_set'] = []
        self.assertDictEqual(result, expected)

        # get notes
        response = client.get('/en/api/call/{}/note/'.format(c1.id))
        self.assertEqual(response.status_code, 200)

        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, expected_callnote_set)

        # logout
        client.logout()

        # login as testuser2
        client.login(username='******', password='******')

        # Will fail for anyone not superuser or staff or dispatcher
        data = {
            'status':
            CallStatus.P.name,
            'priority':
            CallPriority.B.name,
            'sms_notifications': [],
            'ambulancecall_set': [{
                'ambulance_id': self.a1.id
            }, {
                'ambulance_id': self.a2.id
            }],
            'patient_set': [{
                'name': 'Jose',
                'age': 3
            }, {
                'name': 'Maria',
                'age': 10
            }]
        }
        response = client.post('/en/api/call/',
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 403)

        # should fail because user can not read or write to ambulances
        response = client.get('/en/api/call/{}/note/'.format(c1.id))
        self.assertEqual(response.status_code, 403)

        data = {'comment': 'some comment'}
        response = client.post('/en/api/call/{}/note/'.format(c1.id),
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 403)

        # logout
        client.logout()

        # login as staff
        client.login(username='******', password='******')

        # Should not fail, is staff
        data = {
            'status':
            CallStatus.P.name,
            'priority':
            CallPriority.A.name,
            'sms_notifications': [],
            'ambulancecall_set': [{
                'ambulance_id': self.a1.id
            }, {
                'ambulance_id': self.a2.id
            }],
            'patient_set': [{
                'name': 'Jose',
                'age': 3
            }, {
                'name': 'Maria',
                'age': 10
            }]
        }
        response = client.post('/en/api/call/',
                               data,
                               content_type='application/json')
        logger.debug(response.content)
        self.assertEqual(response.status_code, 201)

        c2 = Call.objects.get(priority=CallPriority.A.name)

        # should not fail, user is staff
        response = client.get('/en/api/call/{}/note/'.format(c2.id))
        self.assertEqual(response.status_code, 200)

        data = {'comment': 'yet another comment'}
        response = client.post('/en/api/call/{}/note/'.format(c2.id),
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 201)

        # logout
        client.logout()

        # login as dispatcher
        client.login(username='******', password='******')

        # Should not fail, is dispatcher
        data = {
            'status':
            CallStatus.P.name,
            'priority':
            CallPriority.C.name,
            'sms_notifications': [],
            'ambulancecall_set': [{
                'ambulance_id': self.a3.id
            }],
            'patient_set': [{
                'name': 'Jose',
                'age': 3
            }, {
                'name': 'Maria',
                'age': 10
            }]
        }
        response = client.post('/en/api/call/',
                               data,
                               content_type='application/json')
        logger.debug(response.content)
        self.assertEqual(response.status_code, 201)

        c3 = Call.objects.get(priority=CallPriority.C.name)

        # should not fail, user is dispatcher
        response = client.get('/en/api/call/{}/note/'.format(c3.id))
        self.assertEqual(response.status_code, 200)

        data = {'comment': 'yet another comment'}
        response = client.post('/en/api/call/{}/note/'.format(c3.id),
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 201)

        # Should fail, dispatcher but not in authorized list of ambulances
        data = {
            'status':
            CallStatus.P.name,
            'priority':
            CallPriority.B.name,
            'sms_notifications': [],
            'ambulancecall_set': [{
                'ambulance_id': self.a1.id
            }],
            'patient_set': [{
                'name': 'Jose',
                'age': 3
            }, {
                'name': 'Maria',
                'age': 10
            }]
        }
        response = client.post('/en/api/call/',
                               data,
                               content_type='application/json')
        logger.debug(response.content)
        self.assertEqual(response.status_code, 403)

        # should fail, user is staff
        response = client.get('/en/api/call/{}/note/'.format(c2.id))
        self.assertEqual(response.status_code, 403)

        data = {'comment': 'yet another comment'}
        response = client.post('/en/api/call/{}/note/'.format(c2.id),
                               data,
                               content_type='application/json')
        self.assertEqual(response.status_code, 403)

        # Should fail, dispatcher but not in authorized list of ambulances
        data = {
            'status':
            CallStatus.P.name,
            'priority':
            CallPriority.B.name,
            'sms_notifications': [],
            'ambulancecall_set': [{
                'ambulance_id': self.a3.id
            }, {
                'ambulance_id': self.a1.id
            }],
            'patient_set': [{
                'name': 'Jose',
                'age': 3
            }, {
                'name': 'Maria',
                'age': 10
            }]
        }
        response = client.post('/en/api/call/',
                               data,
                               content_type='application/json')
        logger.debug(response.content)
        self.assertEqual(response.status_code, 403)

        # logout
        client.logout()
    def test(self, username=settings.MQTT['USERNAME'], password=settings.MQTT['PASSWORD'],
             ambulance_id1=None, ambulance_id2=None):

        if not ambulance_id1:
            ambulance_id1 = self.a1.id

        if not ambulance_id2:
            ambulance_id2 = self.a3.id

        # starts subscribe client
        self.start_subscribe_client('test_mqtt_subscribe_client')

        # Start test client
        client_id1 = 'test_mqtt1'
        test_client1 = self.start_mqtt_client(client_id1, username, password)

        # start django client
        django_client1 = self.start_django_client(username, password)

        # login ambulance
        self.set_django_client(django_client1, client_id1, ambulance_id1, None)

        # Start second test client
        client_id2 = 'test_mqtt2'
        username2 = 'testuser2'
        password2 = 'very_secret'
        test_client2 = self.start_mqtt_client(client_id2, username2, password2)

        # start django client
        django_client2 = self.start_django_client(username2, password2)

        # login ambulance
        self.set_django_client(django_client2, client_id2, ambulance_id2, None)

        # subscribe to call and ambulance call status
        test_client1.expect('ambulance/{}/call/+/status'.format(ambulance_id1))
        self.is_subscribed(test_client1)

        # subscribe ambulance call status
        test_client2.expect('ambulance/{}/call/+/status'.format(ambulance_id2))
        self.is_subscribed(test_client2)

        # create call using serializer, two ambulances
        call = {
            'status': CallStatus.P.name,
            'priority': CallPriority.B.name,
            'ambulancecall_set': [
                {
                    'ambulance_id': ambulance_id1,
                    'waypoint_set': [
                        {
                            'order': 0,
                            'location': {
                                'type': LocationType.i.name,
                                'number': '123',
                                'street': 'asdasdasd asd asd asdas'
                            }
                        }
                    ]
                },
                {
                    'ambulance_id': ambulance_id2,
                    'waypoint_set': [
                        {
                            'order': 0,
                            'location': {
                                'type': LocationType.i.name,
                                'number': '123',
                                'street': 'asdasdasd asd asd asdas'
                            }
                        }
                    ]
                }
                ],
            'patient_set': [{'name': 'Jose', 'age': 3}, {'name': 'Maria', 'age': 10}]
        }
        serializer = CallSerializer(data=call)
        serializer.is_valid()
        call = serializer.save(updated_by=self.u1)

        # process messages
        self.loop(test_client1)

        # Check if call status is Pending
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.P.name)

        # Check if ambulancecall status is Requested
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id1)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.R.name)

        # Check if ambulancecall status is Requested
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id2)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.R.name)

        # test_client publishes "Accepted" to call status
        test_client1.publish('user/{}/client/{}/ambulance/{}/call/{}/status'.format(username, client_id1,
                                                                                    ambulance_id1, call.id), 
                             AmbulanceCallStatus.A.name)

        # process messages
        self.loop(test_client1)

        # Check if call status changed to Started
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)

        # Check if ambulancecall status changed to accepted
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id1)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.A.name)

        # Check if ambulancecall status is Requested
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id2)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.R.name)

        # test_client publishes "Accepted" to call status
        test_client2.publish('user/{}/client/{}/ambulance/{}/call/{}/status'.format(username2, client_id2,
                                                                                    ambulance_id2, call.id),
                             AmbulanceCallStatus.A.name)

        # process messages
        self.loop(test_client2)

        # Check if call status is Started
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)

        # Check if ambulancecall1 status is accepted
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id1)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.A.name)

        # Check if ambulancecall2 status is accepted
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id2)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.A.name)

        # test_client publishes "patient bound" to status
        test_client1.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id1, ambulance_id1),
                             json.dumps({
                                 'status': AmbulanceStatus.PB.name,
                             }))

        # process messages
        self.loop(test_client1)

        # test_client2 publishes "patient bound" to status
        test_client2.publish('user/{}/client/{}/ambulance/{}/data'.format(username2, client_id2, ambulance_id2),
                             json.dumps({
                                 'status': AmbulanceStatus.PB.name,
                             }))

        # process messages
        self.loop(test_client2)

        # test_client publishes "at patient" to status
        test_client1.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id1, ambulance_id1),
                             json.dumps({
                                 'status': AmbulanceStatus.AP.name,
                             }))

        # process messages
        self.loop(test_client1)

        # test_client publishes "at patient" to status
        test_client2.publish('user/{}/client/{}/ambulance/{}/data'.format(username2, client_id2, ambulance_id2),
                             json.dumps({
                                 'status': AmbulanceStatus.AP.name,
                             }))

        # process messages
        self.loop(test_client2)

        # test_client publishes "hospital bound" to status
        test_client1.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id1, ambulance_id1),
                             json.dumps({
                                 'status': AmbulanceStatus.HB.name,
                             }))

        # process messages
        self.loop(test_client1)

        # test_client publishes "hospital bound" to status
        test_client2.publish('user/{}/client/{}/ambulance/{}/data'.format(username2, client_id2, ambulance_id2),
                             json.dumps({
                                 'status': AmbulanceStatus.HB.name,
                             }))

        # process messages
        self.loop(test_client2)

        # test_client publishes "at hospital" to status
        test_client1.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id1, ambulance_id1),
                             json.dumps({
                                 'status': AmbulanceStatus.AH.name,
                             }))

        # process messages
        self.loop(test_client1)

        # subscribe to call
        test_client2.expect('call/{}/data'.format(call.id))
        self.is_subscribed(test_client2)

        # will get call because of next call status change
        test_client1.expect('call/{}/data'.format(call.id))
        self.is_subscribed(test_client1)

        # test_client publishes "completed" to call status
        test_client1.publish('user/{}/client/{}/ambulance/{}/call/{}/status'.format(username, client_id1,
                                                                                    ambulance_id1, call.id),
                             AmbulanceCallStatus.C.name)

        # process messages
        self.loop(test_client2, test_client1)

        # Check if ambulancecall status is Completed
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id1)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.C.name)

        # Check if ambulancecall status is Requested
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id2)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.A.name)

        # Check if call status is Started
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)

        # test_client publishes "at hospital" to status
        test_client2.publish('user/{}/client/{}/ambulance/{}/data'.format(username2, client_id2, ambulance_id2),
                             json.dumps({
                                 'status': AmbulanceStatus.AH.name,
                             }))

        # process messages
        self.loop(test_client2)

        # subscribe to call
        test_client2.expect('call/{}/data'.format(call.id))
        self.is_subscribed(test_client2)

        # will get call because of next call status change
        test_client1.expect('call/{}/data'.format(call.id))
        self.is_subscribed(test_client1)

        # test_client publishes "completed" to call status
        test_client2.publish('user/{}/client/{}/ambulance/{}/call/{}/status'.format(username2, client_id2,
                                                                                    ambulance_id2, call.id),
                             AmbulanceCallStatus.C.name)

        # process messages
        self.loop(test_client2, test_client1)

        # Check if ambulancecall status is Completed
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id1)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.C.name)

        # Check if ambulancecall status is Completed
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id2)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.C.name)

        # Check if call status is Ended
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.E.name)

        # Client handshake
        test_client1.publish('user/{}/client/{}/status'.format(username, client_id1), ClientStatus.F.name)

        # process messages
        self.loop(test_client1)

        # Client handshake
        test_client2.publish('user/{}/client/{}/status'.format(username2, client_id2), ClientStatus.F.name)

        # process messages
        self.loop(test_client2)

        # wait for disconnect
        self.wait(test_client1, test_client2)
        django_client1.logout()
        django_client2.logout()
    def test(self, username=settings.MQTT['USERNAME'], password=settings.MQTT['PASSWORD'], ambulance_id=None):

        if not ambulance_id:
            ambulance_id = self.a1.id

        # starts subscribe client
        self.start_subscribe_client('test_mqtt_subscribe_client')

        # Start test client
        client_id = 'test_mqtt_subscribe_admin'
        test_client = self.start_mqtt_client(client_id, username, password)

        # start django client
        django_client = self.start_django_client(username, password)

        # login ambulance
        self.set_django_client(django_client, client_id, ambulance_id, None)

        # subscribe to call and ambulance call status
        test_client.expect('ambulance/{}/call/+/status'.format(ambulance_id))
        self.is_subscribed(test_client)

        # create call using serializer, one ambulance first
        call = {
            'status': CallStatus.P.name,
            'priority': CallPriority.B.name,
            'ambulancecall_set': [
                {
                    'ambulance_id': ambulance_id,
                    'waypoint_set': [
                        {
                            'order': 0,
                            'location': {
                                'type': LocationType.i.name,
                                'number': '123',
                                'street': 'asdasdasd asd asd asdas'
                            }
                        }
                    ]
                }
                ],
            'patient_set': [{'name': 'Jose', 'age': 3}, {'name': 'Maria', 'age': 10}]
        }
        serializer = CallSerializer(data=call)
        serializer.is_valid()
        call = serializer.save(updated_by=self.u1)

        # process messages
        self.loop(test_client)

        # Check if call status is Pending
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.P.name)

        # Check if ambulancecall status is Requested
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.R.name)

        # test_client publishes "Declined" to call status
        test_client.publish('user/{}/client/{}/ambulance/{}/call/{}/status'.format(username, client_id,
                                                                                   ambulance_id, call.id), 
                            AmbulanceCallStatus.D.name)

        # process messages
        self.loop(test_client)

        # Check if call status is Pending
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.P.name)

        # Check if ambulancecall status is Declined
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.D.name)

        # expect status ended call
        test_client.expect('call/{}/data'.format(call.id))
        self.is_subscribed(test_client)

        # Abort call
        call.abort()

        # process messages
        self.loop(test_client)

        # Check if ambulancecall status is Completed
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.C.name)

        # Check if call status is Ended
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.E.name)

        # Client handshake
        test_client.publish('user/{}/client/{}/status'.format(username, client_id), ClientStatus.F.name)

        # process messages
        self.loop(test_client)

        # wait for disconnect
        self.wait(test_client)
        django_client.logout()
    def test(self, username=settings.MQTT['USERNAME'], password=settings.MQTT['PASSWORD'], ambulance_id=None):

        if not ambulance_id:
            ambulance_id = self.a1.id

        # starts subscribe client
        self.start_subscribe_client('test_mqtt_subscribe_client')

        # Start test client
        client_id = 'test_mqtt_subscribe_admin'
        test_client = self.start_mqtt_client(client_id, username, password)

        # start django client
        django_client = self.start_django_client(username, password)

        # login ambulance
        self.set_django_client(django_client, client_id, ambulance_id, None)

        # subscribe to call and ambulance call status
        test_client.expect('ambulance/{}/call/+/status'.format(ambulance_id))
        self.is_subscribed(test_client)

        # create call using serializer, one ambulance first
        call = {
            'status': CallStatus.P.name,
            'priority': CallPriority.B.name,
            'ambulancecall_set': [
                {
                    'ambulance_id': ambulance_id,
                    'waypoint_set': [
                        {
                            'order': 0,
                            'location': {
                                'type': LocationType.i.name,
                                'number': '123',
                                'street': 'asdasdasd asd asd asdas'
                            }
                        }
                    ]
                }
                ],
            'patient_set': [{'name': 'Jose', 'age': 3}, {'name': 'Maria', 'age': 10}]
        }
        serializer = CallSerializer(data=call)
        serializer.is_valid()
        call = serializer.save(updated_by=self.u1)

        # process messages
        self.loop(test_client)

        # Check if call status is Pending
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.P.name)

        # Check if ambulancecall status is Requested
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.R.name)

        # expect ambulance call status
        test_client.expect('ambulance/{}/call/+/status'.format(ambulance_id))
        self.is_subscribed(test_client)

        # test_client publishes "Accepted" to call status
        test_client.publish('user/{}/client/{}/ambulance/{}/call/{}/status'.format(username, client_id,
                                                                                   ambulance_id, call.id),
                            AmbulanceCallStatus.A.name)

        # process messages
        self.loop(test_client)

        # Check if call status changed to Started
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.S.name)

        # Check if ambulancecall status changed to accepted
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.A.name)

        # test_client publishes "patient bound" to status
        test_client.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id, ambulance_id),
                            json.dumps({
                                'status': AmbulanceStatus.PB.name,
                            }))

        # process messages
        self.loop(test_client)

        # test_client publishes "at patient" to status
        test_client.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id, ambulance_id),
                            json.dumps({
                                'status': AmbulanceStatus.AP.name,
                            }))

        # process messages
        self.loop(test_client)

        # test_client publishes "hospital bound" to status
        test_client.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id, ambulance_id),
                            json.dumps({
                                'status': AmbulanceStatus.HB.name,
                            }))

        # process messages
        self.loop(test_client)

        # test_client publishes "at hospital" to status
        test_client.publish('user/{}/client/{}/ambulance/{}/data'.format(username, client_id, ambulance_id),
                            json.dumps({
                                'status': AmbulanceStatus.AH.name,
                            }))

        # process messages
        self.loop(test_client)

        # subscribe to call and ambulance call status
        test_client.expect('call/{}/data'.format(call.id))
        self.is_subscribed(test_client)

        # test_client publishes new waypoint
        test_client.publish('user/{}/client/{}/ambulance/{}/call/{}/waypoint/{}/data'.format(username, client_id,
                                                                                             ambulance_id, call.id, -1),
                            json.dumps({
                                'order': 2,
                                'location': {
                                    'type': LocationType.w.name
                                }
                            }))

        # process messages
        self.loop(test_client)

        # has the waypoint been created?
        waypoint_set = ambulancecall.waypoint_set.all()
        self.assertEqual(len(waypoint_set), 2)

        # subscribe to call and ambulance call status
        test_client.expect('call/{}/data'.format(ambulance_id))
        self.is_subscribed(test_client)

        # test_client updates waypoint
        waypoint = waypoint_set.get(order=2)
        test_client.publish('user/{}/client/{}/ambulance/{}/call/{}/waypoint/{}/data'.format(username, client_id,
                                                                                             ambulance_id, call.id,
                                                                                             waypoint.id),
                            json.dumps({
                                'order': 1,
                                'status': WaypointStatus.V.name
                            }))

        # process messages
        self.loop(test_client)

        # has the waypoint been created?
        waypoint = ambulancecall.waypoint_set.all()
        self.assertEqual(len(waypoint), 2)

        # subscribe to call and ambulance call status
        test_client.expect('call/{}/data'.format(ambulance_id))
        self.is_subscribed(test_client)

        # test_client publishes "completed" to call status
        test_client.publish('user/{}/client/{}/ambulance/{}/call/{}/status'.format(username, client_id,
                                                                                   ambulance_id, call.id),
                            AmbulanceCallStatus.C.name)

        # process messages
        self.loop(test_client)

        # Check if ambulancecall status is Completed
        ambulancecall = call.ambulancecall_set.get(ambulance_id=ambulance_id)
        self.assertEqual(ambulancecall.status, AmbulanceCallStatus.C.name)

        # Check if call status is Ended
        call = Call.objects.get(id=call.id)
        self.assertEqual(call.status, CallStatus.E.name)

        # Client handshake
        test_client.publish('user/{}/client/{}/status'.format(username, client_id), ClientStatus.F.name)

        # process messages
        self.loop(test_client)

        # wait for disconnect
        self.wait(test_client)
        django_client.logout()