Handle mandatory attributes

Change-Id: I68019e8e7d4b0c7a4fae8f97dcc7475c9e519cdb
Fixes-Bug: #1227004
Fixes-Bug: #1227038
This commit is contained in:
Julien Danjou 2013-09-17 19:10:23 +02:00
parent 15c05263c3
commit 2af9917e6b
3 changed files with 62 additions and 3 deletions

View File

@ -12,7 +12,7 @@ from simplegeneric import generic
from wsme.types import Unset from wsme.types import Unset
import wsme.types import wsme.types
import wsme.utils import wsme.utils
from wsme.exc import UnknownArgument from wsme.exc import UnknownArgument, InvalidInput
try: try:
@ -137,6 +137,9 @@ def fromjson(datatype, value):
if attrdef.name in value: if attrdef.name in value:
setattr(obj, attrdef.key, setattr(obj, attrdef.key,
fromjson(attrdef.datatype, value[attrdef.name])) fromjson(attrdef.datatype, value[attrdef.name]))
elif attrdef.mandatory:
raise InvalidInput(attrdef.name, None,
"Mandatory field missing.")
return obj return obj
elif wsme.types.isusertype(datatype): elif wsme.types.isusertype(datatype):
value = datatype.frombasetype( value = datatype.frombasetype(

View File

@ -9,7 +9,7 @@ import xml.etree.ElementTree as et
from simplegeneric import generic from simplegeneric import generic
import wsme.types import wsme.types
from wsme.exc import UnknownArgument from wsme.exc import UnknownArgument, InvalidInput
import re import re
@ -98,10 +98,13 @@ def fromxml(datatype, element):
return datatype.frombasetype(fromxml(datatype.basetype, element)) return datatype.frombasetype(fromxml(datatype.basetype, element))
if wsme.types.iscomplex(datatype): if wsme.types.iscomplex(datatype):
obj = datatype() obj = datatype()
for attrdef in datatype._wsme_attributes: for attrdef in wsme.types.list_attributes(datatype):
sub = element.find(attrdef.name) sub = element.find(attrdef.name)
if sub is not None: if sub is not None:
setattr(obj, attrdef.key, fromxml(attrdef.datatype, sub)) setattr(obj, attrdef.key, fromxml(attrdef.datatype, sub))
elif attrdef.mandatory:
raise InvalidInput(attrdef.name, None,
"Mandatory field missing.")
return obj return obj
if datatype is wsme.types.bytes: if datatype is wsme.types.bytes:
return element.text.encode('ascii') return element.text.encode('ascii')

View File

@ -222,6 +222,59 @@ class TestController(unittest.TestCase):
self.assertEquals(res.body, b('"hellohello"')) self.assertEquals(res.body, b('"hellohello"'))
def test_wsattr_mandatory(self):
class ComplexType(object):
attr = wsme.types.wsattr(int, mandatory=True)
class MyRoot(WSRoot):
@expose(int, body=ComplexType)
@validate(ComplexType)
def clx(self, a):
return a.attr
r = MyRoot(['restjson'])
app = webtest.TestApp(r.wsgiapp())
res = app.post_json('/clx', params={}, expect_errors=True,
headers={'Accept': 'application/json'})
self.assertEqual(res.status_int, 400)
def test_wsproperty_mandatory(self):
class ComplexType(object):
def foo(self):
pass
attr = wsme.types.wsproperty(int, foo, foo, mandatory=True)
class MyRoot(WSRoot):
@expose(int, body=ComplexType)
@validate(ComplexType)
def clx(self, a):
return a.attr
r = MyRoot(['restjson'])
app = webtest.TestApp(r.wsgiapp())
res = app.post_json('/clx', params={}, expect_errors=True,
headers={'Accept': 'application/json'})
self.assertEqual(res.status_int, 400)
def test_validate_enum_mandatory(self):
class Version(object):
number = wsme.types.wsattr(wsme.types.Enum(str, 'v1', 'v2'),
mandatory=True)
class MyWS(WSRoot):
@expose(str)
@validate(Version)
def setcplx(self, version):
pass
r = MyWS(['restjson'])
app = webtest.TestApp(r.wsgiapp())
res = app.post_json('/setcplx', params={'version': {}},
expect_errors=True,
headers={'Accept': 'application/json'})
self.assertEqual(res.status_int, 400)
class TestFunctionDefinition(unittest.TestCase): class TestFunctionDefinition(unittest.TestCase):