def test_get_survey_by_id_fail(self): with responses.RequestsMock() as rsps: rsps.add(rsps.GET, url_get_survey, status=400) with app.app_context(): with self.assertRaises(ApiError): survey_controller.get_survey(self.app_config["SURVEY_URL"], self.app_config["BASIC_AUTH"], survey["id"])
def survey_confirm_organisation(_): # Get and decrypt enrolment code cryptographer = Cryptographer() encrypted_enrolment_code = request.args.get('encrypted_enrolment_code', None) enrolment_code = cryptographer.decrypt( encrypted_enrolment_code.encode()).decode() # Validate enrolment code before retrieving organisation data iac_controller.validate_enrolment_code(enrolment_code) logger.info( 'Attempting to retrieve data for confirm add organisation/survey page') try: # Get organisation name case = case_controller.get_case_by_enrolment_code(enrolment_code) business_party_id = case['caseGroup']['partyId'] business_party = party_controller.get_party_by_business_id( business_party_id, app.config['PARTY_URL'], app.config['BASIC_AUTH']) # Get survey name collection_exercise_id = case['caseGroup']['collectionExerciseId'] collection_exercise = collection_exercise_controller.get_collection_exercise( collection_exercise_id) survey_id = collection_exercise['surveyId'] survey_name = survey_controller.get_survey(app.config['SURVEY_URL'], app.config['BASIC_AUTH'], survey_id).get('longName')
def register_confirm_organisation_survey(): # Get and decrypt enrolment code cryptographer = Cryptographer() encrypted_enrolment_code = request.args.get("encrypted_enrolment_code") try: enrolment_code = cryptographer.decrypt( encrypted_enrolment_code.encode()).decode() except AttributeError: logger.error("No enrolment code supplied", exc_info=True, url=request.url) raise # Validate enrolment code before retrieving organisation data iac_controller.validate_enrolment_code(enrolment_code) logger.info( "Attempting to retrieve data for confirm organisation/survey page", enrolment_code=enrolment_code) try: # Get organisation name case = case_controller.get_case_by_enrolment_code(enrolment_code) business_party_id = case["caseGroup"]["partyId"] business_party = party_controller.get_party_by_business_id( business_party_id, app.config["PARTY_URL"], app.config["BASIC_AUTH"]) # Get survey name collection_exercise_id = case["caseGroup"]["collectionExerciseId"] collection_exercise = collection_exercise_controller.get_collection_exercise( collection_exercise_id) survey_id = collection_exercise["surveyId"] survey_name = survey_controller.get_survey(app.config["SURVEY_URL"], app.config["BASIC_AUTH"], survey_id).get("longName")
def survey_confirm_organisation(_): # Get and decrypt enrolment code cryptographer = Cryptographer() encrypted_enrolment_code = request.args.get("encrypted_enrolment_code", None) enrolment_code = cryptographer.decrypt( encrypted_enrolment_code.encode()).decode() # Validate enrolment code before retrieving organisation data iac_controller.validate_enrolment_code(enrolment_code) logger.info( "Attempting to retrieve data for confirm add organisation/survey page", enrolment_code=enrolment_code) try: # Get organisation name case = case_controller.get_case_by_enrolment_code(enrolment_code) business_party_id = case["caseGroup"]["partyId"] business_party = party_controller.get_party_by_business_id( business_party_id, app.config["PARTY_URL"], app.config["BASIC_AUTH"]) # Get survey name collection_exercise_id = case["caseGroup"]["collectionExerciseId"] collection_exercise = collection_exercise_controller.get_collection_exercise( collection_exercise_id) survey_id = collection_exercise["surveyId"] survey_name = survey_controller.get_survey(app.config["SURVEY_URL"], app.config["BASIC_AUTH"], survey_id).get("longName")
def get_survey(self, key): """ Gets the survey from redis or the collection-instrument service :param key: Key in redis (for this example will be a frontstage:survey:id) :return: Result from either the cache or survey service """ redis_key = f"frontstage:survey:{key}" try: result = redis.get(redis_key) except RedisError: logger.error("Error getting value from cache, please investigate", key=redis_key, exc_info=True) result = None if not result: logger.info("Key not in cache, getting value from survey service", key=redis_key) result = get_survey(app.config["SURVEY_URL"], app.config["BASIC_AUTH"], key) self.save(redis_key, result, self.SURVEY_CATEGORY_EXPIRY) return result return json.loads(result.decode("utf-8"))
def test_get_survey_by_id_success(self): with responses.RequestsMock() as rsps: rsps.add(rsps.GET, url_get_survey, json=survey, status=200, content_type='application/json') with app.app_context(): get_survey = survey_controller.get_survey(survey['id']) self.assertIn( 'Bricks', get_survey['shortName'], 'Bricks short name is not in the returned survey')
def send_instruction_get(session): email = flask_session['share_survey_recipient_email_address'] selected_surveys = [] for survey_id in flask_session['share_survey_surveys_selected']: selected_surveys.append( survey_controller.get_survey(app.config['SURVEY_URL'], app.config['BASIC_AUTH'], survey_id)) selected_business = get_business_by_id( [flask_session['share_survey_business_selected']]) return render_template('surveys/surveys-share/send-instructions.html', email=email, surveys=selected_surveys, form=ConfirmEmailChangeForm(), business_name=selected_business[0]['name'])
def test_get_survey_by_id_success(self): with responses.RequestsMock() as rsps: rsps.add(rsps.GET, url_get_survey, json=survey, status=200, content_type="application/json") with app.app_context(): get_survey = survey_controller.get_survey( self.app_config["SURVEY_URL"], self.app_config["BASIC_AUTH"], survey["id"]) self.assertIn( "Bricks", get_survey["shortName"], "Bricks short name is not in the returned survey")
def get_surveys_listed_against_party_and_business_id(business_id, party_id): """ returns list of surveys associated with a business id and respondent :param business_id: business id :param party_id: The respondent's party id :return: list of surveys :rtype: list """ enrolment_data = get_respondent_enrolments(party_id) survey_ids = { enrolment['survey_id'] for enrolment in enrolment_data if enrolment['business_id'] == business_id } surveys = [] for survey in survey_ids: response = survey_controller.get_survey(app.config['SURVEY_URL'], app.config['BASIC_AUTH'], survey) surveys.append(response) return surveys
def send_instruction_get(session): email = flask_session["share_survey_recipient_email_address"] share_dict = {} for business_id in flask_session["share_survey_data"]: selected_business = get_business_by_id(business_id) surveys = [] for survey_id in flask_session["share_survey_data"][business_id]: surveys.append( survey_controller.get_survey(app.config["SURVEY_URL"], app.config["BASIC_AUTH"], survey_id)) share_dict[selected_business[0]["id"]] = { "name": selected_business[0]["name"], "surveys": surveys, } return render_template( "surveys/surveys-share/send-instructions.html", email=email, share_dict=share_dict, form=ConfirmEmailChangeForm(), )
def get_surveys_listed_against_party_and_business_id(business_id: str, party_id: str) -> list: """ returns list of surveys associated with a business id and respondent :param business_id: business id :param party_id: The respondent's party id :return: list of surveys """ respondent = get_respondent_party_by_id(party_id) enrolment_data = get_respondent_enrolments(respondent) survey_ids = { enrolment["survey_id"] for enrolment in enrolment_data if enrolment["business_id"] == business_id } surveys = [] for survey in survey_ids: response = survey_controller.get_survey(app.config["SURVEY_URL"], app.config["BASIC_AUTH"], survey) surveys.append(response) return surveys
def view_conversation(session, thread_id): """Endpoint to view conversations by thread_id""" party_id = session.get_party_id() logger.info("Getting conversation", thread_id=thread_id, party_id=party_id) conversation = get_conversation(thread_id) # secure message will send category in case the conversation is technical or miscellaneous is_survey_category = ( False if "category" in conversation and conversation["category"] in ["TECHNICAL", "MISC"] else True) # sets appropriate message category category = "SURVEY" if is_survey_category else conversation["category"] logger.info("Successfully retrieved conversation", thread_id=thread_id, party_id=party_id) try: refined_conversation = [ refine(message) for message in reversed(conversation["messages"]) ] except KeyError: logger.error("Message is missing important data", thread_id=thread_id, party_id=party_id) raise if refined_conversation[-1]["unread"]: remove_unread_label(refined_conversation[-1]["message_id"]) form = SecureMessagingForm(request.form) form.subject.data = refined_conversation[0].get("subject") if not conversation["is_closed"]: if form.validate_on_submit(): logger.info("Sending message", thread_id=thread_id, party_id=party_id) msg_to = get_msg_to(refined_conversation) if is_survey_category: send_message( _get_message_json(form, refined_conversation[0], msg_to=msg_to, msg_from=party_id)) else: send_message( _get_non_survey_message_json(form, refined_conversation[0], msg_to=msg_to, msg_from=party_id, category=category)) logger.info("Successfully sent message", thread_id=thread_id, party_id=party_id) thread_url = url_for("secure_message_bp.view_conversation", thread_id=thread_id) + "#latest-message" flash( Markup(f"Message sent. <a href={thread_url}>View Message</a>")) return redirect( url_for("secure_message_bp.view_conversation_list")) unread_message_count = { "unread_message_count": get_message_count_from_api(session) } survey_name = None business_name = None if is_survey_category: try: survey_name = get_survey( app.config["SURVEY_URL"], app.config["BASIC_AUTH"], refined_conversation[-1]["survey_id"]).get("longName") except ApiError as exc: logger.info("Failed to get survey name, setting to None", status_code=exc.status_code) try: business_name = conversation["messages"][-1]["@business_details"][ "name"] except (KeyError, TypeError): logger.info("Failed to get business name, setting to None") return render_template( "secure-messages/conversation-view.html", form=form, conversation=refined_conversation, conversation_data=conversation, unread_message_count=unread_message_count, survey_name=survey_name, business_name=business_name, category=category, )
def get_survey(cache_data, survey_id, survey_url, survey_auth): cache_data['surveys'][survey_id] = survey_controller.get_survey( survey_url, survey_auth, survey_id)
def get_survey_list_details_for_party(party_id, tag, business_party_id, survey_id): for enrolment in get_respondent_enrolments(party_id): business_party = get_party_by_business_id(enrolment['business_id']) survey = survey_controller.get_survey(enrolment['survey_id']) live_collection_exercises = collection_exercise_controller.get_live_collection_exercises_for_survey( survey['id']) collection_exercises_by_id = dict( (ce['id'], ce) for ce in live_collection_exercises) cases = case_controller.get_cases_for_list_type_by_party_id( business_party['id'], tag) enrolled_cases = [ case for case in cases if case['caseGroup']['collectionExerciseId'] in collection_exercises_by_id.keys() ] for case in enrolled_cases: collection_instrument = collection_instrument_controller.get_collection_instrument( case['collectionInstrumentId']) collection_exercise = collection_exercises_by_id[ case['caseGroup']['collectionExerciseId']] added_survey = True if business_party_id == business_party[ 'id'] and survey_id == survey['id'] else None display_access_button = display_button( case['caseGroup']['caseGroupStatus'], collection_instrument['type']) yield { 'case_id': case['id'], 'status': case_controller.calculate_case_status( case['caseGroup']['caseGroupStatus'], collection_instrument['type']), 'collection_instrument_type': collection_instrument['type'], 'survey_id': survey['id'], 'survey_long_name': survey['longName'], 'survey_short_name': survey['shortName'], 'survey_ref': survey['surveyRef'], 'business_party_id': business_party['id'], 'business_name': business_party['name'], 'trading_as': business_party['trading_as'], 'business_ref': business_party['sampleUnitRef'], 'period': collection_exercise['userDescription'], 'submit_by': collection_exercise['events']['return_by']['date'], 'collection_exercise_ref': collection_exercise['exerciseRef'], 'added_survey': added_survey, 'display_button': display_access_button } def display_button(status, ci_type): return not (ci_type == 'EQ' and status in CLOSED_STATE) def is_respondent_enrolled(party_id, business_party_id, survey_short_name, return_survey=False): survey = survey_controller.get_survey_by_short_name(survey_short_name) for enrolment in get_respondent_enrolments(party_id): if enrolment['business_id'] == business_party_id and enrolment[ 'survey_id'] == survey['id']: if return_survey: return {'survey': survey} return True def notify_party_and_respondent_account_locked(respondent_id, email_address, status=None): logger.debug( 'Notifying respondent and party service that account is locked') url = f'{app.config["PARTY_URL"]}/party-api/v1/respondents/edit-account-status/{respondent_id}' data = { 'respondent_id': respondent_id, 'email_address': email_address, 'status_change': status } response = requests.put(url, json=data, auth=app.config['PARTY_AUTH']) try: response.raise_for_status() except requests.exceptions.HTTPError: logger.error('Failed to notify party', respondent_id=respondent_id, status=status) raise ApiError(logger, response) logger.info('Successfully notified party and respondent', respondent_id=respondent_id, status=status)
def get_share_survey_summary(token): """ Endpoint to verify token and retrieve the summary page :param token: share survey token :type token: str """ logger.info("Getting share survey summary", token=token) try: response = party_controller.verify_pending_survey_token(token) pending_share_surveys = response.json() share_dict = {} distinct_businesses = set() batch_number = pending_share_surveys[0]["batch_no"] originator_party = party_controller.get_respondent_party_by_id( pending_share_surveys[0]["shared_by"]) shared_by = originator_party["emailAddress"] for pending_share_survey in pending_share_surveys: distinct_businesses.add(pending_share_survey["business_id"]) for business_id in distinct_businesses: business_surveys = [] for pending_share_survey in pending_share_surveys: if pending_share_survey["business_id"] == business_id: business_surveys.append( survey_controller.get_survey( app.config["SURVEY_URL"], app.config["BASIC_AUTH"], pending_share_survey["survey_id"])) selected_business = get_business_by_id(business_id) share_dict[selected_business[0]["id"]] = { "name": selected_business[0]["name"], "trading_as": selected_business[0]["trading_as"], "surveys": business_surveys, } return render_template("surveys/surveys-share/summary.html", share_dict=share_dict, batch_no=batch_number, shared_by=shared_by) except ApiError as exc: # Handle api errors if exc.status_code == 409: logger.info( "Expired share survey email verification token", token=token, api_url=exc.url, api_status_code=exc.status_code, ) return render_template("surveys/surveys-link-expired.html", is_transfer=False) elif exc.status_code == 404: logger.warning( "Unrecognised share survey email verification token", token=token, api_url=exc.url, api_status_code=exc.status_code, ) return render_template("surveys/surveys-link-not-valid.html", is_transfer=False) else: logger.info("Failed to verify share survey email", token=token, api_url=exc.url, api_status_code=exc.status_code) raise exc
def create_pubsub_payload(self, case, md5sum, size_bytes, file_name, tx_id: str) -> dict: log.info("Creating pubsub payload", case_id=case["id"]) case_group = case.get("caseGroup") if not case_group: raise SurveyResponseError("Case group not found") collection_exercise_id = case_group.get("collectionExerciseId") collection_exercise = get_collection_exercise(collection_exercise_id) if not collection_exercise: raise SurveyResponseError("Collection exercise not found") exercise_ref = collection_exercise.get("exerciseRef") survey_id = collection_exercise.get("surveyId") survey = get_survey(current_app.config["SURVEY_URL"], current_app.config["BASIC_AUTH"], survey_id) survey_ref = survey.get("surveyRef") if not survey_ref: raise SurveyResponseError("Survey ref not found") ru = case_group.get("sampleUnitRef") exercise_ref = self._format_exercise_ref(exercise_ref) payload = { "filename": file_name, "tx_id": tx_id, "survey_id": survey_ref, "period": exercise_ref, "ru_ref": ru, "md5sum": md5sum, "sizeBytes": size_bytes,
def test_get_survey_by_id_fail(self): with responses.RequestsMock() as rsps: rsps.add(rsps.GET, url_get_survey, status=400) with app.app_context(): with self.assertRaises(ApiError): survey_controller.get_survey(survey['id'])
def view_conversation(session, thread_id): """Endpoint to view conversations by thread_id""" party_id = session.get_party_id() logger.info("Getting conversation", thread_id=thread_id, party_id=party_id) conversation = get_conversation(thread_id) logger.info('Successfully retrieved conversation', thread_id=thread_id, party_id=party_id) try: refined_conversation = [ refine(message) for message in reversed(conversation['messages']) ] except KeyError: logger.error('Message is missing important data', thread_id=thread_id, party_id=party_id) raise if refined_conversation[-1]['unread']: remove_unread_label(refined_conversation[-1]['message_id']) form = SecureMessagingForm(request.form) form.subject.data = refined_conversation[0].get('subject') if not conversation['is_closed']: if form.validate_on_submit(): logger.info("Sending message", thread_id=thread_id, party_id=party_id) msg_to = get_msg_to(refined_conversation) send_message( _get_message_json(form, refined_conversation[0], msg_to=msg_to, msg_from=party_id)) logger.info("Successfully sent message", thread_id=thread_id, party_id=party_id) thread_url = url_for("secure_message_bp.view_conversation", thread_id=thread_id) + "#latest-message" flash( Markup(f'Message sent. <a href={thread_url}>View Message</a>')) return redirect( url_for('secure_message_bp.view_conversation_list')) unread_message_count = { 'unread_message_count': get_message_count_from_api(session) } survey_name = None try: survey_name = get_survey( app.config['SURVEY_URL'], app.config['BASIC_AUTH'], refined_conversation[-1]['survey_id']).get('longName') except ApiError as exc: logger.info('Failed to get survey name, setting to None', status_code=exc.status_code) business_name = None try: business_name = conversation['messages'][-1]['@business_details'][ 'name'] except KeyError: logger.info('Failed to get business name, setting to None') return render_template('secure-messages/conversation-view.html', form=form, conversation=refined_conversation, conversation_data=conversation, unread_message_count=unread_message_count, survey_name=survey_name, business_name=business_name)