Skip to content

Commit

Permalink
Rename IdiomClass -> idiom, openapi_class -> OpenApiClass, options_cl…
Browse files Browse the repository at this point in the history
…ass -> OptionsClass.

Increase coverage
  • Loading branch information
paradoxxxzero committed Feb 25, 2019
1 parent 5de88cf commit 2592559
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 111 deletions.
2 changes: 1 addition & 1 deletion examples/flask_unrest_json_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def home():
return "A normal flask route!"


rest = UnRest(app, db.session, IdiomClass=JsonServerIdiom)
rest = UnRest(app, db.session, idiom=JsonServerIdiom)
fruit = rest(
Fruit, methods=rest.all, properties=[rest.Property('square_size', Float())]
)
Expand Down
2 changes: 1 addition & 1 deletion examples/flask_unrest_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def home():
return "A normal flask route!"


rest = UnRest(app, db.session, IdiomClass=YamlIdiom)
rest = UnRest(app, db.session, idiom=YamlIdiom)
fruit = rest(
Fruit, methods=rest.all, properties=[rest.Property('square_size', Float())]
)
Expand Down
4 changes: 0 additions & 4 deletions unrest/coercers.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,8 @@ def __init__(self, model, columns, properties, relationships):

def dict(self):
"""Serialize the given model to a JSON compatible dict"""
if self.model is None:
return {}

def enforce_iterable(it):
if it is None:
return ()
try:
return iter(it)
except TypeError:
Expand Down
4 changes: 2 additions & 2 deletions unrest/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def __init__(
primary_keys=None,
defaults=None,
fixed=None,
IdiomClass=UnRestIdiom,
idiom=UnRestIdiom,
SerializeClass=Serialize,
DeserializeClass=Deserialize,
):
Expand Down Expand Up @@ -145,7 +145,7 @@ def __init__(
self.defaults = defaults or {}
self.fixed = fixed or {}

self.idiom = IdiomClass(self)
self.idiom = idiom(self)

self.SerializeClass = SerializeClass
self.DeserializeClass = DeserializeClass
Expand Down
63 changes: 0 additions & 63 deletions unrest/tests/flask/demo.py

This file was deleted.

85 changes: 82 additions & 3 deletions unrest/tests/flask/test_unrest_init.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
from sqlalchemy.types import Float
import sys

from sqlalchemy.types import Float, String

from unrest import UnRest, __about__
from unrest.coercers import Deserialize, Serialize
from unrest.framework.flask import FlaskFramework
from unrest.rest import Rest

from . import idsorted
from ...framework import Framework
from ...idiom import Idiom
from ...util import Response
from ..model import Fruit, Tree
from .openapi_result import openapi


def test_index(app, db, http):
rest = UnRest(app, db.session)
rest(Tree)
code, json = http.get('/api/')
assert code == 200
assert (
json['html']
== (
'<h1>unrest <small>api server</small></h1> version %s '
'<a href="https://github.com/Kozea/unrest">unrest</a> '
'<a href="/api/openapi.json">openapi.json</a>'
)
% __about__.__version__
)


def test_normal(app, db, http):
rest = UnRest(app, db.session)
rest(Tree)
Expand Down Expand Up @@ -307,7 +327,7 @@ def data_to_response(self, data, method, status=200):
response = Response(payload, headers, status)
return response

rest = UnRest(app, db.session, IdiomClass=FakeIdiom)
rest = UnRest(app, db.session, idiom=FakeIdiom)
rest(Tree, methods=['GET', 'PUT'])
code, json = http.get('/api/tree')
assert code == 200
Expand All @@ -328,4 +348,63 @@ def test_wrong_framework(app, db, http):
except NotImplementedError:
pass
else:
raise Exception('Should have raised')
raise Exception('Should have raised') # pragma: no cover


def test_no_framework(app, db, http):
flask = sys.modules['flask']
sys.modules['flask'] = None
try:
UnRest(app, db.session)
except NotImplementedError:
pass
else:
raise Exception('Should have raised') # pragma: no cover
sys.modules['flask'] = flask


def test_custom_serialization(app, db, http):
class UpperCaseStringSerialize(Serialize):
def serialize(self, name, column):
rv = super().serialize(name, column)
if isinstance(column.type, String):
return rv.upper()
return rv

rest = UnRest(app, db.session, SerializeClass=UpperCaseStringSerialize)
rest(Tree, methods=['GET', 'PUT'])

code, json = http.get('/api/tree')
assert code == 200
assert json['occurences'] == 3
assert idsorted(json['objects']) == [
{'id': 1, 'name': 'PINE'},
{'id': 2, 'name': 'MAPLE'},
{'id': 3, 'name': 'OAK'},
]


def test_custom_deserialization(app, db, http):
class UpperCaseStringDeserialize(Deserialize):
def deserialize(self, name, column, payload=None):
rv = super().deserialize(name, column, payload)
if isinstance(column.type, String):
return rv.upper()
return rv

rest = UnRest(app, db.session, DeserializeClass=UpperCaseStringDeserialize)
rest(Tree, methods=['GET', 'PUT'])

code, json = http.put('/api/tree/1', json={'id': 1, 'name': 'cedar'})
assert code == 200
assert json['occurences'] == 1
assert idsorted(json['objects']) == [{'id': 1, 'name': 'CEDAR'}]

code, json = http.get('/api/tree')
assert code == 200
assert json['occurences'] == 3
assert idsorted(json['objects']) == [
{'id': 1, 'name': 'CEDAR'},
{'id': 2, 'name': 'maple'},
{'id': 3, 'name': 'oak'},
]
66 changes: 42 additions & 24 deletions unrest/tests/flask/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ def name_validator(field):
{'id': 2, 'name': 'maple'},
{'id': 3, 'name': 'oak'},
]
rest(
Tree,
methods=['GET', 'PUT'],
validators={'name': name_validator},
allow_batch=True,
)
code, json = http.put(
'/api/tree',
json={'objects': [{'id': 1, 'name': 'cdr'}, {'id': 2, 'name': 'mgo'}]},
)
assert code == 200


def test_put_pk_tree_validation(rest, http):
Expand Down Expand Up @@ -74,29 +85,8 @@ def name_validator(field):
{'id': 2, 'name': 'maple'},
{'id': 3, 'name': 'oak'},
]


def test_put_pk_tree_validation_ok(rest, http):
def name_validator(field):
if len(field.value) > 3:
raise rest.ValidationError(
'Name must be shorter than 4 characters.'
)
return field.value

rest(Tree, methods=['GET', 'PUT'], validators={'name': name_validator})
code, json = http.put('/api/tree/1', json={'id': 1, 'name': 'elm'})
assert json['occurences'] == 1
assert idsorted(json['objects']) == [{'id': 1, 'name': 'elm'}]

code, json = http.get('/api/tree')
code, json = http.put('/api/tree/1', json={'id': 1, 'name': 'cdr'})
assert code == 200
assert json['occurences'] == 3
assert idsorted(json['objects']) == [
{'id': 1, 'name': 'elm'},
{'id': 2, 'name': 'maple'},
{'id': 3, 'name': 'oak'},
]


def test_post_tree_validation(rest, http):
Expand Down Expand Up @@ -127,6 +117,9 @@ def name_validator(field):
{'id': 3, 'name': 'oak'},
]

code, json = http.post('/api/tree', json={'name': 'mgo'})
assert code == 200


def test_put_fruit_dual_validation(rest, http):
def color_validator(field):
Expand All @@ -143,7 +136,7 @@ def size_validator(field):

def age_validator(field):
if field.value < timedelta(days=100):
raise field.ValidationError('Fruit too old')
raise field.ValidationError('Fruit too young')
return field.value

def tree_id_validator(field):
Expand Down Expand Up @@ -179,12 +172,34 @@ def tree_id_validator(field):
'fields': {
'color': 'A brown fruit cannot become green',
'size': 'Fruit too big for its age',
'age': 'Fruit too old',
'age': 'Fruit too young',
'tree_id': 'Invalid tree_id',
},
}
]

rest(
Fruit,
methods=['GET', 'PUT'],
validators={
'color': color_validator,
'size': size_validator,
'age': age_validator,
'tree_id': tree_id_validator,
},
)
code, json = http.put(
'/api/fruit/2',
json={
'fruit_id': 2,
'color': 'green',
'size': 50.2,
'age': 12_000_000,
'tree_id': 3,
},
)
assert code == 200


def test_validation_error_code(rest, http):
def name_validator(field):
Expand Down Expand Up @@ -217,3 +232,6 @@ def name_validator(field):
{'id': 2, 'name': 'maple'},
{'id': 3, 'name': 'oak'},
]

code, json = http.put('/api/tree/1', json={'id': 1, 'name': 'cdr'})
assert code == 200
3 changes: 0 additions & 3 deletions unrest/tests/tornado/test_tornado.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json as jsonlib
import os
from tempfile import NamedTemporaryFile

from sqlalchemy.engine import create_engine
Expand Down Expand Up @@ -29,8 +28,6 @@ def get(self):
Session.configure(bind=engine)
session = scoped_session(Session)

if os.path.exists(db_url):
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
fill_data(session)
app._engine = engine
Expand Down

0 comments on commit 2592559

Please sign in to comment.