예제 #1
0
    def test_get_intersecting_projects(self, get_dto_for_locale,
                                       _get_intersecting_projects,
                                       get_user_by_username,
                                       validate_bbox_area,
                                       _make_4326_polygon_from_bbox):
        if self.skip_tests:
            return

        # arrange _make_4326_polygon_from_bbox mock
        _make_4326_polygon_from_bbox.return_value = Polygon([
            (34.68826225820438, -12.59912449955007),
            (34.68826225820438, -11.57858317689196),
            (32.50198296132938, -11.57858317689196),
            (32.50198296132938, -12.59912449955007),
            (34.68826225820438, -12.59912449955007)
        ])

        # arrange validate_bbox_area mock
        validate_bbox_area.return_value = True

        # arrange get_user_by_username mock
        get_user_by_username.return_value = User(id=3488526)

        # arrange _get_intersecting_projects mock
        polygon = json.dumps(get_canned_json('search_bbox_feature.json'))
        project = Project(id=2274,
                          status=0,
                          default_locale='en',
                          geometry=polygon)
        projects = [project]
        _get_intersecting_projects.return_value = projects

        # arrange get_dto_for_locale mock
        get_dto_for_locale.return_value = ProjectInfo(
            name='PEPFAR Kenya: Homa Bay')

        # arrange dto
        dto = ProjectSearchBBoxDTO()
        dto.bbox = map(float, '34.404,-1.034, 34.717,-0.624'.split(','))
        dto.preferred_locale = 'en'
        dto.input_srid = 4326
        dto.project_author = 3488526
        dto.validate()

        # arrange expected result
        expected = json.dumps(get_canned_json('search_bbox_result.json'))

        # act
        result = ProjectSearchService.get_projects_geojson(dto)

        # assert
        self.assertEqual(str(expected), str(expected))
예제 #2
0
    def test_make_polygon_from_3857_bbox(self):

        if self.skip_tests:
            return

        # arrange
        expected = (32.50198296132938, -12.59912449955007, 34.68826225820438,
                    -11.578583176891955)

        # act
        polygon = ProjectSearchService._make_4326_polygon_from_bbox([
            3618104.193026841, -1413969.7644834695, 3861479.691086842,
            -1297785.4814900015
        ], 3857)

        # assert
        self.assertEqual(expected, polygon.bounds)
예제 #3
0
    def test_get_area_from_3857_bbox(self):

        if self.skip_tests:
            return

        # arrange

        # polygon = ProjectSearchService._make_4326_polygon_from_bbox([3618104.193026841, -1413969.7644834695, 3861479.691086842, -1297785.4814900015], 3857)
        polygon = Polygon([(34.68826225820438, -12.59912449955007),
                           (34.68826225820438, -11.57858317689196),
                           (32.50198296132938, -11.57858317689196),
                           (32.50198296132938, -12.59912449955007),
                           (34.68826225820438, -12.59912449955007)])

        # act
        expected = ProjectSearchService._get_area_sqm(polygon)

        # assert
        self.assertEqual(expected, 28276407740.2797)
예제 #4
0
    def get(self):
        """
        Search active projects
        ---
        tags:
            - search
        produces:
            - application/json
        parameters:
            - in: header
              name: Authorization
              description: Base64 encoded session token
              type: string
              default: Token sessionTokenHere==
            - in: header
              name: Accept-Language
              description: Language user is requesting
              type: string
              required: true
              default: en
            - in: query
              name: mapperLevel
              type: string
              default: BEGINNER
            - in: query
              name: mappingTypes
              type: string
              default: ROADS,BUILDINGS
            - in: query
              name: organisationTag
              type: string
              default: red cross
            - in: query
              name: campaignTag
              type: string
              default: malaria
            - in: query
              name: page
              description: Page of results user requested
              type: integer
              default: 1
            - in: query
              name: textSearch
              description: text to search
              type: string
              default: serbia
            - in: query
              name: projectStatuses
              description: Authenticated PMs can search for archived or draft statuses
              type: string
        responses:
            200:
                description: Projects found
            404:
                description: No projects found
            500:
                description: Internal Server Error
        """
        try:
            search_dto = ProjectSearchDTO()
            search_dto.preferred_locale = request.environ.get(
                'HTTP_ACCEPT_LANGUAGE')
            search_dto.mapper_level = request.args.get('mapperLevel')
            search_dto.organisation_tag = request.args.get('organisationTag')
            search_dto.campaign_tag = request.args.get('campaignTag')
            search_dto.page = int(
                request.args.get('page')) if request.args.get('page') else 1
            search_dto.text_search = request.args.get('textSearch')

            # See https://github.com/hotosm/tasking-manager/pull/922 for more info
            try:
                verify_token(
                    request.environ.get('HTTP_AUTHORIZATION').split(None,
                                                                    1)[1])
                if UserService.is_user_a_project_manager(
                        tm.authenticated_user_id):
                    search_dto.is_project_manager = True
            except:
                pass

            mapping_types_str = request.args.get('mappingTypes')
            if mapping_types_str:
                search_dto.mapping_types = map(
                    str,
                    mapping_types_str.split(','))  # Extract list from string
            project_statuses_str = request.args.get('projectStatuses')
            if project_statuses_str:
                search_dto.project_statuses = map(
                    str, project_statuses_str.split(','))
            search_dto.validate()
        except DataError as e:
            current_app.logger.error(f'Error validating request: {str(e)}')
            return str(e), 400

        try:
            results_dto = ProjectSearchService.search_projects(search_dto)
            return results_dto.to_primitive(), 200
        except NotFound:
            return {"Error": "No projects found"}, 404
        except Exception as e:
            error_msg = f'Project GET - unhandled error: {str(e)}'
            current_app.logger.critical(error_msg)
            return {"error": error_msg}, 500
예제 #5
0
    def get(self):
        """
        Search for projects by bbox projects
        ---
        tags:
            - search
        produces:
            - application/json
        parameters:
            - in: header
              name: Authorization
              description: Base64 encoded session token
              required: true
              type: string
              default: Token sessionTokenHere==
            - in: header
              name: Accept-Language
              description: Language user is requesting
              type: string
              required: true
              default: en
            - in: query
              name: bbox
              description: comma separated list xmin, ymin, xmax, ymax
              type: string
              default: 34.404,-1.034, 34.717,-0.624
            - in: query
              name: srid
              description: srid of bbox coords
              type: integer
              default: 4326
            - in: query
              name: createdByMe
              description: limit to projects created by authenticated user
              type: boolean
              required: true
              default: false

        responses:
            200:
                description: ok
            400:
                description: Client Error - Invalid Request
            403:
                description: Forbidden
            500:
                description: Internal Server Error
        """
        try:
            search_dto = ProjectSearchBBoxDTO()
            search_dto.bbox = map(float, request.args.get('bbox').split(','))
            search_dto.input_srid = request.args.get('srid')
            search_dto.preferred_locale = request.environ.get(
                'HTTP_ACCEPT_LANGUAGE')
            createdByMe = strtobool(request.args.get(
                'createdByMe')) if request.args.get('createdByMe') else False
            if createdByMe:
                search_dto.project_author = tm.authenticated_user_id
            search_dto.validate()
        except Exception as e:
            current_app.logger.error(f'Error validating request: {str(e)}')
            return str(e), 400
        try:
            geojson = ProjectSearchService.get_projects_geojson(search_dto)
            return geojson, 200
        except BBoxTooBigError:
            return {"Error": "Bounding Box too large"}, 403
        except ProjectSearchServiceError as e:
            return {"error": str(e)}, 400
        except Exception as e:
            error_msg = f'Project GET - unhandled error: {str(e)}'
            current_app.logger.critical(error_msg)
            return {"error": error_msg}, 500
예제 #6
0
    def get(self):
        """
        Search active projects
        ---
        tags:
            - search
        produces:
            - application/json
        parameters:
            - in: header
              name: Accept-Language
              description: Language user is requesting
              type: string
              required: true
              default: en
            - in: query
              name: mapperLevel
              type: string
              default: BEGINNER
            - in: query
              name: mappingTypes
              type: string
              default: ROADS,BUILDINGS
            - in: query
              name: organisationTag
              type: string
              default: red cross
            - in: query
              name: campaignTag
              type: string
              default: malaria
            - in: query
              name: page
              description: Page of results user requested
              type: integer
              default: 1
            - in: query
              name: textSearch
              description: text to search
              type: string
              default: serbia
        responses:
            200:
                description: Projects found
            404:
                description: No projects found
            500:
                description: Internal Server Error
        """
        try:
            search_dto = ProjectSearchDTO()
            search_dto.preferred_locale = request.environ.get('HTTP_ACCEPT_LANGUAGE')
            search_dto.mapper_level = request.args.get('mapperLevel')
            search_dto.organisation_tag = request.args.get('organisationTag')
            search_dto.campaign_tag = request.args.get('campaignTag')
            search_dto.page = int(request.args.get('page')) if request.args.get('page') else 1
            search_dto.text_search = request.args.get('textSearch')

            mapping_types_str = request.args.get('mappingTypes')
            if mapping_types_str:
                search_dto.mapping_types = map(str, mapping_types_str.split(','))  # Extract list from string
            search_dto.validate()
        except DataError as e:
            current_app.logger.error(f'Error validating request: {str(e)}')
            return str(e), 400

        try:
            results_dto = ProjectSearchService.search_projects(search_dto)
            return results_dto.to_primitive(), 200
        except NotFound:
            return {"Error": "No projects found"}, 404
        except Exception as e:
            error_msg = f'Project GET - unhandled error: {str(e)}'
            current_app.logger.critical(error_msg)
            return {"error": error_msg}, 500