mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-05 02:42:26 -05:00
Merge pull request #124 from alphagov/create-job
Uploading csv creates job via api
This commit is contained in:
@@ -11,6 +11,7 @@ from werkzeug.exceptions import abort
|
||||
from app.notify_client.api_client import NotificationsAdminAPIClient
|
||||
from app.notify_client.api_key_api_client import ApiKeyApiClient
|
||||
from app.notify_client.user_api_client import UserApiClient
|
||||
from app.notify_client.job_api_client import JobApiClient
|
||||
from app.its_dangerous_session import ItsdangerousSessionInterface
|
||||
import app.proxy_fix
|
||||
from config import configs
|
||||
@@ -22,6 +23,7 @@ csrf = CsrfProtect()
|
||||
notifications_api_client = NotificationsAdminAPIClient()
|
||||
user_api_client = UserApiClient()
|
||||
api_key_api_client = ApiKeyApiClient()
|
||||
job_api_client = JobApiClient()
|
||||
|
||||
|
||||
def create_app(config_name, config_overrides=None):
|
||||
@@ -36,6 +38,7 @@ def create_app(config_name, config_overrides=None):
|
||||
notifications_api_client.init_app(application)
|
||||
user_api_client.init_app(application)
|
||||
api_key_api_client.init_app(application)
|
||||
job_api_client.init_app(application)
|
||||
|
||||
login_manager.init_app(application)
|
||||
login_manager.login_view = 'main.sign_in'
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import csv
|
||||
import re
|
||||
import os
|
||||
|
||||
from datetime import date
|
||||
|
||||
@@ -9,14 +8,13 @@ from flask import (
|
||||
render_template,
|
||||
redirect,
|
||||
url_for,
|
||||
session,
|
||||
flash,
|
||||
current_app,
|
||||
abort
|
||||
)
|
||||
|
||||
from flask_login import login_required
|
||||
from werkzeug import secure_filename
|
||||
from client.errors import HTTPError
|
||||
|
||||
from app.main import main
|
||||
from app.main.forms import CsvUploadForm
|
||||
@@ -25,6 +23,7 @@ from app.main.uploader import (
|
||||
s3download
|
||||
)
|
||||
from app.main.dao import templates_dao
|
||||
from app import job_api_client
|
||||
|
||||
|
||||
@main.route("/services/<int:service_id>/sms/send", methods=['GET', 'POST'])
|
||||
@@ -38,7 +37,8 @@ def send_sms(service_id):
|
||||
upload_id = s3upload(service_id, filedata)
|
||||
return redirect(url_for('.check_sms',
|
||||
service_id=service_id,
|
||||
upload_id=upload_id))
|
||||
upload_id=upload_id,
|
||||
file_name=filedata['file_name']))
|
||||
except ValueError as e:
|
||||
message = 'There was a problem uploading: {}'.format(
|
||||
csv_file.filename)
|
||||
@@ -67,18 +67,23 @@ def check_sms(service_id, upload_id):
|
||||
if request.method == 'GET':
|
||||
contents = s3download(service_id, upload_id)
|
||||
upload_result = _get_numbers(contents)
|
||||
# TODO get original file name
|
||||
file_name = request.args.get('file_name')
|
||||
return render_template(
|
||||
'views/check-sms.html',
|
||||
upload_result=upload_result,
|
||||
filename='someupload_file_name.csv',
|
||||
file_name=file_name,
|
||||
message_template='''
|
||||
((name)), we’ve received your ((thing)). We’ll contact you again within 1 week.
|
||||
''',
|
||||
service_id=service_id
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
# TODO create the job with template, file location etc.
|
||||
file_name = request.form['original_file_name']
|
||||
|
||||
# TODO need a real template id picked from form
|
||||
template_id = 1
|
||||
|
||||
job_api_client.create_job(service_id, template_id, file_name)
|
||||
return redirect(url_for('main.view_job',
|
||||
service_id=service_id,
|
||||
job_id=upload_id))
|
||||
@@ -89,7 +94,7 @@ def _get_filedata(file):
|
||||
if len(lines) < 2: # must be at least header and one line
|
||||
message = 'The file {} contained no data'.format(file.filename)
|
||||
raise ValueError(message)
|
||||
return {'filename': file.filename, 'data': lines}
|
||||
return {'file_name': file.filename, 'data': lines}
|
||||
|
||||
|
||||
def _format_filename(filename):
|
||||
@@ -100,7 +105,7 @@ def _format_filename(filename):
|
||||
|
||||
|
||||
def _get_numbers(contents):
|
||||
pattern = re.compile(r'^\+44\s?\d{4}\s?\d{6}$') # need better validation
|
||||
pattern = re.compile(r'^\+44\s?\d{4}\s?\d{6}$') # TODO need better validation
|
||||
reader = csv.DictReader(
|
||||
contents.split('\n'),
|
||||
lineterminator='\n',
|
||||
|
||||
29
app/notify_client/job_api_client.py
Normal file
29
app/notify_client/job_api_client.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import uuid
|
||||
|
||||
from client.base import BaseAPIClient
|
||||
|
||||
|
||||
class JobApiClient(BaseAPIClient):
|
||||
def __init__(self, base_url=None, client_id=None, secret=None):
|
||||
super(self.__class__, self).__init__(base_url=base_url or 'base_url',
|
||||
client_id=client_id or 'client_id',
|
||||
secret=secret or 'secret')
|
||||
|
||||
def init_app(self, app):
|
||||
self.base_url = app.config['API_HOST_NAME']
|
||||
self.client_id = app.config['ADMIN_CLIENT_USER_NAME']
|
||||
self.secret = app.config['ADMIN_CLIENT_SECRET']
|
||||
|
||||
def create_job(self, service_id, template_id, file_name):
|
||||
job_id = str(uuid.uuid4())
|
||||
data = {
|
||||
"id": job_id,
|
||||
"service": service_id,
|
||||
"template": template_id,
|
||||
"original_file_name": file_name,
|
||||
"bucket_name": "service-{}-notify".format(service_id),
|
||||
"file_name": "{}.csv".format(job_id)
|
||||
}
|
||||
|
||||
resp = self.post(url='/service/{}/job'.format(service_id), data=data)
|
||||
return resp['data']
|
||||
@@ -59,6 +59,7 @@
|
||||
back_link = url_for(".send_sms", service_id=service_id)
|
||||
)}}
|
||||
|
||||
<input type="hidden" name="file_name" value="{{file_name}}" />
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -117,15 +117,25 @@ def test_upload_csvfile_with_valid_phone_shows_all_if_6_or_less_numbers(app_,
|
||||
|
||||
|
||||
@moto.mock_s3
|
||||
def test_should_redirect_to_job(app_,
|
||||
api_user_active,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email,
|
||||
mock_login):
|
||||
def test_create_job_should_call_api(app_,
|
||||
service_one,
|
||||
api_user_active,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email,
|
||||
mock_login,
|
||||
job_data,
|
||||
mock_create_job):
|
||||
|
||||
service_id = job_data['service']
|
||||
template_id = job_data['template']
|
||||
upload_id = job_data['id']
|
||||
file_name = job_data['original_file_name']
|
||||
|
||||
with app_.test_request_context():
|
||||
with app_.test_client() as client:
|
||||
client.login(api_user_active)
|
||||
response = client.post(url_for('main.check_sms',
|
||||
service_id=123,
|
||||
upload_id='someid'))
|
||||
assert response.status_code == 302
|
||||
url = url_for('main.check_sms', service_id=service_id, upload_id=upload_id, file_name=file_name)
|
||||
response = client.post(url, data=job_data, follow_redirects=True)
|
||||
|
||||
assert response.status_code == 200
|
||||
mock_create_job.assert_called_with(service_id, template_id, file_name)
|
||||
|
||||
@@ -422,6 +422,25 @@ def mock_check_verify_code_code_expired(mocker):
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def mock_send_email(mocker):
|
||||
return mocker.patch(
|
||||
'app.notifications_api_client.send_email', return_value=None)
|
||||
def job_data(mocker):
|
||||
import uuid
|
||||
job_id = uuid.uuid4()
|
||||
original_file_name = 'thisisatest.csv'
|
||||
bucket_name = 'service-2-notify'
|
||||
file_name = '{}.csv'.format(job_id)
|
||||
data = {
|
||||
'id': str(job_id),
|
||||
'service': 1,
|
||||
'template': 1,
|
||||
'original_file_name': original_file_name,
|
||||
'bucket_name': bucket_name,
|
||||
'file_name': file_name,
|
||||
}
|
||||
return data
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def mock_create_job(mocker, job_data):
|
||||
def _create(service_id, template_id, file_name):
|
||||
return job_data
|
||||
return mocker.patch('app.job_api_client.create_job', side_effect=_create)
|
||||
|
||||
Reference in New Issue
Block a user