def post_update_source_information():
    current_app.logger.info("Post Update Source information page requested")

    if g.session.source_information is None or g.session.source_information_id is None:
        return redirect(url_for('source_info.get_source_information'))

    source_info = request.form['source-information'].strip()

    current_app.logger.info("Running validation")
    validation_errors = SourceInformationValidator.validate(source_info)

    if validation_errors.errors:
        current_app.logger.warning("Validation errors occurred")
        return render_template('update-source-information.html',
                               source_information=source_info,
                               validation_errors=validation_errors.errors,
                               validation_summary_heading=validation_errors.summary_heading_text), 400

    submit_token = request.form.get('csrf_token')
    local_authority_service = LocalAuthorityService(current_app.config)

    if submit_token != g.session.submit_token:
        g.session.submit_token = submit_token
        g.session.source_information = source_info
        g.session.commit()

        local_authority_service.update_source_information_for_organisation(
            g.session.source_information_id,
            g.session.source_information,
            g.session.user.organisation)

    return redirect(url_for('source_info.get_update_source_information_success'))
    def test_get_get_bounding_box_success(self, mock_current_app):
        with main.app.test_request_context():
            g.requests = MagicMock()
            local_authority_name = "Winchester District (B)"
            response = MagicMock()
            response.status_code = 200
            response.json.return_value = {
                "geometry": {
                    "type":
                    "Polygon",
                    "coordinates": [[[438199.90401036787, 106603.8042336921],
                                     [438199.90401036787, 144431.39619812733],
                                     [468030.1970266425, 144431.39619812733],
                                     [468030.1970266425, 106603.8042336921],
                                     [438199.90401036787, 106603.8042336921]]]
                },
                "type": "Feature",
                "properties": {
                    "local-authority-name": local_authority_name
                }
            }

            g.requests.get.return_value = response
            la_api_url = "http://localhost:8080"
            mock_current_app.config = {'LA_API_URL': la_api_url}

            local_authority_service = LocalAuthorityService(
                mock_current_app.config)
            response = local_authority_service.get_bounding_box(
                "Winchester District (B)")
            self.assertEqual(response.status_code, 200)

            g.requests.get.assert_called_with(
                "{}/v1.0/local-authorities/{}/bounding_box".format(
                    la_api_url, local_authority_name))
    def test_is_extent_within_migrated_area_200_result(self, mock_current_app):
        with main.app.test_request_context():
            expected_result = True

            response = MagicMock()
            response.status_code = 200
            response.json.return_value = expected_result

            g.requests = MagicMock()
            g.requests.post.return_value = response

            some_input = {"test": "test"}
            some_url = "some_url"
            mock_current_app.config = {'LA_API_URL': some_url}

            local_authority_service = LocalAuthorityService(
                mock_current_app.config)
            response = local_authority_service.is_extent_within_migrated_area(
                some_input)

            self.assertEqual(response, expected_result)

            g.requests.post.assert_called_with(
                "{}/v1.0/local-authorities/is_extent_within_migrated_area".
                format(some_url),
                data=some_input,
                headers={'Content-Type': 'application/json'})
def post_originating_authority_page():
    authority = request.form.get('authority-search-field')

    local_authority_service = LocalAuthorityService(current_app.config)
    response = local_authority_service.get_organisations()
    authorities = list(map(lambda org: org.get('title'), response))

    current_app.logger.info("Running validation")
    validation_errors = AuthorityValidator.validate(authority, authorities)

    if validation_errors.errors:
        current_app.logger.warning("Validation errors occurred")
        return render_template(
            'originating_authority.html',
            authorities=authorities,
            validation_errors=validation_errors.errors,
            validation_summary_heading=validation_errors.summary_heading_text,
            submit_url=url_for(
                'add_land_charge.post_originating_authority_page')), 400

    ReviewRouter.update_edited_field('originating_authority', authority)
    g.session.add_charge_state.originating_authority = authority
    g.session.commit()

    return redirect(
        ReviewRouter.get_redirect_url('add_land_charge.get_charge_type'))
def local_authority_service_boundingbox(authority):
    current_app.logger.info("Local Authority bounding box requested")
    if not request.is_xhr:
        current_app.logger.error("Request not xhr")
        raise ApplicationError(500)

    local_authority_service = LocalAuthorityService(current_app.config)
    response = local_authority_service.get_bounding_box(authority)
    return Response(json.dumps(response.json())), response.status_code, {
        "Content-Type": "application/json"
    }
def get_source_information():
    current_app.logger.info("Source information page requested")
    g.session.source_information = None
    g.session.source_information_id = None
    g.session.commit()

    local_authority_service = LocalAuthorityService(current_app.config)
    source_information_list = local_authority_service.get_source_information_for_organisation(
        g.session.user.organisation)

    return render_template('source-information.html', source_information_list=source_information_list)
    def test_add_organisation_source_information_fail(self, mock_current_app):
        with main.app.test_request_context():
            response = MagicMock()
            response.status_code = 500

            g.requests = MagicMock()
            g.requests.post.return_value = response

            local_authority_service = LocalAuthorityService(
                mock_current_app.config)
            with self.assertRaises(ApplicationError):
                local_authority_service.add_source_information_for_organisation(
                    "Test Source", "Test Organisation")
示例#8
0
def post_add_source_information_confirm():
    if g.session.source_information is None:
        return redirect(url_for('source_info.get_add_source_information'))

    submit_token = request.form.get('csrf_token')
    local_authority_service = LocalAuthorityService(current_app.config)

    if submit_token != g.session.submit_token:
        g.session.submit_token = submit_token
        g.session.commit()
        local_authority_service.add_source_information_for_organisation(
            g.session.source_information, g.session.user.organisation)
    return redirect(url_for('source_info.get_add_source_information_success'))
def get_source_information_list():
    source_information_list = None

    if g.application_permissions.view_source_information in g.session.user.permissions:
        current_app.logger.info(
            'User has permission to view source information, retrieving')
        local_authority_service = LocalAuthorityService(current_app.config)
        source_information_list = local_authority_service.get_source_information_for_organisation(
            g.session.user.organisation)
        source_information_list = list(
            map(lambda source: source['source-information'],
                source_information_list))

    return source_information_list
def get_originating_authority_page():
    if g.session.add_charge_state is None or g.session.adding_charge_for_other_authority is False:
        current_app.logger.info(
            "Redirecting to: %s",
            url_for("add_land_charge.new_behalf_of_authority"))
        return redirect(url_for("add_land_charge.new_behalf_of_authority"))

    local_authority_service = LocalAuthorityService(current_app.config)
    response = local_authority_service.get_organisations()
    authorities = list(map(lambda org: org.get('title'), response))

    current_app.logger.info("Displaying page 'charge_type.html'")
    return render_template(
        'originating_authority.html',
        authorities=authorities,
        submit_url=url_for('add_land_charge.post_originating_authority_page'))
    def test_get_originating_authorities_success(self, mock_current_app):
        with main.app.test_request_context():
            g.requests = MagicMock()
            response = MagicMock()
            response.status_code = 200
            response.json.return_value = ORIGINATING_AUTHORITIES

            g.requests.get.return_value = response
            la_api_url = "http://localhost:8080"
            mock_current_app.config = {'LA_API_URL': la_api_url}

            local_authority_service = LocalAuthorityService(
                mock_current_app.config)
            response = local_authority_service.get_organisations()
            self.assertEqual(response, ORIGINATING_AUTHORITIES)

            g.requests.get.assert_called_with(
                "{}/v1.0/organisations".format(la_api_url))
    def test_get_authorities_by_extent_success(self, mock_current_app):
        with main.app.test_request_context():
            g.requests = MagicMock()
            response = MagicMock()
            response.status_code = 200
            response.json.return_value = {"abc": True, "def": False}

            g.requests.post.return_value = response
            la_api_url = "ABC"
            mock_current_app.config = {'LA_API_URL': la_api_url}

            local_authority_service = LocalAuthorityService(
                mock_current_app.config)
            response = local_authority_service.get_authorities_by_extent(
                {"test": "test"})
            self.assertEqual(response, {"abc": True, "def": False})

            g.requests.post.assert_called_with(
                "{}/v1.0/local-authorities".format(la_api_url),
                data='{"test": "test"}',
                headers={'Content-Type': 'application/json'})
    def test_get_organisation_source_information_success(
            self, mock_current_app):
        with main.app.test_request_context():
            response = MagicMock()
            response.status_code = 200
            response.json.return_value = [{"source-information": "test"}]

            g.requests = MagicMock()
            g.requests.get.return_value = response

            la_api_url = "http://test-url"
            mock_current_app.config = {'LA_API_URL': la_api_url}

            local_authority_service = LocalAuthorityService(
                mock_current_app.config)
            response = local_authority_service.get_source_information_for_organisation(
                "Test Organisation")

            self.assertEqual(response, [{"source-information": "test"}])
            g.requests.get.assert_called_with(
                "{}/v1.0/organisations/Test Organisation/source-information".
                format(la_api_url))
def llc1_set_extent():
    current_app.logger.info('Endpoint called')
    if g.session.llc1_state is None:
        current_app.logger.info('Redirect to %s', url_for('create_llc1.create_llc1'))
        return redirect(url_for('create_llc1.create_llc1'))

    search_extent = None
    if 'saved-features' in request.form:
        search_extent = json.loads(request.form['saved-features'].strip())

    current_app.logger.info("Running validation")
    validation_errors = SearchExtentValidator.validate(search_extent)

    if validation_errors.errors:
        current_app.logger.warning('Validation errors occurred')
        return render_template("search_extent.html",
                               coordinates=g.session.llc1_state.map_coordinates,
                               submit_url=url_for('create_llc1.llc1_set_extent'),
                               validation_errors=validation_errors.errors,
                               validation_summary_heading=validation_errors.summary_heading_text), 400

    current_app.logger.info("Updating session object")
    g.session.llc1_state.extent = search_extent
    g.session.commit()

    local_authority_service = LocalAuthorityService(current_app.config)
    formatted_search_extent = build_extents_from_features(search_extent)
    is_extent_within_migrated_area = local_authority_service.is_extent_within_migrated_area(formatted_search_extent)

    if not is_extent_within_migrated_area:
        current_app.logger.warning('Drawn extent is outside of migrated area')
        return render_template("search_extent.html",
                               information=search_extent,
                               submit_url=url_for('create_llc1.llc1_set_extent'),
                               is_valid_search_extent=is_extent_within_migrated_area), 400

    current_app.logger.info("Redirecting to next step: %s", url_for("create_llc1.llc1_get_description"))
    return redirect(url_for("create_llc1.llc1_get_description"))
def post_location():
    current_app.logger.info('Endpoint called')

    features = None
    selected_address = None

    if request.form.get('saved-features'):
        features = json.loads(request.form['saved-features'].strip())

    if request.form.get('selected-address'):
        selected_address = json.loads(request.form['selected-address'])

    current_app.logger.info('Running validation')
    validation_errors = AddLocationMapValidator.validate(features)

    if validation_errors.errors:
        current_app.logger.warning('Validation errors occurred')
        return render_template(
            'location.html',
            validation_errors=validation_errors.errors,
            validation_summary_heading=validation_errors.summary_heading_text,
            information=features,
            submit_url=url_for('add_land_charge.post_location')), 400

    current_app.logger.info('Updating session object')
    ReviewRouter.update_edited_field('geometry', features)

    select_address_param = False
    add_extent_anywhere_redirect_url = 'add_land_charge.get_address_for_charge'

    if selected_address and select_address_valid(selected_address):
        g.session.previously_selected_address = selected_address
        select_address_param = True
        add_extent_anywhere_redirect_url = 'add_land_charge.get_address_confirmation'

    g.session.add_charge_state.geometry = features
    g.session.commit()

    if Permissions.add_extent_anywhere not in g.session.user.permissions:
        extent = build_extents_from_features(features)
        result = LocalAuthorityService(
            current_app.config).get_authorities_by_extent(extent)

        if should_show_confirmation_warning(result):
            return redirect(
                url_for('add_land_charge.get_location_confirmation',
                        address_selected=select_address_param))

    return redirect(
        ReviewRouter.get_redirect_url(add_extent_anywhere_redirect_url))
def cancel_charge(charge_id):
    current_app.logger.info("Endpoint called with charge_id='{}'".format(charge_id))
    local_land_charge_service = LocalLandChargeService(current_app.config)
    current_app.logger.info("Retrieving charge information from charge_id='{}'".format(charge_id))
    response = local_land_charge_service.get_by_charge_number(charge_id)
    if response.status_code == 404:
        current_app.logger.warning("Charge not found for charge_id='{}' - Returning not found".format(charge_id))
        raise ApplicationError(404)
    response.raise_for_status()

    charge_data = response.json()[0]['item']
    charge_item = LocalLandChargeItem.from_json(charge_data)

    # add the charge to the session for checking the geometry is within the user's authority
    g.session.add_charge_state = charge_item
    g.session.commit()

    current_app.logger.info("Charge information retrieved for charge_id='{}'".format(charge_id))
    if request.method == 'GET':
        # Check if the charge is outside of the user's authority
        extent = build_extents_from_features(charge_item.geometry)
        result = LocalAuthorityService(current_app.config).get_authorities_by_extent(extent)

        if should_show_confirmation_warning(result):
            # In this case the charge is outside of the user's authority
            if Permissions.add_extent_anywhere in g.session.user.permissions:
                # If the user has permission to add a charge anywhere, give them cancel permission without asking
                g.session.other_authority_cancel_permission = True
                g.session.commit()

            if not g.session.other_authority_cancel_permission:
                # if the user has not confirmed that they can edit charges outside of their authority, make them
                return redirect(url_for('cancel_land_charge.get_cancel_location_confirmation'))

        current_app.logger.info("Rendering response for charge_id='{}'".format(charge_id))
        return render_template('cancel.html', charge_id=charge_id, charge_item=charge_item,
                               geometry=json.dumps(charge_item.geometry))
    else:
        charge_item.end_date = date.today()
        current_app.logger.info("Updating charge with cancellation date for charge_id='{}'".format(charge_id))
        AuditAPIService.audit_event("Cancelling charge", supporting_info={'id': charge_id})
        if g.session.other_authority_cancel_permission:
            AuditAPIService.audit_event(
                "Charge cancelled outside users authority.",
                supporting_info={'originating-authority': g.session.user.organisation})
        MaintainApiService.update_charge(charge_item)
        current_app.logger.info("Rendering response for charge_id='{}'".format(charge_id))
        # This is required because if the render_template is called from this post method then the flow won't be able
        # to return to the confirmation page if the user goes to the feedback form from the confirmation page
        return redirect(url_for('cancel_land_charge.cancel_confirmation', charge_id=charge_id))
    def test_add_organisation_source_information_success(
            self, mock_current_app):
        with main.app.test_request_context():
            response = MagicMock()
            response.status_code = 201
            response.json.return_value = [{"source-information": "test"}]

            g.requests = MagicMock()
            g.requests.post.return_value = response

            la_api_url = "http://test-url"
            mock_current_app.config = {'LA_API_URL': la_api_url}

            local_authority_service = LocalAuthorityService(
                mock_current_app.config)
            response = local_authority_service.add_source_information_for_organisation(
                "Test Source", "Test Organisation")

            self.assertEqual(response, [{"source-information": "test"}])
            g.requests.post.assert_called_with(
                "{}/v1.0/organisations/Test Organisation/source-information".
                format(la_api_url),
                data=json.dumps({"source-information": "Test Source"}),
                headers={'Content-Type': 'application/json'})
def post_location():
    current_app.logger.info("Endpoint called")
    if g.session.add_charge_state is None:
        current_app.logger.error(
            "Charge state not found in session - Returning error")
        raise ApplicationError(500)
    information = None

    if 'saved-features' in request.form:
        information = json.loads(request.form['saved-features'].strip())

    current_app.logger.info("Validating location geometry")
    validation_errors = AddLocationMapValidator.validate(information)

    if validation_errors.errors:
        current_app.logger.warning(
            "Validation errors present - Rendering page with validation errors"
        )
        return render_template(
            'location.html',
            validation_errors=validation_errors.errors,
            validation_summary_heading=validation_errors.summary_heading_text,
            information=information,
            submit_url=url_for('modify_land_charge.post_location')), 400

    current_app.logger.info("Field values validated - Updating session charge")
    if has_value_changed(g.session.add_charge_state.geometry, information):
        g.session.edited_fields.append('location_info')
        g.session.add_charge_state.geometry = information
        g.session.commit()

    if 'LLC LR Admins' not in g.session.user.roles and 'LLC LR Users' not in g.session.user.roles:
        result = LocalAuthorityService(
            current_app.config).get_authorities_by_extent(
                build_extents_from_features(information))
        if len(result) != 1 or g.session.user.organisation not in result:
            return redirect(
                url_for('modify_land_charge.get_location_confirmation'))

    charge_display_id = calc_display_id(
        g.session.add_charge_state.local_land_charge)
    current_app.logger.info(
        "Session charge updated - Redirecting back to modify_land_charge with local_land_charge='{}'"
        .format(charge_display_id))
    return redirect(
        url_for("modify_land_charge.modify_land_charge",
                local_land_charge=charge_display_id))
示例#19
0
def modify_land_charge(local_land_charge):
    current_app.logger.info(
        "Endpoint called with local_land_charge='{}'".format(
            local_land_charge))

    validate_charge_id(local_land_charge)

    local_land_charge_service = LocalLandChargeService(current_app.config)
    response = local_land_charge_service.get_by_charge_number(
        local_land_charge)

    if response.status_code == 404:
        current_app.logger.warning(
            "Charge not found for local_land_charge='{}' - Returning not found"
            .format(local_land_charge))
        raise ApplicationError(404)

    response.raise_for_status()

    updated, updated_date = get_history_update_info_by_charge_id(
        local_land_charge, local_land_charge_service)

    if not g.session.add_charge_state:
        current_app.logger.info(
            "Retrieving charge with local_land_charge='{}'".format(
                local_land_charge))
        # If the charge does not exist in the session, load it from the database, otherwise we are in the
        # process of updating it and as such it should be loaded from the session data

        charge_data = response.json()[0]['item']
        charge_item = LocalLandChargeItem.from_json(charge_data)

        current_app.logger.info(
            "Charge information retrieved for local_land_charge='{}' - Updating session charge"
            .format(local_land_charge))

        g.session.add_charge_state = charge_item
        g.session.edited_fields = []
        g.session.commit()

        current_app.logger.info("Session charge updated - Rendering Template")
    else:
        charge_id = calc_display_id(
            g.session.add_charge_state.local_land_charge)
        current_app.logger.info('charge_id: {}'.format(charge_id))
        current_app.logger.info(
            'local_land_charge: {}'.format(local_land_charge))

        # Check that charge ID in session and URL match.
        # If they don't, redirect user to the charge ID they entered and clear session
        if charge_id != local_land_charge:
            g.session.add_charge_state = None
            g.session.edited_fields = None
            g.session.commit()
            return modify_land_charge(local_land_charge)

        charge_item = g.session.add_charge_state

        current_app.logger.info("Session charge updated - Rendering Template")

    # Check that charge hasn't been cancelled in case user attempts to navigate to update URL manually
    if charge_item.end_date:
        current_app.logger.error(
            'Attempted to update a cancelled charge.  Charge ID: {}'.format(
                local_land_charge))
        raise ApplicationError(500)

    # Check if the charge is outside of the user's authority, if user hasn't already updated the map
    if not g.session.charge_added_outside_users_authority:
        extent = build_extents_from_features(charge_item.geometry)
        result = LocalAuthorityService(
            current_app.config).get_authorities_by_extent(extent)

        if should_show_confirmation_warning(result):
            # In this case the charge is outside of the user's authority
            if Permissions.add_extent_anywhere in g.session.user.permissions:
                # If the user has permission to add a charge anywhere, give them update permission without asking
                g.session.other_authority_update_permission = True
                g.session.commit()

            if not g.session.other_authority_update_permission:
                # if the user has not confirmed that they can edit charges outside of their authority, make them
                return redirect(
                    url_for(
                        'modify_land_charge.get_update_location_confirmation'))

    return render_template('modify_charge.html',
                           charge_item=charge_item,
                           updated=updated,
                           updated_date=updated_date,
                           charge_id=response.json()[0]['display_id'],
                           geometry=json.dumps(charge_item.geometry),
                           edited_fields=get_ordered_edited_fields(
                               g.session.edited_fields, ReviewMap),
                           map=ReviewMap)