def test_get_letter_validation_error_for_known_errors( client_request, error_message, invalid_pages, expected_title, expected_content, expected_summary, ): error = get_letter_validation_error(error_message, invalid_pages=invalid_pages, page_count=13) detail = BeautifulSoup(error['detail'], 'html.parser') summary = BeautifulSoup(error['summary'], 'html.parser') assert error['title'] == expected_title assert detail.text == expected_content if detail.select_one('a'): assert detail.select_one('a')['href'] == url_for( '.letter_specification') assert summary.text == expected_summary if summary.select_one('a'): assert summary.select_one('a')['href'] == url_for( '.letter_specification')
def uploaded_letter_preview(service_id, file_id): re_upload_form = PDFUploadForm() try: metadata = get_letter_metadata(service_id, file_id) except ClientError as e: # if the file's not there, it's probably because we've already created the notification and the letter has been # moved to the normal letters-pdf bucket. So lets just bounce out to the notification page if e.response['Error']['Code'] == 'NoSuchKey': return redirect( url_for( '.view_notification', service_id=service_id, notification_id=file_id, )) else: raise original_filename = metadata.get('filename') page_count = metadata.get('page_count') status = metadata.get('status') error_shortcode = metadata.get('message') invalid_pages = metadata.get('invalid_pages') postal_address = PostalAddress(metadata.get('recipient', '')) if invalid_pages: invalid_pages = json.loads(invalid_pages) error_message = get_letter_validation_error(error_shortcode, invalid_pages, page_count) template_dict = service_api_client.get_precompiled_template(service_id) # Override pre compiled letter template postage to none as it has not yet been picked even though # the pre compiled letter template has its postage set as second class as the DB currently requires # a non null value of postage for letter templates template_dict['postage'] = None form = LetterUploadPostageForm(postage_zone=postal_address.postage) template = get_template(template_dict, service_id, letter_preview_url=url_for( '.view_letter_upload_as_preview', service_id=service_id, file_id=file_id), page_count=page_count) return render_template( 'views/uploads/preview.html', original_filename=original_filename, template=template, status=status, file_id=file_id, message=error_message, error_code=error_shortcode, form=form, allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS, postal_address=postal_address, re_upload_form=re_upload_form)
def letter_validation_preview(from_platform_admin): message, pages, passed_validation, error_code = None, [], None, None form = PDFUploadForm() view_location = 'views/platform-admin/letter-validation-preview.html' \ if from_platform_admin else'views/letter-validation-preview.html' if form.validate_on_submit(): pdf_file = form.file.data virus_free = antivirus_client.scan(pdf_file) if not virus_free: return render_template( view_location, form=form, message="Document did not pass the virus scan", pages=pages, passed_validation=passed_validation ), 400 try: if len(pdf_file.read()) > (2 * 1024 * 1024): return render_template( view_location, form=form, message="File must be less than 2MB", pages=pages, passed_validation=passed_validation ), 400 pdf_file.seek(0) response = validate_letter(pdf_file) response.raise_for_status() if response.status_code == 200: pages, message = response.json()["pages"], response.json()["message"], passed_validation = response.json()["result"] invalid_pages = response.json().get('invalid_pages') page_count = len(pages) if page_count > LETTER_MAX_PAGE_COUNT: message = "letter-too-long" passed_validation = False if not passed_validation: error_code = message message = get_letter_validation_error( message, invalid_pages=invalid_pages, page_count=page_count ) except RequestException as error: if error.response and error.response.status_code == 400: message = "Something was wrong with the file you tried to upload. Please upload a valid PDF file." return render_template( view_location, form=form, message=message, pages=pages, passed_validation=passed_validation ), 400 else: raise error return render_template( view_location, form=form, message=message, pages=pages, passed_validation=passed_validation, error_code=error_code )
def uploaded_letter_preview(service_id, file_id): re_upload_form = PDFUploadForm() metadata = get_letter_metadata(service_id, file_id) original_filename = metadata.get('filename') page_count = metadata.get('page_count') status = metadata.get('status') error_shortcode = metadata.get('message') invalid_pages = metadata.get('invalid_pages') recipient = format_recipient(metadata.get('recipient', '')) if invalid_pages: invalid_pages = json.loads(invalid_pages) error_message = get_letter_validation_error(error_shortcode, invalid_pages, page_count) template_dict = service_api_client.get_precompiled_template(service_id) # Override pre compiled letter template postage to none as it has not yet been picked even though # the pre compiled letter template has its postage set as second class as the DB currently requires # a non null value of postage for letter templates template_dict['postage'] = None form = LetterUploadPostageForm() template = get_template( template_dict, service_id, letter_preview_url=url_for( '.view_letter_upload_as_preview', service_id=service_id, file_id=file_id ), page_count=page_count ) return render_template( 'views/uploads/preview.html', original_filename=original_filename, template=template, status=status, file_id=file_id, message=error_message, error_code=error_shortcode, form=form, recipient=recipient, re_upload_form=re_upload_form )
def view_notification(service_id, notification_id): notification = notification_api_client.get_notification( service_id, str(notification_id)) notification['template'].update( {'reply_to_text': notification['reply_to_text']}) personalisation = get_all_personalisation_from_notification(notification) error_message = None if notification['template']['is_precompiled_letter']: try: file_contents, metadata = get_letter_file_data(service_id, notification_id, "pdf", with_metadata=True) page_count = int(metadata["page_count"]) if metadata.get( "page_count") else pdf_page_count(io.BytesIO(file_contents)) if notification["status"] == "validation-failed": invalid_pages = metadata.get("invalid_pages") invalid_pages = json.loads( invalid_pages) if invalid_pages else invalid_pages error_message = get_letter_validation_error( metadata.get("message"), invalid_pages, page_count) except PdfReadError: return render_template( 'views/notifications/invalid_precompiled_letter.html', created_at=notification['created_at']) else: page_count = get_page_count_for_letter(notification['template'], values=personalisation) if notification.get('postage'): if notification["status"] == "validation-failed": notification['template']['postage'] = None else: notification['template']['postage'] = notification['postage'] template = get_template( notification['template'], current_service, letter_preview_url=url_for( '.view_letter_notification_as_preview', service_id=service_id, notification_id=notification_id, filetype='png', ), page_count=page_count, show_recipient=True, redact_missing_personalisation=True, ) template.values = personalisation if notification['job']: job = job_api_client.get_job(service_id, notification['job']['id'])['data'] else: job = None letter_print_day = get_letter_printing_statement( notification['status'], notification['created_at']) notification_created = parser.parse( notification['created_at']).replace(tzinfo=None) show_cancel_button = notification['notification_type'] == 'letter' and \ letter_can_be_cancelled(notification['status'], notification_created) if get_help_argument() or request.args.get('help') == '0': # help=0 is set when you’ve just sent a notification. We # only want to show the back link when you’ve navigated to a # notification, not when you’ve just sent it. back_link = None elif request.args.get('from_job'): back_link = url_for( 'main.view_job', service_id=current_service.id, job_id=request.args.get('from_job'), ) elif request.args.get('from_uploaded_letters'): back_link = url_for( 'main.uploaded_letters', service_id=current_service.id, letter_print_day=request.args.get('from_uploaded_letters'), ) else: back_link = url_for( 'main.view_notifications', service_id=current_service.id, message_type=template.template_type, status='sending,delivered,failed', ) if notification['notification_type'] == 'letter': estimated_letter_delivery_date = get_letter_timings( notification['created_at'], postage=notification['postage']).earliest_delivery else: estimated_letter_delivery_date = None return render_template( 'views/notifications/notification.html', finished=(notification['status'] in (DELIVERED_STATUSES + FAILURE_STATUSES)), notification_status=notification['status'], message=error_message, uploaded_file_name='Report', template=template, job=job, updates_url=url_for(".view_notification_updates", service_id=service_id, notification_id=notification['id'], status=request.args.get('status'), help=get_help_argument()), partials=get_single_notification_partials(notification), created_by=notification.get('created_by'), created_at=notification['created_at'], updated_at=notification['updated_at'], help=get_help_argument(), estimated_letter_delivery_date=estimated_letter_delivery_date, notification_id=notification['id'], postage=notification['postage'], can_receive_inbound=(current_service.has_permission('inbound_sms')), is_precompiled_letter=notification['template'] ['is_precompiled_letter'], letter_print_day=letter_print_day, show_cancel_button=show_cancel_button, sent_with_test_key=(notification.get('key_type') == KEY_TYPE_TEST), back_link=back_link, )
def test_get_letter_validation_error_for_unknown_error(): assert get_letter_validation_error('Unknown error') == { 'title': 'Validation failed' }