Browse Source

update places

master
Julio Biason 11 years ago
parent
commit
a9f397c1ba
  1. 36
      luncho/blueprints/groups.py
  2. 66
      luncho/blueprints/places.py
  3. 32
      luncho/exceptions.py
  4. 4
      luncho/server.py
  5. 41
      tests/base.py
  6. 4
      tests/group_tests.py
  7. 55
      tests/place_tests.py

36
luncho/blueprints/groups.py

@ -19,38 +19,8 @@ from luncho.server import db
from luncho.exceptions import LunchoException from luncho.exceptions import LunchoException
from luncho.exceptions import ElementNotFoundException from luncho.exceptions import ElementNotFoundException
from luncho.exceptions import AccountNotVerifiedException from luncho.exceptions import AccountNotVerifiedException
from luncho.exceptions import NewMaintainerDoesNotExistException
from luncho.exceptions import UserIsNotAdminException
class NewMaintainerDoesNotExistException(LunchoException):
"""The account for the new admin does not exist.
.. sourcecode:: http
HTTP/1.1 404 Not found
Content-Type: test/json
{ "status": "ERROR", "message": "New admin not found" }
"""
def __init__(self):
super(NewMaintainerDoesNotExistException, self).__init__()
self.status = 404
self.message = 'New admin not found'
class UserIsNotAdminException(LunchoException):
"""The user is not the admin of the group.
.. sourcecode:: http
HTTP/1.1 403 Forbidden
Content-Type: test/json
{ "status": "ERROR", "message": "User is not admin" }
"""
def __init__(self):
super(UserIsNotAdminException, self).__init__()
self.status = 403
self.message = 'User is not admin'
class UserIsNotMemberException(LunchoException): class UserIsNotMemberException(LunchoException):
@ -178,7 +148,7 @@ def create_group():
json = request.get_json(force=True) json = request.get_json(force=True)
new_group = Group(name=json['name'], new_group = Group(name=json['name'],
owner=user.username) owner=user)
LOG.debug('Current user groups: {groups}'.format(groups=user.groups)) LOG.debug('Current user groups: {groups}'.format(groups=user.groups))
user.groups.append(new_group) user.groups.append(new_group)

66
luncho/blueprints/places.py

@ -6,12 +6,14 @@ from flask import request
from flask import jsonify from flask import jsonify
from luncho.server import Place from luncho.server import Place
from luncho.server import User
from luncho.server import db from luncho.server import db
from luncho.helpers import auth from luncho.helpers import auth
from luncho.helpers import ForceJSON from luncho.helpers import ForceJSON
from luncho.exceptions import AccountNotVerifiedException from luncho.exceptions import AccountNotVerifiedException
from luncho.exceptions import ElementNotFoundException
places = Blueprint('places', __name__) places = Blueprint('places', __name__)
@ -51,7 +53,7 @@ def create_place():
raise AccountNotVerifiedException() raise AccountNotVerifiedException()
json = request.get_json(force=True) json = request.get_json(force=True)
new_place = Place(name=json['name'], owner=request.user.username) new_place = Place(name=json['name'], owner=request.user)
db.session.add(new_place) db.session.add(new_place)
db.session.commit() db.session.commit()
@ -101,3 +103,65 @@ def get_places():
return jsonify(status='OK', return jsonify(status='OK',
places=places.values()) places=places.values())
@places.route('<placeId>/', methods=['PUT'])
@ForceJSON()
@auth
def update_place(placeId):
"""*Authenticated request* Update the place information. The user must be
the maintainer of the place to change any information. Partial requests
are accepted and missing fields will not be changed.
**Example request**:
.. sourcecode:: http
{ "name": "New name", "admin": "newAdmin" }
**Success (200)**:
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: text/json
**Request not in JSON format (400)**:
:py:class:`RequestMustBeJSONException`
**User is not administrator of the group (403)**:
:py:class:`UserIsNotAdminException`
**User not found (via token) (404)**:
:py:class:`UserNotFoundException`
**The new admin does not exist (404)**:
:py:class:`NewMaintainerDoesNotExistException`
**The place does not exist (404)**:
:py:class:`ElementNotFoundException`
**Authorization required (412)**:
:py:class:`AuthorizationRequiredException`
"""
place = Place.query.get(placeId)
if not place:
raise ElementNotFoundException('Place')
if not place.owner == request.user.username:
raise UserIsNotAdminException()
name = request.as_json.get('name')
if name:
place.name = name
admin = request.as_json.get('admin')
if admin:
new_maintainer = User.query.get(admin)
if not new_maintainer:
raise NewMaintainerDoesNotExistException()
place.owner = new_maintainer.username
db.session.commit()
return jsonify(status='OK')

32
luncho/exceptions.py

@ -138,3 +138,35 @@ class AccountNotVerifiedException(LunchoException):
super(AccountNotVerifiedException, self).__init__() super(AccountNotVerifiedException, self).__init__()
self.status = 412 self.status = 412
self.message = 'Account not verified' self.message = 'Account not verified'
class NewMaintainerDoesNotExistException(LunchoException):
"""The account for the new admin does not exist.
.. sourcecode:: http
HTTP/1.1 404 Not found
Content-Type: test/json
{ "status": "ERROR", "message": "New admin not found" }
"""
def __init__(self):
super(NewMaintainerDoesNotExistException, self).__init__()
self.status = 404
self.message = 'New admin not found'
class UserIsNotAdminException(LunchoException):
"""The user is not the admin of the group.
.. sourcecode:: http
HTTP/1.1 403 Forbidden
Content-Type: test/json
{ "status": "ERROR", "message": "User is not admin" }
"""
def __init__(self):
super(UserIsNotAdminException, self).__init__()
self.status = 403
self.message = 'User is not admin'

4
luncho/server.py

@ -104,7 +104,7 @@ class Group(db.Model):
def __init__(self, name, owner): def __init__(self, name, owner):
self.name = name self.name = name
self.owner = owner self.owner = owner.username
def __repr__(self): def __repr__(self):
return 'Group {id}-{name}-{owner}'.format(id=self.id, return 'Group {id}-{name}-{owner}'.format(id=self.id,
@ -119,7 +119,7 @@ class Place(db.Model):
def __init__(self, name, owner=None): def __init__(self, name, owner=None):
self.name = name self.name = name
self.owner = owner self.owner = owner.username
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Blueprints # Blueprints

41
tests/base.py

@ -7,6 +7,8 @@ import base64
from luncho import server from luncho import server
from luncho.server import User
def _token_header(token=None): def _token_header(token=None):
"""Generate the headers required for using the token as an auth.""" """Generate the headers required for using the token as an auth."""
@ -32,9 +34,44 @@ class LunchoTests(unittest.TestCase):
self.app = server.app.test_client() self.app = server.app.test_client()
server.db.create_all() server.db.create_all()
return
def tearDown(self): def tearDown(self):
if hasattr(self, 'user'):
server.db.session.delete(self.user)
server.db.session.commit()
server.db.drop_all(bind=None) server.db.drop_all(bind=None)
return
# ------------------------------------------------------------
# Common data
# ------------------------------------------------------------
def create_user(self, name='test', fullname='Test User', passhash='hash',
verified=True, create_token=False):
"""Add a user.
:param name: The name for the user
:param fullname: The full name of the user
:param passhash: The user passhash
:return: The user
:rtype: :py:class:`server.User`"""
user = User(username=name,
fullname=fullname,
passhash=passhash)
user.verified = verified
server.db.session.add(user)
server.db.session.commit()
if create_token:
user.get_token()
return user
def default_user(self):
"""Add the default user in the database; it will be stored in 'self'
for access."""
self.user = self.create_user(create_token=True)
return
# ------------------------------------------------------------ # ------------------------------------------------------------
# Common assertions for lunch-o # Common assertions for lunch-o
@ -59,10 +96,12 @@ class LunchoTests(unittest.TestCase):
key=key, key=key,
expected=expected[key], expected=expected[key],
response=response[key])) response=response[key]))
return
def assertStatusCode(self, response, status): def assertStatusCode(self, response, status):
"""Check the status code of the response.""" """Check the status code of the response."""
self.assertEqual(response.status_code, status) self.assertEqual(response.status_code, status)
return
def assertJsonOk(self, response, **extras): def assertJsonOk(self, response, **extras):
"""Assert the the response is an OK. Extra fields can be expected """Assert the the response is an OK. Extra fields can be expected
@ -72,6 +111,7 @@ class LunchoTests(unittest.TestCase):
expected.update(extras) expected.update(extras)
self.assertStatusCode(response, 200) self.assertStatusCode(response, 200)
self.assertJson(response, expected) self.assertJson(response, expected)
return
def assertJsonError(self, response, status, message, **extras): def assertJsonError(self, response, status, message, **extras):
"""Assert that the response is an error. Extra fields returned in """Assert that the response is an error. Extra fields returned in
@ -82,6 +122,7 @@ class LunchoTests(unittest.TestCase):
self.assertStatusCode(response, status) self.assertStatusCode(response, status)
self.assertJson(response, expected) self.assertJson(response, expected)
return
# ------------------------------------------------------------ # ------------------------------------------------------------
# Easy way to convert the data to JSON and do requests # Easy way to convert the data to JSON and do requests

4
tests/group_tests.py

@ -106,7 +106,7 @@ class TestExistingGroups(LunchoTests):
# create a group for the user # create a group for the user
self.group = Group(name='Test group', self.group = Group(name='Test group',
owner=self.user.username) owner=self.user)
server.db.session.add(self.group) server.db.session.add(self.group)
server.db.session.commit() server.db.session.commit()
self.user.get_token() self.user.get_token()
@ -231,7 +231,7 @@ class TestUsersInGroup(LunchoTests):
# create a group for the user # create a group for the user
self.group = Group(name='Test group', self.group = Group(name='Test group',
owner=self.user.username) owner=self.user)
server.db.session.add(self.group) server.db.session.add(self.group)
self.user.groups.append(self.group) self.user.groups.append(self.group)

55
tests/place_tests.py

@ -8,6 +8,7 @@ from json import loads
from luncho import server from luncho import server
from luncho.server import User from luncho.server import User
from luncho.server import Place
from base import LunchoTests from base import LunchoTests
@ -17,13 +18,12 @@ class TestPlaces(LunchoTests):
def setUp(self): def setUp(self):
super(TestPlaces, self).setUp() super(TestPlaces, self).setUp()
self.user = User(username='test', self.default_user()
fullname='Test User', return
passhash='hash')
self.user.verified = True def tearDown(self):
server.db.session.add(self.user) super(TestPlaces, self).tearDown()
server.db.session.commit() return
self.user.get_token()
def test_create_place(self): def test_create_place(self):
"""Try to create a place.""" """Try to create a place."""
@ -47,5 +47,46 @@ class TestPlaces(LunchoTests):
self.assertEqual(len(json['places']), 1) # just the new place self.assertEqual(len(json['places']), 1) # just the new place
class TestExistingPlaces(LunchoTests):
"""Tests for existing places."""
def setUp(self):
super(TestExistingPlaces, self).setUp()
self.default_user()
self.place = Place(name='Place',
owner=self.user)
server.db.session.add(self.place)
server.db.session.commit()
def test_update_name(self):
"""Try to update a place."""
request = {'name': 'New name'}
placeId = self.place.id
rv = self.put('/place/{placeId}/'.format(placeId=placeId),
request,
token=self.user.token)
self.assertJsonOk(rv)
# check the database
place = Place.query.get(placeId)
self.assertEqual(place.name, request['name'])
def test_update_owner(self):
"""Update the owner of the group."""
new_user = self.create_user(name='newUser',
fullname='New User',
passhash='hash',
verified=True)
placeId = self.place.id
request = {'admin': new_user.username}
rv = self.put('/place/{placeId}/'.format(placeId=placeId),
request,
token=self.user.token)
self.assertJsonOk(rv)
# check the database
place = Place.query.get(placeId)
self.assertEqual(place.owner, 'newUser')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

Loading…
Cancel
Save