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())
Exemple #2
0
    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
Exemple #3
0
    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)
Exemple #5
0
    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)
Exemple #11
0
    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()
Exemple #12
0
    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)