def handle_noargs(self, **options): client = ProximityClient() try: client.flush() except ProximityClientConnectionError, e: raise CommandError(e)
class ProximityClientTestCase(TestCase): def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_good_add_set_get_flush(self): self.proximity_client.add_device('aa:aa:aa:aa:aa:aa') group = self.proximity_client.get_group('aa:aa:aa:aa:aa:aa') self.assertEqual(group, []) self.proximity_client.add_device('bb:bb:bb:bb:bb:bb') group = self.proximity_client.get_group('aa:aa:aa:aa:aa:aa') self.assertEqual(group, []) self.proximity_client.add_device('cc:cc:cc:cc:cc:cc') group = self.proximity_client.get_group('cc:cc:cc:cc:cc:cc') self.assertEqual(group, []) self.proximity_client.set_group('aa:aa:aa:aa:aa:aa', ['bb:bb:bb:bb:bb:bb']) group = self.proximity_client.get_group('aa:aa:aa:aa:aa:aa') self.assertEqual(group, ['bb:bb:bb:bb:bb:bb']) group = self.proximity_client.get_group('bb:bb:bb:bb:bb:bb') self.assertEqual(group, ['aa:aa:aa:aa:aa:aa']) group = self.proximity_client.get_group('cc:cc:cc:cc:cc:cc') self.assertEqual(group, []) self.proximity_client.set_group('cc:cc:cc:cc:cc:cc', ['bb:bb:bb:bb:bb:bb']) group = self.proximity_client.get_group('aa:aa:aa:aa:aa:aa') self.assertEqual(group, ['bb:bb:bb:bb:bb:bb', 'cc:cc:cc:cc:cc:cc']) group = self.proximity_client.get_group('bb:bb:bb:bb:bb:bb') self.assertEqual(group, ['aa:aa:aa:aa:aa:aa', 'cc:cc:cc:cc:cc:cc']) group = self.proximity_client.get_group('cc:cc:cc:cc:cc:cc') self.assertEqual(group, ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb']) self.proximity_client.flush() group = self.proximity_client.get_group('aa:aa:aa:aa:aa:aa') self.assertEqual(group, []) group = self.proximity_client.get_group('bb:bb:bb:bb:bb:bb') self.assertEqual(group, []) group = self.proximity_client.get_group('cc:cc:cc:cc:cc:cc') self.assertEqual(group, [])
class InterfaceFileAPITestCase(TestCase): fixtures = ['interface_file_api_testdata'] def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_good_upload(self, MirriMockClass): # Check the initial amount of interfaces in the database self.assertEqual(Interface.objects.count(), 1) # Check the initial amount of methods in the database self.assertEqual(Method.objects.count(), 2) # Check the initial amount of method parameters in the database self.assertEqual(MethodParameter.objects.count(), 0) # Check the initial amount of triggers in the database self.assertEqual(Trigger.objects.count(), 0) # TalkingDevice f = open('core/fixtures/talkingDevices/talkingDevice.py') response = self.client.post('/api/interface_file/', {'file': f}) f.seek(0) interface_code = f.read() f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Interface.objects.filter(name='TalkingDevice').exists()) self.assertTrue(Method.objects.filter(interface__name='TalkingDevice', name='isWilling').exists()) self.assertTrue(Method.objects.filter(interface__name='TalkingDevice', name='isSilent').exists()) self.assertTrue(Trigger.objects.filter(method__interface__name='TalkingDevice', method__name='isSilent').exists()) # Check that the file was uploaded to Mirri mirri_mock = MirriMockClass.return_value self.assertEqual(mirri_mock.upload_interface_file.call_count, 1) self.assertEqual(len(mirri_mock.upload_interface_file.call_args[0]), 2) self.assertEqual(mirri_mock.upload_interface_file.call_args[0][0], 'TalkingDevice') mirri_mock.upload_interface_file.call_args[0][1].seek(0) self.assertEqual(mirri_mock.upload_interface_file.call_args[0][1].read(), interface_code) # CalendarSource mirri_mock.reset_mock() f = open('core/fixtures/calendarReminders/calendarSource.py') response = self.client.post('/api/interface_file/', {'file': f}) f.seek(0) interface_code = f.read() f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Interface.objects.filter(name='CalendarSource').exists()) self.assertTrue(Method.objects.filter(interface__name='CalendarSource', name='eventApproaching').exists()) self.assertTrue(MethodParameter.objects.filter(method__interface__name='CalendarSource', method__name='eventApproaching', name='eid').exists()) self.assertTrue(Trigger.objects.filter(method__interface__name='CalendarSource', method__name='eventApproaching').exists()) # Check that the file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 1) self.assertEqual(len(mirri_mock.upload_interface_file.call_args[0]), 2) self.assertEqual(mirri_mock.upload_interface_file.call_args[0][0], 'CalendarSource') mirri_mock.upload_interface_file.call_args[0][1].seek(0) self.assertEqual(mirri_mock.upload_interface_file.call_args[0][1].read(), interface_code) # Check the final amount of interfaces in the database self.assertEqual(Interface.objects.count(), 3) # Check the final amount of methods in the database self.assertEqual(Method.objects.count(), 5) # Check the final amount of method parameters in the database self.assertEqual(MethodParameter.objects.count(), 1) # Check the final amount of triggers in the database self.assertEqual(Trigger.objects.count(), 2) def test_bad_upload(self, MirriMockClass): # Check the initial amount of interfaces in the database self.assertEqual(Interface.objects.count(), 1) # Check the initial amount of methods in the database self.assertEqual(Method.objects.count(), 2) # Check the initial amount of method parameters in the database self.assertEqual(MethodParameter.objects.count(), 0) # Check the initial amount of triggers in the database self.assertEqual(Trigger.objects.count(), 0) # A syntax error in the interface file f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_syntax_error.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['File talkingDevice_syntax_error.py contains syntax errors (line 15, col 22): class TalkingDevice()\n']) # Check that no file was uploaded to Mirri mirri_mock = MirriMockClass.return_value self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface file does not contain any interfaces mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_no_interface.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file talkingDevice_no_interface.py: Interface decorator @deviceInterface is missing.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface file does not contain any precondition methods mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_no_precondition_methods.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file talkingDevice_no_precondition_methods.py: Interface TalkingDevice does not have any precondition methods defined with decorator @precondition.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface file does not contain any triggers mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_no_triggers.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file talkingDevice_no_triggers.py: No trigger method class with base class TriggeringEvent has been defined.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # A trigger in the interface file does not match any of the interface precondition methods mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_no_trigger_match.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file talkingDevice_no_trigger_match.py: The name of the trigger method class IsFree does not match any of the precondition methods defined in interface TalkingDevice.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface file contains multiple interfaces mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_multiple_interfaces.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file talkingDevice_multiple_interfaces.py: Multiple interface classes with decorator @deviceInterface have been defined.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface file contains a duplicate precondition method mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_duplicate_precondition_method.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file talkingDevice_duplicate_precondition_method.py: Duplicate precondition method isWilling.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface file contains a duplicate trigger mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_duplicate_trigger.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file talkingDevice_duplicate_trigger.py: Duplicate trigger method class IsSilent.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface file contains a duplicate method parameter mirri_mock.reset_mock() f = open('core/fixtures/calendarReminders/invalid_files/calendarSource_duplicate_method_parameter.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface parse error in file calendarSource_duplicate_method_parameter.py: Duplicate parameter eid for precondition method eventApproaching in interface CalendarSource.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The interface in the interface file already exists mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevice_interface_exists.py') response = self.client.post('/api/interface_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface TalkingDeviceTest already exists.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # Check the final amount of interfaces in the database self.assertEqual(Interface.objects.count(), 1) # Check the final amount of methods in the database self.assertEqual(Method.objects.count(), 2) # Check the final amount of method parameters in the database self.assertEqual(MethodParameter.objects.count(), 0) # Check the final amount of triggers in the database self.assertEqual(Trigger.objects.count(), 0)
class DeviceInterfaceAPITestCase(TestCase): fixtures = ['devices_testdata'] def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_good_device_interface_post(self): mac_address = 'aa:aa:aa:aa:aa:aa' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check the initial amount of interfaces that the device has in the database self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 4) # The interface data payload = json.dumps({'interface_name': 'CalendarDevice'}) # Issue a POST request response = self.client.post('/api/v2/device/' + mac_address + '/interface/', payload, 'application/json') # Check that the response is 201 Created self.assertEqual(response.status_code, 201) self.assertEqual(response['Location'], 'http://testserver/api/v2/device/' + mac_address + '/interface/CalendarDevice/') # Check the final amount of devices in the database self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 5) def test_bad_device_interface_posts(self): mac_address = 'aa:aa:aa:aa:aa:aa' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check the initial amount of interfaces that the device has in the database self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 4) # Send post without data and check that the response is 400 Bad Request response = self.client.post('/api/v2/device/' + mac_address + '/interface/', content_type='application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['interface_name'], 'Interface name is a required field') # Send post without interface name and check that the response is 400 Bad Request payload = json.dumps({}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['interface_name'], 'Interface name is a required field') # Send junk data and check that the response is 400 Bad Request payload = json.dumps({'foo': 'bar'}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['interface_name'], 'Interface name is a required field') # Send post with non-existent interface name and check that the response is 400 Bad Request payload = json.dumps({'interface_name': 'FooBarInterface'}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['interface_name'], 'Interface FooBarInterface does not exist.') # Send post with empty interface name payload = json.dumps({'interface_name': ''}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['interface_name'], 'Interface name cannot be an empty string') # Send post for non-existent device payload = json.dumps({'interface_name': 'TalkingDevice'}) response = self.client.post('/api/v2/device/aa:bb:cc:dd:ee:ff/interface/', payload, 'application/json') self.assertEqual(response.status_code, 404) content = json.loads(response.content) self.assertEqual(content['error_message'], 'Sorry, this request could not be processed. Please try again later.') # Send post with an interface name that already exists for the specific device in the database self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name='TalkingDevice').exists()) payload = json.dumps({'interface_name': 'TalkingDevice'}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['interface_name'], 'Duplicate interface. Device aa:aa:aa:aa:aa:aa already has interface TalkingDevice.') # Check the final amount of interfaces for the device in the database is the same as in the beginning self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 4) def test_good_device_interface_delete(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check the initial amount of interfaces that the device has in the database self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 4) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Issue a DELETE request response = self.client.delete('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/') # Check that the response is 204 No Content self.assertEqual(response.status_code, 204) # Check that the device interface does not exist in the database anymore self.assertFalse(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check the final amount of device interfaces in the database self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 3) # TODO: cascade check def test_bad_device_interface_deletes(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check the initial amount of interfaces that the device has in the database self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 4) # Ensure that the deletion of a non-existent device interface throws 404 Not Found self.assertFalse(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name='FooBarInterface').exists()) response = self.client.delete('/api/v2/device/' + mac_address + '/interface/FooBarInterface/') self.assertEqual(response.status_code, 404) # Ensure that the deletion of an interface of a non-existent device throws 404 Not Found self.assertFalse(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name='FooBarInterface').exists()) response = self.client.delete('/api/v2/device/aa:bb:cc:dd:ee:ff/interface/' + interface_name + '/') self.assertEqual(response.status_code, 404) # The deletion of all device interfaces should throw 405 Method Not Allowed response = self.client.delete('/api/v2/device/' + mac_address + '/interface/') self.assertEqual(response.status_code, 405) # Check the final amount of interfaces that the device has in the database is the same as in the beginning self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 4) def test_good_device_interface_get_list(self): mac_address = 'aa:aa:aa:aa:aa:aa' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check the initial amount of interfaces that the device has in the database self.assertEqual(DeviceInterface.objects.filter(device__mac_address=mac_address).count(), 4) # Get a list of devices including their information response = self.client.get('/api/v2/device/' + mac_address + '/interface/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Convert the json to python content = json.loads(response.content) # Check that all the interfaces of the device are in the list self.assertEqual([deviceinterface['interface_name'] for deviceinterface in content['objects']], ['TalkingDevice', 'SingingDevice', 'CalendarSource', 'ScreenDevice']) # Check that the number of device interfaces in the list is 4 self.assertEqual(len(content['objects']), 4) def test_good_device_interface_get_detail(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Get the information related to one device interface response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Check that the values are correct content = json.loads(response.content) self.assertEqual(content['created_at'], '2011-12-19T16:21:43.912345') self.assertEqual(content['interface_name'], 'TalkingDevice') self.assertEqual(content['resource_uri'], '/api/v2/device/aa:aa:aa:aa:aa:aa/interface/TalkingDevice/') def test_bad_device_interface_get_details(self): # Get a device interface for a non-existent interface mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TestInterface' self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) self.assertFalse(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/') self.assertEqual(response.status_code, 404) # Get a device interface for a non-existent device mac_address = 'aa:bb:cc:dd:ee:ff' interface_name = 'TalkingDevice' self.assertFalse(Device.objects.filter(mac_address=mac_address).exists()) self.assertFalse(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/') self.assertEqual(response.status_code, 404) def test_bad_device_interface_update(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # The device data to be updated payload = json.dumps({'interface_name': 'TestInterface'}) # Issue a PUT request response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/', payload, 'application/json') # Check that the response is 405 Method Not Allowed self.assertEqual(response.status_code, 405)
class InterfaceAPITestCase(TestCase): fixtures = ['interfaces_testdata'] def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_bad_interface_post(self): # Check the initial amount of interfaces in the database self.assertEqual(Interface.objects.count(), 2) # The interface data payload = json.dumps({'name': 'SingingDevice'}) # Issue a POST request response = self.client.post('/api/v2/interface/', payload, 'application/json') # Check that the response is 405 Method Not Allowed self.assertEqual(response.status_code, 405) # Check the amount of interfaces in the database is the same as in the beginning self.assertEqual(Interface.objects.count(), 2) def test_bad_interface_delete(self): # Check the initial amount of interfaces in the database self.assertEqual(Interface.objects.count(), 2) # The deletion of all devices should throw 405 Method Not Allowed response = self.client.delete('/api/v2/interface/') self.assertEqual(response.status_code, 405) # The deletion of an interface should throw 405 Method Not Allowed name = 'TalkingDevice' response = self.client.delete('/api/v2/interface/' + name + '/') self.assertEqual(response.status_code, 405) # Check the amount of interfaces in the database is the same as in the beginning self.assertEqual(Interface.objects.count(), 2) def test_good_interface_get_list(self): # Check the initial amount of interfaces in the database self.assertEqual(Interface.objects.count(), 2) # Get a list of interfaces including their information response = self.client.get('/api/v2/interface/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Convert the json to python content = json.loads(response.content) # Check that all the interfaces are in the list self.assertEqual([interface['name'] for interface in content['objects']], ['TalkingDevice', 'CalendarSource']) # Check that the number of interfaces in the list is 2 self.assertEqual(len(content['objects']), 2) def test_good_interface_get_detail(self): name = 'TalkingDevice' # Check that the interface actually exists in the database self.assertTrue(Interface.objects.filter(name=name).exists()) # Get the information related to one interface response = self.client.get('/api/v2/interface/' + name + '/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Check that the values are correct content = json.loads(response.content) self.assertEqual(content['created_at'], '2011-12-22T16:21:43.834112') self.assertEqual(content['name'], 'TalkingDevice') self.assertEqual(content['resource_uri'], '/api/v2/interface/TalkingDevice/') self.assertEqual(content['updated_at'], '2011-12-22T23:49:03.998318') def test_bad_interface_get_details(self): name = 'SingingDevice' # Check that the device does not exist in the database self.assertFalse(Interface.objects.filter(name=name).exists()) # Issue a get request on a non-existent interface response = self.client.get('/api/v2/interface/' + name + '/') # Check that the response code is 404 Not Found self.assertEqual(response.status_code, 404) def test_bad_interface_update(self): name = 'TalkingDevice' # Check that the device actually exists in the database self.assertTrue(Interface.objects.filter(name=name).exists()) # The interface data to be updated payload = json.dumps({'name': 'SingingDevice'}) # Issue a PUT request in order to update the interface response = self.client.put('/api/v2/interface/' + name + '/', payload, 'application/json') # Check that the response is 405 Method Not Allowed self.assertEqual(response.status_code, 405)
class ActionFileAPITestCase(TestCase): fixtures = ['action_file_api_testdata'] def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_good_upload(self, MirriMockClass): # Check the initial amount of actions in the database self.assertEqual(Action.objects.count(), 1) # Check the initial amount of action devices in the database self.assertEqual(ActionDevice.objects.count(), 2) # Check the initial amount of action device interfaces in the database self.assertEqual(ActionDeviceInterface.objects.count(), 2) # Check the initial amount of action precondition methods in the database self.assertEqual(ActionPreconditionMethod.objects.count(), 3) # TalkingDevice - Dialog f = open('core/fixtures/talkingDevices/dialog.py') response = self.client.post('/api/action_file/', {'file': f}) f.seek(0) action_code = f.read() f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Action.objects.filter(name='Dialog', precondition_expression='(? and ? and ?)').exists()) self.assertTrue(ActionDevice.objects.filter(action__name='Dialog', name='d1', parameter_position=0).exists()) self.assertTrue(ActionDevice.objects.filter(action__name='Dialog', name='d2', parameter_position=1).exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='Dialog', action_device__name='d1', interface__name='TalkingDevice').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='Dialog', action_device__name='d2', interface__name='TalkingDevice').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=0, action__name='Dialog', action_device__name='d1', method__name='isWilling').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=1, action__name='Dialog', action_device__name='d2', method__name='isWilling').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=2, action__name='Dialog', action_device__name='d1', method__name='isSilent').exists()) # Check that the file was uploaded to Mirri mirri_mock = MirriMockClass.return_value self.assertEqual(mirri_mock.upload_action_file.call_count, 1) self.assertEqual(len(mirri_mock.upload_action_file.call_args[0]), 1) mirri_mock.upload_action_file.call_args[0][0].seek(0) self.assertEqual(mirri_mock.upload_action_file.call_args[0][0].read(), action_code) # TalkingDevice - ConversationOfThree mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/conversationOfThree.py') response = self.client.post('/api/action_file/', {'file': f}) f.seek(0) action_code = f.read() f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Action.objects.filter(name='ConversationOfThree', precondition_expression='(? and ? and ? and ?)').exists()) self.assertTrue(ActionDevice.objects.filter(action__name='ConversationOfThree', name='d1', parameter_position=0).exists()) self.assertTrue(ActionDevice.objects.filter(action__name='ConversationOfThree', name='d2', parameter_position=1).exists()) self.assertTrue(ActionDevice.objects.filter(action__name='ConversationOfThree', name='d3', parameter_position=2).exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='ConversationOfThree', action_device__name='d1', interface__name='TalkingDevice').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='ConversationOfThree', action_device__name='d2', interface__name='TalkingDevice').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='ConversationOfThree', action_device__name='d3', interface__name='TalkingDevice').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=0, action__name='ConversationOfThree', action_device__name='d1', method__name='isWilling').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=1, action__name='ConversationOfThree', action_device__name='d2', method__name='isWilling').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=2, action__name='ConversationOfThree', action_device__name='d3', method__name='isWilling').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=3, action__name='ConversationOfThree', action_device__name='d1', method__name='isSilent').exists()) # Check that the file was uploaded to Mirri self.assertEqual(mirri_mock.upload_action_file.call_count, 1) self.assertEqual(len(mirri_mock.upload_action_file.call_args[0]), 1) mirri_mock.upload_action_file.call_args[0][0].seek(0) self.assertEqual(mirri_mock.upload_action_file.call_args[0][0].read(), action_code) # CalendarSource - Conversation mirri_mock.reset_mock() f = open('core/fixtures/calendarReminders/conversation.py') response = self.client.post('/api/action_file/', {'file': f}) f.seek(0) action_code = f.read() f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Action.objects.filter(name='Conversation', precondition_expression='(?)').exists()) self.assertTrue(ActionDevice.objects.filter(action__name='Conversation', name='source', parameter_position=0).exists()) self.assertTrue(ActionDevice.objects.filter(action__name='Conversation', name='d2', parameter_position=1).exists()) self.assertTrue(ActionDevice.objects.filter(action__name='Conversation', name='d3', parameter_position=2).exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='Conversation', action_device__name='source', interface__name='TalkingDevice').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='Conversation', action_device__name='source', interface__name='CalendarSource').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='Conversation', action_device__name='d2', interface__name='TalkingDevice').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='Conversation', action_device__name='d3', interface__name='TalkingDevice').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=0, action__name='Conversation', action_device__name='source', method__name='eventApproaching').exists()) # Check that the file was uploaded to Mirri self.assertEqual(mirri_mock.upload_action_file.call_count, 1) self.assertEqual(len(mirri_mock.upload_action_file.call_args[0]), 1) mirri_mock.upload_action_file.call_args[0][0].seek(0) self.assertEqual(mirri_mock.upload_action_file.call_args[0][0].read(), action_code) # CalendarSource - FakeCall mirri_mock.reset_mock() f = open('core/fixtures/calendarReminders/fakeCall.py') response = self.client.post('/api/action_file/', {'file': f}) f.seek(0) action_code = f.read() f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Action.objects.filter(name='FakeCall', precondition_expression='(?)').exists()) self.assertTrue(ActionDevice.objects.filter(action__name='FakeCall', name='d1', parameter_position=0).exists()) self.assertTrue(ActionDevice.objects.filter(action__name='FakeCall', name='d2', parameter_position=1).exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='FakeCall', action_device__name='d1', interface__name='TalkingDevice').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='FakeCall', action_device__name='d1', interface__name='CalendarSource').exists()) self.assertTrue(ActionDeviceInterface.objects.filter(action_device__action__name='FakeCall', action_device__name='d2', interface__name='TalkingDevice').exists()) self.assertTrue(ActionPreconditionMethod.objects.filter(expression_position=0, action__name='FakeCall', action_device__name='d1', method__name='eventApproaching').exists()) # Check that the file was uploaded to Mirri self.assertEqual(mirri_mock.upload_action_file.call_count, 1) self.assertEqual(len(mirri_mock.upload_action_file.call_args[0]), 1) mirri_mock.upload_action_file.call_args[0][0].seek(0) self.assertEqual(mirri_mock.upload_action_file.call_args[0][0].read(), action_code) # Check the final amount of actions in the database self.assertEqual(Action.objects.count(), 5) # Check the final amount of action devices in the database self.assertEqual(ActionDevice.objects.count(), 12) # Check the final amount of action device interfaces in the database self.assertEqual(ActionDeviceInterface.objects.count(), 14) # Check the final amount of action precondition methods in the database self.assertEqual(ActionPreconditionMethod.objects.count(), 12) def test_bad_upload(self, MirriMockClass): # Check the initial amount of actions in the database self.assertEqual(Action.objects.count(), 1) # Check the initial amount of action devices in the database self.assertEqual(ActionDevice.objects.count(), 2) # Check the initial amount of action device interfaces in the database self.assertEqual(ActionDeviceInterface.objects.count(), 2) # Check the initial amount of action precondition methods in the database self.assertEqual(ActionPreconditionMethod.objects.count(), 3) # A syntax error in the action file f = open('core/fixtures/talkingDevices/invalid_files/dialog_syntax_error.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['File dialog_syntax_error.py contains syntax errors (line 13, col 21): class Dialog(Action)\n']) # Check that no file was uploaded to Mirri mirri_mock = MirriMockClass.return_value self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The action file does not contain any actions mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_action.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_action.py: No action class with base class Action has been defined.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The action file does not contain an action precondition mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_action_precondition.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_action_precondition.py: No method with decorator @actionprecondition has been defined for action class Dialog.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The action precondition does not have any parameters mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_action_precondition_parameters.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_action_precondition_parameters.py: Precondition method precondition does not have any parameters.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The action precondition does not have a return statement mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_action_precondition_return.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_action_precondition_return.py: The precondition method precondition does not have a return statement.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The return statement in the action precondition does not contain a boolean expression mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_boolean_in_return.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_boolean_in_return.py: The return statement in the precondition method does not contain a boolean expression.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # No interfaces have been declared for the devices in the action precondition mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_action_device_interfaces.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_action_device_interfaces.py: Method hasInterface() has not been called in the return statement of the precondition method.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The return statement does not contain a valid boolean precondition expression mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_precondition_expression.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_precondition_expression.py: The return statement of the precondition method in class Dialog does not contain a valid boolean precondition expression consisting of precondition methods.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # An action device is not declared in the precondition parameters mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_no_device_parameter.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_no_device_parameter.py: Device d1 is not declared in the precondition parameters.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # A precondition method call is incorrect in the action precondition mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_precondition_method_call_error.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_precondition_method_call_error.py: The format of the precondition method call is incorrect (line 21, col 44): isWilling. The format should be <device>.<interface>.<precondition_method>.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # A device has not been declared any interfaces mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_device_without_interfaces.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_device_without_interfaces.py: No interfaces have been declared for device d1 with method hasInterface().']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # A device has not been declared any interfaces mirri_mock.reset_mock() f = open('core/fixtures/calendarReminders/invalid_files/conversation_device_interface_missing.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file conversation_device_interface_missing.py: Interface TalkingDevice has not been declared for device source with method hasInterface().']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The return statement in the action precondition contains a value other than # a function call or a boolean expression mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_invalid_return.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_invalid_return.py: The boolean expression in the return statement of the action precondition method can only consist of function calls or nested boolean expressions.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The action file contains multiple actions mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_multiple_actions.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_multiple_actions.py: Multiple action classes with base class Action have been defined.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # The action precondition contains a duplicate parameter mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_duplicate_precondition_parameter.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_duplicate_precondition_parameter.py: Duplicate parameter d1 for precondition method precondition.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # A device has a duplicate interface mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_duplicate_device_interface.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action parse error in file dialog_duplicate_device_interface.py: Method hasInterface(\'TalkingDevice\') called multiple times for action device d1.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # An action already exists mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_action_exists.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action DialogTest already exists.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # A non-existent interface mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_non_existent_interface.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Interface TalkingDeviceTest does not exist.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # A non-existent method mirri_mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/dialog_non_existent_method.py') response = self.client.post('/api/action_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Method isWillingTest does not exist for interface TalkingDevice.']) # Check that no file was uploaded to Mirri self.assertEqual(mirri_mock.upload_interface_file.call_count, 0) # Check the final amount of actions in the database self.assertEqual(Action.objects.count(), 1) # Check the final amount of action devices in the database self.assertEqual(ActionDevice.objects.count(), 2) # Check the final amount of action device interfaces in the database self.assertEqual(ActionDeviceInterface.objects.count(), 2) # Check the final amount of action precondition methods in the database self.assertEqual(ActionPreconditionMethod.objects.count(), 3)
class DeviceAPITestCase(TestCase): fixtures = ['devices_testdata'] def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_good_device_post(self): # Check the initial amount of devices in the database self.assertEqual(Device.objects.count(), 4) # The device data (mac_address, name) payload = json.dumps({'mac_address': 'aa:bb:cc:dd:ee:ff', 'name': 'Device one'}) # Issue a POST request response = self.client.post('/api/v2/device/', payload, 'application/json') # Check that the response is 201 Created and that the location is correct self.assertEqual(response.status_code, 201) self.assertEqual(response['Location'], 'http://testserver/api/v2/device/aa:bb:cc:dd:ee:ff/') # Check the final amount of devices in the database self.assertEqual(Device.objects.count(), 5) def test_bad_device_posts(self): # Check the initial amount of devices in the database self.assertEqual(Device.objects.count(), 4) # Send post without data and check that the response is 400 Bad Request response = self.client.post('/api/v2/device/', content_type='application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['__all__'], 'Missing data') # Send post without mac address and check that the response is 400 Bad Request payload = json.dumps({'name': 'Device one'}) response = self.client.post('/api/v2/device/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) # Send post without name and check that the response is 400 Bad Request payload = json.dumps({'mac_address': 'aa:bb:cc:dd:ee:ff'}) response = self.client.post('/api/v2/device/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['name'], 'Device name is a required field') # Send junk data and check that the response is 400 Bad Request payload = json.dumps({'foo': 'bar'}) response = self.client.post('/api/v2/device/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['mac_address'], 'Mac address is a required field') self.assertEqual(content['name'], 'Device name is a required field') # Send post with invalid mac address and check that the response is 400 Bad Request payload = json.dumps({'mac_address': 'aa:bb:cc:aa:ee:ff:tt', 'name': 'Device one'}) response = self.client.post('/api/v2/device/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['mac_address'], 'Mac address format is incorrect') # Send post with a mac address that already exists in the database self.assertTrue(Device.objects.filter(mac_address='aa:aa:aa:aa:aa:aa').exists()) payload = json.dumps({'mac_address': 'aa:aa:aa:aa:aa:aa', 'name': 'Device one'}) response = self.client.post('/api/v2/device/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['mac_address'], 'Duplicate mac address. Mac address aa:aa:aa:aa:aa:aa already exists.') # Send post with empty name payload = json.dumps({'mac_address': 'aa:bb:cc:dd:ee:ff', 'name': ''}) response = self.client.post('/api/v2/device/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['name'], 'Device name cannot be an empty string') # Check the amount of devices in the database is the same as in the beginning self.assertEqual(Device.objects.count(), 4) def test_good_device_delete(self): # Check the initial amount of devices in the database self.assertEqual(Device.objects.count(), 4) mac_address = 'aa:aa:aa:aa:aa:aa' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Issue a DELETE request response = self.client.delete('/api/v2/device/' + mac_address + '/') # Check that the response is 204 No Content self.assertEqual(response.status_code, 204) # Check that the device does not exist in the database anymore self.assertFalse(Device.objects.filter(mac_address=mac_address).exists()) # Check the final amount of devices in the database self.assertEqual(Device.objects.count(), 3) def test_bad_device_deletes(self): # Check the initial amount of devices in the database self.assertEqual(Device.objects.count(), 4) # Ensure that the deletion of a non-existent device throws 404 Not Found mac_address = 'ff:ff:ff:ff:ff:ff' self.assertFalse(Device.objects.filter(mac_address=mac_address).exists()) response = self.client.delete('/api/v2/device/' + mac_address + '/') self.assertEqual(response.status_code, 404) # The deletion of all devices should throw 405 Method Not Allowed response = self.client.delete('/api/v2/device/') self.assertEqual(response.status_code, 405) # Check the amount of devices in the database is the same as in the beginning self.assertEqual(Device.objects.count(), 4) def test_good_device_get_list(self): # Check the initial amount of devices in the database self.assertEqual(Device.objects.count(), 4) # Get a list of devices including their information response = self.client.get('/api/v2/device/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Convert the json to python content = json.loads(response.content) # Check that all the devices are in the list self.assertEqual([device['mac_address'] for device in content['objects']], ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb', 'cc:cc:cc:cc:cc:cc', 'dd:dd:dd:dd:dd:dd']) # Check that the number of devices in the list is 4 # (the amount of devices in the fixture) self.assertEqual(len(content['objects']), 4) def test_good_device_get_detail(self): mac_address = 'aa:aa:aa:aa:aa:aa' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Get the information related to one device response = self.client.get('/api/v2/device/' + mac_address + '/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Check that the values are correct content = json.loads(response.content) self.assertEqual(content['created_at'], '2011-12-19T16:21:43.834112') self.assertFalse(content['is_reserved']) self.assertEqual(content['mac_address'], 'aa:aa:aa:aa:aa:aa') self.assertEqual(content['name'], 'Device one') self.assertEqual(content['proximity_devices'], []) self.assertEqual(content['resource_uri'], '/api/v2/device/aa:aa:aa:aa:aa:aa/') self.assertEqual(content['updated_at'], '2011-12-20T12:49:03.998318') def test_bad_device_get_details(self): mac_address = 'ff:ff:ff:ff:ff:ff' # Check that the device does not exist in the database self.assertFalse(Device.objects.filter(mac_address=mac_address).exists()) # Issue a get request on a non-existent device response = self.client.get('/api/v2/device/' + mac_address + '/') # Check that the response code is 404 Not Found self.assertEqual(response.status_code, 404) def test_good_device_updates(self): mac_address = 'aa:aa:aa:aa:aa:aa' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Send a put request to update is_reserved to True response = self.client.get('/api/v2/device/' + mac_address + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertFalse(content['is_reserved']) payload = json.dumps({'is_reserved': True}) response = self.client.put('/api/v2/device/' + mac_address + '/', payload, 'application/json') self.assertEqual(response.status_code, 204) response = self.client.get('/api/v2/device/' + mac_address + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertTrue(content['is_reserved']) # Send a put request to update the device name response = self.client.get('/api/v2/device/' + mac_address + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['name'], 'Device one') payload = json.dumps({'name': 'Test device'}) response = self.client.put('/api/v2/device/' + mac_address + '/', payload, 'application/json') self.assertEqual(response.status_code, 204) response = self.client.get('/api/v2/device/' + mac_address + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['name'], 'Test device') # TODO: update proximity devices def test_bad_device_updates(self): mac_address = 'aa:aa:aa:aa:aa:aa' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Send a put request to update the device mac address payload = json.dumps({'mac_address': 'aa:bb:cc:dd:ee:ff'}) response = self.client.put('/api/v2/device/' + mac_address + '/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['mac_address'], 'Mac address cannot be updated') # Send a put request to update the created_at field payload = json.dumps({'created_at': '2011-12-22T16:21:43.834112'}) response = self.client.put('/api/v2/device/' + mac_address + '/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['created_at'], 'Created at cannot be updated') # Send a put request to update the updated_at field payload = json.dumps({'updated_at': '2011-12-22T16:21:43.834112'}) response = self.client.put('/api/v2/device/' + mac_address + '/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['updated_at'], 'Updated at cannot be updated') # Send a put request to update a non-existent device payload = json.dumps({'is_reserved': True}) response = self.client.put('/api/v2/device/aa:bb:cc:dd:ee:ff/', payload, 'application/json') self.assertEqual(response.status_code, 404)
class ScheduleFileAPITestCase(TestCase): fixtures = ['schedule_file_api_testdata'] def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_good_upload(self, MockClass): # Check the initial amount of schedules in the database self.assertEqual(Schedule.objects.count(), 1) # Check the initial amount of schedule actions in the database self.assertEqual(ScheduleAction.objects.count(), 2) # talkingDevicesSCH f = open('core/fixtures/talkingDevices/talkingDevicesSCH.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Schedule.objects.filter(name='talkingDevicesSCH', trigger__method__interface__name='TalkingDevice', trigger__method__name='isSilent').exists()) self.assertTrue(ScheduleAction.objects.filter(schedule__name='talkingDevicesSCH', action__name='Dialog', trigger_device__action__name='Dialog', trigger_device__parameter_position=0).exists()) self.assertTrue(ScheduleAction.objects.filter(schedule__name='talkingDevicesSCH', action__name='ConversationOfThree', trigger_device__action__name='ConversationOfThree', trigger_device__parameter_position=0).exists()) # Check that the upload of the schedule file triggered a signal # to generate the configuration model in a thread self.assertEqual(MockClass.call_count, 1) self.assertEqual(MockClass.call_args[0][0].name, 'talkingDevicesSCH') mock = MockClass.return_value self.assertEqual(mock.start.call_count, 1) # calendarReminderSCH MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/calendarReminders/calendarReminderSCH.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 201) self.assertTrue(Schedule.objects.filter(name='calendarReminder', trigger__method__interface__name='CalendarSource', trigger__method__name='eventApproaching').exists()) self.assertTrue(ScheduleAction.objects.filter(schedule__name='calendarReminder', action__name='Conversation', trigger_device__action__name='Conversation', trigger_device__parameter_position=0).exists()) self.assertTrue(ScheduleAction.objects.filter(schedule__name='calendarReminder', action__name='FakeCall', trigger_device__action__name='FakeCall', trigger_device__parameter_position=0).exists()) # Check that the upload of the schedule file triggered a signal # to generate the configuration model in a thread self.assertEqual(MockClass.call_count, 1) self.assertEqual(MockClass.call_args[0][0].name, 'calendarReminder') mock = MockClass.return_value self.assertEqual(mock.start.call_count, 1) # Check the final amount of schedules in the database self.assertEqual(Schedule.objects.count(), 3) # Check the final amount of schedule actions in the database self.assertEqual(ScheduleAction.objects.count(), 6) def test_bad_upload(self, MockClass): # Check the initial amount of schedules in the database self.assertEqual(Schedule.objects.count(), 1) # Check the initial amount of schedule actions in the database self.assertEqual(ScheduleAction.objects.count(), 2) # A syntax error in the schedule file f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_syntax_error.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['File talkingDevicesSCH_syntax_error.py contains syntax errors (line 16, col 39): def talkingDevicesSCH(triggeringEvent)\n']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The schedule file does not contain any schedules MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_no_schedule.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_no_schedule.py: No schedule function with decorator @schedulingFunction has been defined.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The schedule file does not contain any schedule actions MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_no_schedule_actions.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_no_schedule_actions.py: The schedule function does not contain any actions.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The schedule file does not contain a trigger method for the schedule MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_no_trigger.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_no_trigger.py: No trigger method defined for the schedule with scheduling.addSchedule() in __main__.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The schedule file does not contain an interface for the trigger method of the schedule MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_no_trigger_interface.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_no_trigger_interface.py: The trigger method has not been imported from an interface module.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The schedule function does not have a return statement MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_no_return.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_no_return.py: The schedule function talkingDevicesSCH does not have a return statement.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The return statement of the schedule function does not contain a list MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_no_return_list.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_no_return_list.py: The return statement of the schedule function does not contain a list.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The return statement of the schedule function does not contain a list of variables MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_no_return_list_variables.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_no_return_list_variables.py: The list in the return statement of the schedule function does not have variable names as list members.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # The schedule contains a duplicate action MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_duplicate_action.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule parse error in file talkingDevicesSCH_duplicate_action.py: Duplicate schedule action Dialog.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # A schedule already exists MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_schedule_exists.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Schedule talkingDevicesSCHTest already exists.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # Trigger method does not exist MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_non_existent_trigger.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Trigger method isSilentTest does not exist for interface TalkingDevice.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # Action does not exist MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_non_existent_action.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Action DialogTest does not exist.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # Action device does not exist for a specific trigger from position MockClass.reset_mock() mock.reset_mock() f = open('core/fixtures/talkingDevices/invalid_files/talkingDevicesSCH_non_existent_action_device.py') response = self.client.post('/api/schedule_file/', {'file': f}) f.close() self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['file'], ['Trigger from position 2 does not correspond to any valid action device position in action Dialog.']) # Check that the configuration model generator thread is not started self.assertEqual(MockClass.call_count, 0) mock = MockClass.return_value self.assertEqual(mock.start.call_count, 0) # Check the final amount of schedules in the database self.assertEqual(Schedule.objects.count(), 1) # Check the final amount of schedule actions in the database self.assertEqual(ScheduleAction.objects.count(), 2)
class DeviceStateValueAPITestCase(TestCase): fixtures = ['devices_testdata'] def setUp(self): self.old_setting = settings.PROXIMITY_SERVER['default'] settings.PROXIMITY_SERVER['default'] = settings.PROXIMITY_SERVER['test'] self.proximity_client = ProximityClient() self.proximity_client.flush() def tearDown(self): settings.PROXIMITY_SERVER['default'] = self.old_setting def test_good_device_statevalue_post(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' method_name = 'isSilent' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name='isSilent').exists()) # Check the initial amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address).count(), 2) # The state value data without arguments payload = json.dumps({'method_name': method_name, 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 201) self.assertEqual(response['Location'], 'http://testserver/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') interface_name = 'CalendarSource' method_name = 'eventApproaching' # The state value data with arguments payload = json.dumps({'method_name': method_name, 'arguments': {'eid': '1234'}, 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 201) self.assertEqual(response['Location'], 'http://testserver/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') interface_name = 'ScreenDevice' method_name = 'screenAvailable' # The state value data with an empty argument dictionary payload = json.dumps({'method_name': method_name, 'arguments': {}, 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 201) self.assertEqual(response['Location'], 'http://testserver/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') # Check the final amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address).count(), 5) def test_bad_device_statevalue_posts(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name='isSilent').exists()) # Check the initial amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name).count(), 1) # Send post without data and check that the response is 400 Bad Request response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', content_type='application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Method name is a required field') self.assertEqual(content['value'], 'Value is a required field') # Send post without method name and check that the response is 400 Bad Request payload = json.dumps({'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Method name is a required field') # Send post without value and check that the response is 400 Bad Request payload = json.dumps({'method_name': 'isSilent'}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['value'], 'Value is a required field') # Send junk data and check that the response is 400 Bad Request payload = json.dumps({'foo': 'bar'}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Method name is a required field') self.assertEqual(content['value'], 'Value is a required field') # Send post with non-existent method name and check that the response is 400 Bad Request payload = json.dumps({'method_name': 'fooBarMethod', 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Method fooBarMethod does not exist.') # Send post with empty method name payload = json.dumps({'method_name': '', 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Method name cannot be an empty string') # Send post without arguments for a state value that requires arguments payload = json.dumps({'method_name': 'eventApproaching', 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/CalendarSource/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['arguments'], 'eid is missing from arguments.') # Send post with arguments for a state value that does not require any arguments payload = json.dumps({'method_name': 'isWilling', 'arguments': {'eid': '1234'}, 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['arguments'], 'Method isWilling does not accept eid as an argument.') # Send post with extra arguments (same as the above) payload = json.dumps({'method_name': 'eventApproaching', 'arguments': {'eid': '1234', 'test': '12345'}, 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/CalendarSource/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['arguments'], 'Method eventApproaching does not accept test as an argument.') # Send post for non-existent device payload = json.dumps({'method_name': 'isSilent', 'value': False}) response = self.client.post('/api/v2/device/aa:bb:cc:dd:ee:ff/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 404) content = json.loads(response.content) self.assertEqual(content['error_message'], 'Sorry, this request could not be processed. Please try again later.') # Send post for non-existent interface payload = json.dumps({'method_name': 'isSilent', 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/fooBarInterface/method/', payload, 'application/json') self.assertEqual(response.status_code, 404) content = json.loads(response.content) self.assertEqual(content['error_message'], 'Sorry, this request could not be processed. Please try again later.') # Send post with a state value that already exists for the specific device in the database self.assertTrue(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name='TalkingDevice', method__name='isWilling').exists()) payload = json.dumps({'method_name': 'isWilling', 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Duplicate method. Device aa:aa:aa:aa:aa:aa has already added a value for method isWilling in interface TalkingDevice.') # Send post for interface that exists, but is not bound with the device self.assertTrue(Interface.objects.filter(name='CalendarDevice').exists()) payload = json.dumps({'method_name': 'hasEvents', 'value': False}) response = self.client.post('/api/v2/device/' + mac_address + '/interface/CalendarDevice/method/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Device aa:aa:aa:aa:aa:aa does not have the appropriate interface for being able to store a state value for method hasEvents.') # Check the final amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name).count(), 1) def test_good_device_statevalue_delete(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' method_name = 'isWilling' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name=method_name).exists()) # Check the initial amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name).count(), 1) # Check that the state value actually exists in the database self.assertTrue(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name=method_name).exists()) # Issue a DELETE request response = self.client.delete('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') # Check that the response is 204 No Content self.assertEqual(response.status_code, 204) # Check that the state value does not exist in the database anymore self.assertFalse(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name=method_name).exists()) # Check the final amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name).count(), 0) # TODO: cascade check def test_bad_device_statevalue_deletes(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' method_name = 'isWilling' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name=method_name).exists()) # Check the initial amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name).count(), 1) # Ensure that the deletion of a non-existent state value throws 404 Not Found self.assertFalse(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name='fooBarMethod').exists()) response = self.client.delete('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/fooBarMethod/') self.assertEqual(response.status_code, 404) # Ensure that the deletion of a state value of a non-existent device throws 404 Not Found self.assertFalse(Device.objects.filter(mac_address='aa:bb:cc:dd:ee:ff').exists()) response = self.client.delete('/api/v2/device/aa:bb:cc:dd:ee:ff/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 404) # Ensure that the deletion of a state value of a non-existent interface throws 404 Not Found self.assertFalse(Interface.objects.filter(name='FooBarInterface').exists()) response = self.client.delete('/api/v2/device/' + mac_address + '/interface/FooBarInterface/method/' + method_name + '/') self.assertEqual(response.status_code, 404) # The deletion of all device state values should throw 405 Method Not Allowed response = self.client.delete('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/') self.assertEqual(response.status_code, 405) # Check that the final amount of state values that the device has in the database is the same as in the beginning self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name).count(), 1) def test_good_device_statevalue_get_list(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check the initial amount of state values for the device in the database self.assertEqual(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name).count(), 1) # Get a list of devices including their information response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Convert the json to python content = json.loads(response.content) # Check that all the state values of the device are in the list self.assertEqual([statevalue['method_name'] for statevalue in content['objects']], ['isWilling']) # Check that the number of state values in the list is 1 self.assertEqual(len(content['objects']), 1) def test_good_device_statevalue_get_detail(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' method_name = 'isWilling' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name=method_name).exists()) # Check that the state value actually exists in the database self.assertTrue(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name=method_name).exists()) # Get the information related to one state value response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Check that the values are correct content = json.loads(response.content) self.assertEqual(content['arguments'], {}) self.assertEqual(content['created_at'], '2011-12-20T17:10:41.314132') self.assertEqual(content['method_name'], 'isWilling') self.assertEqual(content['resource_uri'], '/api/v2/device/aa:aa:aa:aa:aa:aa/interface/TalkingDevice/method/isWilling/') self.assertEqual(content['updated_at'], '2011-12-20T17:10:41.314132') self.assertEqual(content['value'], 'False') interface_name = 'ScreenDevice' method_name = 'hasNext' # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name=method_name).exists()) # Check that the state value actually exists in the database self.assertTrue(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name=method_name).exists()) # Get the information related to one state value response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') # Check that the response code is 200 OK self.assertEqual(response.status_code, 200) # Check that the values are correct content = json.loads(response.content) self.assertEqual(content['arguments'], {'screenId': '1234'}) self.assertEqual(content['created_at'], '2011-12-20T17:10:41.314132') self.assertEqual(content['method_name'], 'hasNext') self.assertEqual(content['resource_uri'], '/api/v2/device/aa:aa:aa:aa:aa:aa/interface/ScreenDevice/method/hasNext/') self.assertEqual(content['updated_at'], '2011-12-20T17:10:41.314132') self.assertEqual(content['value'], 'False') def test_bad_device_statevalue_get_details(self): # Get a state value for a non-existent interface method mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' method_name = 'fooBarMethod' self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) self.assertFalse(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name=method_name).exists()) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 404) # Get a state value for a non-existent device mac_address = 'aa:bb:cc:dd:ee:ff' interface_name = 'TalkingDevice' method_name = 'isWilling' self.assertFalse(Device.objects.filter(mac_address=mac_address).exists()) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 404) # Get a state value for a non-existent interface mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'FooBarInterface' method_name = 'isWilling' self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) self.assertFalse(Interface.objects.filter(name=interface_name).exists()) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 404) def test_good_device_statevalue_update(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' method_name = 'isWilling' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name=method_name).exists()) # Check that the state value actually exists in the database self.assertTrue(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name=method_name).exists()) # Send a put request to update the value of isWilling to True response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['value'], 'False') payload = json.dumps({'value': 'True'}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/', payload, 'application/json') self.assertEqual(response.status_code, 204) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['value'], 'True') # Send a put request to update the value of isWilling to True with an empty argument dictionary response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['value'], 'True') payload = json.dumps({'arguments': {}, 'value': 'False'}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/', payload, 'application/json') self.assertEqual(response.status_code, 204) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['value'], 'False') interface_name = 'ScreenDevice' method_name = 'hasNext' # Send a put request to update the value of eventApproaching to True with arguments response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['value'], 'False') self.assertEqual(content['arguments']['screenId'], '1234') payload = json.dumps({'arguments': {'screenId': '12345'}, 'value': 'True'}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/', payload, 'application/json') self.assertEqual(response.status_code, 204) response = self.client.get('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/') self.assertEqual(response.status_code, 200) content = json.loads(response.content) self.assertEqual(content['value'], 'True') self.assertEqual(content['arguments']['screenId'], '12345') def test_bad_device_statevalue_updates(self): mac_address = 'aa:aa:aa:aa:aa:aa' interface_name = 'TalkingDevice' method_name = 'isWilling' # Check that the device actually exists in the database self.assertTrue(Device.objects.filter(mac_address=mac_address).exists()) # Check that the device interface actually exists self.assertTrue(DeviceInterface.objects.filter(device__mac_address=mac_address, interface__name=interface_name).exists()) # Check that the method exists for the interface self.assertTrue(Method.objects.filter(interface__name=interface_name, name=method_name).exists()) # Check that the state value actually exists in the database self.assertTrue(StateValue.objects.filter(device__mac_address=mac_address, method__interface__name=interface_name, method__name=method_name).exists()) # Send a put request to update the method name payload = json.dumps({'method_name': 'fooBarMethod'}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['method_name'], 'Method name cannot be updated') # Send a put request to update the created_at field payload = json.dumps({'created_at': '2011-12-22T16:21:43.834112'}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['created_at'], 'Created at cannot be updated') # Send a put request to update the updated_at field payload = json.dumps({'updated_at': '2011-12-22T16:21:43.834112'}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['updated_at'], 'Updated at cannot be updated') # Send a put request without arguments for a state value that requires arguments payload = json.dumps({'value': False}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/ScreenDevice/method/hasNext/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['arguments'], 'screenId is missing from arguments.') # Send a put request with arguments for a state value that does not require any arguments payload = json.dumps({'arguments': {'eid': '1234'}, 'value': False}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/' + interface_name + '/method/' + method_name + '/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['arguments'], 'Method isWilling does not accept eid as an argument.') # Send a put request with extra arguments (same as the above) payload = json.dumps({'arguments': {'screenId': '1234', 'test': '12345'}, 'value': False}) response = self.client.put('/api/v2/device/' + mac_address + '/interface/ScreenDevice/method/hasNext/', payload, 'application/json') self.assertEqual(response.status_code, 400) content = json.loads(response.content) self.assertEqual(content['arguments'], 'Method hasNext does not accept test as an argument.')