Skip to content

Commit

Permalink
[#1117] Add mocking to user_update auth tests
Browse files Browse the repository at this point in the history
These tests now run without touching the model.

Also added one extra test case.
  • Loading branch information
Sean Hammond committed Aug 2, 2013
1 parent ccc47e0 commit 4f34165
Showing 1 changed file with 112 additions and 24 deletions.
136 changes: 112 additions & 24 deletions ckan/new_tests/logic/auth/test_update.py
@@ -1,8 +1,7 @@
'''Unit tests for ckan/logic/auth.update.py.
'''
import ckan.new_tests.helpers as helpers
import ckan.new_tests.factories as factories
import mock


class TestUpdate(object):
Expand All @@ -12,13 +11,12 @@ def _call_auth(self, auth_name, context=None, **kwargs):
'''Call a ckan.logic.auth function more conveniently for testing.
'''
import ckan.model
import ckan.logic.auth.update
if context is None:
context = {}
context.setdefault('user', '127.0.0.1')

context.setdefault('model', ckan.model)
assert 'user' in context, ('Test methods must put a user name in the '
'context dict')
assert 'model' in context, ('Test methods must put a model in the '
'context dict')

# FIXME: Do we want to go through check_access() here?
auth_function = ckan.logic.auth.update.__getattribute__(auth_name)
Expand All @@ -27,35 +25,125 @@ def _call_auth(self, auth_name, context=None, **kwargs):
def test_user_update_visitor_cannot_update_user(self):
'''Visitors should not be able to update users' accounts.'''

user = factories.User()
user['name'] = 'updated'
# Make a mock ckan.model.User object, Fred.
fred = mock.MagicMock()
# Give the mock user object some attributes it's going to need.
fred.reset_key = 'fred_reset_key'
fred.id = 'fred_user_id'
fred.name = 'fred'

# Try to update the user, but without passing any API key.
result = self._call_auth('user_update', **user)
assert result['success'] is False
# Make a mock ckan.model object.
mock_model = mock.MagicMock()
# model.User.get(user_id) should return Fred.
mock_model.User.get.return_value = fred

# Put the mock model in the context.
# This is easier than patching import ckan.model.
context = {'model': mock_model}

# No user is going to be logged-in.
context['user'] = '127.0.0.1'

# TODO: Assert result['msg'] as well? In this case the message is not
# very sensible: "User 127.0.0.1 is not authorized to edit user foo".
# Also applies to the rest of these tests.
# Make the visitor try to update Fred's user account.
params = {
'id': fred.id,
'name': 'updated_user_name',
}
result = self._call_auth('user_update', context=context, **params)

assert result['success'] is False

def test_user_update_user_cannot_update_another_user(self):
'''Users should not be able to update other users' accounts.'''

fred = factories.User(name='fred')
bob = factories.User(name='bob')
fred['name'] = 'updated'
# Make a mock ckan.model.User object, Fred.
fred = mock.MagicMock()
# Give the mock user object some attributes it's going to need.
fred.reset_key = 'fred_reset_key'
fred.id = 'fred_user_id'
fred.name = 'fred'

# Make a mock ckan.model object.
mock_model = mock.MagicMock()
# model.User.get(user_id) should return Fred.
mock_model.User.get.return_value = fred

# Put the mock model in the context.
# This is easier than patching import ckan.model.
context = {'model': mock_model}

# The logged-in user is going to be Bob, not Fred.
context['user'] = 'bob'

# Make Bob try to update Fred's user account.
context = {'user': bob['name']}
result = self._call_auth('user_update', context=context, **fred)
params = {
'id': fred.id,
'name': 'updated_user_name',
}
result = self._call_auth('user_update', context=context, **params)

assert result['success'] is False

def test_user_update_user_can_update_herself(self):
'''Users should be authorized to update their own accounts.'''

user = factories.User()
# Make a mock ckan.model.User object, Fred.
fred = mock.MagicMock()
# Give the mock user object some attributes it's going to need.
fred.reset_key = 'fred_reset_key'
fred.id = 'fred_user_id'
fred.name = 'fred'

# Make a mock ckan.model object.
mock_model = mock.MagicMock()
# model.User.get(user_id) should return our mock user.
mock_model.User.get.return_value = fred

# Put the mock model in the context.
# This is easier than patching import ckan.model.
context = {'model': mock_model}

# The 'user' in the context has to match fred.name, so that the
# auth function thinks that the user being updated is the same user as
# the user who is logged-in.
context['user'] = fred.name

# Make Fred try to update his own user name.
params = {
'id': fred.id,
'name': 'updated_user_name',
}
result = self._call_auth('user_update', context=context, **params)

context = {'user': user['name']}
user['name'] = 'updated'
result = self._call_auth('user_update', context=context, **user)
assert result['success'] is True

def test_user_update_with_no_user_in_context(self):

# Make a mock ckan.model.User object.
mock_user = mock.MagicMock()
# Give the mock user object some attributes it's going to need.
mock_user.reset_key = 'mock reset key'
mock_user.id = 'mock user id'
mock_user.name = 'mock_user'

# Make a mock ckan.model object.
mock_model = mock.MagicMock()
# model.User.get(user_id) should return our mock user.
mock_model.User.get.return_value = mock_user

# Put the mock model in the context.
# This is easier than patching import ckan.model.
context = {'model': mock_model}

# For this test we're going to have no 'user' in the context.
context['user'] = None

params = {
'id': mock_user.id,
'name': 'updated_user_name',
}
result = self._call_auth('user_update', context=context, **params)

assert result['success'] is False

# TODO: Tests for user_update's reset_key behavior.

0 comments on commit 4f34165

Please sign in to comment.