Make _attach_current_user a pure function

Mutating dictionaries is gross and doesn’t work as you’d expect. Better
to have the function return a new dictionary instead.

Means we can be explicit that `created_by` is one of the allowed params
when updating a service.
This commit is contained in:
Chris Hill-Scott
2016-08-11 14:20:43 +01:00
parent 0cfe10639a
commit da1fa2e61c
8 changed files with 23 additions and 21 deletions

View File

@@ -2,5 +2,7 @@ from flask.ext.login import current_user
def _attach_current_user(data): def _attach_current_user(data):
data['created_by'] = current_user.id return dict(
return data created_by=current_user.id,
**data
)

View File

@@ -30,7 +30,7 @@ class ApiKeyApiClient(BaseAPIClient):
'name': key_name, 'name': key_name,
'key_type': key_type 'key_type': key_type
} }
_attach_current_user(data) data = _attach_current_user(data)
key = self.post(url='/service/{}/api-key'.format(service_id), data=data) key = self.post(url='/service/{}/api-key'.format(service_id), data=data)
return key['data'] return key['data']

View File

@@ -23,7 +23,7 @@ class InviteApiClient(BaseAPIClient):
'from_user': invite_from_id, 'from_user': invite_from_id,
'permissions': permissions 'permissions': permissions
} }
_attach_current_user(data) data = _attach_current_user(data)
resp = self.post(url='/service/{}/invite'.format(service_id), data=data) resp = self.post(url='/service/{}/invite'.format(service_id), data=data)
return InvitedUser(**resp['data']) return InvitedUser(**resp['data'])
@@ -40,7 +40,7 @@ class InviteApiClient(BaseAPIClient):
def cancel_invited_user(self, service_id, invited_user_id): def cancel_invited_user(self, service_id, invited_user_id):
data = {'status': 'cancelled'} data = {'status': 'cancelled'}
_attach_current_user(data) data = _attach_current_user(data)
self.post(url='/service/{0}/invite/{1}'.format(service_id, invited_user_id), self.post(url='/service/{0}/invite/{1}'.format(service_id, invited_user_id),
data=data) data=data)

View File

@@ -32,6 +32,6 @@ class JobApiClient(BaseAPIClient):
"original_file_name": original_file_name, "original_file_name": original_file_name,
"notification_count": notification_count "notification_count": notification_count
} }
_attach_current_user(data) data = _attach_current_user(data)
resp = self.post(url='/service/{}/job'.format(service_id), data=data) resp = self.post(url='/service/{}/job'.format(service_id), data=data)
return resp['data'] return resp['data']

View File

@@ -29,5 +29,5 @@ class ProviderClient(BaseAPIClient):
data = { data = {
"priority": priority "priority": priority
} }
_attach_current_user(data) data = _attach_current_user(data)
return self.post(url='/provider-details/{}'.format(provider_id), data=data) return self.post(url='/provider-details/{}'.format(provider_id), data=data)

View File

@@ -30,7 +30,7 @@ class ServiceAPIClient(NotificationsAPIClient):
"restricted": restricted, "restricted": restricted,
"email_from": email_from "email_from": email_from
} }
_attach_current_user(data) data = _attach_current_user(data)
return self.post("/service", data)['data']['id'] return self.post("/service", data)['data']['id']
def delete_service(self, service_id): def delete_service(self, service_id):
@@ -81,7 +81,8 @@ class ServiceAPIClient(NotificationsAPIClient):
""" """
Update a service. Update a service.
""" """
disallowed_attributes = set(kwargs.keys()) - { data = _attach_current_user(kwargs)
disallowed_attributes = set(data.keys()) - {
'name', 'name',
'users', 'users',
'message_limit', 'message_limit',
@@ -89,14 +90,14 @@ class ServiceAPIClient(NotificationsAPIClient):
'restricted', 'restricted',
'email_from', 'email_from',
'reply_to_email_address', 'reply_to_email_address',
'sms_sender' 'sms_sender',
'created_by'
} }
if disallowed_attributes: if disallowed_attributes:
raise TypeError('Not allowed to update service attributes: {}'.format( raise TypeError('Not allowed to update service attributes: {}'.format(
", ".join(disallowed_attributes) ", ".join(disallowed_attributes)
)) ))
_attach_current_user(kwargs)
endpoint = "/service/{0}".format(service_id) endpoint = "/service/{0}".format(service_id)
return self.post(endpoint, data) return self.post(endpoint, data)
@@ -127,7 +128,7 @@ class ServiceAPIClient(NotificationsAPIClient):
data.update({ data.update({
'subject': subject 'subject': subject
}) })
_attach_current_user(data) data = _attach_current_user(data)
endpoint = "/service/{0}/template".format(service_id) endpoint = "/service/{0}/template".format(service_id)
return self.post(endpoint, data) return self.post(endpoint, data)
@@ -146,7 +147,7 @@ class ServiceAPIClient(NotificationsAPIClient):
data.update({ data.update({
'subject': subject 'subject': subject
}) })
_attach_current_user(data) data = _attach_current_user(data)
endpoint = "/service/{0}/template/{1}".format(service_id, id_) endpoint = "/service/{0}/template/{1}".format(service_id, id_)
return self.post(endpoint, data) return self.post(endpoint, data)
@@ -187,7 +188,7 @@ class ServiceAPIClient(NotificationsAPIClient):
data = { data = {
'archived': True 'archived': True
} }
_attach_current_user(data) data = _attach_current_user(data)
return self.post(endpoint, data=data) return self.post(endpoint, data=data)
def find_all_service_email_from(self, user_id=None): def find_all_service_email_from(self, user_id=None):

View File

@@ -7,20 +7,19 @@ def test_client_creates_job_data_correctly(mocker, fake_uuid):
template_id = fake_uuid template_id = fake_uuid
original_file_name = 'test.csv' original_file_name = 'test.csv'
notification_count = 1 notification_count = 1
mocker.patch('app.notify_client.current_user', id='1')
expected_data = { expected_data = {
"id": job_id, "id": job_id,
"template": template_id, "template": template_id,
"original_file_name": original_file_name, "original_file_name": original_file_name,
"notification_count": 1 "notification_count": 1,
"created_by": '1'
} }
expected_url = '/service/{}/job'.format(service_id) expected_url = '/service/{}/job'.format(service_id)
client = JobApiClient() client = JobApiClient()
mock_attach_user = mocker.patch(
'app.notify_client.job_api_client._attach_current_user',
return_value={'created_by': fake_uuid})
mock_post = mocker.patch('app.notify_client.job_api_client.JobApiClient.post') mock_post = mocker.patch('app.notify_client.job_api_client.JobApiClient.post')
client.create_job(job_id, service_id, template_id, original_file_name, notification_count) client.create_job(job_id, service_id, template_id, original_file_name, notification_count)

View File

@@ -7,17 +7,16 @@ from tests.conftest import fake_uuid
def test_client_posts_archived_true_when_deleting_template(mocker): def test_client_posts_archived_true_when_deleting_template(mocker):
service_id = fake_uuid service_id = fake_uuid
template_id = fake_uuid template_id = fake_uuid
mocker.patch('app.notify_client.current_user', id='1')
expected_data = { expected_data = {
'archived': True, 'archived': True,
'created_by': fake_uuid 'created_by': '1'
} }
expected_url = '/service/{}/template/{}'.format(service_id, template_id) expected_url = '/service/{}/template/{}'.format(service_id, template_id)
client = ServiceAPIClient() client = ServiceAPIClient()
mock_post = mocker.patch('app.notify_client.service_api_client.ServiceAPIClient.post') mock_post = mocker.patch('app.notify_client.service_api_client.ServiceAPIClient.post')
mock_attach_user = mocker.patch('app.notify_client.service_api_client._attach_current_user',
side_effect=lambda x: x.update({'created_by': fake_uuid}))
client.delete_service_template(service_id, template_id) client.delete_service_template(service_id, template_id)
mock_post.assert_called_once_with(expected_url, data=expected_data) mock_post.assert_called_once_with(expected_url, data=expected_data)
@@ -40,6 +39,7 @@ def test_client_gets_service(mocker, function, params):
def test_client_only_updates_allowed_attributes(mocker): def test_client_only_updates_allowed_attributes(mocker):
mocker.patch('app.notify_client.current_user', id='1')
with pytest.raises(TypeError) as error: with pytest.raises(TypeError) as error:
ServiceAPIClient().update_service('service_id', foo='bar') ServiceAPIClient().update_service('service_id', foo='bar')
assert str(error.value) == 'Not allowed to update service attributes: foo' assert str(error.value) == 'Not allowed to update service attributes: foo'