def test_group_constraint(self): """Test model with group constraint""" self.assertTrue(self._check_subset_string()) admin01 = self.test_user1 group1 = admin01.groups.all()[0] world = self.world constraint = SingleLayerConstraint(layer=world, active=True) constraint.save() rule = ConstraintExpressionRule(constraint=constraint, group=group1, rule="NAME != 'ITALY'") rule.save() self.assertEqual(rule.user_or_group, group1) self.assertEqual( ConstraintExpressionRule.get_constraints_for_user(admin01, world)[0], rule) constraint.active = False constraint.save() self.assertEqual( ConstraintExpressionRule.get_active_constraints_for_user( admin01, world), []) constraint.active = True constraint.save() self.assertEqual( ConstraintExpressionRule.get_active_constraints_for_user( admin01, world)[0], rule) self.assertEqual( ConstraintExpressionRule.get_rule_definition_for_user( admin01, world.pk), "(NAME != 'ITALY')") self.assertFalse(self._check_subset_string())
def layerFilterExpression(self, layer): """Retrieve and sets user layer constraints""" try: qdjango_layer = Layer.objects.get(project=QGS_SERVER.project, qgs_layer_id=layer.id()) except Layer.DoesNotExist: return "" rule = ConstraintExpressionRule.get_rule_definition_for_user(QGS_SERVER.user, qdjango_layer.pk) QgsMessageLog.logMessage("SingleLayerExpressionAccessControlFilter rule for user %s and layer id %s: %s" % (QGS_SERVER.user, layer.id(), rule), "", Qgis.Info) return rule
def apply_filter(self, request, metadata_layer, qgis_feature_request, view=None): """Apply the filter to the QGIS feature request or the layer's subset string Warning: if the filter alters the layer instance (for example by settings a subset string) make sure to restore the original state or to work on a clone. """ qgis_layer = metadata_layer.qgis_layer expression_text = ConstraintExpressionRule.get_rule_definition_for_user(request.user, view.layer.pk, context=getattr(view, 'context', 'v')) if not expression_text: return qgis_feature_request.combineFilterExpression(expression_text)
def test_user_constraint(self): """Test model with user constraint""" self.assertTrue(self._check_subset_string()) admin01 = self.test_user1 world = self.world constraint = SingleLayerConstraint(layer=world, active=True) constraint.save() rule = ConstraintExpressionRule(constraint=constraint, user=admin01, rule="NAME != 'ITALY'") rule.save() self.assertEqual(rule.user_or_group, admin01) self.assertEqual( ConstraintExpressionRule.get_constraints_for_user(admin01, world)[0], rule) constraint.active = False constraint.save() self.assertEqual( ConstraintExpressionRule.get_active_constraints_for_user( admin01, world), []) constraint.active = True constraint.save() self.assertEqual( ConstraintExpressionRule.get_active_constraints_for_user( admin01, world)[0], rule) self.assertEqual( ConstraintExpressionRule.get_rule_definition_for_user( admin01, world.pk), "(NAME != 'ITALY')") self.assertFalse(self._check_subset_string()) self.assertEqual(constraint.layer_name, 'world') self.assertEqual(constraint.qgs_layer_id, 'world20181008111156525') self.assertEqual(constraint.rule_count, 1)
def apply_filter(self, request, qgis_layer, qgis_feature_request, view=None): """Apply the filter to the QGIS feature request or the layer's subset string Warning: if the filter alters the layer instance (for example by settings a subset string) make sure to restore the original state or to work on a clone. """ expression_text = ConstraintExpressionRule.get_rule_definition_for_user( request.user, view.layer.pk, context=getattr(view, 'context', 'v')) if not expression_text: return original_expression = qgis_feature_request.filterExpression( ) if qgis_feature_request is not None else None if original_expression is not None: qgis_feature_request.setFilterExpression( "({original_expression}) AND ({extra_expression})".format( original_expression=original_expression.expression(), extra_expression=expression_text)) else: qgis_feature_request.setFilterExpression(expression_text)
def test_csv_api(self): """Test CSV export""" world = self.world world.download_csv = True world.save() response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'csv', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id }.values()) self.assertEqual(response.status_code, 200) temp = QTemporaryDir() fname = temp.path() + '/temp.csv' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('NAME = \'ITALY\''))) ]), 1) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('NAME = \'GERMANY\''))) ]), 1) # Add a rule admin01 = self.test_user1 group1 = admin01.groups.all()[0] world = self.world constraint = SingleLayerConstraint(layer=world, active=True) constraint.save() rule = ConstraintExpressionRule(constraint=constraint, group=group1, rule="NAME != 'ITALY'") rule.save() response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'csv', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values()) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp2.csv' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('NAME = \'ITALY\''))) ]), 0) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('NAME = \'GERMANY\''))) ]), 1) # TEST filter FID # =============== response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'csv', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values(), kwargs={'fid': '2'}) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp3.csv' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual(len([f for f in vl.getFeatures()]), 1) # TEST filter FIDS # ================ response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'csv', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values(), kwargs={'fids': '2,3'}) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp4.csv' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual(len([f for f in vl.getFeatures()]), 2) # TEST filter FIELD # ================= response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'csv', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values(), kwargs={'field': 'NAME|eq|FRANCE'}) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp5.csv' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual(len([f for f in vl.getFeatures()]), 1)
def test_gpx_api(self): """Test GPX export""" points = self.spatialite_points points.download_gpx = True points.save() response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'gpx', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': points.qgs_layer_id }.values()) self.assertEqual(response.status_code, 200) temp = QTemporaryDir() fname = temp.path() + '/temp.gpx' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression( 'name = \'another point\''))) ]), 1) #self.assertEqual(len([f for f in vl.getFeatures( # QgsFeatureRequest(QgsExpression('NAME = \'point\'')))]), 1) # Add a rule admin01 = self.test_user1 group1 = admin01.groups.all()[0] world = self.world constraint = SingleLayerConstraint(layer=points, active=True) constraint.save() rule = ConstraintExpressionRule(constraint=constraint, group=group1, rule="name != 'another point'") rule.save() response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'gpx', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': points.qgs_layer_id, }.values()) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp2.gpx' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression( 'name = \'another point\''))) ]), 0) #self.assertEqual(len([f for f in vl.getFeatures( # QgsFeatureRequest(QgsExpression('NAME = \'GERMANY\'')))]), 1) constraint.delete() # TEST filter FID # =============== response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'gpx', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': points.qgs_layer_id, }.values(), kwargs={'fid': '2'}) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp3.gpx' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression( 'name = \'another point\''))) ]), 1) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('name = \'point\''))) ]), 0) # TEST filter FIDS # ================ response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'gpx', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': points.qgs_layer_id, }.values(), kwargs={'fids': '2,3'}) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp4.gpx' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression( 'name = \'another point\''))) ]), 1) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('name = \'point\''))) ]), 0) # TEST filter FIELD # ================= response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'gpx', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': points.qgs_layer_id, }.values(), kwargs={'field': 'name|eq|a point'}) self.assertEqual(response.status_code, 200) fname = temp.path() + '/temp5.gpx' with open(fname, 'wb+') as f: f.write(response.content) vl = QgsVectorLayer(fname) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression( 'name = \'another point\''))) ]), 0) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('name = \'a point\''))) ]), 1)
def test_shp_api(self): """Test that the filter applies to shp api""" world = self.world world.download = True world.save() response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'shp', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values()) self.assertEqual(response.status_code, 200) z = zipfile.ZipFile(BytesIO(response.content)) temp = QTemporaryDir() z.extractall(temp.path()) vl = QgsVectorLayer(temp.path()) self.assertTrue(vl.isValid()) vl.getFeatures(QgsFeatureRequest(QgsExpression('NAME = \'ITALY\''))) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('NAME = \'ITALY\''))) ]), 1) # Add a rule admin01 = self.test_user1 group1 = admin01.groups.all()[0] world = self.world constraint = SingleLayerConstraint(layer=world, active=True) constraint.save() rule = ConstraintExpressionRule(constraint=constraint, group=group1, rule="NAME != 'ITALY'") rule.save() response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'shp', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values()) self.assertEqual(response.status_code, 200) z = zipfile.ZipFile(BytesIO(response.content)) temp = QTemporaryDir() z.extractall(temp.path()) vl = QgsVectorLayer(temp.path()) self.assertTrue(vl.isValid()) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('NAME = \'ITALY\''))) ]), 0) self.assertEqual( len([ f for f in vl.getFeatures( QgsFeatureRequest(QgsExpression('NAME = \'GERMANY\''))) ]), 1) # TEST filter FID # =============== response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'shp', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values(), kwargs={'fid': '2'}) self.assertEqual(response.status_code, 200) z = zipfile.ZipFile(BytesIO(response.content)) temp = QTemporaryDir() z.extractall(temp.path()) vl = QgsVectorLayer(temp.path()) self.assertTrue(vl.isValid()) self.assertEqual(len([f for f in vl.getFeatures()]), 1) # TEST filter FIDS # ================ response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'shp', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values(), kwargs={'fids': '2,3'}) self.assertEqual(response.status_code, 200) z = zipfile.ZipFile(BytesIO(response.content)) temp = QTemporaryDir() z.extractall(temp.path()) vl = QgsVectorLayer(temp.path()) self.assertTrue(vl.isValid()) self.assertEqual(len([f for f in vl.getFeatures()]), 2) # TEST filter FIELD # ================= response = self._testApiCallAdmin01( 'core-vector-api', args={ 'mode_call': 'shp', 'project_type': 'qdjango', 'project_id': self.qdjango_project.id, # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING: it's the qgs_layer_id, not the name! # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 'layer_name': world.qgs_layer_id, }.values(), kwargs={'field': 'NAME|eq|FRANCE'}) self.assertEqual(response.status_code, 200) z = zipfile.ZipFile(BytesIO(response.content)) temp = QTemporaryDir() z.extractall(temp.path()) vl = QgsVectorLayer(temp.path()) self.assertTrue(vl.isValid()) self.assertEqual(len([f for f in vl.getFeatures()]), 1)
def test_validate_sql(self): """Test rule validation""" admin01 = self.test_user1 group1 = admin01.groups.all()[0] world = self.world constraint = SingleLayerConstraint(layer=world, active=True) constraint.save() rule = ConstraintExpressionRule(constraint=constraint, group=group1, rule="NAME != 'ITALY'") rule.save() self.assertTrue(rule.validate_sql()[0], rule.validate_sql()[1]) rule.rule = "not a valid rule!" rule.save() self.assertFalse(rule.validate_sql()[0]) # Valid syntax rule but wrong column name rule.rule = "NOT_IN_MY_NAME != 'ITALY'" rule.save() self.assertFalse(rule.validate_sql()[0])
def test_bbox_filter(self): """Test a rule with geometry filter""" admin01 = self.test_user1 world = self.world constraint = SingleLayerConstraint(layer=world, active=True) constraint.save() rule = ConstraintExpressionRule( constraint=constraint, user=admin01, rule= "intersects_bbox( $geometry, geom_from_wkt( 'POLYGON((8 51, 11 51, 11 52, 11 52, 8 51))') )" ) rule.save() self.assertFalse(self._check_subset_string()) rule.delete() rule = ConstraintExpressionRule( constraint=constraint, user=admin01, rule= "intersects_bbox( $geometry, geom_from_wkt( 'POLYGON((10 42, 13 42, 13 44, 10 44, 10 42))') )" ) rule.save() ows_url = reverse('OWS:ows', kwargs={ 'group_slug': self.qdjango_project.group.slug, 'project_type': 'qdjango', 'project_id': self.qdjango_project.id }) # Make a request to the server c = Client() self.assertTrue(c.login(username='******', password='******')) response = c.get( ows_url, { 'REQUEST': 'GetFeatureInfo', 'SERVICE': 'WMS', 'VERSION': '1.1.0', 'LAYERS': 'world', 'SRS': 'EPSG:4326', 'BBOX': '7,45,7.2,45.2', 'FORMAT': 'image/png', 'INFO_FORMAT': 'application/json', 'WIDTH': '100', 'HEIGHT': '100', 'QUERY_LAYERS': 'world', 'FEATURE_COUNT': 1, 'X': '50', 'Y': '50', }) self.assertTrue(b'ROME' in response.content) self.assertFalse(b'BERLIN' in response.content) # Add a second rule rule2 = ConstraintExpressionRule(constraint=constraint, user=admin01, rule="NAME != 'ITALY'") rule2.save() response = c.get( ows_url, { 'REQUEST': 'GetFeatureInfo', 'SERVICE': 'WMS', 'VERSION': '1.1.0', 'LAYERS': 'world', 'SRS': 'EPSG:4326', 'BBOX': '7,45,7.2,45.2', 'FORMAT': 'image/png', 'INFO_FORMAT': 'application/json', 'WIDTH': '100', 'HEIGHT': '100', 'QUERY_LAYERS': 'world', 'FEATURE_COUNT': 1, 'X': '50', 'Y': '50', }) self.assertFalse(b'ROME' in response.content) self.assertFalse(b'BERLIN' in response.content) # Update second rule rule2.rule = "NAME = 'ITALY'" rule2.save() response = c.get( ows_url, { 'REQUEST': 'GetFeatureInfo', 'SERVICE': 'WMS', 'VERSION': '1.1.0', 'LAYERS': 'world', 'SRS': 'EPSG:4326', 'BBOX': '7,45,7.2,45.2', 'FORMAT': 'image/png', 'INFO_FORMAT': 'application/json', 'WIDTH': '100', 'HEIGHT': '100', 'QUERY_LAYERS': 'world', 'FEATURE_COUNT': 1, 'X': '50', 'Y': '50', }) self.assertTrue(b'ROME' in response.content) self.assertFalse(b'BERLIN' in response.content)
def test_trace_api(self): """/qplotly/api/trace API""" qplotlywidget_id = QplotlyWidget.objects.all()[0].pk qplotlywidget_3857_id = QplotlyWidget.objects.all()[1].pk response = self._testApiCall( 'qplotly-api-trace', args=[self.project.instance.pk, qplotlywidget_id]) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 51) self.assertIn('Italia', trace_data[0]['x']) # for 3857 projetc response = self._testApiCall( 'qplotly-api-trace', args=[self.project_3857.instance.pk, qplotlywidget_3857_id]) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 51) self.assertIn('Italia', trace_data[0]['x']) # With a session token filter # --------------------------- countries = Layer.objects.get( project_id=self.project.instance.pk, qgs_layer_id='countries_d53dfb9a_98e1_4196_a601_eed9a33f47c3') # create a token filter session_token = SessionTokenFilter.objects.create( user=self.test_user1) # as admin01 session_filter = session_token.stf_layers.create( layer=countries, qgs_expr="NAME_IT = 'Albania'") response = self._testApiCall( 'qplotly-api-trace', args=[self.project.instance.pk, qplotlywidget_id], kwargs={'filtertoken': session_token.token}) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 1) self.assertNotIn('Italia', trace_data[0]['x']) # Geometry contraint layer # ------------------------ constraint = SingleLayerConstraint(layer=countries, active=True) constraint.save() rule = ConstraintExpressionRule( constraint=constraint, user=self.test_user1, rule= "intersects_bbox( $geometry, geom_from_wkt( 'POLYGON((8 51, 11 51, 11 52, 11 52, 8 51))') )" ) rule.save() response = self._testApiCall( 'qplotly-api-trace', args=[self.project.instance.pk, qplotlywidget_id]) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 1) self.assertIn('Germania', trace_data[0]['x']) # add new plotly widget for cities layer # ====================================== cities = self.project.instance.layer_set.get( qgs_layer_id='cities10000eu_399beab0_e385_4ce1_9b59_688d02930517') widget = QplotlyWidget.objects.create( xml=self.cities_histogram_plot_xml, datasource=cities.datasource, type='histogram', title='', project=self.project.instance) widget.layers.add(cities) cities_3857 = self.project_3857.instance.layer_set.get( qgs_layer_id='cities10000eu_399beab0_e385_4ce1_9b59_688d02930517') widget_3857 = QplotlyWidget.objects.create( xml=self.cities_histogram_plot_xml, datasource=cities_3857.datasource, type='histogram', title='', project=self.project_3857.instance) widget_3857.layers.add(cities_3857) response = self._testApiCall( 'qplotly-api-trace', args=[self.project.instance.pk, widget.pk]) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 8965) self.assertIn('IT', trace_data[0]['x']) self.assertIn('DE', trace_data[0]['x']) # check relation one to many response = self._testApiCall( 'qplotly-api-trace', args=[self.project.instance.pk, widget.pk], kwargs={ 'relationonetomany': 'cities1000_ISO2_CODE_countries__ISOCODE|18' }) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 1124) self.assertIn('IT', trace_data[0]['x']) self.assertNotIn('DE', trace_data[0]['x']) # test in_bbox filter # ------------------------------------- response = self._testApiCall( 'qplotly-api-trace', args=[self.project.instance.pk, widget.pk], kwargs={'in_bbox': '9.7,41.4,13.0,45.6'}) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 329) self.assertIn('IT', trace_data[0]['x']) self.assertNotIn('DE', trace_data[0]['x']) # for 3857 and reproject response = self._testApiCall( 'qplotly-api-trace', args=[self.project_3857.instance.pk, widget_3857.pk], kwargs={ 'in_bbox': '1079799.06069475435651839,5071521.81142560951411724,1447153.38031255709938705,5716479.01532683055847883' }) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 329) self.assertIn('IT', trace_data[0]['x']) self.assertNotIn('DE', trace_data[0]['x']) # Geocontraint # ------------------------ constraint = GeoConstraint(layer=cities, constraint_layer=countries, active=True) constraint.save() rule = GeoConstraintRule(constraint=constraint, user=self.test_user1, rule="ISOCODE = 'IT'") rule.save() response = self._testApiCall( 'qplotly-api-trace', args=[self.project.instance.pk, widget.pk]) jcontent = json.loads(response.content) trace_data = json.loads(response.content)['data'] self.assertEqual(len(trace_data), 1) self.assertEqual(trace_data[0]['type'], 'histogram') self.assertEqual(len(trace_data[0]['x']), 1115) self.assertIn('IT', trace_data[0]['x']) self.assertNotIn('DE', trace_data[0]['x']) widget.delete()
def test_editing_api_with_constraint_by_group(self): """Test editing mode with contraint to single user gorup""" cities_layer_id = 'cities_54d40b01_2af8_4b17_8495_c5833485536e' cities_layer = self.editing_project.instance.layer_set.filter( qgs_layer_id=cities_layer_id)[0] # add test_suser_admin1 to scls.group self.test_user_admin1.groups.add(self.group) # CONSTRAINTS TEST # ---------------------------------------------- # SUBSETSTRING RULE # ---------------------------------------------- # Context 'v' (view) # ------------------ constraint = SingleLayerConstraint(layer=cities_layer, active=True) constraint.save() rule = ConstraintSubsetStringRule( constraint=constraint, group=self.group, rule="name = 'Genova' OR name = 'Grosseto'") rule.save() response = self._testApiCall('editing-commit-vector-api', [ 'editing', 'qdjango', self.editing_project.instance.pk, cities_layer_id ]) jres = json.loads(response.content) # check features self.assertEqual(len(jres['vector']['data']['features']), 481) # Context 've' (view + editing) # ------------------------------ constraint.for_editing = True constraint.save() response = self._testApiCall('editing-commit-vector-api', [ 'editing', 'qdjango', self.editing_project.instance.pk, cities_layer_id ]) jres = json.loads(response.content) # check features self.assertEqual(len(jres['vector']['data']['features']), 2) # Context 'e' (editing) # ------------------------------ constraint.for_view = False constraint.for_editing = True constraint.save() response = self._testApiCall('editing-commit-vector-api', [ 'editing', 'qdjango', self.editing_project.instance.pk, cities_layer_id ]) jres = json.loads(response.content) # check features self.assertEqual(len(jres['vector']['data']['features']), 2) # EXPRESSION RULE # ---------------------------------------------- constraint.for_view = True constraint.for_editing = False constraint.save() rule.delete() rule = ConstraintExpressionRule( constraint=constraint, group=self.group, rule= "\"name\" = 'Genova' OR \"name\" = 'Grosseto' OR \"name\" = 'Agliana'" ) rule.save() # context 'v' (view) # ================== response = self._testApiCall('editing-commit-vector-api', [ 'editing', 'qdjango', self.editing_project.instance.pk, cities_layer_id ]) jres = json.loads(response.content) # check features self.assertEqual(len(jres['vector']['data']['features']), 481) # context 've' (view + editing) # ================== constraint.for_editing = True constraint.save() response = self._testApiCall('editing-commit-vector-api', [ 'editing', 'qdjango', self.editing_project.instance.pk, cities_layer_id ]) jres = json.loads(response.content) # check features self.assertEqual(len(jres['vector']['data']['features']), 3) # context 'e' (editing) # ================== constraint.for_editing = False constraint.for_editing = True constraint.save() response = self._testApiCall('editing-commit-vector-api', [ 'editing', 'qdjango', self.editing_project.instance.pk, cities_layer_id ]) jres = json.loads(response.content) # check features self.assertEqual(len(jres['vector']['data']['features']), 3) # remove admin01 from group self.test_user_admin1.groups.remove(self.group) response = self._testApiCall('editing-commit-vector-api', [ 'editing', 'qdjango', self.editing_project.instance.pk, cities_layer_id ]) jres = json.loads(response.content) # check features self.assertEqual(len(jres['vector']['data']['features']), 481)