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")
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))
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)