def test_yaml_idiom_no_yaml(client): sys.modules['yaml'] = None rest = UnRest( client.app, client.session, idiom=YamlIdiom, framework=client.__framework__, ) with raises(ImportError): rest(Tree, methods=['GET', 'PUT'], allow_batch=True) del sys.modules['yaml']
def test_idiom_alter_query(client): class FakeIdiom(UnRestIdiom): def alter_query(client, request, query): if request.query.get('limit'): query = query.limit(request.query['limit'][0]) return query rest = UnRest( client.app, client.session, idiom=FakeIdiom, framework=client.__framework__, ) tree = rest(Tree, methods=['GET', 'PUT']) assert tree.query.count() == 3 code, json = client.fetch('/api/tree?limit=1') assert code == 200 assert idsorted(json['objects']) == [{'id': 1, 'name': 'pine'}] code, json = client.fetch('/api/tree?limit=2') assert code == 200 assert idsorted(json['objects']) == [ { 'id': 1, 'name': 'pine' }, { 'id': 2, 'name': 'maple' }, ] code, json = client.fetch('/api/tree') assert code == 200 assert idsorted(json['objects']) == [ { 'id': 1, 'name': 'pine' }, { 'id': 2, 'name': 'maple' }, { 'id': 3, 'name': 'oak' }, ] assert tree.query.count() == 3
def test_idiom_partial_implementation(client): class FakeIdiom(Idiom): def request_to_payload(client, request): pass rest = UnRest( client.app, client.session, idiom=FakeIdiom, framework=client.__framework__, ) rest(Tree, methods=['GET', 'PUT']) code, html = client.fetch('/api/tree') assert code == 500
def test_json_server_bad_json(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Tree, methods=['GET', 'POST']) code, json = client.fetch('/api/tree', method="POST", body="{'name'; 'cedar'}") assert code == 400 assert (json['message'] == 'JSON Error in payload: ' 'Expecting property name enclosed in double quotes: ' 'line 1 column 2 (char 1)')
def test_yaml_idiom_empty_get_pk_as_404(client): rest = UnRest( client.app, client.session, idiom=YamlIdiom, framework=client.__framework__, empty_get_as_404=True, ) rest(Tree) code, yaml = client.fetch('/api/tree/6') assert code == 404 assert (yaml == '''\ objects: [] occurences: 0 primary_keys: - id ''')
def test_wrong_method(client): rest = UnRest(client.app, client.session, framework=client.__framework__) rest(Tree, methods=['GET', 'POST']) code, html = client.fetch( '/api/tree', method="PUT", json={ 'objects': [{ 'id': 1, 'name': 'cedar' }, { 'id': 2, 'name': 'mango' }] }, ) assert code == 405
def test_json_server_filter_fruits_ne(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Fruit) code, json = client.fetch('/api/fruit?age_ne=1970-01-01%2000:40:00.000000') assert code == 200 assert idsorted(json, 'fruit_id') == [ { 'fruit_id': 1, 'color': 'grey', 'size': 12.0, 'double_size': 24.0, 'age': 1_041_300.0, 'tree_id': 1, }, { 'fruit_id': 2, 'color': 'darkgrey', 'size': 23.0, 'double_size': 46.0, 'age': 4_233_830.213, 'tree_id': 1, }, { 'fruit_id': 3, 'color': 'brown', 'size': 2.12, 'double_size': 4.24, 'age': 0.0, 'tree_id': 1, }, { 'fruit_id': 5, 'color': 'orangered', 'size': 100.0, 'double_size': 200.0, 'age': 7200.000_012, 'tree_id': None, }, ]
def test_yaml_idiom_put(client): rest = UnRest( client.app, client.session, idiom=YamlIdiom, framework=client.__framework__, ) rest(Tree, methods=['GET', 'PUT'], allow_batch=True) code, yaml = client.fetch( '/api/tree', method="PUT", body='''\ objects: - id: 1 name: cedar - id: 2 name: mango ''', ) assert (yaml == '''\ objects: - id: 1 name: cedar - id: 2 name: mango occurences: 2 primary_keys: - id ''') code, yaml = client.fetch('/api/tree') assert code == 200 assert (yaml == '''\ objects: - id: 1 name: cedar - id: 2 name: mango occurences: 2 primary_keys: - id ''')
def test_endpoint_options_no_methods_but_declare(client): rest = UnRest(client.app, client.session, framework=client.__framework__) tree = rest(Tree, methods=[]) @tree.declare('GET') def get(payload, id=None): return {'Hey': 'Overridden'} @tree.declare('POST') def post(payload, id=None): return {'Hey': 'Overridden'} code, json = client.fetch('/api/tree', method="GET") assert code == 200 code, json = client.fetch('/api/tree', method="POST", json={}) assert code == 200 code, json = client.fetch('/api/tree', method="OPTIONS") assert code == 200
def test_json_server_put_trees(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Tree, methods=['GET', 'PUT'], allow_batch=True) code, json = client.fetch( '/api/tree', method="PUT", json=[{ 'id': 1, 'name': 'cedar' }, { 'id': 2, 'name': 'mango' }], ) assert code == 200 assert idsorted(json) == [ { 'id': 1, 'name': 'cedar' }, { 'id': 2, 'name': 'mango' }, ] code, json = client.fetch('/api/tree') assert code == 200 assert idsorted(json) == [ { 'id': 1, 'name': 'cedar' }, { 'id': 2, 'name': 'mango' }, ]
def test_custom_deserialization(client): class UpperCaseStringDeserialize(Deserialize): def deserialize(client, name, column, payload=None): rv = super().deserialize(name, column, payload) if isinstance(column.type, String): return rv.upper() return rv rest = UnRest( client.app, client.session, DeserializeClass=UpperCaseStringDeserialize, framework=client.__framework__, ) rest(Tree, methods=['GET', 'PUT']) code, json = client.fetch('/api/tree/1', method="PUT", json={ 'id': 1, 'name': 'cedar' }) assert code == 200 assert json['occurences'] == 1 assert idsorted(json['objects']) == [{'id': 1, 'name': 'CEDAR'}] code, json = client.fetch('/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' }, ]
def test_alternative_rest_class(client): class NewRest(Rest): def __init__(client, *args, **kwargs): kwargs['name'] = 'new_' + kwargs['name'] super().__init__(*args, **kwargs) new_rest = UnRest( client.app, client.session, framework=client.__framework__, RestClass=NewRest, ) new_tree = new_rest(Tree, name='tree') assert isinstance(new_tree, NewRest) code, json = client.fetch('/api/tree') assert code == 404 code, json = client.fetch('/api/new_tree') assert code == 200 assert json['occurences'] == 3
def test_json_server_slice(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Fruit, only=['color']) code, json = client.fetch('/api/fruit?_start=1&_end=3') assert code == 200 assert json == [ { 'fruit_id': 2, 'color': 'darkgrey' }, { 'fruit_id': 3, 'color': 'brown' }, ]
def test_json_server_paginate(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Fruit, only=['color']) code, json = client.fetch('/api/fruit?_page=2&_limit=2') assert code == 200 print(json) assert json == [ { 'fruit_id': 3, 'color': 'brown' }, { 'fruit_id': 4, 'color': 'red' }, ]
def test_json_server_sort_multiple(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Tree, methods=['GET', 'POST']) client.fetch('/api/tree', method="POST", json={'name': 'pine'}) client.fetch('/api/tree', method="POST", json={'name': 'oak'}) client.fetch('/api/tree', method="POST", json={'name': 'oak'}) code, json = client.fetch('/api/tree?_sort=name,id&_order=asc,desc') assert code == 200 assert json == [ { 'id': 2, 'name': 'maple' }, { 'id': 6, 'name': 'oak' }, { 'id': 5, 'name': 'oak' }, { 'id': 3, 'name': 'oak' }, { 'id': 4, 'name': 'pine' }, { 'id': 1, 'name': 'pine' }, ]
def test_json_server_filter_fruits(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Fruit) code, json = client.fetch('/api/fruit?color=red') assert code == 200 assert idsorted(json, 'fruit_id') == [{ 'fruit_id': 4, 'color': 'red', 'size': 0.5, 'double_size': 1.0, 'age': 2400.0, 'tree_id': 2, }] code, json = client.fetch('/api/fruit?color=red&color=brown') assert code == 200 assert idsorted(json, 'fruit_id') == [ { 'fruit_id': 3, 'color': 'brown', 'size': 2.12, 'double_size': 4.24, 'age': 0.0, 'tree_id': 1, }, { 'fruit_id': 4, 'color': 'red', 'size': 0.5, 'double_size': 1.0, 'age': 2400.0, 'tree_id': 2, }, ]
def test_yaml_idiom_put_bad_formed(client): rest = UnRest( client.app, client.session, idiom=YamlIdiom, framework=client.__framework__, ) rest(Tree, methods=['GET', 'PUT'], allow_batch=True) code, yaml = client.fetch( '/api/tree', method="PUT", body='''\ objects: ][ ''', ) assert code == 400 assert ( yaml == '''message: "YAML Error in payload: while parsing a block node\ \\nexpected the node content,\\\n \\ but found \']\'\\n in \ \\"<unicode string>\\", line 1, column 10:\\n objects: ][\\n\\\n \ \\ ^" ''')
def test_yaml_idiom_get(client): rest = UnRest( client.app, client.session, idiom=YamlIdiom, framework=client.__framework__, ) rest(Tree) code, yaml = client.fetch('/api/tree') assert code == 200 assert (yaml == '''\ objects: - id: 1 name: pine - id: 2 name: maple - id: 3 name: oak occurences: 3 primary_keys: - id ''')
def test_json_server_get_tree_with_relationship_with_multi_pk(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) fruit = rest(Fruit, methods=[], primary_keys=['color', 'age']) rest(Tree, relationships={'fruits': fruit}) code, json = client.fetch('/api/tree') assert code == 200 assert idsorted(json) == [ { 'id': 1, 'name': 'pine', 'fruits': [ 'grey___1041300.0', 'darkgrey___4233830.213', 'brown___0.0', ], }, { 'id': 2, 'name': 'maple', 'fruits': ['red___2400.0'] }, { 'id': 3, 'name': 'oak', 'fruits': [] }, ] code, json = client.fetch('/api/fruit') assert code == 404
def test_json_server_sort_desc(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Tree) code, json = client.fetch('/api/tree?_sort=name&_order=desc') assert code == 200 assert json == [ { 'id': 1, 'name': 'pine' }, { 'id': 3, 'name': 'oak' }, { 'id': 2, 'name': 'maple' }, ]
def test_json_server_filter_fruits_gte(client): rest = UnRest( client.app, client.session, idiom=JsonServerIdiom, framework=client.__framework__, ) rest(Fruit) code, json = client.fetch('/api/fruit?color_gte=forestgreen') assert code == 200 assert idsorted(json, 'fruit_id') == [ { 'fruit_id': 1, 'color': 'grey', 'size': 12.0, 'double_size': 24.0, 'age': 1_041_300.0, 'tree_id': 1, }, { 'fruit_id': 4, 'color': 'red', 'size': 0.5, 'double_size': 1.0, 'age': 2400.0, 'tree_id': 2, }, { 'fruit_id': 5, 'color': 'orangered', 'size': 100.0, 'double_size': 200.0, 'age': 7200.000_012, 'tree_id': None, }, ]
def test_normal(client): rest = UnRest(client.app, client.session, framework=client.__framework__) rest(Tree) code, json = client.fetch('/api/tree') assert code == 200 assert json['occurences'] == 3
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{sqlite_db}' app.debug = True db = SQLAlchemy(app) if not os.path.exists(sqlite_db): Base.metadata.create_all(bind=db.engine) fill_data(db.session) db.session.remove() @app.route("/") def home(): return "A normal flask route!" rest = UnRest(app, db.session, idiom=JsonServerIdiom) fruit = rest(Fruit, methods=rest.all, properties=[rest.Property('square_size', Float())]) rest( Tree, methods=rest.all, relationships={'fruits': fruit}, properties=['fruit_colors'], allow_batch=True, ) app.run()
def test_auto_framework(client): if 'Flask' not in client.__framework__.__name__: return rest = UnRest(client.app, client.session) assert isinstance(rest.framework, FlaskFramework)
def test_wrong_url(client): rest = UnRest(client.app, client.session, framework=client.__framework__) rest(Tree) code, html = client.fetch('/apy/trea') assert code == 404
def test_duplicate_rest(client): rest = UnRest(client.app, client.session, framework=client.__framework__) rest(Tree) with raises(Exception): rest(Tree)
def test_normal_rest_class(client): rest = UnRest(client.app, client.session, framework=client.__framework__) tree = rest(Tree, name='tree') assert isinstance(tree, Rest)
from unrest import UnRest from .. import app, db from ..model import Color, Shape rest = UnRest(app, db.session) color = rest(Color, methods=['GET', 'POST', 'PUT', 'DELETE']) shape = rest(Shape, methods=['GET', 'POST', 'PUT', 'DELETE'])
if not os.path.exists(sqlite_db): Base.metadata.create_all(bind=engine) fill_data(session) session.remove() @app.route("/") async def home(request): return response.text("A normal sanic route!") @app.middleware('response') async def after_request(request, response): session.remove() rest = UnRest(app, session, framework=SanicFramework) fruit = rest( Fruit, methods=rest.all, properties=[rest.Property('square_size', Float())] ) rest( Tree, methods=rest.all, relationships={'fruits': fruit}, properties=['fruit_colors'], allow_batch=True, ) app.run()
def test_wrong_framework(client): with raises(NotImplementedError): UnRest(client.app, client.session, framework=Framework)