def test_update_treenode_radius_prev_branch(self): self.fake_authentication() # Test to branch node treenode_id = 257 new_r = 5 old_r = -1 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), { 'radius': new_r, 'option': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) expected = [(261, old_r), (259, old_r), (257, new_r), (255, new_r), (253, old_r)] for x in expected: self.assertTreenodeHasRadius(*x) # Test to root node treenode_id = 253 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), { 'radius': new_r, 'option': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) expected = [(255, new_r), (263, old_r), (253, new_r), (251, new_r), (249, new_r), (247, new_r), (247, new_r), (245, new_r), (243, new_r), (241, new_r), (239, new_r), (237, old_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_update_treenode_radius_prev_branch(self): self.fake_authentication() # Test to branch node treenode_id = 257 new_r = 5 old_r = -1 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), {'radius': new_r, 'option': 2, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) expected = [(261, old_r), (259, old_r), (257, new_r), (255, new_r), (253, old_r)] for x in expected: self.assertTreenodeHasRadius(*x) # Test to root node treenode_id = 253 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), {'radius': new_r, 'option': 2, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) expected = [(255, new_r), (263, old_r), (253, new_r), (251, new_r), (249, new_r), (247, new_r), (247, new_r), (245, new_r), (243, new_r), (241, new_r), (239, new_r), (237, old_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_update_treenode_radius_prev_defined_node(self): self.fake_authentication() # Set radius at ancestor node ancestor = Treenode.objects.get(id=251) ancestor.radius = 7 ancestor.save() # Test to previous defined node treenode_id = 257 new_r = 5 old_r = -1 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), {'radius': new_r, 'option': 3, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) expected = [(261, old_r), (259, old_r), (257, new_r), (255, new_r), (253, new_r), (251, 7)] # Test on node with defined radius (and propagation to root) treenode_id = ancestor.id response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), {'radius': new_r, 'option': 3, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) expected = [(253, new_r), (251, new_r), (249, new_r), (247, new_r), (247, new_r), (245, new_r), (243, new_r), (241, new_r), (239, new_r), (237, new_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_check_disabling(self): no_check_state = {"nocheck": True} s = state.parse_state(json.dumps(no_check_state)) self.assertEqual(s, no_check_state) self.assertTrue(state.is_disabled(s)) s2 = state.make_nocheck_state(parsed=True) self.assertEqual(s, s2) s3 = state.make_nocheck_state(parsed=False) self.assertEqual(json.dumps(no_check_state), s3)
def test_check_disabling(self): no_check_state = { "nocheck": True } s = state.parse_state(json.dumps(no_check_state)) self.assertEqual(s, no_check_state) self.assertTrue(state.is_disabled(s)) s2 = state.make_nocheck_state(parsed=True) self.assertEqual(s, s2) s3 = state.make_nocheck_state(parsed=False) self.assertEqual(json.dumps(no_check_state), s3)
def test_update_confidence_of_treenode_connector(self): treenode_id = 285 treenode_connector_id = 360 self.fake_authentication() response = self.client.post( '/%d/treenodes/%d/confidence' % (self.test_project_id, treenode_id), {'new_confidence': '4', 'to_connector': 'true', 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) connector = TreenodeConnector.objects.filter(id=treenode_connector_id).get() parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'message': 'success', 'updated_partners': { '356': { 'edition_time': '2016-04-13T05:57:44.444Z', 'old_confidence': 5 } } } self.assertIn('message', parsed_response) self.assertEqual(expected_result.get('message'), parsed_response.get('message')) self.assertIn('updated_partners', parsed_response) self.assertIn('356', parsed_response.get('updated_partners')) self.assertEqual(expected_result.get('updated_partners').get('356').get('old_confidence'), parsed_response.get('updated_partners').get('356').get('old_confidence')) self.assertEqual(4, connector.confidence) response = self.client.post( '/%d/treenodes/%d/confidence' % (self.test_project_id, treenode_id), {'new_confidence': '5', 'to_connector': 'true', 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) connector = TreenodeConnector.objects.filter(id=treenode_connector_id).get() parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'message': 'success', 'updated_partners': { '356': { 'edition_time': '2016-04-13T05:57:44.444Z', 'old_confidence': 4 } } } self.assertIn('message', parsed_response) self.assertEqual(expected_result.get('message'), parsed_response.get('message')) self.assertIn('updated_partners', parsed_response) self.assertIn('356', parsed_response.get('updated_partners')) self.assertEqual(expected_result.get('updated_partners').get('356').get('old_confidence'), parsed_response.get('updated_partners').get('356').get('old_confidence')) self.assertEqual(5, connector.confidence)
def test_node_no_update_many_nodes(self): self.fake_authentication() self.maxDiff = None node_id = [2368, 2370, 2372, 2374] x = [2990, 3060, 3210, 3460] y = [5200, 4460, 4990, 4830] z = [1, 2, 3, 4] types = ['t', 't', 't', 't'] def insert_params(dictionary, param_id, params): """ Creates a parameter representation that is expected by the backend. Parameters are identified by a number: 0: id, 1: X, 2: Y and 3: Z. """ for i,param in enumerate(params): dictionary['%s[%s][%s]' % (types[i], i, param_id)] = params[i] param_dict = { 'state': make_nocheck_state() } insert_params(param_dict, 0, node_id) insert_params(param_dict, 1, x) insert_params(param_dict, 2, y) insert_params(param_dict, 3, z) response = self.client.post( '/%d/node/update' % self.test_project_id, param_dict) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = {'error': 'User test2 cannot edit all of the 4 ' 'unique objects from table treenode'} self.assertEqual(expected_result['error'], parsed_response['error'])
def test_delete_non_root_treenode(self): self.fake_authentication() treenode_id = 265 relation_map = get_relation_to_id_map(self.test_project_id) get_skeleton = lambda: TreenodeClassInstance.objects.filter( project=self.test_project_id, relation=relation_map['element_of'], treenode=treenode_id) self.assertEqual(1, get_skeleton().count()) children = Treenode.objects.filter(parent=treenode_id) self.assertTrue(children.count() > 0) tn_count = Treenode.objects.all().count() parent = get_object_or_404(Treenode, id=treenode_id).parent response = self.client.post( '/%d/treenode/delete' % self.test_project_id, { 'treenode_id': treenode_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = 'Removed treenode successfully.' self.assertEqual(expected_result, parsed_response['success']) self.assertEqual(0, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(0, get_skeleton().count()) self.assertEqual(tn_count - 1, Treenode.objects.all().count()) for child in children: child_after_change = get_object_or_404(Treenode, id=child.id) self.assertEqual(parent, child_after_change.parent)
def test_delete_root_treenode(self): self.fake_authentication() treenode_id = 2437 treenode = Treenode.objects.filter(id=treenode_id)[0] children = Treenode.objects.filter(parent=treenode_id) self.assertEqual(0, children.count()) self.assertEqual(None, treenode.parent) tn_count = Treenode.objects.all().count() response = self.client.post( '/%d/treenode/delete' % self.test_project_id, { 'treenode_id': treenode_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'success': 'Removed treenode successfully.', 'parent_id': None, 'deleted_neuron': True, 'skeleton_id': 2433, 'children': [], 'confidence': 5, 'radius': -1.0, 'links': [], 'x': 5290.0, 'y': 3930.0, 'z': 279.0 } self.assertEqual(expected_result, parsed_response) self.assertEqual(0, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(tn_count - 1, Treenode.objects.all().count())
def test_delete_root_treenode(self): self.fake_authentication() treenode_id = 2437 treenode = Treenode.objects.filter(id=treenode_id)[0] children = Treenode.objects.filter(parent=treenode_id) self.assertEqual(0, children.count()) self.assertEqual(None, treenode.parent) tn_count = Treenode.objects.all().count() response = self.client.post( '/%d/treenode/delete' % self.test_project_id, {'treenode_id': treenode_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'success': 'Removed treenode successfully.', 'parent_id': None, 'deleted_neuron': True, 'skeleton_id': 2433, 'children': [], 'confidence': 5, 'radius': -1.0, 'links': [], 'x': 5290.0, 'y': 3930.0, 'z': 279.0 } self.assertEqual(expected_result, parsed_response) self.assertEqual(0, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(tn_count - 1, Treenode.objects.all().count())
def test_unparsed_nocheck_state_creation(self): nocheck_state = state.make_nocheck_state(parsed=False) expected_state = "{\"nocheck\": true}" self.assertEqual(str, type(nocheck_state)) self.assertEqual(expected_state, nocheck_state) parsed_state = json.loads(nocheck_state) self.assertTrue(state.is_disabled(parsed_state))
def test_node_no_update_many_nodes(self): self.fake_authentication() self.maxDiff = None node_id = [2368, 2370, 2372, 2374] x = [2990, 3060, 3210, 3460] y = [5200, 4460, 4990, 4830] z = [1, 2, 3, 4] types = ['t', 't', 't', 't'] def insert_params(dictionary, param_id, params): """ Creates a parameter representation that is expected by the backend. Parameters are identified by a number: 0: id, 1: X, 2: Y and 3: Z. """ for i, param in enumerate(params): dictionary['%s[%s][%s]' % (types[i], i, param_id)] = params[i] param_dict = {'state': make_nocheck_state()} insert_params(param_dict, 0, node_id) insert_params(param_dict, 1, x) insert_params(param_dict, 2, y) insert_params(param_dict, 3, z) response = self.client.post('/%d/node/update' % self.test_project_id, param_dict) self.assertEqual(response.status_code, 403) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'error': 'User test2 cannot edit all of the 4 ' 'unique objects from table treenode' } self.assertEqual(expected_result['error'], parsed_response['error'])
def test_update_treenode_parent(self): self.fake_authentication() skeleton_id = 373 treenode_id = 405 new_parent_id = 403 response = self.client.post( '/%d/treenodes/%d/parent' % (self.test_project_id, treenode_id), { 'parent_id': new_parent_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) response = self.client.post('/%d/%d/1/1/compact-skeleton' % (self.test_project_id, skeleton_id)) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_response = [[[377, None, 3, 7620.0, 2890.0, 0.0, -1.0, 5], [403, 377, 3, 7840.0, 2380.0, 0.0, -1.0, 5], [405, 403, 3, 7390.0, 3510.0, 0.0, -1.0, 5], [407, 405, 3, 7080.0, 3960.0, 0.0, -1.0, 5], [409, 407, 3, 6630.0, 4330.0, 0.0, -1.0, 5]], [[377, 356, 1, 6730.0, 2700.0, 0.0], [409, 421, 1, 6260.0, 3990.0, 0.0]], { "uncertain end": [403] }] six.assertCountEqual(self, parsed_response[0], expected_response[0]) six.assertCountEqual(self, parsed_response[1], expected_response[1]) self.assertEqual(parsed_response[2], expected_response[2])
def create_partition(self, partition, root=None): ids = [] skeleton_id = None if root is None: root = -1 parent = root for pos in partition: # Create new skeleton response = self.client.post( '/%d/treenode/create' % self.project_id, { 'x': pos[0], 'y': pos[1], 'z': pos[2], 'confidence': 5, 'parent_id': parent, 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) parent = parsed_response['treenode_id'] ids.append(parsed_response['treenode_id']) if not skeleton_id: skeleton_id = parsed_response['skeleton_id'] return ids, skeleton_id
def test_delete_link_success(self): self.fake_authentication() connector_id = 356 treenode_id = 377 tc_count = TreenodeConnector.objects.all().count() response = self.client.post( '/%d/link/delete' % self.test_project_id, { 'connector_id': connector_id, 'treenode_id': treenode_id, 'state': make_nocheck_state() }) self.assertStatus(response) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'link_id': 382, 'link_type': 'postsynaptic_to', 'link_type_id': 1024, 'result': 'Removed treenode to connector link' } self.assertEqual(expected_result, parsed_response) self.assertEqual( 0, TreenodeConnector.objects.filter(connector=connector_id, treenode=treenode_id).count()) self.assertEqual(tc_count - 1, TreenodeConnector.objects.all().count())
def test_delete_non_root_treenode(self): self.fake_authentication() treenode_id = 265 relation_map = get_relation_to_id_map(self.test_project_id) get_skeleton = lambda: TreenodeClassInstance.objects.filter( project=self.test_project_id, relation=relation_map['element_of'], treenode=treenode_id) self.assertEqual(1, get_skeleton().count()) children = Treenode.objects.filter(parent=treenode_id) self.assertTrue(children.count() > 0) tn_count = Treenode.objects.all().count() parent = get_object_or_404(Treenode, id=treenode_id).parent response = self.client.post( '/%d/treenode/delete' % self.test_project_id, {'treenode_id': treenode_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = 'Removed treenode successfully.' self.assertEqual(expected_result, parsed_response['success']) self.assertEqual(0, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(0, get_skeleton().count()) self.assertEqual(tn_count - 1, Treenode.objects.all().count()) for child in children: child_after_change = get_object_or_404(Treenode, id=child.id) self.assertEqual(parent, child_after_change.parent)
def test_update_treenode_radius_all_nodes(self): self.fake_authentication() treenode_id = 2417 new_r = 5.0 old_r = -1.0 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), {'radius': new_r, 'option': 5, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_response = { 'success': True, 'new_radius': new_r, 'updated_nodes': { '2415': {'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411}, '2417': {'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411}, '2419': {'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411}, '2423': {'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411}} } # The response has updated timetamps (since we updated nodes), we have # to compare fields manually to ignore them for k,v in six.iteritems(expected_response): self.assertIn(k, parsed_response) if 'updated_nodes' == k: continue self.assertEqual(v, parsed_response.get(k)) for k,v in six.iteritems(expected_response['updated_nodes']): self.assertIn(k, parsed_response['updated_nodes']) result_node = parsed_response['updated_nodes'][k] for p,pv in six.iteritems(v): self.assertIn(p, result_node) result_value = result_node.get(p) if 'edition_time' == p: # Changes through the updated, and the test can't know the # value, but only check if it changed self.assertNotEqual(pv, result_value) else: self.assertEqual(pv, result_value) # Don't expect any more items than the above: self.assertEqual(len(expected_response['updated_nodes']), len(parsed_response['updated_nodes'])) expected = [(2419, new_r), (2417, new_r), (2415, new_r), (2423, new_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_update_treenode_parent(self): self.fake_authentication() skeleton_id = 373 treenode_id = 405 new_parent_id = 403 response = self.client.post( '/%d/treenodes/%d/parent' % (self.test_project_id, treenode_id), {'parent_id': new_parent_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) response = self.client.post( '/%d/%d/1/1/compact-skeleton' % (self.test_project_id, skeleton_id)) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_response = [ [[377, None, 3, 7620.0, 2890.0, 0.0, -1.0, 5], [403, 377, 3, 7840.0, 2380.0, 0.0, -1.0, 5], [405, 403, 3, 7390.0, 3510.0, 0.0, -1.0, 5], [407, 405, 3, 7080.0, 3960.0, 0.0, -1.0, 5], [409, 407, 3, 6630.0, 4330.0, 0.0, -1.0, 5]], [[377, 356, 1, 6730.0, 2700.0, 0.0], [409, 421, 1, 6260.0, 3990.0, 0.0]], {"uncertain end": [403]}] six.assertCountEqual(self, parsed_response[0], expected_response[0]) six.assertCountEqual(self, parsed_response[1], expected_response[1]) self.assertEqual(parsed_response[2], expected_response[2])
def create_partition(self, partition, root=None): ids = [] skeleton_id = None if root is None: root = -1 parent = root for pos in partition: # Create new skeleton response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': pos[0], 'y': pos[1], 'z': pos[2], 'confidence': 5, 'parent_id': parent, 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) parent = parsed_response['treenode_id'] ids.append(parsed_response['treenode_id']) if not skeleton_id: skeleton_id = parsed_response['skeleton_id'] return ids, skeleton_id
def test_delete_connector(self): self.fake_authentication() connector_id = 356 connector = Connector.objects.get(id=connector_id) connector_count = Connector.objects.all().count() treenode_connector_count = TreenodeConnector.objects.all().count() response = self.client.post( '/%d/connector/delete' % self.test_project_id, { 'connector_id': connector_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'message': u'Removed connector and class_instances', 'connector_id': 356, 'x': 6730.0, 'y': 2700.0, 'z': 0.0, 'confidence': 5, 'partners': [{ 'id': 285, 'link_id': 360, 'rel': 'presynaptic_to', 'rel_id': 1023, 'confidence': 5, 'edition_time': '2011-12-04T13:51:36.955Z', }, { 'id': 367, 'link_id': 372, 'rel': 'postsynaptic_to', 'rel_id': 1024, 'confidence': 5, 'edition_time': '2011-12-05T13:51:36.955Z', }, { 'id': 377, 'link_id': 382, 'rel': 'postsynaptic_to', 'rel_id': 1024, 'confidence': 5, 'edition_time': '2011-12-05T13:51:36.955Z', }] } self.assertEqual(expected_result, parsed_response) self.assertEqual(connector_count - 1, Connector.objects.all().count()) self.assertEqual(treenode_connector_count - 3, TreenodeConnector.objects.all().count()) self.assertEqual(0, Connector.objects.filter(id=connector_id).count()) self.assertEqual( 0, TreenodeConnector.objects.filter(connector=connector).count())
def test_suppressed_virtual_nodes(self): self.fake_authentication() response = self.client.post( '/%d/treenode/create' % (self.test_project_id, ), {'x': 1, 'y': -1, 'z': 0}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) parent_id = parsed_response['treenode_id'] skeleton_id = parsed_response['skeleton_id'] response = self.client.post( '/%d/treenode/create' % (self.test_project_id, ), {'x': 3, 'y': -3, 'z': 2, 'parent_id': parent_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) child_id = parsed_response['treenode_id'] # Initially no nodes should be supppressed response = self.client.get( '/%d/treenodes/%d/suppressed-virtual/' % (self.test_project_id, child_id)) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = [] self.assertEqual(expected_result, parsed_response) # Reject attempt to suppress root node response = self.client.post( '/%d/treenodes/%d/suppressed-virtual/' % (self.test_project_id, parent_id), {'location_coordinate': 1, 'orientation': 0}) self.assertEqual(response.status_code, 400) # Reject coordinate outside edge response = self.client.post( '/%d/treenodes/%d/suppressed-virtual/' % (self.test_project_id, child_id), {'location_coordinate': 4, 'orientation': 0}) self.assertEqual(response.status_code, 400) # Create virtual node response = self.client.post( '/%d/treenodes/%d/suppressed-virtual/' % (self.test_project_id, child_id), {'location_coordinate': 2, 'orientation': 0}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) suppressed_id = parsed_response['id'] # Delete virtual node response = self.client.delete( '/%d/treenodes/%d/suppressed-virtual/%d' % (self.test_project_id, child_id, suppressed_id)) self.assertEqual(response.status_code, 204)
def test_insert_treenoded_not_on_edge_with_permission(self): self.fake_authentication() class_map = get_class_to_id_map(self.test_project_id) count_treenodes = lambda: Treenode.objects.all().count() count_skeletons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['skeleton' ]).count() count_neurons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['neuron' ]).count() treenode_count = count_treenodes() skeleton_count = count_skeletons() neuron_count = count_neurons() # Get two nodes and calculate point between them child_id = 2374 parent_id = 2372 child = Treenode.objects.get(pk=child_id) parent = Treenode.objects.get(pk=parent_id) new_node_x = 0.5 * (child.location_x + parent.location_x) new_node_y = 0.5 * (child.location_y + parent.location_y) + 10 new_node_z = 0.5 * (child.location_z + parent.location_z) # Try to insert with a slight distorition in Y. This is allowed if the # user has permission to edit the neuron. response = self.client.post( '/%d/treenode/insert' % self.test_project_id, { 'x': new_node_x, 'y': new_node_y, 'z': new_node_z, 'child_id': child_id, 'parent_id': parent_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content) self.assertTrue('treenode_id' in parsed_response) self.assertTrue('skeleton_id' in parsed_response) self.assertEqual(treenode_count + 1, count_treenodes()) self.assertEqual(skeleton_count, count_skeletons()) self.assertEqual(neuron_count, count_neurons()) new_node_id = parsed_response['treenode_id'] new_node = Treenode.objects.get(pk=new_node_id) child = Treenode.objects.get(pk=child_id) self.assertEqual(new_node.parent_id, parent_id) self.assertEqual(child.parent_id, new_node_id) self.assertEqual(new_node.user, child.user) self.assertEqual(new_node.creation_time, child.creation_time) self.assertEqual(new_node.skeleton_id, child.skeleton_id) self.assertEqual(new_node.location_x, new_node_x) self.assertEqual(new_node.location_y, new_node_y) self.assertEqual(new_node.location_z, new_node_z)
def test_insert_treenoded_not_on_edge_with_permission(self): self.fake_authentication() class_map = get_class_to_id_map(self.test_project_id) count_treenodes = lambda: Treenode.objects.all().count() count_skeletons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['skeleton']).count() count_neurons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['neuron']).count() treenode_count = count_treenodes() skeleton_count = count_skeletons() neuron_count = count_neurons() # Get two nodes and calculate point between them child_id = 2374 parent_id = 2372 child = Treenode.objects.get(pk=child_id) parent = Treenode.objects.get(pk=parent_id) new_node_x = 0.5 * (child.location_x + parent.location_x) new_node_y = 0.5 * (child.location_y + parent.location_y) + 10 new_node_z = 0.5 * (child.location_z + parent.location_z) # Try to insert with a slight distorition in Y. This is allowed if the # user has permission to edit the neuron. response = self.client.post('/%d/treenode/insert' % self.test_project_id, { 'x': new_node_x, 'y': new_node_y, 'z': new_node_z, 'child_id': child_id, 'parent_id': parent_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content) self.assertTrue('treenode_id' in parsed_response) self.assertTrue('skeleton_id' in parsed_response) self.assertEqual(treenode_count + 1, count_treenodes()) self.assertEqual(skeleton_count, count_skeletons()) self.assertEqual(neuron_count, count_neurons()) new_node_id = parsed_response['treenode_id'] new_node = Treenode.objects.get(pk=new_node_id) child = Treenode.objects.get(pk=child_id) self.assertEqual(new_node.parent_id, parent_id) self.assertEqual(child.parent_id, new_node_id) self.assertEqual(new_node.user, child.user) self.assertEqual(new_node.creation_time, child.creation_time) self.assertEqual(new_node.skeleton_id, child.skeleton_id) self.assertEqual(new_node.location_x, new_node_x) self.assertEqual(new_node.location_y, new_node_y) self.assertEqual(new_node.location_z, new_node_z)
def test_insert_treenoded_on_edge(self): self.fake_authentication() class_map = get_class_to_id_map(self.test_project_id) count_treenodes = lambda: Treenode.objects.all().count() count_skeletons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['skeleton' ]).count() count_neurons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['neuron' ]).count() treenode_count = count_treenodes() skeleton_count = count_skeletons() neuron_count = count_neurons() # Get two nodes and calculate point between them child_id = 2374 parent_id = 2372 child = Treenode.objects.get(pk=child_id) parent = Treenode.objects.get(pk=parent_id) new_node_x = 0.5 * (child.location_x + parent.location_x) new_node_y = 0.5 * (child.location_y + parent.location_y) new_node_z = 0.5 * (child.location_z + parent.location_z) response = self.client.post( '/%d/treenode/insert' % self.test_project_id, { 'x': new_node_x, 'y': new_node_y, 'z': new_node_z, 'child_id': child_id, 'parent_id': parent_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertTrue('treenode_id' in parsed_response) self.assertTrue('skeleton_id' in parsed_response) self.assertEqual(treenode_count + 1, count_treenodes()) self.assertEqual(skeleton_count, count_skeletons()) self.assertEqual(neuron_count, count_neurons()) new_node_id = parsed_response['treenode_id'] new_node = Treenode.objects.get(pk=new_node_id) child = Treenode.objects.get(pk=child_id) self.assertEqual(new_node.parent_id, parent_id) self.assertEqual(child.parent_id, new_node_id) self.assertEqual(new_node.user_id, self.test_user_id) self.assertEqual(new_node.skeleton_id, child.skeleton_id) self.assertEqual(new_node.location_x, new_node_x) self.assertEqual(new_node.location_y, new_node_y) self.assertEqual(new_node.location_z, new_node_z)
def test_insert_treenoded_on_edge(self): self.fake_authentication() class_map = get_class_to_id_map(self.test_project_id) count_treenodes = lambda: Treenode.objects.all().count() count_skeletons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['skeleton']).count() count_neurons = lambda: ClassInstance.objects.filter( project=self.test_project_id, class_column=class_map['neuron']).count() treenode_count = count_treenodes() skeleton_count = count_skeletons() neuron_count = count_neurons() # Get two nodes and calculate point between them child_id = 2374 parent_id = 2372 child = Treenode.objects.get(pk=child_id) parent = Treenode.objects.get(pk=parent_id) new_node_x = 0.5 * (child.location_x + parent.location_x) new_node_y = 0.5 * (child.location_y + parent.location_y) new_node_z = 0.5 * (child.location_z + parent.location_z) response = self.client.post('/%d/treenode/insert' % self.test_project_id, { 'x': new_node_x, 'y': new_node_y, 'z': new_node_z, 'child_id': child_id, 'parent_id': parent_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertTrue('treenode_id' in parsed_response) self.assertTrue('skeleton_id' in parsed_response) self.assertEqual(treenode_count + 1, count_treenodes()) self.assertEqual(skeleton_count, count_skeletons()) self.assertEqual(neuron_count, count_neurons()) new_node_id = parsed_response['treenode_id'] new_node = Treenode.objects.get(pk=new_node_id) child = Treenode.objects.get(pk=child_id) self.assertEqual(new_node.parent_id, parent_id) self.assertEqual(child.parent_id, new_node_id) self.assertEqual(new_node.user_id, self.test_user_id) self.assertEqual(new_node.skeleton_id, child.skeleton_id) self.assertEqual(new_node.location_x, new_node_x) self.assertEqual(new_node.location_y, new_node_y) self.assertEqual(new_node.location_z, new_node_z)
def test_update_treenode_radius_prev_defined_node(self): self.fake_authentication() # Set radius at ancestor node ancestor = Treenode.objects.get(id=251) ancestor.radius = 7 ancestor.save() # Test to previous defined node treenode_id = 257 new_r = 5 old_r = -1 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), { 'radius': new_r, 'option': 3, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) expected = [(261, old_r), (259, old_r), (257, new_r), (255, new_r), (253, new_r), (251, 7)] # Test on node with defined radius (and propagation to root) treenode_id = ancestor.id response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), { 'radius': new_r, 'option': 3, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) expected = [(253, new_r), (251, new_r), (249, new_r), (247, new_r), (247, new_r), (245, new_r), (243, new_r), (241, new_r), (239, new_r), (237, new_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_update_treenode_radius_single_node(self): self.fake_authentication() treenode_id = 257 new_r = 5 old_r = -1 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), {'radius': new_r, 'option': 0, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) expected = [(259, old_r), (257, new_r), (255, old_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_delete_non_root_non_parent_treenode(self): self.fake_authentication() treenode_id = 349 tn_count = Treenode.objects.all().count() response = self.client.post( '/%d/treenode/delete' % self.test_project_id, {'treenode_id': treenode_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = 'Removed treenode successfully.' self.assertEqual(expected_result, parsed_response['success']) self.assertEqual(0, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(tn_count - 1, Treenode.objects.all().count())
def test_delete_connector(self): self.fake_authentication() connector_id = 356 connector = Connector.objects.get(id=connector_id) connector_count = Connector.objects.all().count() treenode_connector_count = TreenodeConnector.objects.all().count() response = self.client.post( '/%d/connector/delete' % self.test_project_id, {'connector_id': connector_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'message': u'Removed connector and class_instances', 'connector_id': 356, 'x': 6730.0, 'y': 2700.0, 'z': 0.0, 'confidence': 5, 'partners': [{ 'id': 285, 'link_id': 360, 'rel': 'presynaptic_to', 'rel_id': 1023, 'confidence': 5, 'edition_time': '2011-12-04T13:51:36.955Z', },{ 'id': 367, 'link_id': 372, 'rel': 'postsynaptic_to', 'rel_id': 1024, 'confidence': 5, 'edition_time': '2011-12-05T13:51:36.955Z', }, { 'id': 377, 'link_id': 382, 'rel': 'postsynaptic_to', 'rel_id': 1024, 'confidence': 5, 'edition_time': '2011-12-05T13:51:36.955Z', }] } self.assertEqual(expected_result, parsed_response) self.assertEqual(connector_count - 1, Connector.objects.all().count()) self.assertEqual(treenode_connector_count - 3, TreenodeConnector.objects.all().count()) self.assertEqual(0, Connector.objects.filter(id=connector_id).count()) self.assertEqual(0, TreenodeConnector.objects.filter(connector=connector).count())
def test_delete_non_root_non_parent_treenode(self): self.fake_authentication() treenode_id = 349 tn_count = Treenode.objects.all().count() response = self.client.post( '/%d/treenode/delete' % self.test_project_id, { 'treenode_id': treenode_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = 'Removed treenode successfully.' self.assertEqual(expected_result, parsed_response['success']) self.assertEqual(0, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(tn_count - 1, Treenode.objects.all().count())
def test_delete_link_failure(self): self.fake_authentication() connector_id = 202020 treenode_id = 202020 tc_count = TreenodeConnector.objects.all().count() response = self.client.post( '/%d/link/delete' % self.test_project_id, {'connector_id': connector_id, 'treenode_id': treenode_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = {'error': 'Couldn\'t find link between connector {0} and node {0}'.format(connector_id)} self.assertIn('error', parsed_response) self.assertEqual(expected_result['error'], parsed_response['error']) self.assertEqual(tc_count, TreenodeConnector.objects.all().count())
def test_merge(self): self.authenticate() cursor = connection.cursor() # Main branch main_trunk = [(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15)] main_trunk_ids, skeleton_id = self.create_partition(main_trunk) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.78460969082) self.assertEqual(skeleton_summary['num_nodes'], 5) # Branch A branch_a = [(2, 6, 2), (6, 2, 1), (4, 6, 1)] branch_a_ids, skeleton_id_a = self.create_partition(branch_a) skeleton_summary = self.get_summary(cursor, skeleton_id_a) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 10.216698601) self.assertEqual(skeleton_summary['num_nodes'], 3) # Merge A into main branch response = self.client.post( '/%d/skeleton/join' % self.project_id, { 'from_id': main_trunk_ids[1], 'to_id': branch_a_ids[0], 'annotation_set': '{}', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertEqual(parsed_response['result_skeleton_id'], skeleton_id) self.assertEqual(parsed_response['deleted_skeleton_id'], skeleton_id_a) # Check summary of kept skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 35.58388398682) self.assertEqual(skeleton_summary['num_nodes'], 8) # Check summary of removed skeleton skeleton_summary = self.get_summary(cursor, skeleton_id_a) self.assertIs(skeleton_summary, None)
def test_create_presynaptic_link_success(self): from_id = 237 to_id = 2458 link_type = 'presynaptic_to' self.fake_authentication() response = self.client.post( '/%d/link/create' % self.test_project_id, { 'from_id': from_id, 'to_id': to_id, 'link_type': link_type, 'state': make_nocheck_state() }) self.assertStatus(response) parsed_response = json.loads(response.content.decode('utf-8')) self.assertIn('message', parsed_response) self.assertIn('link_id', parsed_response) self.assertEqual('success', parsed_response['message'])
def test_create_presynaptic_link_fail_due_to_other_presynaptic_links(self): from_id = 237 to_id = 432 link_type = 'presynaptic_to' self.fake_authentication() response = self.client.post( '/%d/link/create' % self.test_project_id, { 'from_id': from_id, 'to_id': to_id, 'link_type': link_type, 'state': make_nocheck_state() }) self.assertStatus(response, 400) parsed_response = json.loads(response.content.decode('utf-8')) self.assertIn('error', parsed_response) error_message = f'Connector {to_id} does not have zero presynaptic connections.' self.assertEqual(error_message, parsed_response.get('error'))
def test_update_treenode_radius_single_node(self): self.fake_authentication() treenode_id = 257 new_r = 5 old_r = -1 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), { 'radius': new_r, 'option': 0, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) expected = [(259, old_r), (257, new_r), (255, old_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_create_presynaptic_link_fail_due_to_other_presynaptic_links(self): from_id = 237 to_id = 432 link_type = 'presynaptic_to' self.fake_authentication() response = self.client.post( '/%d/link/create' % self.test_project_id, { 'from_id': from_id, 'to_id': to_id, 'link_type': link_type, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = {'error': 'Connector %s does not have zero presynaptic connections.' % to_id} self.assertEqual(expected_result, parsed_response)
def test_delete_root_treenode_with_children_failure(self): self.fake_authentication() treenode_id = 367 tn_count = Treenode.objects.all().count() child_count = Treenode.objects.filter(parent=treenode_id).count() response = self.client.post( '/%d/treenode/delete' % self.test_project_id, {'treenode_id': treenode_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = "Could not delete root node: You can't delete the " \ "root node when it has children." self.assertEqual(expected_result, parsed_response['error']) self.assertEqual(1, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(tn_count, Treenode.objects.all().count()) self.assertEqual(child_count, Treenode.objects.filter(parent=treenode_id).count())
def test_create_presynaptic_link_success(self): from_id = 237 to_id = 2458 link_type = 'presynaptic_to' self.fake_authentication() response = self.client.post( '/%d/link/create' % self.test_project_id, { 'from_id': from_id, 'to_id': to_id, 'link_type': link_type, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertIn('message', parsed_response) self.assertIn('link_id', parsed_response) self.assertEqual('success', parsed_response['message'])
def test_node_update_single_treenode(self): self.fake_authentication() treenode_id = 289 x = 5690 y = 3340 z = 0 response = self.client.post( '/%d/node/update' % self.test_project_id, { 'state': make_nocheck_state(), 't[0][0]': treenode_id, 't[0][1]': x, 't[0][2]': y, 't[0][3]': z }) self.assertStatus(response) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'updated': 1, 'old_connectors': None, 'old_treenodes': [[289, '2016-04-13T06:20:47.473Z', 6210.0, 3480.0, 0.0]] } self.assertIn('updated', parsed_response) self.assertEqual(expected_result['updated'], parsed_response['updated']) self.assertIn('old_connectors', parsed_response) self.assertEqual(expected_result['old_connectors'], parsed_response['old_connectors']) self.assertIn('old_treenodes', parsed_response) for n, r in enumerate(expected_result.get('old_treenodes')): for i in range(5): # Skip edition time, which changed during last request if 1 == i: continue self.assertEqual( expected_result.get('old_treenodes')[n][i], parsed_response.get('old_treenodes')[n][i]) treenode = Treenode.objects.filter(id=treenode_id)[0] self.assertEqual(x, treenode.location_x) self.assertEqual(y, treenode.location_y) self.assertEqual(z, treenode.location_z)
def test_create_treenode_with_nonexisting_parent_failure(self): self.fake_authentication() parent_id = 555555 treenode_count = Treenode.objects.all().count() relation_count = TreenodeClassInstance.objects.all().count() response = self.client.post('/%d/treenode/create' % self.test_project_id, { 'x': 5, 'y': 10, 'z': 15, 'confidence': 5, 'parent_id': parent_id, 'radius': 2, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = {'error': 'Parent treenode %d does not exist' % parent_id} self.assertIn(expected_result['error'], parsed_response['error']) self.assertEqual(treenode_count, Treenode.objects.all().count()) self.assertEqual(relation_count, TreenodeClassInstance.objects.all().count())
def test_create_presynaptic_link_fail_due_to_other_presynaptic_links(self): from_id = 237 to_id = 432 link_type = 'presynaptic_to' self.fake_authentication() response = self.client.post( '/%d/link/create' % self.test_project_id, { 'from_id': from_id, 'to_id': to_id, 'link_type': link_type, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'error': 'Connector %s does not have zero presynaptic connections.' % to_id } self.assertEqual(expected_result, parsed_response)
def test_merge(self): self.authenticate() cursor = connection.cursor() # Main branch main_trunk = [(1,2,3), (4,5,6), (7,8,9), (10,11,12), (13,14,15)] main_trunk_ids, skeleton_id = self.create_partition(main_trunk) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.78460969082) self.assertEqual(skeleton_summary['num_nodes'], 5) # Branch A branch_a = [(2,6,2), (6,2,1), (4,6,1)] branch_a_ids, skeleton_id_a = self.create_partition(branch_a) skeleton_summary = self.get_summary(cursor, skeleton_id_a) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 10.216698601) self.assertEqual(skeleton_summary['num_nodes'], 3) # Merge A into main branch response = self.client.post('/%d/skeleton/join' % self.project_id, { 'from_id': main_trunk_ids[1], 'to_id': branch_a_ids[0], 'annotation_set': '{}', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertEqual(parsed_response['result_skeleton_id'], skeleton_id) self.assertEqual(parsed_response['deleted_skeleton_id'], skeleton_id_a) # Check summary of kept skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 35.58388398682) self.assertEqual(skeleton_summary['num_nodes'], 8) # Check summary of removed skeleton skeleton_summary = self.get_summary(cursor, skeleton_id_a) self.assertIs(skeleton_summary, None)
def test_delete_root_treenode_with_children_failure(self): self.fake_authentication() treenode_id = 367 tn_count = Treenode.objects.all().count() child_count = Treenode.objects.filter(parent=treenode_id).count() response = self.client.post( '/%d/treenode/delete' % self.test_project_id, { 'treenode_id': treenode_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = "Could not delete root node: You can't delete the " \ "root node when it has children." self.assertEqual(expected_result, parsed_response['error']) self.assertEqual(1, Treenode.objects.filter(id=treenode_id).count()) self.assertEqual(tn_count, Treenode.objects.all().count()) self.assertEqual(child_count, Treenode.objects.filter(parent=treenode_id).count())
def test_delete_link_success(self): self.fake_authentication() connector_id = 356 treenode_id = 377 tc_count = TreenodeConnector.objects.all().count() response = self.client.post( '/%d/link/delete' % self.test_project_id, {'connector_id': connector_id, 'treenode_id': treenode_id, 'state': make_nocheck_state()}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'link_id': 382, 'link_type': 'postsynaptic_to', 'link_type_id': 1024, 'result': 'Removed treenode to connector link' } self.assertEqual(expected_result, parsed_response) self.assertEqual(0, TreenodeConnector.objects.filter(connector=connector_id, treenode=treenode_id).count()) self.assertEqual(tc_count - 1, TreenodeConnector.objects.all().count())
def test_delete_link_failure(self): self.fake_authentication() connector_id = 202020 treenode_id = 202020 tc_count = TreenodeConnector.objects.all().count() response = self.client.post( '/%d/link/delete' % self.test_project_id, { 'connector_id': connector_id, 'treenode_id': treenode_id, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 400) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'error': f'Could not find link between connector {connector_id} and node {treenode_id}' } self.assertIn('error', parsed_response) self.assertEqual(expected_result['error'], parsed_response['error']) self.assertEqual(tc_count, TreenodeConnector.objects.all().count())
def test_node_update_single_treenode(self): self.fake_authentication() treenode_id = 289 x = 5690 y = 3340 z = 0 response = self.client.post( '/%d/node/update' % self.test_project_id, { 'state': make_nocheck_state(), 't[0][0]': treenode_id, 't[0][1]': x, 't[0][2]': y, 't[0][3]': z}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'updated': 1, 'old_connectors': None, 'old_treenodes': [[289, '2016-04-13T06:20:47.473Z', 6210.0, 3480.0, 0.0]] } self.assertIn('updated', parsed_response) self.assertEqual(expected_result['updated'], parsed_response['updated']) self.assertIn('old_connectors', parsed_response) self.assertEqual(expected_result['old_connectors'], parsed_response['old_connectors']) self.assertIn('old_treenodes', parsed_response) for n, r in enumerate(expected_result.get('old_treenodes')): for i in range(5): # Skip edition time, which changed during last request if 1 == i: continue self.assertEqual(expected_result.get('old_treenodes')[n][i], parsed_response.get('old_treenodes')[n][i]) treenode = Treenode.objects.filter(id=treenode_id)[0] self.assertEqual(x, treenode.location_x) self.assertEqual(y, treenode.location_y) self.assertEqual(z, treenode.location_z)
def test_create_treenode_with_nonexisting_parent_failure(self): self.fake_authentication() parent_id = 555555 treenode_count = Treenode.objects.all().count() relation_count = TreenodeClassInstance.objects.all().count() response = self.client.post( '/%d/treenode/create' % self.test_project_id, { 'x': 5, 'y': 10, 'z': 15, 'confidence': 5, 'parent_id': parent_id, 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'error': 'Parent treenode %d does not exist' % parent_id } self.assertIn(expected_result['error'], parsed_response['error']) self.assertEqual(treenode_count, Treenode.objects.all().count()) self.assertEqual(relation_count, TreenodeClassInstance.objects.all().count())
def test_node_update_many_nodes(self): self.fake_authentication() self.maxDiff = None node_id = [2368, 2370, 356, 421] x = [2990, 3060, 3640, 3850] y = [5200, 4460, 5060, 4800] z = [1, 2, 5, 6] types = ['t', 't', 'c', 'c'] def insert_params(dictionary, param_id, params): """ Creates a parameter representation that is expected by the backend. Parameters are identified by a number: 0: id, 1: X, 2: Y and 3: Z. """ for i,param in enumerate(params): dictionary['%s[%s][%s]' % (types[i], i, param_id)] = params[i] param_dict = { 'state': make_nocheck_state() } insert_params(param_dict, 0, node_id) insert_params(param_dict, 1, x) insert_params(param_dict, 2, y) insert_params(param_dict, 3, z) response = self.client.post( '/%d/node/update' % self.test_project_id, param_dict) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'updated': 4, 'old_treenodes': [ [2368, '2016-04-13T05:40:25.445Z', 1820.0, 5390.0, 0.0], [2370, '2016-04-13T05:40:25.445Z', 2140.0, 4620.0, 0.0]], 'old_connectors': [ [356, '2016-04-13T05:40:25.445Z', 6730.0, 2700.0, 0.0], [421, '2016-04-13T05:40:25.445Z', 6260.0, 3990.0, 0.0]] } self.assertEqual(expected_result.get('updated'), parsed_response.get('updated')) for i in range(2): for j in range(5): # Skip edition time, because it changes through the request if 1 == j: continue self.assertEqual(expected_result.get('old_treenodes')[i][j], parsed_response.get('old_treenodes')[i][j]) for i in range(2): for j in range(5): # Skip edition time, because it changes through the request if 1 == j: continue self.assertEqual(expected_result.get('old_connectors')[i][j], parsed_response.get('old_connectors')[i][j]) i = 0 for n_id in node_id: if types[i] == 't': node = Treenode.objects.filter(id=n_id)[0] else: node = Connector.objects.filter(id=n_id)[0] self.assertEqual(x[i], node.location_x) self.assertEqual(y[i], node.location_y) self.assertEqual(z[i], node.location_z) i += 1
def test_branches_and_split(self): self.authenticate() cursor = connection.cursor() # Main branch main_trunk = [(1,2,3), (4,5,6), (7,8,9), (10,11,12), (13,14,15)] main_trunk_ids, skeleton_id = self.create_partition(main_trunk) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.78460969082) self.assertEqual(skeleton_summary['num_nodes'], 5) # Branch A branch_a = [(2,6,2), (6,2,1), (4,6,1)] branch_a_ids, _ = self.create_partition(branch_a, main_trunk_ids[1]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 35.58388398682) self.assertEqual(skeleton_summary['num_nodes'], 8) # Branch B branch_b = [(17,12,2), (42,21,12), (52,61,-1)] branch_b_ids, _ = self.create_partition(branch_b, main_trunk_ids[3]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 119.453404476) self.assertEqual(skeleton_summary['num_nodes'], 11) # Branch C branch_c = [(10,-12,23), (-4,11,122), (5,12,-11)] branch_c_ids, _ = self.create_partition(branch_c, main_trunk_ids[3]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 380.85271251741471) self.assertEqual(skeleton_summary['num_nodes'], 14) # Split response = self.client.post('/%d/skeleton/split' % self.project_id, { 'treenode_id': main_trunk_ids[3], 'upstream_annotation_map': '{}', 'downstream_annotation_map': '{}', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertEqual(parsed_response['existing_skeleton_id'], skeleton_id) new_skeleton_id = parsed_response['new_skeleton_id'] # Old skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 25.1915791414) self.assertEqual(skeleton_summary['num_nodes'], 6) # New skeleton is bigger one by default skeleton_summary = self.get_summary(cursor, new_skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 350.46498095330807811942) self.assertEqual(skeleton_summary['num_nodes'], 8)
def test_parsed_nocheck_state_creation(self): nocheck_state = state.make_nocheck_state(parsed=True) expected_state = {'nocheck': True} self.assertEqual(dict, type(nocheck_state)) self.assertEqual(expected_state, nocheck_state) self.assertTrue(state.is_disabled(nocheck_state))
def test_locaton_lookup_treenode(self): """Test if the location of a newly created treenode can be retrieved through the transaction log. Also test if this works for the updated location and the historic creation event.""" cursor = connection.cursor() # Create a new treenode response = self.client.post('/%d/treenode/create' % self.project.id, { 'x': 5.5, 'y': 10.5, 'z': 15.5, 'confidence': 5, 'parent_id': -1, 'radius': 2}) transaction.commit() self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content) self.assertTrue('treenode_id' in parsed_response) self.assertTrue('skeleton_id' in parsed_response) treenode_id = parsed_response['treenode_id'] after_insert_tx_entries = self.get_tx_entries(cursor) n_after_insert_tx_entries = len(after_insert_tx_entries) after_insert_tx = after_insert_tx_entries[0][0] txid = after_insert_tx['transaction_id'] exec_time = after_insert_tx['execution_time'] label = after_insert_tx['label'] # Get location based on the transaction ID and time, expect it to be the # same like the location of the created node above. txid_locaton = self.get_location(txid, exec_time, label) self.assertEqual(5.5, txid_locaton['x']) self.assertEqual(10.5, txid_locaton['y']) self.assertEqual(15.5, txid_locaton['z']) # Update the node location and response = self.client.post( '/%d/node/update' % self.project.id, { 'state': make_nocheck_state(), 't[0][0]': treenode_id, 't[0][1]': 6.2, 't[0][2]': 11.2, 't[0][3]': 16.2}) transaction.commit() self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content) after_update_tx_entries = self.get_tx_entries(cursor) n_after_update_tx_entries = len(after_update_tx_entries) after_update_tx = after_update_tx_entries[1][0] self.assertEqual(n_after_insert_tx_entries + 1, n_after_update_tx_entries) txid_2 = after_update_tx['transaction_id'] exec_time_2 = after_update_tx['execution_time'] label_2 = after_update_tx['label'] # Test locaton of original node with original transaction txid_locaton = self.get_location(txid, exec_time, label) self.assertEqual(5.5, txid_locaton['x']) self.assertEqual(10.5, txid_locaton['y']) self.assertEqual(15.5, txid_locaton['z']) # Test locaton of updated node with new transaction txid_locaton_2 = self.get_location(txid_2, exec_time_2, label_2) self.assertEqual(6.2, txid_locaton_2['x']) self.assertEqual(11.2, txid_locaton_2['y']) self.assertEqual(16.2, txid_locaton_2['z'])
def test_parsed_nocheck_state_creation(self): nocheck_state = state.make_nocheck_state(parsed=True) expected_state = {'nocheck': True } self.assertEqual(dict, type(nocheck_state)) self.assertEqual(expected_state, nocheck_state) self.assertTrue(state.is_disabled(nocheck_state))
def test_branches_and_split(self): self.authenticate() cursor = connection.cursor() # Main branch main_trunk = [(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15)] main_trunk_ids, skeleton_id = self.create_partition(main_trunk) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.78460969082) self.assertEqual(skeleton_summary['num_nodes'], 5) # Branch A branch_a = [(2, 6, 2), (6, 2, 1), (4, 6, 1)] branch_a_ids, _ = self.create_partition(branch_a, main_trunk_ids[1]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 35.58388398682) self.assertEqual(skeleton_summary['num_nodes'], 8) # Branch B branch_b = [(17, 12, 2), (42, 21, 12), (52, 61, -1)] branch_b_ids, _ = self.create_partition(branch_b, main_trunk_ids[3]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 119.453404476) self.assertEqual(skeleton_summary['num_nodes'], 11) # Branch C branch_c = [(10, -12, 23), (-4, 11, 122), (5, 12, -11)] branch_c_ids, _ = self.create_partition(branch_c, main_trunk_ids[3]) skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 380.85271251741471) self.assertEqual(skeleton_summary['num_nodes'], 14) # Split response = self.client.post( '/%d/skeleton/split' % self.project_id, { 'treenode_id': main_trunk_ids[3], 'upstream_annotation_map': '{}', 'downstream_annotation_map': '{}', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) self.assertEqual(parsed_response['existing_skeleton_id'], skeleton_id) new_skeleton_id = parsed_response['new_skeleton_id'] # Old skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 25.1915791414) self.assertEqual(skeleton_summary['num_nodes'], 6) # New skeleton is bigger one by default skeleton_summary = self.get_summary(cursor, new_skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 350.46498095330807811942) self.assertEqual(skeleton_summary['num_nodes'], 8)
def test_create_update_delete_skeleton(self): """Test summary before and after creating a new neuron. """ self.authenticate() cursor = connection.cursor() # Create new skeleton response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 1, 'y': 2, 'z': 3, 'confidence': 5, 'parent_id': -1, 'radius': 2 }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) skeleton_id = parsed_response['skeleton_id'] # Expect basic summary setup initial_skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(initial_skeleton_summary, None) self.assertEqual(initial_skeleton_summary['cable_length'], 0.0) self.assertEqual(initial_skeleton_summary['num_nodes'], 1) # Add second node response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 4, 'y': 5, 'z': 6, 'confidence': 5, 'parent_id': parsed_response['treenode_id'], 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 5.1961524) self.assertEqual(skeleton_summary['num_nodes'], 2) # Remember second node second_node_id = parsed_response['treenode_id'] # Add third node response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 7, 'y': 8, 'z': 9, 'confidence': 5, 'parent_id': second_node_id, 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Remember third node third_node_id = parsed_response['treenode_id'] # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 10.3923048) self.assertEqual(skeleton_summary['num_nodes'], 3) # Move second node response = self.client.post( '/%d/node/update' % self.project_id, { 'state': make_nocheck_state(), 't[0][0]': second_node_id, 't[0][1]': 10, 't[0][2]': 11, 't[0][3]': 12}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.7846096908265) self.assertEqual(skeleton_summary['num_nodes'], 3) # Delete last node response = self.client.post( '/%d/treenode/delete' % self.project_id, { 'state': make_nocheck_state(), 'treenode_id': third_node_id }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 15.588457268119) self.assertEqual(skeleton_summary['num_nodes'], 2) # Delete neuron response = self.client.post('/%d/neurons/from-models' % self.project_id, { 'model_ids[0]': skeleton_id }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) neuron_id = parsed_response[str(skeleton_id)] response = self.client.post( '/{}/neuron/{}/delete'.format(self.project_id, neuron_id)) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect no summary entry for deleted skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIs(skeleton_summary, None)
def test_update_confidence_of_treenode(self): treenode_id = 11 self.fake_authentication() response = self.client.post( '/%d/treenodes/%d/confidence' % (self.test_project_id, treenode_id), { 'new_confidence': '4', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) treenode = Treenode.objects.filter(id=treenode_id).get() parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'message': 'success', 'updated_partners': { '7': { 'edition_time': '2016-04-13T05:57:44.444Z', 'old_confidence': 5 } } } self.assertIn('message', parsed_response) self.assertEqual(expected_result.get('message'), parsed_response.get('message')) self.assertIn('updated_partners', parsed_response) self.assertIn('7', parsed_response.get('updated_partners')) self.assertEqual( expected_result.get('updated_partners').get('7').get( 'old_confidence'), parsed_response.get('updated_partners').get('7').get( 'old_confidence')) self.assertEqual(4, treenode.confidence) response = self.client.post( '/%d/treenodes/%d/confidence' % (self.test_project_id, treenode_id), { 'new_confidence': '5', 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) treenode = Treenode.objects.filter(id=treenode_id).get() parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'message': 'success', 'updated_partners': { '7': { 'edition_time': '2016-04-13T05:57:44.444Z', 'old_confidence': 4 } } } self.assertIn('message', parsed_response) self.assertEqual(expected_result.get('message'), parsed_response.get('message')) self.assertIn('updated_partners', parsed_response) self.assertIn('7', parsed_response.get('updated_partners')) self.assertEqual( expected_result.get('updated_partners').get('7').get( 'old_confidence'), parsed_response.get('updated_partners').get('7').get( 'old_confidence')) self.assertEqual(5, treenode.confidence)
def test_update_treenode_radius_all_nodes(self): self.fake_authentication() treenode_id = 2417 new_r = 5.0 old_r = -1.0 response = self.client.post( '/%d/treenode/%d/radius' % (self.test_project_id, treenode_id), { 'radius': new_r, 'option': 5, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) expected_response = { 'success': True, 'new_radius': new_r, 'updated_nodes': { '2415': { 'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411 }, '2417': { 'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411 }, '2419': { 'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411 }, '2423': { 'edition_time': u'2016-04-08T15:33:16.133Z', 'new': 5.0, 'old': -1.0, 'skeleton_id': 2411 } } } # The response has updated timetamps (since we updated nodes), we have # to compare fields manually to ignore them for k, v in six.iteritems(expected_response): self.assertIn(k, parsed_response) if 'updated_nodes' == k: continue self.assertEqual(v, parsed_response.get(k)) for k, v in six.iteritems(expected_response['updated_nodes']): self.assertIn(k, parsed_response['updated_nodes']) result_node = parsed_response['updated_nodes'][k] for p, pv in six.iteritems(v): self.assertIn(p, result_node) result_value = result_node.get(p) if 'edition_time' == p: # Changes through the updated, and the test can't know the # value, but only check if it changed self.assertNotEqual(pv, result_value) else: self.assertEqual(pv, result_value) # Don't expect any more items than the above: self.assertEqual(len(expected_response['updated_nodes']), len(parsed_response['updated_nodes'])) expected = [(2419, new_r), (2417, new_r), (2415, new_r), (2423, new_r)] for x in expected: self.assertTreenodeHasRadius(*x)
def test_node_update_many_nodes(self): self.fake_authentication() self.maxDiff = None node_id = [2368, 2370, 356, 421] x = [2990, 3060, 3640, 3850] y = [5200, 4460, 5060, 4800] z = [1, 2, 5, 6] types = ['t', 't', 'c', 'c'] def insert_params(dictionary, param_id, params): """ Creates a parameter representation that is expected by the backend. Parameters are identified by a number: 0: id, 1: X, 2: Y and 3: Z. """ for i, param in enumerate(params): dictionary['%s[%s][%s]' % (types[i], i, param_id)] = params[i] param_dict = {'state': make_nocheck_state()} insert_params(param_dict, 0, node_id) insert_params(param_dict, 1, x) insert_params(param_dict, 2, y) insert_params(param_dict, 3, z) response = self.client.post('/%d/node/update' % self.test_project_id, param_dict) self.assertStatus(response) parsed_response = json.loads(response.content.decode('utf-8')) expected_result = { 'updated': 4, 'old_treenodes': [[2368, '2016-04-13T05:40:25.445Z', 1820.0, 5390.0, 0.0], [2370, '2016-04-13T05:40:25.445Z', 2140.0, 4620.0, 0.0]], 'old_connectors': [[356, '2016-04-13T05:40:25.445Z', 6730.0, 2700.0, 0.0], [421, '2016-04-13T05:40:25.445Z', 6260.0, 3990.0, 0.0]] } self.assertEqual(expected_result.get('updated'), parsed_response.get('updated')) for i in range(2): for j in range(5): # Skip edition time, because it changes through the request if 1 == j: continue self.assertEqual( expected_result.get('old_treenodes')[i][j], parsed_response.get('old_treenodes')[i][j]) for i in range(2): for j in range(5): # Skip edition time, because it changes through the request if 1 == j: continue self.assertEqual( expected_result.get('old_connectors')[i][j], parsed_response.get('old_connectors')[i][j]) i = 0 for n_id in node_id: if types[i] == 't': node = Treenode.objects.filter(id=n_id)[0] else: node = Connector.objects.filter(id=n_id)[0] self.assertEqual(x[i], node.location_x) self.assertEqual(y[i], node.location_y) self.assertEqual(z[i], node.location_z) i += 1
def test_create_update_delete_skeleton(self): """Test summary before and after creating a new neuron. """ self.authenticate() cursor = connection.cursor() # Create new skeleton response = self.client.post('/%d/treenode/create' % self.project_id, { 'x': 1, 'y': 2, 'z': 3, 'confidence': 5, 'parent_id': -1, 'radius': 2 }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) skeleton_id = parsed_response['skeleton_id'] # Expect basic summary setup initial_skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(initial_skeleton_summary, None) self.assertEqual(initial_skeleton_summary['cable_length'], 0.0) self.assertEqual(initial_skeleton_summary['num_nodes'], 1) # Add second node response = self.client.post( '/%d/treenode/create' % self.project_id, { 'x': 4, 'y': 5, 'z': 6, 'confidence': 5, 'parent_id': parsed_response['treenode_id'], 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 5.1961524) self.assertEqual(skeleton_summary['num_nodes'], 2) # Remember second node second_node_id = parsed_response['treenode_id'] # Add third node response = self.client.post( '/%d/treenode/create' % self.project_id, { 'x': 7, 'y': 8, 'z': 9, 'confidence': 5, 'parent_id': second_node_id, 'radius': 2, 'state': make_nocheck_state() }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Remember third node third_node_id = parsed_response['treenode_id'] # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 10.3923048) self.assertEqual(skeleton_summary['num_nodes'], 3) # Move second node response = self.client.post( '/%d/node/update' % self.project_id, { 'state': make_nocheck_state(), 't[0][0]': second_node_id, 't[0][1]': 10, 't[0][2]': 11, 't[0][3]': 12 }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 20.7846096908265) self.assertEqual(skeleton_summary['num_nodes'], 3) # Delete last node response = self.client.post('/%d/treenode/delete' % self.project_id, { 'state': make_nocheck_state(), 'treenode_id': third_node_id }) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect updated summary setup skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIsNot(skeleton_summary, None) self.assertAlmostEqual(skeleton_summary['cable_length'], 15.588457268119) self.assertEqual(skeleton_summary['num_nodes'], 2) # Delete neuron response = self.client.post( '/%d/neurons/from-models' % self.project_id, {'model_ids[0]': skeleton_id}) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) neuron_id = parsed_response[str(skeleton_id)] response = self.client.post('/{}/neuron/{}/delete'.format( self.project_id, neuron_id)) self.assertEqual(response.status_code, 200) parsed_response = json.loads(response.content.decode('utf-8')) # Expect no summary entry for deleted skeleton skeleton_summary = self.get_summary(cursor, skeleton_id) self.assertIs(skeleton_summary, None)