def process_precompiled_letter_notifications(*, letter_data, api_key, template, reply_to_text): try: status = NOTIFICATION_PENDING_VIRUS_CHECK letter_content = base64.b64decode(letter_data['content']) pages = pdf_page_count(io.BytesIO(letter_content)) except ValueError: raise BadRequestError(message='Cannot decode letter content (invalid base64 encoding)', status_code=400) except PdfReadError: current_app.logger.exception(msg='Invalid PDF received') raise BadRequestError(message='Letter content is not a valid PDF', status_code=400) notification = create_letter_notification(letter_data=letter_data, template=template, api_key=api_key, status=status, reply_to_text=reply_to_text) filename = upload_letter_pdf(notification, letter_content, precompiled=True) pages_per_sheet = 2 notification.billable_units = math.ceil(pages / pages_per_sheet) dao_update_notification(notification) current_app.logger.info('Calling task scan-file for {}'.format(filename)) # call task to add the filename to anti virus queue notify_celery.send_task( name=TaskNames.SCAN_FILE, kwargs={'filename': filename}, queue=QueueNames.ANTIVIRUS, ) return notification
def test_create_letter_notification_creates_notification( sample_letter_template, sample_api_key): data = { 'personalisation': { 'address_line_1': 'The Queen', 'address_line_2': 'Buckingham Palace', 'postcode': 'SW1 1AA', } } notification = create_letter_notification(data, sample_letter_template, sample_api_key, NOTIFICATION_CREATED) assert notification == Notification.query.one() assert notification.job is None assert notification.status == NOTIFICATION_CREATED assert notification.template_id == sample_letter_template.id assert notification.template_version == sample_letter_template.version assert notification.api_key == sample_api_key assert notification.notification_type == LETTER_TYPE assert notification.key_type == sample_api_key.key_type assert notification.reference is not None assert notification.client_reference is None assert notification.postage == 'second'
def process_precompiled_letter_notifications(*, letter_data, api_key, template, reply_to_text): try: status = NOTIFICATION_PENDING_VIRUS_CHECK letter_content = base64.b64decode(letter_data['content']) except ValueError: raise BadRequestError( message='Cannot decode letter content (invalid base64 encoding)', status_code=400) notification = create_letter_notification(letter_data=letter_data, template=template, api_key=api_key, status=status, reply_to_text=reply_to_text) filename = upload_letter_pdf(notification, letter_content, precompiled=True) current_app.logger.info('Calling task scan-file for {}'.format(filename)) # call task to add the filename to anti virus queue if current_app.config['ANTIVIRUS_ENABLED']: notify_celery.send_task( name=TaskNames.SCAN_FILE, kwargs={'filename': filename}, queue=QueueNames.ANTIVIRUS, ) else: # stub out antivirus in dev sanitise_letter.apply_async([filename], queue=QueueNames.LETTERS) return notification
def test_create_letter_notification_creates_notification( sample_letter_template, sample_api_key): data = { "personalisation": { "address_line_1": "The Queen", "address_line_2": "Buckingham Palace", "postcode": "SW1 1AA", } } notification = create_letter_notification(data, sample_letter_template, sample_api_key, NOTIFICATION_CREATED) assert notification == Notification.query.one() assert notification.job is None assert notification.status == NOTIFICATION_CREATED assert notification.template_id == sample_letter_template.id assert notification.template_version == sample_letter_template.version assert notification.api_key == sample_api_key assert notification.notification_type == LETTER_TYPE assert notification.key_type == sample_api_key.key_type assert notification.reference is not None assert notification.client_reference is None assert notification.postage == "second"
def test_create_letter_notification_sets_reference(sample_letter_template, sample_api_key): data = { 'personalisation': { 'address_line_1': 'The Queen', 'address_line_2': 'Buckingham Palace', 'postcode': 'SW1 1AA', }, 'reference': 'foo' } notification = create_letter_notification(data, sample_letter_template, sample_api_key, NOTIFICATION_CREATED) assert notification.client_reference == 'foo'
def test_create_letter_notification_sets_reference(sample_letter_template, sample_api_key): data = { "personalisation": { "address_line_1": "The Queen", "address_line_2": "Buckingham Palace", "postcode": "SW1 1AA", }, "reference": "foo", } notification = create_letter_notification(data, sample_letter_template, sample_api_key, NOTIFICATION_CREATED) assert notification.client_reference == "foo"
def process_letter_notification(*, letter_data, api_key, template, reply_to_text, precompiled=False): if api_key.key_type == KEY_TYPE_TEAM: raise BadRequestError( message='Cannot send letters with a team api key', status_code=403) if not api_key.service.research_mode and api_key.service.restricted and api_key.key_type != KEY_TYPE_TEST: raise BadRequestError( message='Cannot send letters when service is in trial mode', status_code=403) if precompiled: return process_precompiled_letter_notifications( letter_data=letter_data, api_key=api_key, template=template, reply_to_text=reply_to_text) test_key = api_key.key_type == KEY_TYPE_TEST # if we don't want to actually send the letter, then start it off in SENDING so we don't pick it up status = NOTIFICATION_CREATED if not test_key else NOTIFICATION_SENDING queue = QueueNames.CREATE_LETTERS_PDF if not test_key else QueueNames.RESEARCH_MODE notification = create_letter_notification(letter_data=letter_data, template=template, api_key=api_key, status=status, reply_to_text=reply_to_text) create_letters_pdf.apply_async([str(notification.id)], queue=queue) if test_key: if current_app.config['NOTIFY_ENVIRONMENT'] in [ 'preview', 'development' ]: create_fake_letter_response_file.apply_async( (notification.reference, ), queue=queue) else: update_notification_status_by_reference(notification.reference, NOTIFICATION_DELIVERED) return notification
def test_create_letter_notification_sets_billable_units( sample_letter_template, sample_api_key): data = { 'personalisation': { 'address_line_1': 'The Queen', 'address_line_2': 'Buckingham Palace', 'postcode': 'SW1 1AA', }, } notification = create_letter_notification(data, sample_letter_template, sample_api_key, NOTIFICATION_CREATED, billable_units=3) assert notification.billable_units == 3
def test_create_letter_notification_sets_billable_units( sample_letter_template, sample_api_key): data = { "personalisation": { "address_line_1": "The Queen", "address_line_2": "Buckingham Palace", "postcode": "SW1 1AA", }, } notification = create_letter_notification( data, sample_letter_template, sample_api_key, NOTIFICATION_CREATED, billable_units=3, ) assert notification.billable_units == 3
def test_create_letter_notification_sets_billable_units( sample_letter_template, sample_api_key): data = { 'personalisation': { 'address_line_1': 'The Queen', 'address_line_2': 'Buckingham Palace', 'postcode': 'SW1 1AA', }, } template = SerialisedTemplate.from_id_and_service_id( sample_letter_template.id, sample_letter_template.service_id) notification = create_letter_notification( data, template, sample_letter_template.service, sample_api_key, NOTIFICATION_CREATED, billable_units=3, ) assert notification.billable_units == 3
def process_letter_notification(*, letter_data, api_key, template, reply_to_text, precompiled=False): if api_key.key_type == KEY_TYPE_TEAM: raise BadRequestError( message='Cannot send letters with a team api key', status_code=403) if not api_key.service.research_mode and api_key.service.restricted and api_key.key_type != KEY_TYPE_TEST: raise BadRequestError( message='Cannot send letters when service is in trial mode', status_code=403) if precompiled: return process_precompiled_letter_notifications( letter_data=letter_data, api_key=api_key, template=template, reply_to_text=reply_to_text) address = PostalAddress.from_personalisation( letter_data['personalisation'], allow_international_letters=api_key.service.has_permission( INTERNATIONAL_LETTERS), ) if not address.has_enough_lines: raise ValidationError( message=f'Address must be at least {PostalAddress.MIN_LINES} lines' ) if address.has_too_many_lines: raise ValidationError( message= f'Address must be no more than {PostalAddress.MAX_LINES} lines') if not address.has_valid_last_line: if address.allow_international_letters: raise ValidationError( message= f'Last line of address must be a real UK postcode or another country' ) raise ValidationError(message='Must be a real UK postcode') test_key = api_key.key_type == KEY_TYPE_TEST # if we don't want to actually send the letter, then start it off in SENDING so we don't pick it up status = NOTIFICATION_CREATED if not test_key else NOTIFICATION_SENDING queue = QueueNames.CREATE_LETTERS_PDF if not test_key else QueueNames.RESEARCH_MODE notification = create_letter_notification(letter_data=letter_data, template=template, api_key=api_key, status=status, reply_to_text=reply_to_text) create_letters_pdf.apply_async([str(notification.id)], queue=queue) if test_key: if current_app.config['NOTIFY_ENVIRONMENT'] in [ 'preview', 'development' ]: create_fake_letter_response_file.apply_async( (notification.reference, ), queue=queue) else: update_notification_status_by_reference(notification.reference, NOTIFICATION_DELIVERED) return notification
def process_letter_notification(*, letter_data, api_key, service, template, template_with_content, reply_to_text, precompiled=False): if api_key.key_type == KEY_TYPE_TEAM: raise BadRequestError( message='Cannot send letters with a team api key', status_code=403) if not service.research_mode and service.restricted and api_key.key_type != KEY_TYPE_TEST: raise BadRequestError( message='Cannot send letters when service is in trial mode', status_code=403) if precompiled: return process_precompiled_letter_notifications( letter_data=letter_data, api_key=api_key, service=service, template=template, reply_to_text=reply_to_text) postage = validate_address(service, letter_data['personalisation']) test_key = api_key.key_type == KEY_TYPE_TEST status = NOTIFICATION_CREATED updated_at = None if test_key: # if we don't want to actually send the letter, then start it off in SENDING so we don't pick it up if current_app.config['NOTIFY_ENVIRONMENT'] in [ 'preview', 'development' ]: status = NOTIFICATION_SENDING # mark test letter as delivered and do not create a fake response later else: status = NOTIFICATION_DELIVERED updated_at = datetime.utcnow() queue = QueueNames.CREATE_LETTERS_PDF if not test_key else QueueNames.RESEARCH_MODE notification = create_letter_notification(letter_data=letter_data, service=service, template=template, api_key=api_key, status=status, reply_to_text=reply_to_text, updated_at=updated_at, postage=postage) get_pdf_for_templated_letter.apply_async([str(notification.id)], queue=queue) if test_key and current_app.config['NOTIFY_ENVIRONMENT'] in [ 'preview', 'development' ]: create_fake_letter_response_file.apply_async( (notification.reference, ), queue=queue) resp = create_response_for_post_notification( notification_id=notification.id, client_reference=notification.client_reference, template_id=notification.template_id, template_version=notification.template_version, notification_type=notification.notification_type, reply_to=reply_to_text, service_id=notification.service_id, template_with_content=template_with_content) return resp