示例#1
0
class SQLAlchemySequenceTestCase(BaseTestCase):
    def setUp(self):
        super(SQLAlchemySequenceTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app)
        self.sa = SQLAlchemy(self.app, session_options={"autoflush": False})

    def test_sequence_primary_key(self):
        sa = self.sa

        user_id_seq = sa.Sequence('user_id_seq')

        class User(sa.Model):
            id = sa.Column(sa.Integer, user_id_seq, primary_key=True)
            username = sa.Column(sa.String, unique=True)

        sa.create_all()

        class UserResource(ModelResource):
            class Schema:
                username = fields.String()

            class Meta:
                model = User
                include_id = True

        self.api.add_resource(UserResource)

        response = self.client.post('/user', data={"username": "******"})
        self.assert200(response)

        self.assertJSONEqual({"$id": 1, "username": "******"}, response.json)
示例#2
0
    def test_api_register_resource(self):
        class BookResource(ModelResource):
            class Meta:
                name = "book"
                model = "book"
                manager = MemoryManager

        api = Api(self.app)
        api.add_resource(BookResource)

        response = self.client.get("/schema")

        self.assertEqual(
            {
                "$schema": "http://json-schema.org/draft-04/hyper-schema#",
                "properties": {
                    "book": {
                        "$ref": "/book/schema#"
                    }
                },
            },
            response.json,
        )

        response = self.client.get("/book/schema")
        self.assert200(response)
class SQLAlchemyInspectionTestCase(BaseTestCase):
    def setUp(self):
        super(SQLAlchemyInspectionTestCase, self).setUp()
        self.app.config["SQLALCHEMY_ENGINE"] = "sqlite://"
        self.api = Api(self.app)
        self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False})

    def test_inspection_auto_id_attribute_type(self):
        sa = self.sa

        class User(sa.Model):
            username = sa.Column(sa.String, primary_key=True)
            first_name = sa.Column(sa.String)
            last_name = sa.Column(sa.String)

        sa.create_all()

        class UserResource(ModelResource):
            class Schema:
                username = fields.String()

            class Meta:
                model = User
                include_id = True

        self.api.add_resource(UserResource)
        self.assertEqual(User.username, UserResource.manager.id_column)
        self.assertEqual("username", UserResource.manager.id_field.attribute)
        self.assertIsInstance(UserResource.manager.id_field, fields.String)

        response = self.client.post("/user", data={"username": "******", "first_name": "Foo"})
        self.assert200(response)

        self.assertJSONEqual({"$id": "foo", "first_name": "Foo", "last_name": None, "username": "******"}, response.json)
示例#4
0
    def test_api_blueprint(self):
        api_bp = Blueprint("potion_blueprint", __name__.split(".")[0])
        api = Api(api_bp)
        api.add_resource(self.SampleResource)

        # Register Blueprint
        self.app.register_blueprint(api_bp)
        response = self.client.get("/samples")
示例#5
0
    def test_api_blueprint(self):
        api_bp = Blueprint("potion_blueprint", __name__.split(".")[0])
        api = Api(api_bp)
        api.add_resource(self.SampleResource)

        # Register Blueprint
        self.app.register_blueprint(api_bp)
        self.client.get("/samples")
示例#6
0
class ErrorMessagesTestCase(BaseTestCase):
    def setUp(self):
        super(ErrorMessagesTestCase, self).setUp()
        self.api = Api(self.app, prefix='/prefix')

        class ErrorResource(Resource):
            @Route.GET
            def forbidden(self):
                raise Forbidden()

            @Route.GET
            def python_exception(self):
                raise ValueError()

            @Route.GET
            def duplicate_key(self):
                raise DuplicateKey()

            class Meta:
                name = 'error'

        self.api.add_resource(ErrorResource)

    def test_werkzeug_exception(self):
        response = self.client.get('/prefix/error/forbidden')
        self.assert403(response)
        self.assertEqual({
            "message": "You don't have the permission to access the requested resource. "
                       "It is either read-protected or not readable by the server.",
            "status": 403
        }, response.json)

    def test_potion_exception(self):
        response = self.client.get('/prefix/error/duplicate-key')
        self.assertStatus(response, 409)
        self.assertEqual({
            "message": "Conflict",
            "status": 409
        }, response.json)

    def test_not_found_exception(self):
        response = self.client.get('/prefix/error/missing')
        self.assert404(response)
        self.assertEqual({
            "message": "The requested URL was not found on the server.  If you entered "
                        "the URL manually please check your spelling and try again.",
            "status": 404
        }, response.json)

    def test_exception_outside_api(self):
        response = self.client.get('/missing')
        self.assert404(response)

    @unittest.SkipTest
    def test_python_exception(self):
        response = self.client.get('/prefix/error/python-exception')
        self.assert500(response)
        self.assertEqual({}, response.json)
示例#7
0
    def test_api_blueprint_w_prefix(self):
        api_bp = Blueprint("potion_blueprint", __name__.split(".")[0])
        api = Api(api_bp, prefix="/api/v1")
        api.add_resource(self.SampleResource)

        # Register Blueprint
        self.app.register_blueprint(api_bp)
        response = self.client.get("/api/v1/samples")
        self.assert200(response)

        response = self.client.get("/api/v1/samples/schema")
        self.assertEqual('^\\/api\\/v1\\/samples\\/[^/]+$', response.json['properties']['$uri']['pattern'])
示例#8
0
def init_app(app):
    """
    Configuring the Flask app's extensions
    """
    # initialize Flask extensions
    app.db = init_db(app)

    # setup Flask-Potion routes
    v1_api = Api(app)
    v1_api.add_resource(BetaResource)
    v1_api.add_resource(AlphaResource)

    return app
示例#9
0
    def test_route_decorator(self):

        def unauthorize(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                raise Unauthorized()
            return wrapper

        def denormalize(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                return 'not ' + fn(*args, **kwargs)
            return wrapper

        class FooResource(Resource):

            @Route.GET
            def no_decorator(self):
                return 'normal'

            @Route.GET
            def simple_decorator(self):
                return 'normal'

            @Route.GET
            def unauthorize_decorator(self):
                return 'normal'

            class Meta:
                name = 'foo'
                title = 'Foo bar'
                route_decorators = {
                    'readSimpleDecorator': denormalize,
                    'readUnauthorizeDecorator': unauthorize
                }

        self.assertEqual('normal', FooResource().no_decorator())
        self.assertEqual('normal', FooResource().simple_decorator())
        self.assertEqual('normal', FooResource().unauthorize_decorator())

        api = Api(self.app)
        api.add_resource(FooResource)

        response = self.client.get("/foo/no-decorator")
        self.assertEqual('normal', response.json)

        response = self.client.get("/foo/simple-decorator")
        self.assertEqual('not normal', response.json)

        response = self.client.get("/foo/unauthorize-decorator")
        self.assert401(response)
示例#10
0
    def test_route_decorator(self):
        def unauthorize(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                raise Unauthorized()

            return wrapper

        def denormalize(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                return 'not ' + fn(*args, **kwargs)

            return wrapper

        class FooResource(Resource):
            @Route.GET
            def no_decorator(self):
                return 'normal'

            @Route.GET
            def simple_decorator(self):
                return 'normal'

            @Route.GET
            def unauthorize_decorator(self):
                return 'normal'

            class Meta:
                name = 'foo'
                title = 'Foo bar'
                route_decorators = {
                    'readSimpleDecorator': denormalize,
                    'readUnauthorizeDecorator': unauthorize,
                }

        self.assertEqual('normal', FooResource().no_decorator())
        self.assertEqual('normal', FooResource().simple_decorator())
        self.assertEqual('normal', FooResource().unauthorize_decorator())

        api = Api(self.app)
        api.add_resource(FooResource)

        response = self.client.get("/foo/no-decorator")
        self.assertEqual('normal', response.json)

        response = self.client.get("/foo/simple-decorator")
        self.assertEqual('not normal', response.json)

        response = self.client.get("/foo/unauthorize-decorator")
        self.assert401(response)
示例#11
0
    def test_api_prefix(self):
        api = Api(self.app, prefix='/api/v1')

        class BookResource(ModelResource):
            class Meta:
                name = "book"
                model = "book"
                manager = MemoryManager

            @Route.GET
            def genres(self):
                return ['fiction', 'non-fiction']

            @ItemRoute.GET
            def rating(self):
                return 4.5

        api.add_resource(BookResource)

        response = self.client.get("/schema")
        self.assert404(response)

        response = self.client.get("/api/v1/schema")

        self.assertEqual(
            {
                "$schema": "http://json-schema.org/draft-04/hyper-schema#",
                "properties": {
                    "book": {
                        "$ref": "/api/v1/book/schema#"
                    }
                },
            },
            response.json,
        )

        response = self.client.get("/api/v1/book/schema")
        self.assert200(response)
        self.assertEqual(
            {
                "/api/v1/book",
                "/api/v1/book/schema",
                "/api/v1/book/genres",
                "/api/v1/book/{id}",
                "/api/v1/book/{id}/rating",
            },
            {link_['href']
             for link_ in response.json['links']},
        )
示例#12
0
    def test_route_success_code(self):
        class FooResource(Resource):
            @Route.GET(success_code=201)
            def foo(self):
                return 'foo'

            class Meta:
                name = 'foo'

        api = Api(self.app)
        api.add_resource(FooResource)

        response = self.client.get("/foo/foo")
        self.assertEqual(201, response.status_code)
        self.assertEqual('foo', response.json)
def initialize_app(flask_app):
    configure_app(flask_app)

    api = Api(app)

    blueprint = Blueprint('api', __name__, url_prefix='/api')
    api.init_app(blueprint)
    flask_app.register_blueprint(blueprint)

    api.add_resource(CampaignResource)
    api.add_resource(Resource)

    # Swagger(app)

    db.init_app(flask_app)
示例#14
0
    def test_api_blueprint_w_prefix(self):
        api_bp = Blueprint("potion_blueprint", __name__.split(".")[0])
        api = Api(api_bp, prefix="/api/v1")
        api.add_resource(self.SampleResource)

        # Register Blueprint
        self.app.register_blueprint(api_bp)
        response = self.client.get("/api/v1/samples")
        self.assert200(response)

        response = self.client.get("/api/v1/samples/schema")
        self.assertEqual(
            '^\\/api\\/v1\\/samples\\/[^/]+$',
            response.json['properties']['$uri']['pattern'],
        )
示例#15
0
class SQLAlchemyInspectionTestCase(BaseTestCase):
    def setUp(self):
        super(SQLAlchemyInspectionTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app)
        self.sa = SQLAlchemy(self.app, session_options={"autoflush": False})

    def test_inspection_auto_id_attribute_type(self):
        sa = self.sa

        class User(sa.Model):
            username = sa.Column(sa.String, primary_key=True)
            first_name = sa.Column(sa.String)
            last_name = sa.Column(sa.String)

        sa.create_all()

        class UserResource(ModelResource):
            class Schema:
                username = fields.String()

            class Meta:
                model = User
                include_id = True

        self.api.add_resource(UserResource)
        self.assertEqual(User.username, UserResource.manager.id_column)
        self.assertEqual('username', UserResource.manager.id_field.attribute)
        self.assertIsInstance(UserResource.manager.id_field, fields.String)

        response = self.client.post('/user',
                                    data={
                                        "username": "******",
                                        "first_name": "Foo"
                                    })
        self.assert200(response)

        self.assertJSONEqual(
            {
                "$id": "foo",
                "first_name": "Foo",
                "last_name": None,
                "username": "******"
            },
            response.json,
        )
示例#16
0
def run():
    """ Main entry point """
    app = Flask(__name__, static_path='')
    app.config['DATABASE'] = 'sqlite://'
    # pylint: disable=no-member
    if not Position.table_exists():
        Position.create_table()

    if not Search.table_exists():
        Search.create_table()
    app.config["POTION_DEFAULT_PER_PAGE"] = 10000000
    app.config["POTION_MAX_PER_PAGE"] = 10000000

    api = Api(app, default_manager=PeeweeManager)
    api.add_resource(PositionResource)
    api.add_resource(SearchResource)
    app.run(debug=True,
            host="127.0.0.1",
            port=int(CONFIG['main'].get("port", 8000)))
示例#17
0
class ResourceTestCase(BaseTestCase):
    def setUp(self):
        super(ResourceTestCase, self).setUp()
        self.api = Api(self.app)

    def test_resource(self):
        class FooResource(Resource):
            class Schema:
                name = fields.String()

            class Meta:
                name = 'foo'

        self.api.add_resource(FooResource)

        #self.assertEqual(['create', 'update', 'schema'], list(FooResource.routes.()))

        data, code, headers = FooResource().described_by()
        self.assertEqual({"name": {"type": "string"}}, data["properties"])
示例#18
0
class ResourceTestCase(BaseTestCase):
    def setUp(self):
        super(ResourceTestCase, self).setUp()
        self.api = Api(self.app)

    def test_resource(self):
        class FooResource(Resource):
            class Schema:
                name = fields.String()

            class Meta:
                name = "foo"

        self.api.add_resource(FooResource)

        # self.assertEqual(['create', 'update', 'schema'], list(FooResource.routes.()))

        data, code, headers = FooResource().described_by()
        self.assertEqual({"name": {"type": "string"}}, data["properties"])
示例#19
0
    def test_schema_decoration(self):
        def is_teapot(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                return '', 418, {}
            return wrapper

        api = Api(self.app, decorators=[is_teapot])

        class FooResource(Resource):
            class Meta:
                name = 'foo'

        api.add_resource(FooResource)

        response = self.client.get("/schema")
        self.assertEqual(response.status_code, 418)

        response = self.client.get("/foo/schema")
        self.assertEqual(response.status_code, 418)
示例#20
0
    def test_schema_decoration(self):
        def is_teapot(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                return '', 418, {}

            return wrapper

        api = Api(self.app, decorators=[is_teapot])

        class FooResource(Resource):
            class Meta:
                name = 'foo'

        api.add_resource(FooResource)

        response = self.client.get("/schema")
        self.assertEqual(response.status_code, 418)

        response = self.client.get("/foo/schema")
        self.assertEqual(response.status_code, 418)
示例#21
0
    def test_api_register_resource(self):
        class BookResource(ModelResource):
            class Meta:
                name = "book"
                model = "book"
                manager = MemoryManager

        api = Api(self.app)
        api.add_resource(BookResource)

        response = self.client.get("/schema")

        self.assertEqual({
                             "$schema": "http://json-schema.org/draft-04/hyper-schema#",
                             "properties": {
                                 "book": {"$ref": "/book/schema#"}
                             }
                         }, response.json)

        response = self.client.get("/book/schema")
        self.assert200(response)
示例#22
0
    def test_api_prefix(self):
        api = Api(self.app, prefix='/api/v1')

        class BookResource(ModelResource):
            class Meta:
                name = "book"
                model = "book"
                manager = MemoryManager

            @Route.GET
            def genres(self):
                return ['fiction', 'non-fiction']

            @ItemRoute.GET
            def rating(self):
                return 4.5

        api.add_resource(BookResource)

        response = self.client.get("/schema")
        self.assert404(response)

        response = self.client.get("/api/v1/schema")

        self.assertEqual({
                             "$schema": "http://json-schema.org/draft-04/hyper-schema#",
                             "properties": {
                                 "book": {"$ref": "/api/v1/book/schema#"}
                             }
                         }, response.json)

        response = self.client.get("/api/v1/book/schema")
        self.assert200(response)
        self.assertEqual({
                    "/api/v1/book",
                    "/api/v1/book/schema",
                    "/api/v1/book/genres",
                    "/api/v1/book/{id}",
                    "/api/v1/book/{id}/rating"
                 }, {l['href'] for l in response.json['links']})
示例#23
0
    def test_schema_decoration_disable(self):
        def is_teapot(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                return '', 418, {}

            return wrapper

        self.app.config['POTION_DECORATE_SCHEMA_ENDPOINTS'] = False
        api = Api(self.app, decorators=[is_teapot])

        class FooResource(Resource):
            class Meta:
                name = 'foo'

        api.add_resource(FooResource)

        response = self.client.get("/schema")
        self.assert200(response)

        response = self.client.get("/foo/schema")
        self.assert200(response)
示例#24
0
    def test_schema_decoration_disable(self):
        def is_teapot(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                return '', 418, {}

            return wrapper

        self.app.config['POTION_DECORATE_SCHEMA_ENDPOINTS'] = False
        api = Api(self.app, decorators=[is_teapot])

        class FooResource(Resource):
            class Meta:
                name = 'foo'

        api.add_resource(FooResource)

        response = self.client.get("/schema")
        self.assert200(response)

        response = self.client.get("/foo/schema")
        self.assert200(response)
class SQLAlchemySequenceTestCase(BaseTestCase):

    def setUp(self):
        super(SQLAlchemySequenceTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app)
        self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False})

    def test_sequence_primary_key(self):
        sa = self.sa

        user_id_seq = sa.Sequence('user_id_seq')

        class User(sa.Model):
            id = sa.Column(sa.Integer, user_id_seq, primary_key=True)
            username = sa.Column(sa.String, unique=True)

        sa.create_all()

        class UserResource(ModelResource):
            class Schema:
                username = fields.String()

            class Meta:
                model = User
                include_id = True

        self.api.add_resource(UserResource)

        response = self.client.post('/user', data={"username": "******"})
        self.assert200(response)

        self.assertJSONEqual({
            "$id": 1,
            "username": "******"
        }, response.json)
示例#26
0
    class Schema:
        article = fields.ToOne('article')
        author = fields.ToOne('user')

    class Meta:
        model = Comment
        read_only_fields = ['author']
        permissions = {
            'create': 'anybody',
            'update': 'user:author',
            'delete': ['update:article', 'admin']
        }


for resource in (UserResource, ArticleResource, CommentResource):
    api.add_resource(resource)


@signals.before_create.connect_via(ANY)
def before_create_article_comment(sender, item):
    if issubclass(sender, (ArticleResource, CommentResource)):
        item.author_id = current_user.id

db.create_all()

if __name__ == '__main__':
    # Add some example users
    db.session.add(User(username='******', is_editor=True))
    db.session.add(User(username='******', is_editor=True))
    db.session.add(User(username='******', is_admin=True))
    db.session.add(User(username='******'))
示例#27
0
class FilterTestCase(BaseTestCase):
    def setUp(self):
        super(FilterTestCase, self).setUp()
        app = self.app
        app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        app.config['TESTING'] = True

        self.api = Api(self.app)
        self.sa = sa = SQLAlchemy(app)

        class User(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            first_name = sa.Column(sa.String(60), nullable=False)
            last_name = sa.Column(sa.String(60), nullable=False)

            gender = sa.Column(sa.String(1))

            age = sa.Column(sa.Integer)

            is_staff = sa.Column(sa.Boolean, default=None)

        class Thing(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)

            name = sa.Column(sa.String(60), nullable=False)

            belongs_to_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
            belongs_to = sa.relationship(User, backref=backref('things', lazy='dynamic'))

            date_time = sa.Column(sa.DateTime)
            date = sa.Column(sa.Date)

        sa.create_all()


        class UserResource(ModelResource):
            class Schema:
                gender = fields.String(enum=['f', 'm'], nullable=True)

            class Meta:
                model = User
                include_id = True

        class ThingResource(ModelResource):
            class Schema:
                belongs_to = fields.ToOne('user', nullable=True)

            class Meta:
                model = Thing
                filters = {
                    '$uri': {
                        None: filters.EqualFilter,
                        'eq': filters.EqualFilter,
                        'ne': filters.NotEqualFilter,
                        'in': filters.InFilter
                    },
                    '*': True
                }

        class AllowUserResource(ModelResource):
            class Meta:
                model = User
                name = 'allow-user'
                filters = {
                    'first_name': ['eq'],
                    'is_staff': True
                }

        class UseToManyResource(ModelResource):
            class Schema:
                things = fields.ToMany('thing')

            class Meta:
                name = 'user-to-many'
                model = User

        self.api.add_resource(UserResource)
        self.api.add_resource(ThingResource)
        self.api.add_resource(UseToManyResource)
        self.api.add_resource(AllowUserResource)

    def post_sample_set_a(self):
        for user in [
            {'first_name': 'John', 'last_name': 'Doe', 'age': 32, 'is_staff': True, 'gender': 'm'},
            {'first_name': 'Jonnie', 'last_name': 'Doe', 'age': 25, 'is_staff': False, 'gender': 'm'},
            {'first_name': 'Jane', 'last_name': 'Roe', 'age': 18, 'is_staff': False, 'gender': 'f'},
            {'first_name': 'Joe', 'last_name': 'Bloggs', 'age': 21, 'is_staff': True, 'gender': 'm'},
            {'first_name': 'Sue', 'last_name': 'Watts', 'age': 25, 'is_staff': True}
        ]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

    def test_equality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": "Doe"}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                ], response.json, without=['$uri', '$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": 25}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe', 'age': 25},
                                    {'first_name': 'Sue', 'last_name': 'Watts', 'age': 25},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'is_staff'])

        response = self.client.get('/user?where={"last_name": "Doe", "age": 25}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_inequality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$ne": "Watts"}, "age": {"$ne": 32}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gt": 25}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gte": 25}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lte": 21}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": 21.0}}')
        self.assert400(response)

        response = self.client.get('/user?where={"age": {"$lt": null}}')
        self.assert400(response)

        response = self.client.get('/user?where={"first_name": {"$gt": "Jo"}}')
        self.assert400(response)

    def test_in(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$in": ["Bloggs", "Watts"]}}')

        self.assertEqualWithout([
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"last_name": {"$in": []}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_startswith(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$startswith": "Jo"}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"first_name": {"$startswith": "J%e"}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_istartswith(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$istartswith": "jo"}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_iendswith(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$iendswith": "Oe"}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_contains(self):
        self.post_sample_set_a()

        response = self.client.get('/user')
        user_ids = [user['$id'] for user in response.json]

        for thing in [
            {'name': 'A', 'belongs_to': user_ids[0]},
            {'name': 'B', 'belongs_to': user_ids[2]},
            {'name': 'C', 'belongs_to': user_ids[1]},
            {'name': 'D', 'belongs_to': user_ids[4]},
            {'name': 'E', 'belongs_to': user_ids[3]},
            {'name': 'F', 'belongs_to': None}
        ]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        response = self.client.get('/user-to-many?where={"things": {"$contains": {"$ref": "/thing/1"}}}')

        self.assertEqualWithout([
                                    {
                                        "things": [{"$ref": "/thing/1"}],
                                        "first_name": "John",
                                        "last_name": "Doe"
                                    }
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_text_search(self):
        self.post_sample_set_a()

        response = self.client.get('/user?search=sbc+dedf&rank=1')

    def test_sort(self):
        self.post_sample_set_a()

        response = self.client.get('/user?sort={"last_name": true, "first_name": false}')

        self.assert200(response)
        self.assertEqualWithout([
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json,
                                without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?sort={"age": false, "first_name": false}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                ], response.json,
                                without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_sort_relationship(self):
        self.post_sample_set_a()

        response = self.client.get('/user')
        user_ids = [user['$id'] for user in response.json]

        for thing in [
            {'name': 'A', 'belongs_to': user_ids[0]},
            {'name': 'B', 'belongs_to': user_ids[2]},
            {'name': 'C', 'belongs_to': user_ids[1]},
            {'name': 'D', 'belongs_to': user_ids[4]},
            {'name': 'E', 'belongs_to': user_ids[3]},
            {'name': 'F', 'belongs_to': None}
        ]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        thinggetter = lambda thing: thing['belongs_to']['$ref'] if thing['belongs_to'] else ''

        response = self.client.get('/thing?sort={"belongs_to": false}')
        self.assertEqual(sorted(response.json, key=thinggetter), response.json)

        response = self.client.get('/thing?sort={"belongs_to": true}')
        self.assertEqual(list(reversed(sorted(response.json, key=thinggetter))), response.json)


        response = self.client.get('/thing?sort={"name": false, "belongs_to": false}')
        self.assertEqual(sorted(response.json, key=lambda thing: thing['name']), response.json)

    def test_sort_relationship_none(self):
        for thing in [
            {'name': 'A', 'belongs_to': None},
            {'name': 'B', 'belongs_to': None},
            {'name': 'C', 'belongs_to': None}
        ]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        response = self.client.get('/thing?sort={"belongs_to": false}')
        self.assertEqual(3, len(response.json))


    def test_filter_and_sort_uri(self):
        for thing in [
            {"name": "A thing"},
            {"name": "B thing"}
        ]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        response1 = self.client.get('/thing?where={"$uri": "/thing/1"}')
        response2 = self.client.get('/thing?where={"$uri": {"$eq": "/thing/1"}}')
        response3 = self.client.get('/thing?where={"$uri": {"$ne": "/thing/2"}}')
        response4 = self.client.get('/thing?where={"$uri": {"$in": ["/thing/1"]}}')

        for response in [response1, response2, response3, response4]:
            self.assert200(response1)
            self.assertEqualWithout([{'$uri': u'/thing/1', 'name': 'A thing'}], response.json,
                                    without=['date', 'date_time', 'belongs_to'])

        response_multi = self.client.get('/thing?where={"$uri": {"$in": ["/thing/1", "/thing/2"]}}')
        self.assert200(response_multi)
        self.assertEqualWithout([{'$uri': '/thing/1', 'name': 'A thing'},
                                 {'$uri': '/thing/2', 'name': 'B thing'}],
                                response_multi.json, without=['date', 'date_time', 'belongs_to'])

        response_sort = self.client.get('/thing?sort={"$uri": false}')
        self.assert200(response_sort)
        self.assertEqualWithout([{'$uri': '/thing/1', 'name': 'A thing'},
                                 {'$uri': '/thing/2', 'name': 'B thing'}],
                                response_sort.json, without=['date', 'date_time', 'belongs_to'])

    def test_sort_filter_date(self):
        for thing in [
            {'name': 'A', 'date_time': {'$date': 1446561100000}},
            {'name': 'B', 'date_time': {'$date': 1000000000000}},
            {'name': 'C', 'date_time': {'$date': 1446561110000}},
            {'name': 'D', 'date_time': {'$date': 1446561120000}},
            {'name': 'E', 'date_time': {'$date': 1446561130000}}
        ]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        response = self.client.get('/thing?sort={"date_time": false}')
        self.assertEqual(sorted(response.json, key=lambda thing: thing['date_time']['$date']), response.json)

        response = self.client.get('/thing?where={"date_time": {"$eq": {"$date": 1000000000000}}}')

        self.assertEqualWithout([
            {'name': 'B', 'date_time': {'$date': 1000000000000}},
        ], response.json,
            without=['$uri', 'date', 'belongs_to'])

        response = self.client.get('/thing?where={"date_time": {"$gt": {"$date": 1000000000000}}}')
        self.assertEqualWithout([
            {'name': 'A', 'date_time': {'$date': 1446561100000}},
            {'name': 'C', 'date_time': {'$date': 1446561110000}},
            {'name': 'D', 'date_time': {'$date': 1446561120000}},
            {'name': 'E', 'date_time': {'$date': 1446561130000}}
        ], response.json,
            without=['$uri', 'date', 'belongs_to'])

        response = self.client.get('/thing?where={"date_time": {"$lt": {"$date": 1000000000000}}}')
        self.assertEqualWithout([], response.json, without=['$uri', 'date', 'belongs_to'])

        response = self.client.get('/thing?where={"date_time": {"$between": [{"$date": 1446561110000}, {"$date": 1446561120000}]}}')
        self.assertEqualWithout([
            {'name': 'C', 'date_time': {'$date': 1446561110000}},
            {'name': 'D', 'date_time': {'$date': 1446561120000}},
        ], response.json, without=['$uri', 'date', 'belongs_to'])

    def test_sort_and_where(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$startswith": "Jo"}}&sort={"first_name": false}')

        self.assertEqualWithout([
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_inherited_filters(self):
        self.assertEqual({
            'string': {
                'eq': filters.EqualFilter,
            },
            'email': {
                None: filters.EqualFilter,
                'eq': filters.EqualFilter,
                'ne': filters.NotEqualFilter,
                'in': filters.InFilter,
                'contains': filters.StringContainsFilter,
                'icontains': filters.StringIContainsFilter,
                'endswith': filters.EndsWithFilter,
                'iendswith': filters.IEndsWithFilter,
                'startswith': filters.StartsWithFilter,
                'istartswith': filters.IStartsWithFilter,
            },
            'uri': {
                'eq': filters.EqualFilter,
                'ne': filters.NotEqualFilter,
                'endswith': filters.EndsWithFilter
            },
            'date_string': {
                None: filters.EqualFilter,
                'eq': filters.EqualFilter,
                'ne': filters.NotEqualFilter,
                'in': filters.InFilter,
                'lt': filters.LessThanFilter,
                'lte': filters.LessThanEqualFilter,
                'gt': filters.GreaterThanFilter,
                'gte': filters.GreaterThanEqualFilter,
                'between': filters.DateBetweenFilter,
            }
        }, filters_for_fields({
            'string': fields.String(),

            # inherit from String
            'email': fields.Email(),
            'uri': fields.Uri(),

            # no filter defined for Raw
            'raw': fields.Raw({}),

            # inherits from String, but there is a filter for DateString
            'date_string': fields.DateString()
        },
            filter_names=FILTER_NAMES,
            filters_by_type=FILTERS_BY_TYPE,
            filters_expression={
                'string': ['eq'],
                'email': True,
                'uri': ['eq', 'ne', 'endswith'],
                '*': True
            }))

    @unittest.SkipTest
    def test_sort_pages(self):
        pass

    @unittest.SkipTest
    def test_disallowed_where_filters(self):
        pass

    @unittest.SkipTest
    def test_schema(self):
        pass
示例#28
0
    def test_multiple_blueprints(self):
        # Create Blueprints
        api_bp1 = Blueprint("potion1", __name__.split(".")[0])
        api_bp2 = Blueprint("potion2", __name__.split(".")[0], url_prefix="/api")

        # Create Api objects, add resources, and register blueprints with app
        api1 = Api(api_bp1, prefix="/api/v1")
        api2 = Api(api_bp2, prefix="/v2")
        api1.add_resource(self.SampleResource)

        with self.assertRaises(RuntimeError):
            api2.add_resource(self.SampleResource)

        api2.add_resource(self.SampleResource2)
        self.app.register_blueprint(api_bp1)
        self.app.register_blueprint(api_bp2)

        # Test both endpoints
        response = self.client.get("/api/v1/samples")
        self.assert200(response)

        response = self.client.get("/api/v2/samples")
        self.assert200(response)

        response = self.client.get("/api/v1/schema")
        self.assert200(response)
        self.assertEqual(
            '/api/v1/samples/schema#', response.json['properties']['samples']['$ref']
        )

        response = self.client.get("/api/v2/schema")
        self.assert200(response)
        self.assertEqual(
            '/api/v2/samples/schema#', response.json['properties']['samples']['$ref']
        )

        response = self.client.get("/api/v1/samples/schema")
        self.assertEqual(
            '^\\/api\\/v1\\/samples\\/[^/]+$',
            response.json['properties']['$uri']['pattern'],
        )

        response = self.client.get("/api/v2/samples/schema")
        self.assertEqual(
            '^\\/api\\/v2\\/samples\\/[^/]+$',
            response.json['properties']['$uri']['pattern'],
        )

        # Test that we have two prefix'd schemas
        response = self.client.get("/api/v1/schema")
        self.assert200(response)
        v1_schema = json.loads(response.data)
        response = self.client.get("/api/v2/schema")
        self.assert200(response)
        v2_schema = json.loads(response.data)
        assert v1_schema != v2_schema
        assert v1_schema["properties"]["samples"] != v2_schema["properties"]["samples"]

        # Test that endpoints are linked to same resource
        response = self.client.post('/api/v1/samples', data={"name": "to_v1"})
        self.assert200(response)
        response = self.client.post('/api/v2/samples', data={"name": "to_v2"})
        self.assert200(response)
        response = self.client.get("/api/v1/samples/1")
        assert response.json['$uri'] == "/api/v1/samples/1"
        self.assert200(response)
        response = self.client.get("/api/v2/samples/1")
        assert response.json['$uri'] == "/api/v2/samples/1"
        self.assert200(response)
class PrincipalTestCase(BaseTestCase):
    def create_app(self):
        app = super(PrincipalTestCase, self).create_app()
        app.test_client_class = AuthorizedApiClient

        self.principal = Principal(app)
        self.sa = sa = SQLAlchemy(app)

        class User(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String())

        class BookStore(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String())

            owner_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
            owner = sa.relationship(User, backref=backref('stores', lazy='dynamic'))

        class Book(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            title = sa.Column(sa.String(), nullable=False)

            author_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
            author = sa.relationship(User, backref=backref('books', lazy='dynamic'))

        class BookSigning(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            book_id = sa.Column(sa.Integer, sa.ForeignKey(Book.id), nullable=False)
            store_id = sa.Column(sa.Integer, sa.ForeignKey(BookStore.id), nullable=False)

            book = sa.relationship(Book)
            store = sa.relationship(BookStore)

        sa.create_all()

        for model in (BookStore, User, Book, BookSigning):
            setattr(self, model.__tablename__.upper(), model)

        return app

    def setUp(self):
        super(PrincipalTestCase, self).setUp()
        self.mock_user = None

        @identity_loaded.connect_via(self.app)
        def on_identity_loaded(sender, identity):
            identity.provides.add(UserNeed(identity.id))

            for role in self.mock_user.get('roles', []):
                identity.provides.add(RoleNeed(role))

            for need in self.mock_user.get('needs', []):
                identity.provides.add(need)

        def authenticate(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                auth = request.authorization

                if not auth:
                    raise Unauthorized()

                if auth.password == 'password':
                    identity_changed.send(current_app._get_current_object(), identity=Identity(self.mock_user['id']))
                else:
                    raise Unauthorized()
                return fn(*args, **kwargs)

            return wrapper

        self.api = Api(self.app, decorators=[authenticate])

    def test_role(self):
        with self.assertRaises(RuntimeError):
            manager = principals(MemoryManager)

    def test_role(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'create': 'author'
                }

        self.api.add_resource(BookResource)

        response = self.client.post('/book', data={'title': 'Foo'}, auth=False)
        self.assert401(response)

        self.mock_user = {'id': 1}
        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert403(response)

        self.mock_user = {'id': 1, 'roles': ['author']}
        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert200(response)
        self.assertEqual({'title': 'Foo', '$uri': '/book/1'}, response.json)

        self.assert200(self.client.patch('/book/1', data={'title': 'Foo I'}))

        self.mock_user = {'id': 1}
        self.assert403(self.client.patch('/book/1', data={'title': 'Bar'}))

        self.assert403(self.client.delete('/book/1'))

        # self.user = {'id': 1, 'roles': ['author']}
        # self.assert200(self.client.delete('/book/1'))

        # response = self.client.post('/book', data={'title': 'Foo'})
        #
        # self.assert200(response)

    def test_access_forbidden_to_resource_collection(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': 'author',
                    'create': 'author',
                }

        self.api.add_resource(BookResource)
        self.mock_user = {'id': 1, 'roles': ['author']}
        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert200(response)
        self.assertEqual({'title': 'Foo', '$uri': '/book/1'}, response.json)
        self.assert200(self.client.get('/book'))
        self.mock_user = {'id': 1}
        self.assert403(self.client.get('/book'))

    def test_inherit_role_to_one_field(self):

        class BookStoreResource(PrincipalResource):
            class Meta:
                model = self.BOOK_STORE
                permissions = {
                    'create': 'admin',
                    'update': ['admin']
                }

        class BookSigningResource(PrincipalResource):
            class Schema:
                book = fields.ToOne('book')
                store = fields.ToOne('book_store')

            class Meta:
                model = self.BOOK_SIGNING
                permissions = {
                    'create': 'update:store'
                }

        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'create': 'yes'
                }

        self.api.add_resource(BookStoreResource)
        self.api.add_resource(BookSigningResource)
        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.assert200(self.client.post('/book_store', data={
            'name': 'Foo Books'
        }))

        self.assert200(self.client.post('/book', data={
            'title': 'Bar'
        }))

        self.mock_user = {'id': 2}

        response = self.client.post('/book_signing', data={
            'book': {'$ref': '/book/1'},
            'store': {'$ref': '/book_store/1'}
        })
        self.assert403(response)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.assert200(self.client.post('/book_signing', data={
            'book': {'$ref': '/book/1'},
            'store': {'$ref': '/book_store/1'}
        }))

    def test_user_need(self):

        class BookStoreResource(PrincipalResource):
            class Schema:
                owner = fields.ToOne('user')

            class Meta:
                model = self.BOOK_STORE
                permissions = {
                    'create': 'admin',
                    'update': ['admin', 'user:owner']
                }

        class UserResource(PrincipalResource):
            class Meta:
                model = self.USER
                permissions = {
                    'create': 'admin'
                }

        self.api.add_resource(BookStoreResource)
        self.api.add_resource(UserResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        self.assert200(self.client.post('/user', data={'name': 'Admin'}))

        for i, store in enumerate([
            {
                'name': 'Books & More',
                'owner': {
                    'name': 'Mr. Moore'
                }
            },
            {
                'name': 'Foo Books',
                'owner': {
                    'name': 'Foo'
                }
            }
        ]):
            response = self.client.post('/user', data=store['owner'])

            owner = {'$ref': response.json['$uri']}
            response = self.client.post('/book_store', data={
                'name': store['name'],
                'owner': owner
            })

            self.assertEqual({'$uri': '/book_store/{}'.format(i + 1), 'name': store['name'], 'owner': owner},
                             response.json)

        response = self.client.patch('/book_store/1', data={'name': 'books & moore'})
        self.assert200(response)

        self.mock_user = {'id': 3}
        response = self.client.patch('/book_store/1', data={'name': 'Books & Foore'})
        self.assert403(response)

        self.mock_user = {'id': 2}
        response = self.client.patch('/book_store/1', data={'name': 'Books & Moore'})

        self.assert200(response)

        self.assertEqual({
            '$uri': '/book_store/1',
            'name': 'Books & Moore',
            'owner': {'$ref': '/user/2'}
        }, response.json)

        response = self.client.patch('/book_store/2', data={'name': 'Moore Books'})
        self.assert403(response)

    def test_item_need_update(self):

        class BookStoreResource(PrincipalResource):
            class Meta:
                model = self.BOOK_STORE
                permissions = {
                    'create': 'admin',
                    'update': 'update'
                }

        self.api.add_resource(BookStoreResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        # response = self.client.post('/book_store', data=[
        # {'name': 'Bar Books'},
        #     {'name': 'Foomazon'}
        # ])
        response = self.client.post('/book_store', data={'name': 'Bar Books'})
        self.assert200(response)
        response = self.client.post('/book_store', data={'name': 'Foomazon'})
        self.assert200(response)

        self.mock_user = {'id': 1, 'needs': [ItemNeed('update', 2, 'book_store')]}

        self.assert403(self.client.patch('/book_store/1', data={'name': 'Foo'}))

        response = self.client.patch('/book_store/2', data={'name': 'Foo'})
        self.assert200(response)
        self.assertEqual({'$uri': '/book_store/2', 'name': 'Foo'}, response.json)

        # TODO DELETE

    def test_yes_no(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': 'yes',
                    'create': 'admin',
                    'update': 'no'
                }

        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.assert200(self.client.post('/book', data={'title': 'Foo'}))
        self.assert403(self.client.patch('/book/1', data={'title': 'Bar'}))
        self.assert200(self.client.get('/book/1'))
        self.assert200(self.client.get('/book'))

    def test_item_need_read(self):

        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': ['owns-copy', 'admin'],
                    'create': 'admin',
                    'owns-copy': 'owns-copy'
                }

        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        # TODO Bulk inserts
        # response = self.client.post('/book', data=[
        # {'title': 'GoT Vol. {}'.format(i + 1)} for i in range(20)
        # ])

        for i in range(20):
            self.client.post('/book', data={'title': 'GoT Vol. {}'.format(i + 1)})

        self.assertEqual(20, len(self.client.get('/book').json))

        self.mock_user = {'id': 2, 'needs': [ItemNeed('owns-copy', i, 'book') for i in (1, 4, 6, 8, 11, 15, 19)]}
        self.assertEqual(7, len(self.client.get('/book').json))

        self.mock_user = {'id': 3, 'needs': [ItemNeed('owns-copy', i, 'book') for i in (2, 7, 19)]}

        self.assertEqual([
            {'$uri': '/book/2', 'title': 'GoT Vol. 2'},
            {'$uri': '/book/7', 'title': 'GoT Vol. 7'},
            {'$uri': '/book/19', 'title': 'GoT Vol. 19'}
        ], self.client.get('/book').json)

        self.assert404(self.client.get('/book/15'))
        self.assert200(self.client.get('/book/2'))
        self.assert200(self.client.get('/book/7'))
        self.assert404(self.client.get('/book/1'))
        self.assert404(self.client.get('/book/99'))

        self.mock_user = {'id': 4}
        self.assertEqual([], self.client.get('/book').json)

    def test_relationship(self):
        "should require update permission on parent resource for updating, read permissions on both"

        class BookResource(PrincipalResource):
            class Schema:
                author = fields.ToOne('user', nullable=True)

            class Meta:
                model = self.BOOK
                permissions = {
                    'read': ['owns-copy', 'update', 'admin'],
                    'create': 'writer',
                    'update': 'user:author',
                    'owns-copy': 'owns-copy'
                }

        class UserResource(PrincipalResource):
            books = Relation(BookResource)

            class Meta:
                model = self.USER
                permissions = {
                    'create': 'admin'
                }

        self.api.add_resource(UserResource)
        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        for user in [
            {'name': 'Admin'},
            {'name': 'Author 1'},
            {'name': 'Author 2'}
        ]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

        response = self.client.post('/book', data={
            'title': 'Foo'
        })
        self.assert403(response)

        self.mock_user = {'id': 2, 'roles': ['writer']}
        response = self.client.post('/book', data={
            'author': {'$ref': '/user/2'},
            'title': 'Bar'
        })

        self.assert200(response)

        self.mock_user = {'id': 3, 'roles': ['writer']}

        response = self.client.post('/book', data={'title': 'Spying: Novel'})
        self.assert200(response)

        response = self.client.post('/book', data={'title': 'Spied: The Sequel'})
        self.assert200(response)

        response = self.client.post('/book', data={'title': 'Spy: The Prequel'})
        self.assert200(response)
        self.assertJSONEqual({'$uri': '/book/4', 'author': None, 'title': 'Spy: The Prequel'}, response.json)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.client.post('/user/3/books', data={'$ref': '/book/2'})
        self.client.post('/user/3/books', data={'$ref': '/book/3'})
        self.client.post('/user/3/books', data={'$ref': '/book/4'})

        self.mock_user = {'id': 3, 'roles': ['writer']}
        self.assert200(response)

        response = self.client.get('/user/3/books')
        self.assert200(response)
        self.assertEqual(3, len(response.json))  # read -> update -> user:author

        self.mock_user = {'id': 4, 'needs': [ItemNeed('owns-copy', 3, 'book')]}

        response = self.client.get('/user/3/books')
        self.assertEqual(1, len(response.json))  # read -> owns-copy

        self.assert200(self.client.get('/book/3'))
        self.assert404(self.client.get('/book/2'))

        self.mock_user = {'id': 5}
        response = self.client.get('/user/3/books')
        self.assertEqual(0, len(response.json))
        self.assert404(self.client.get('/book/2'))

    @unittest.SkipTest
    def test_item_route(self):
        "should require read permission on parent resource plus any additional permissions"
        pass

    def test_permission_circular(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': 'create',
                    'create': 'read',
                    'update': 'create',
                    'delete': 'update'
                }

        self.api.add_resource(BookResource)

        with self.assertRaises(RuntimeError):
            BookResource.manager._needs
示例#30
0
            'create': super_admin_only,
            'update': super_admin_only,
            'delete': 'no',
        }

    class Schema:
        id = fields.String(min_length=3, max_length=3)


@signals.before_create.connect_via(GatewayResource)
@signals.before_create.connect_via(UserResource)
@signals.before_create.connect_via(VoucherResource)
@signals.before_create.connect_via(CategoryResource)
@signals.before_create.connect_via(ProductResource)
def set_scope(sender, item):
    if current_user.has_role('network-admin') or current_user.has_role(
            'gateway-admin'):
        item.network_id = current_user.network_id

    if current_user.has_role('gateway-admin'):
        item.gateway_id = current_user.gateway_id


api.add_resource(UserResource)
api.add_resource(VoucherResource)
api.add_resource(GatewayResource)
api.add_resource(NetworkResource)
api.add_resource(CategoryResource)
api.add_resource(ProductResource)
api.add_resource(CurrencyResource)
class SQLAlchemyTestCase(BaseTestCase):
    def setUp(self):
        super(SQLAlchemyTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app, default_manager=SQLAlchemyManager)
        self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False})

        class Type(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False, unique=True)
            version = sa.Column(sa.Integer(), nullable=True)

        class Machine(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False)

            wattage = sa.Column(sa.Float)

            type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id))
            type = sa.relationship(Type, backref=backref('machines', lazy='dynamic', uselist=True))

        sa.create_all()

        class MachineResource(ModelResource):
            class Meta:
                model = Machine
                include_id = True
                include_type = True

            class Schema:
                type = fields.ToOne('type')

        class TypeResource(ModelResource):
            class Meta:
                model = Type
                include_id = True
                include_type = True

            class Schema:
                machines = fields.ToMany('machine')

        self.MachineResource = MachineResource
        self.TypeResource = TypeResource

        self.api.add_resource(MachineResource)
        self.api.add_resource(TypeResource)

    def tearDown(self):
        self.sa.drop_all()

    def test_field_discovery(self):
        self.assertEqual(set(self.MachineResource.schema.fields.keys()), {'$id', '$type', 'name', 'type', 'wattage'})
        self.assertEqual(set(self.TypeResource.schema.fields.keys()), {'$id', '$type', 'name', 'version', 'machines'})
        self.assertEqual(self.MachineResource.meta.name, 'machine')
        self.assertEqual(self.TypeResource.meta.name, 'type')

    def test_create_no_json(self):
        response = self.client.post('/machine', data='invalid')
        self.assert400(response)

    def test_create_json_string(self):
        response = self.client.post('/machine', data='invalid', force_json=True)
        self.assert400(response)

    def test_conflict(self):
        response = self.client.post('/type', data={"name": "foo"})
        self.assert200(response)

        response = self.client.post('/type', data={"name": "foo"})
        self.assertStatus(response, 409)

    def test_create(self):
        response = self.client.post('/type', data={})
        self.assert400(response)
        self.assertEqual({
            "errors": [
                {
                    "message": "'name' is a required property",
                    "path": [],
                    "validationOf": {
                        "required": [
                            "name"
                        ]
                    }
                }
            ],
            "message": "Bad Request",
            "status": 400
        }, response.json)

        response = self.client.post('/type', data={"name": "x-ray"})
        self.assertJSONEqual({'$id': 1, '$type': 'type', 'machines': [], "name": "x-ray", 'version': None}, response.json)

        response = self.client.post('/machine', data={"name": "Irradiator I", "type": 1})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'machine', 'type': {"$ref": "/type/1"}, "wattage": None, "name": "Irradiator I"}, response.json)

        response = self.client.post('/machine', data={"name": "Sol IV", "type": 1, "wattage": 1.23e45})
        self.assert200(response)
        self.assertJSONEqual({'$id': 2, '$type': 'machine', 'type': {"$ref": "/type/1"}, "wattage":  1.23e45, "name": "Sol IV"}, response.json)

        response = self.client.get('/type/1')
        self.assert200(response)
        self.assertJSONEqual({
                                 '$id': 1,
                                 '$type': 'type',
                                 'machines': [
                                     {'$ref': '/machine/1'},
                                     {'$ref': '/machine/2'}
                                 ],
                                 "name": "x-ray",
                                 'version': None
                             }, response.json)

    def test_get(self):
        type_ = lambda i: {"$id": i, "$type": "type", "name": "Type-{}".format(i), "machines": [], 'version': None}

        for i in range(1, 10):
            response = self.client.post('/type', data={"name": "Type-{}".format(i), "machines": []})
            self.assert200(response)
            self.assertJSONEqual(type_(i), response.json)

            response = self.client.get('/type/{}'.format(i))
            self.assert200(response)
            self.assertJSONEqual(type_(i), response.json)

            response = self.client.get('/type')
            self.assert200(response)
            self.assertJSONEqual([type_(i) for i in range(1, i + 1)], response.json)

            response = self.client.get('/type/{}'.format(i + 1))
            self.assert404(response)
            self.assertJSONEqual({
                                     'item': {'$id': i + 1, '$type': 'type'},
                                     'message': 'Not Found',
                                     'status': 404
                                 }, response.json)

    @unittest.SkipTest
    def test_pagination(self):
        pass # TODO

    def test_update(self):
        response = self.client.post('/type', data={"name": "T1"})
        self.assert200(response)

        response = self.client.post('/type', data={"name": "T2"})
        self.assert200(response)

        response = self.client.post('/machine', data={"name": "Robot", "type": 1})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'machine', 'type': {"$ref": "/type/1"}, "wattage": None, "name": "Robot"}, response.json)

        response = self.client.patch('/machine/1', data={})
        self.assert200(response)

        response = self.client.patch('/machine/1', data={"wattage": 10000})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'machine', 'type': {"$ref": "/type/1"}, "wattage": 10000, "name": "Robot"}, response.json)

        response = self.client.patch('/machine/1', data={"type": {"$ref": "/type/2"}})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'machine', 'type': {"$ref": "/type/2"}, "wattage": 10000, "name": "Robot"}, response.json)

        response = self.client.patch('/type/1', data={"version": 1})
        self.assertJSONEqual({'$id': 1, '$type': 'type', 'name': 'T1', 'version': 1, 'machines': []}, response.json)

        response = self.client.patch('/type/1', data={"version": None})
        self.assertJSONEqual({'$id': 1, '$type': 'type', 'name': 'T1', 'machines': [], 'version': None}, response.json)

        response = self.client.patch('/machine/1', data={"type": None})
        self.assert400(response)
        self.assertJSONEqual({
                                 'errors': [
                                     {
                                         "message": "None is not valid under any of the given schemas",
                                         "path": [
                                             "type"
                                         ],
                                         "validationOf": {
                                             "anyOf": [
                                                 {
                                                     "additionalProperties": False,
                                                     "properties": {
                                                         "$ref": {
                                                             "pattern": "^\\/type\\/[^/]+$",
                                                             "type": "string"
                                                         }
                                                     },
                                                     "type": "object"
                                                 },
                                                 {
                                                     "type": "integer"
                                                 }
                                             ]
                                         }
                                     }
                                 ],
                                 'message': 'Bad Request',
                                 'status': 400
                             }, response.json)

        response = self.client.patch('/machine/1', data={"name": "Foo"})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'machine', 'type': {"$ref": "/type/2"}, "wattage": 10000, "name": "Foo"}, response.json)

    def test_delete(self):
        response = self.client.delete('/type/1')
        self.assert404(response)

        response = self.client.post('/type', data={"name": "Foo", "machines": []})
        self.assert200(response)

        response = self.client.delete('/type/1')
        self.assertStatus(response, 204)

        response = self.client.delete('/type/1')
        self.assert404(response)
示例#32
0
class FieldsTestCase(BaseTestCase):
    def setUp(self):
        super(FieldsTestCase, self).setUp()
        app = self.app
        app.config['MONGODB_DB'] = 'potion-test-db'
        app.config['TESTING'] = True

        self.api = Api(self.app, default_manager=MongoEngineManager)
        self.me = MongoEngine(app)

    def test_object_id_field(self):
        class Model(self.me.Document):
            meta = {'collection': 'model'}

            an_id = ObjectIdField()

        class Resource(ModelResource):
            class Meta:
                model = Model

        self.api.add_resource(Resource)

        response = self.client.get('/model/schema')
        self.assertEqual(response.json['properties']['an_id'],
                         {'type': 'string'})
        self.assertRaises(InvalidId,
                          self.client.post,
                          '/model',
                          data={'an_id': "abc"})

        hex = 'adfb48a6763c5741b92f6ade'
        object_id = ObjectId('adfb48a6763c5741b92f6ade')
        response = self.client.post('/model', data={'an_id': hex})
        self.assertEqual(object_id, ObjectId(response.json['an_id']))

    def test_map_field(self):
        class ReferenceModel(EmbeddedDocument):
            id = ObjectIdField()
            meta = {'collection': 'reference-model'}

        class Model(self.me.Document):
            meta = {'collection': 'model'}

            float_mapping = MapField(FloatField())
            string_mapping = MapField(StringField())
            object_id_mapping = MapField(ObjectIdField())
            reference_mapping = MapField(EmbeddedDocumentField(ReferenceModel))

        class Resource(ModelResource):
            class Meta:
                model = Model

        self.api.add_resource(Resource)

        response = self.client.get('/model/schema')
        self.assertEqual(
            response.json['properties']['float_mapping']
            ['additionalProperties'], {'type': 'number'})
        self.assertEqual(
            response.json['properties']['float_mapping']['default'], {})
        self.assertEqual(
            response.json['properties']['string_mapping']
            ['additionalProperties'], {'type': 'string'})
        self.assertEqual(
            response.json['properties']['string_mapping']['default'], {})
        self.assertEqual(
            response.json['properties']['reference_mapping']
            ['additionalProperties'], {
                'additionalProperties': False,
                'type': 'object',
                'properties': {
                    'id': {
                        'type': 'string'
                    }
                }
            })
        self.assertEqual(
            response.json['properties']['reference_mapping']['default'], {})
        ref_model = dict(id='adfb48a6763c5741b92f6ade')
        response = self.client.post("/model",
                                    data={
                                        'reference_mapping': {
                                            "1": ref_model
                                        },
                                        'object_id_mapping': {
                                            "a": ref_model["id"]
                                        }
                                    })
        self.assertEqualWithout(response.json, {
            'reference_mapping': {
                '1': {
                    'id': 'adfb48a6763c5741b92f6ade'
                }
            },
            '$uri': '/model/561e6a807f551ce7d5df1003',
            'float_mapping': {},
            'object_id_mapping': {
                'a': 'adfb48a6763c5741b92f6ade'
            },
            'string_mapping': {}
        },
                                without=["$uri"])

    def tearDown(self):
        self.me.connection.drop_database('potion-test-db')
示例#33
0
        # database from being destroyed after each request.
        pass


app = Flask(__name__)
app.debug = True
app.config['DATABASE'] = 'sqlite://'

db = DB(app)


class Book(db.Model):
    title = CharField(null=True, unique=True)
    year_published = IntegerField()


class BookResource(ModelResource):
    class Meta:
        name = 'book'
        model = Book

    class Schema:
        year_published = fields.Integer(minimum=1400)


api = Api(app, default_manager=PeeweeManager)
api.add_resource(BookResource)

if __name__ == '__main__':
    app.run()
示例#34
0
class FilterTestCase(BaseTestCase):
    def setUp(self):
        super(FilterTestCase, self).setUp()
        app = self.app
        app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        app.config['TESTING'] = True

        self.api = Api(self.app)
        self.sa = sa = SQLAlchemy(app)

        class User(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            first_name = sa.Column(sa.String(60), nullable=False)
            last_name = sa.Column(sa.String(60), nullable=False)

            gender = sa.Column(sa.String(1))

            age = sa.Column(sa.Integer)

            is_staff = sa.Column(sa.Boolean, default=None)

        class Thing(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)

            name = sa.Column(sa.String(60), nullable=False)

            belongs_to_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
            belongs_to = sa.relationship(User,
                                         backref=backref('things',
                                                         lazy='dynamic'))

            date_time = sa.Column(sa.DateTime)
            date = sa.Column(sa.Date)

        sa.create_all()

        class UserResource(ModelResource):
            class Schema:
                gender = fields.String(enum=['f', 'm'], nullable=True)

            class Meta:
                model = User
                include_id = True

        class ThingResource(ModelResource):
            class Schema:
                belongs_to = fields.ToOne('user', nullable=True)

            class Meta:
                model = Thing

        class AllowUserResource(ModelResource):
            class Meta:
                model = User
                name = 'allow-user'
                filters = {'first_name': ['eq'], 'is_staff': True}

        class UseToManyResource(ModelResource):
            class Schema:
                things = fields.ToMany('thing')

            class Meta:
                name = 'user-to-many'
                model = User

        self.api.add_resource(UserResource)
        self.api.add_resource(ThingResource)
        self.api.add_resource(UseToManyResource)
        self.api.add_resource(AllowUserResource)

    def post_sample_set_a(self):
        for user in [{
                'first_name': 'John',
                'last_name': 'Doe',
                'age': 32,
                'is_staff': True,
                'gender': 'm'
        }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe',
                'age': 25,
                'is_staff': False,
                'gender': 'm'
        }, {
                'first_name': 'Jane',
                'last_name': 'Roe',
                'age': 18,
                'is_staff': False,
                'gender': 'f'
        }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs',
                'age': 21,
                'is_staff': True,
                'gender': 'm'
        }, {
                'first_name': 'Sue',
                'last_name': 'Watts',
                'age': 25,
                'is_staff': True
        }]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

    def test_equality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": "Doe"}')

        self.assertEqualWithout([
            {
                'first_name': 'John',
                'last_name': 'Doe'
            },
            {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            },
        ],
                                response.json,
                                without=[
                                    '$uri', '$uri', '$id', '$type', 'gender',
                                    'age', 'is_staff'
                                ])

        response = self.client.get('/user?where={"age": 25}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe',
                    'age': 25
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts',
                    'age': 25
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'is_staff'])

        response = self.client.get(
            '/user?where={"last_name": "Doe", "age": 25}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_inequality(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$ne": "Watts"}, "age": {"$ne": 32}}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Jane',
                    'last_name': 'Roe'
                },
                {
                    'first_name': 'Joe',
                    'last_name': 'Bloggs'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gt": 25}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gte": 25}}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'John',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lte": 21}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Jane',
                'last_name': 'Roe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": 21.0}}')
        self.assert400(response)

        response = self.client.get('/user?where={"age": {"$lt": null}}')
        self.assert400(response)

        response = self.client.get('/user?where={"first_name": {"$gt": "Jo"}}')
        self.assert400(response)

    def test_in(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$in": ["Bloggs", "Watts"]}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }, {
                'first_name': 'Sue',
                'last_name': 'Watts'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"last_name": {"$in": []}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_startswith(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "Jo"}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "J%e"}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_istartswith(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$istartswith": "jo"}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_iendswith(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$iendswith": "Oe"}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jane',
                'last_name': 'Roe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_contains(self):
        self.post_sample_set_a()

        response = self.client.get('/user')
        user_ids = [user['$id'] for user in response.json]

        for thing in [{
                'name': 'A',
                'belongs_to': user_ids[0]
        }, {
                'name': 'B',
                'belongs_to': user_ids[2]
        }, {
                'name': 'C',
                'belongs_to': user_ids[1]
        }, {
                'name': 'D',
                'belongs_to': user_ids[4]
        }, {
                'name': 'E',
                'belongs_to': user_ids[3]
        }, {
                'name': 'F',
                'belongs_to': None
        }]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        response = self.client.get(
            '/user-to-many?where={"things": {"$contains": {"$ref": "/thing/1"}}}'
        )

        self.assertEqualWithout(
            [{
                "things": [{
                    "$ref": "/thing/1"
                }],
                "first_name": "John",
                "last_name": "Doe"
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_text_search(self):
        self.post_sample_set_a()

        response = self.client.get('/user?search=sbc+dedf&rank=1')

    def test_sort(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?sort={"last_name": true, "first_name": false}')

        self.assert200(response)
        self.assertEqualWithout(
            [{
                'first_name': 'Sue',
                'last_name': 'Watts'
            }, {
                'first_name': 'Jane',
                'last_name': 'Roe'
            }, {
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?sort={"age": false, "first_name": false}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jane',
                    'last_name': 'Roe'
                },
                {
                    'first_name': 'Joe',
                    'last_name': 'Bloggs'
                },
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts'
                },
                {
                    'first_name': 'John',
                    'last_name': 'Doe'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_sort_relationship(self):
        self.post_sample_set_a()

        response = self.client.get('/user')
        user_ids = [user['$id'] for user in response.json]

        for thing in [{
                'name': 'A',
                'belongs_to': user_ids[0]
        }, {
                'name': 'B',
                'belongs_to': user_ids[2]
        }, {
                'name': 'C',
                'belongs_to': user_ids[1]
        }, {
                'name': 'D',
                'belongs_to': user_ids[4]
        }, {
                'name': 'E',
                'belongs_to': user_ids[3]
        }, {
                'name': 'F',
                'belongs_to': None
        }]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        thinggetter = lambda thing: thing['belongs_to']['$ref'] if thing[
            'belongs_to'] else ''

        response = self.client.get('/thing?sort={"belongs_to": false}')
        self.assertEqual(sorted(response.json, key=thinggetter), response.json)

        response = self.client.get('/thing?sort={"belongs_to": true}')
        self.assertEqual(
            list(reversed(sorted(response.json, key=thinggetter))),
            response.json)

        response = self.client.get(
            '/thing?sort={"name": false, "belongs_to": false}')
        self.assertEqual(
            sorted(response.json, key=lambda thing: thing['name']),
            response.json)

    def test_sort_relationship_none(self):
        for thing in [{
                'name': 'A',
                'belongs_to': None
        }, {
                'name': 'B',
                'belongs_to': None
        }, {
                'name': 'C',
                'belongs_to': None
        }]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        response = self.client.get('/thing?sort={"belongs_to": false}')
        self.assertEqual(3, len(response.json))

    def test_sort_filter_date(self):
        for thing in [{
                'name': 'A',
                'date_time': {
                    '$date': 1446561100000
                }
        }, {
                'name': 'B',
                'date_time': {
                    '$date': 1000000000000
                }
        }, {
                'name': 'C',
                'date_time': {
                    '$date': 1446561110000
                }
        }, {
                'name': 'D',
                'date_time': {
                    '$date': 1446561120000
                }
        }, {
                'name': 'E',
                'date_time': {
                    '$date': 1446561130000
                }
        }]:
            response = self.client.post('/thing', data=thing)
            self.assert200(response)

        response = self.client.get('/thing?sort={"date_time": false}')
        self.assertEqual(
            sorted(response.json,
                   key=lambda thing: thing['date_time']['$date']),
            response.json)

        response = self.client.get(
            '/thing?where={"date_time": {"$eq": {"$date": 1000000000000}}}')

        self.assertEqualWithout([
            {
                'name': 'B',
                'date_time': {
                    '$date': 1000000000000
                }
            },
        ],
                                response.json,
                                without=['$uri', 'date', 'belongs_to'])

        response = self.client.get(
            '/thing?where={"date_time": {"$gt": {"$date": 1000000000000}}}')
        self.assertEqualWithout([{
            'name': 'A',
            'date_time': {
                '$date': 1446561100000
            }
        }, {
            'name': 'C',
            'date_time': {
                '$date': 1446561110000
            }
        }, {
            'name': 'D',
            'date_time': {
                '$date': 1446561120000
            }
        }, {
            'name': 'E',
            'date_time': {
                '$date': 1446561130000
            }
        }],
                                response.json,
                                without=['$uri', 'date', 'belongs_to'])

        response = self.client.get(
            '/thing?where={"date_time": {"$lt": {"$date": 1000000000000}}}')
        self.assertEqualWithout([],
                                response.json,
                                without=['$uri', 'date', 'belongs_to'])

        response = self.client.get(
            '/thing?where={"date_time": {"$between": [{"$date": 1446561110000}, {"$date": 1446561120000}]}}'
        )
        self.assertEqualWithout([
            {
                'name': 'C',
                'date_time': {
                    '$date': 1446561110000
                }
            },
            {
                'name': 'D',
                'date_time': {
                    '$date': 1446561120000
                }
            },
        ],
                                response.json,
                                without=['$uri', 'date', 'belongs_to'])

    def test_sort_and_where(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "Jo"}}&sort={"first_name": false}'
        )

        self.assertEqualWithout(
            [{
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }, {
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_sort_pages(self):
        pass

    @unittest.SkipTest
    def test_disallowed_where_filters(self):
        pass

    @unittest.SkipTest
    def test_schema(self):
        pass
示例#35
0
class PeeweeTestCase(BaseTestCase):
    def setUp(self):
        super(PeeweeTestCase, self).setUp()
        self.app.config['DATABASE'] = 'sqlite://'
        self.db = db = PeeweeTestDB(self.app)
        self.api = Api(self.app)

        class Type(db.Model):
            name = pw.CharField(max_length=60, null=False, unique=True)

        class Machine(db.Model):
            name = pw.CharField(max_length=60, null=False)
            wattage = pw.FloatField(null=True)
            type = pw.ForeignKeyField(Type, related_name='machines')

        self.db.database.connect()
        self.db.database.create_tables([Type, Machine])

        class MachineResource(ModelResource):
            class Meta:
                model = Machine
                include_id = True
                include_type = True
                manager = PeeweeManager

            class Schema:
                type = fields.ToOne('type')

        class TypeResource(ModelResource):
            class Meta:
                model = Type
                include_id = True
                include_type = True
                manager = PeeweeManager

            class Schema:
                machines = fields.ToMany(MachineResource)

        self.MachineResource = MachineResource
        self.TypeResource = TypeResource

        self.api.add_resource(MachineResource)
        self.api.add_resource(TypeResource)

    def tearDown(self):
        self.db.database.close()

    def test_field_discovery(self):
        self.assertEqual(
            set(self.MachineResource.schema.fields.keys()),
            {'$id', '$type', 'name', 'type', 'wattage'})
        self.assertEqual(
            set(self.TypeResource.schema.fields.keys()),
            {'$id', '$type', 'name', 'machines'})
        self.assertEqual(self.MachineResource.meta.name, 'machine')
        self.assertEqual(self.TypeResource.meta.name, 'type')

    def test_create_no_json(self):
        response = self.client.post('/machine', data='invalid')
        self.assert400(response)

    def test_create_json_string(self):
        response = self.client.post(
            '/machine', data='invalid', force_json=True)
        self.assert400(response)

    def test_conflict(self):
        response = self.client.post('/type', data={'name': 'foo'})
        self.assert200(response)

        response = self.client.post('/type', data={'name': 'foo'})
        self.assertStatus(response, 409)

    def test_create(self):
        response = self.client.post('/type', data={})
        self.assert400(response)
        self.assertEqual({
            'errors': [
                {
                    'message': "'name' is a required property",
                    'path': [],
                    'validationOf': {
                        'required': [
                            'name'
                        ]
                    }
                }
            ],
            'message': 'Bad Request',
            'status': 400
        }, response.json)

        response = self.client.post('/type', data={'name': 'x-ray'})
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'type',
            'machines': [],
            'name': 'x-ray'},
            response.json)

        response = self.client.post(
            '/machine', data={'name': 'Irradiator I', 'type': 1})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'machine',
            'type': {'$ref': '/type/1'},
            'wattage': None,
            'name': 'Irradiator I'},
            response.json)

        response = self.client.post(
            '/machine', data={'name': 'Sol IV', 'type': 1, 'wattage': 1.23e45})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 2,
            '$type': 'machine',
            'type': {'$ref': '/type/1'},
            'wattage': 1.23e45,
            'name': 'Sol IV'},
            response.json)

        response = self.client.get('/type/1')
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'type',
            'machines': [
                {'$ref': '/machine/1'},
                {'$ref': '/machine/2'}],
            'name': 'x-ray'},
            response.json)

    def test_get(self):
        def type_(i):
            return {
                '$id': i,
                '$type': 'type',
                'name': 'Type-{}'.format(i),
                'machines': []}

        for i in range(1, 10):
            response = self.client.post(
                '/type',
                data={'name': 'Type-{}'.format(i), 'machines': []})
            self.assert200(response)
            self.assertJSONEqual(type_(i), response.json)

            response = self.client.get('/type/{}'.format(i))
            self.assert200(response)
            self.assertJSONEqual(type_(i), response.json)

            response = self.client.get('/type')
            self.assert200(response)
            self.assertJSONEqual(
                [type_(i) for i in range(1, i + 1)],
                response.json)

            response = self.client.get('/type/{}'.format(i + 1))
            self.assert404(response)
            self.assertJSONEqual({
                'item': {'$id': i + 1, '$type': 'type'},
                'message': 'Not Found',
                'status': 404},
                response.json)

    @unittest.SkipTest
    def test_pagination(self):
        pass # TODO

    def test_update(self):
        response = self.client.post('/type', data={'name': 'T1'})
        self.assert200(response)

        response = self.client.post('/type', data={'name': 'T2'})
        self.assert200(response)

        response = self.client.post(
            '/machine', data={'name': 'Robot', 'type': 1})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'machine',
            'type': {'$ref': '/type/1'},
            'wattage': None,
            'name': 'Robot'},
            response.json)

        response = self.client.patch('/machine/1', data={})
        self.assert200(response)

        response = self.client.patch('/machine/1', data={'wattage': 10000})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'machine',
            'type': {'$ref': '/type/1'},
            'wattage': 10000,
            'name': 'Robot'},
            response.json)

        response = self.client.patch(
            '/machine/1', data={'type': {'$ref': '/type/2'}})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'machine',
            'type': {'$ref': '/type/2'},
            'wattage': 10000,
            'name': 'Robot'},
            response.json)

        response = self.client.patch('/machine/1', data={'type': None})
        self.assert400(response)
        self.assertJSONEqual({
            'errors': [{
                'message': 'None is not valid under any of the given schemas',
                'path': [
                    'type'],
                'validationOf': {
                    'anyOf': [{
                        'additionalProperties': False,
                        'properties': {
                            '$ref': {
                                'format': 'uri',
                                'pattern': '^\\/type\\/[^/]+$',
                                'type': 'string'}},
                            'type': 'object'}, {
                                'type': 'integer'}]}}],
            'message': 'Bad Request',
            'status': 400},
            response.json)

        response = self.client.patch('/machine/1', data={'name': 'Foo'})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'machine',
            'type': {'$ref': '/type/2'},
            'wattage': 10000,
            'name': 'Foo'},
            response.json)

    def test_delete(self):
        response = self.client.delete('/type/1')
        self.assert404(response)

        response = self.client.post(
            '/type', data={'name': 'Foo', 'machines': []})
        self.assert200(response)

        response = self.client.delete('/type/1')
        self.assertStatus(response, 204)

        response = self.client.delete('/type/1')
        self.assert404(response)
class SQLAlchemySortTestCase(BaseTestCase):

    def setUp(self):
        super(SQLAlchemySortTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app)
        self.sa = sa = SQLAlchemy(
            self.app, session_options={"autoflush": False})

        class Type(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False)

        class Machine(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False)

            type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id))
            type = sa.relationship(Type, foreign_keys=[type_id])

        sa.create_all()

        class MachineResource(ModelResource):
            class Meta:
                model = Machine

            class Schema:
                type = fields.ToOne('type')

        class TypeResource(ModelResource):
            class Meta:
                model = Type
                sort_attribute = ('name', True)

        self.MachineResource = MachineResource
        self.TypeResource = TypeResource

        self.api.add_resource(MachineResource)
        self.api.add_resource(TypeResource)

    def test_default_sorting_with_desc(self):
        self.client.post('/type', data={"name": "aaa"})
        self.client.post('/type', data={"name": "ccc"})
        self.client.post('/type', data={"name": "bbb"})
        response = self.client.get('/type')
        self.assert200(response)
        self.assertJSONEqual(
            [{'$uri': '/type/2', 'name': 'ccc'},
             {'$uri': '/type/3', 'name': 'bbb'},
             {'$uri': '/type/1', 'name': 'aaa'}],
            response.json)

    def test_sort_by_related_field(self):
        response = self.client.post('/type', data={"name": "aaa"})
        self.assert200(response)
        aaa_uri = response.json["$uri"]
        response = self.client.post('/type', data={"name": "bbb"})
        self.assert200(response)
        bbb_uri = response.json["$uri"]
        self.client.post(
            '/machine', data={"name": "foo", "type": {"$ref": aaa_uri}})
        self.assert200(response)
        self.client.post(
            '/machine', data={"name": "bar", "type": {"$ref": bbb_uri}})
        self.assert200(response)
        response = self.client.get('/machine?sort={"type": true}')
        self.assert200(response)
        type_uris = [entry['type']['$ref'] for entry in response.json]
        self.assertTrue(type_uris, [bbb_uri, aaa_uri])
        response = self.client.get('/machine?sort={"type": false}')
        self.assert200(response)
        type_uris = [entry['type']['$ref'] for entry in response.json]
        self.assertTrue(type_uris, [bbb_uri, aaa_uri])
示例#37
0
    title = db.Column(db.String(), nullable=False)
    year_published = db.Column(db.Integer)

    author = db.relationship(Author, backref=backref('books', lazy='dynamic'))


db.create_all()


class BookResource(ModelResource):
    class Meta:
        model = Book

    class Schema:
        author = fields.ToOne('author')


class AuthorResource(ModelResource):
    books = Relation('book')

    class Meta:
        model = Author
        natural_key = ('first_name', 'last_name')


api = Api(app)
api.add_resource(BookResource)
api.add_resource(AuthorResource)

if __name__ == '__main__':
    app.run()
示例#38
0
class QueryOptionsSQLAlchemyTestCase(BaseTestCase):
    def setUp(self):
        super(QueryOptionsSQLAlchemyTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app, default_manager=SQLAlchemyManager)
        self.sa = sa = SQLAlchemy(self.app,
                                  session_options={"autoflush": False})

        class Type(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False, unique=True)
            version = sa.Column(sa.Integer(), nullable=True)
            machines = sa.relationship('Machine', back_populates='type')

        class Machine(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False)

            wattage = sa.Column(sa.Float)

            type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id))
            type = sa.relationship(Type, back_populates='machines')

        sa.create_all()

        class MachineResource(ModelResource):
            class Meta:
                model = Machine
                include_type = True

            class Schema:
                type = fields.ToOne('type')

        class TypeResource(ModelResource):
            class Meta:
                model = Type
                include_type = True
                query_options = [joinedload(Type.machines)]

            class Schema:
                machines = fields.ToMany('machine')

        self.MachineResource = MachineResource
        self.TypeResource = TypeResource

        self.api.add_resource(MachineResource)
        self.api.add_resource(TypeResource)

    def tearDown(self):
        self.sa.drop_all()

    def test_get(self):
        response = self.client.post('/type', data={"name": "aaa"})
        self.assert200(response)
        aaa_uri = response.json["$uri"]

        response = self.client.post('/machine',
                                    data={
                                        "name": "foo",
                                        "type": {
                                            "$ref": aaa_uri
                                        }
                                    })
        self.assert200(response)
        machine_uri = response.json['$uri']

        with DBQueryCounter(self.sa.session) as counter:
            response = self.client.get(aaa_uri)
            self.assert200(response)
        self.assertJSONEqual(
            response.json,
            {
                '$type': 'type',
                '$uri': aaa_uri,
                'machines': [{
                    '$ref': machine_uri
                }],
                'name': 'aaa',
                'version': None,
            },
        )
        counter.assert_count(1)
class QueryOptionsSQLAlchemyTestCase(BaseTestCase):
    def setUp(self):
        super(QueryOptionsSQLAlchemyTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app, default_manager=SQLAlchemyManager)
        self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False})

        class Type(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False, unique=True)
            version = sa.Column(sa.Integer(), nullable=True)
            machines = sa.relationship('Machine', back_populates='type')

        class Machine(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False)

            wattage = sa.Column(sa.Float)

            type_id = sa.Column(sa.Integer, sa.ForeignKey(Type.id))
            type = sa.relationship(Type, back_populates='machines')

        sa.create_all()

        class MachineResource(ModelResource):
            class Meta:
                model = Machine
                include_type = True

            class Schema:
                type = fields.ToOne('type')

        class TypeResource(ModelResource):
            class Meta:
                model = Type
                include_type = True
                query_options = [joinedload(Type.machines)]

            class Schema:
                machines = fields.ToMany('machine')

        self.MachineResource = MachineResource
        self.TypeResource = TypeResource

        self.api.add_resource(MachineResource)
        self.api.add_resource(TypeResource)

    def tearDown(self):
        self.sa.drop_all()

    def test_get(self):
        response = self.client.post('/type', data={"name": "aaa"})
        self.assert200(response)
        aaa_uri = response.json["$uri"]

        response = self.client.post(
            '/machine', data={"name": "foo", "type": {"$ref": aaa_uri}})
        self.assert200(response)
        machine_uri = response.json['$uri']

        with DBQueryCounter(self.sa.session) as counter:
            response = self.client.get(aaa_uri)
            self.assert200(response)
        self.assertJSONEqual(
            response.json,
            {'$type': 'type',
             '$uri': aaa_uri,
             'machines': [{'$ref': machine_uri}],
             'name': 'aaa',
             'version': None,
             })
        counter.assert_count(1)
示例#40
0
class RelationTestCase(BaseTestCase):

    def setUp(self):
        super(RelationTestCase, self).setUp()
        self.api = Api(self.app)

    def test_pagination(self):
        class Person(ModelResource):
            class Schema:
                name = fields.String()

            class Meta:
                name = "person"
                model = name
                manager = MemoryManager

        self.api.add_resource(Person)

        response = self.client.get('/person')
        self.assert200(response)

        self.assertEqual('0', response.headers.get('X-Total-Count'))
        self.assertEqual('</person?page=1&per_page=20>; rel="self",'
                         '</person?page=1&per_page=20>; rel="last"', response.headers['Link'])

        for i in range(1, 51):
            response = self.client.post('/person', data={"name": str(i)})
            self.assert200(response)

        response = self.client.get('/person')
        self.assert200(response)
        self.assertJSONEqual([{"$uri": "/person/{}".format(i), "name": str(i)} for i in range(1, 21)], response.json)

        response = self.client.get('/person?page=3')
        self.assert200(response)

        self.assertEqual('50', response.headers.get('X-Total-Count'))
        self.assertEqual('</person?page=3&per_page=20>; rel="self",'
                         '</person?page=1&per_page=20>; rel="first",'
                         '</person?page=2&per_page=20>; rel="prev",'
                         '</person?page=3&per_page=20>; rel="last"', response.headers['Link'])
        self.assertJSONEqual([{"$uri": "/person/{}".format(i), "name": str(i)} for i in range(41, 51)], response.json)




    def test_where_to_one(self):
        class Person(ModelResource):
            class Schema:
                name = fields.String()
                mother = fields.ToOne('person', nullable=True)

            class Meta:
                name = "person"
                model = name
                manager = MemoryManager

        self.api.add_resource(Person)

        response = self.client.post('/person', data={
            'name': 'Anna'
        })  # No. Bad

        self.assert200(response)
        self.assertJSONEqual({'$uri': '/person/1',
                              'mother': None,
                              'name': 'Anna'}, response.json)

        self.client.post('/person', data={
            'name': 'Betty',
            'mother': {"$ref": "/person/1"}
        })

        self.client.post('/person', data={
            'name': 'Bob',
            'mother': {"$ref": "/person/1"}
        })

        self.client.post('/person', data={
            'name': 'Foo',
            'mother': {"$ref": "/person/2"}
        })

        self.client.post('/person', data={
            'name': 'Clare',
            'mother': {"$ref": "/person/2"}
        })

        response = self.client.get('/person?where={"mother": null}')
        self.assertJSONEqual([
            {'$uri': '/person/1', 'mother': None, 'name': 'Anna'}
        ], response.json)

        response = self.client.get('/person?where={"mother": {"$ref": "/person/1"}}')
        self.assertJSONEqual([
            {'$uri': '/person/2', 'mother': {'$ref': '/person/1'}, 'name': 'Betty'},
            {'$uri': '/person/3', 'mother': {'$ref': '/person/1'}, 'name': 'Bob'}
        ], response.json)

        response = self.client.get('/person?where={"mother": {"$ref": "/person/2"}, "name": {"$startswith": "C"}}')
        self.assertJSONEqual([
            {'$uri': '/person/5', 'mother': {'$ref': '/person/2'}, 'name': 'Clare'}
        ], response.json)
示例#41
0
class PeeeeFilterTestCase(BaseTestCase):
    def setUp(self):
        super(PeeeeFilterTestCase, self).setUp()
        app = self.app
        app.config['DATABASE'] = 'sqlite://'

        self.db = db = PeeweeTestDB(self.app)
        self.api = Api(self.app, default_manager=PeeweeManager)
        app.debug = True

        class User(db.Model):
            id = IntegerField(primary_key=True)
            first_name = CharField(max_length=60, null=False)
            last_name = CharField(max_length=60, null=False)

            gender = CharField(max_length=1, null=True)

            age = IntegerField()

            is_staff = BooleanField(default=None)

        db.database.connect()
        db.database.create_tables([User])

        class UserResource(ModelResource):
            class Schema:
                gender = fields.String(enum=['f', 'm'], nullable=True)

            class Meta:
                model = User

        class AllowUserResource(ModelResource):
            class Meta:
                model = User
                name = 'allow-user'
                allowed_filters = {
                    'first_name': ['$eq'],
                    'is_staff': '*'
                }

        self.api.add_resource(UserResource)
        self.api.add_resource(AllowUserResource)

    def post_sample_set_a(self):
        for user in [
            {'first_name': 'John', 'last_name': 'Doe', 'age': 32, 'is_staff': True, 'gender': 'm'},
            {'first_name': 'Jonnie', 'last_name': 'Doe', 'age': 25, 'is_staff': False, 'gender': 'm'},
            {'first_name': 'Jane', 'last_name': 'Roe', 'age': 18, 'is_staff': False, 'gender': 'f'},
            {'first_name': 'Joe', 'last_name': 'Bloggs', 'age': 21, 'is_staff': True, 'gender': 'm'},
            {'first_name': 'Sue', 'last_name': 'Watts', 'age': 25, 'is_staff': True}
        ]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

    def test_equality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": "Doe"}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                ], response.json, without=['$uri', '$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": 25}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe', 'age': 25},
                                    {'first_name': 'Sue', 'last_name': 'Watts', 'age': 25},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'is_staff'])

        response = self.client.get('/user?where={"last_name": "Doe", "age": 25}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_inequality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$ne": "Watts"}, "age": {"$ne": 32}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gt": 25}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gte": 25}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lte": 21}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": 21.0}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": null}}')
        self.assert400(response)

        response = self.client.get('/user?where={"first_name": {"$gt": "Jo"}}')
        self.assert400(response)

    def test_in(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$in": ["Bloggs", "Watts"]}}')

        self.assertEqualWithout([
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"last_name": {"$in": []}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_startswith(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$startswith": "Jo"}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"first_name": {"$startswith": "J%e"}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_istartswith(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$istartswith": "jo"}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_iendswith(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$iendswith": "Oe"}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_text_search(self):
        self.post_sample_set_a()

        response = self.client.get('/user?search=sbc+dedf&rank=1')

    def test_sort(self):
        self.post_sample_set_a()

        response = self.client.get('/user?sort={"last_name": true, "first_name": false}')

        self.assert200(response)
        self.assertEqualWithout([
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json,
                                without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?sort={"age": false, "first_name": false}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                ], response.json,
                                without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])


    def test_sort_and_where(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$startswith": "Jo"}}&sort={"first_name": false}')

        self.assertEqualWithout([
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_sort_pages(self):
        pass

    @unittest.SkipTest
    def test_disallowed_where_filters(self):
        pass

    @unittest.SkipTest
    def test_schema(self):
        pass
示例#42
0
# coding: utf-8
from ..models import Call
from flask_potion import Api, ModelResource, fields
from flask_potion.routes import ItemRoute
api = Api()


class CallResource(ModelResource):
    class Meta:
        model = Call

    '''
    @ItemRoute.GET('/calling')
    def greeting(self, call) -> fields.String():
        return "Hello, {}!".format(call.id)
	'''


api.add_resource(CallResource)
class SQLAlchemyRelationTestCase(BaseTestCase):

    def setUp(self):
        super(SQLAlchemyRelationTestCase, self).setUp()
        self.app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
        self.api = Api(self.app)
        self.sa = sa = SQLAlchemy(self.app, session_options={"autoflush": False})

        group_members = sa.Table('group_members',
                               sa.Column('group_id', sa.Integer(), sa.ForeignKey('group.id')),
                               sa.Column('user_id', sa.Integer(), sa.ForeignKey('user.id')))

        class User(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            parent_id = sa.Column(sa.Integer, sa.ForeignKey(id))
            name = sa.Column(sa.String(60), nullable=False)

            parent = sa.relationship('User', remote_side=[id], backref=backref('children', lazy='dynamic'))

        class Group(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String(60), nullable=False)
            members = sa.relationship('User', secondary=group_members,
                                      backref=backref('memberships', lazy='dynamic'))

        sa.create_all()

        class UserResource(ModelResource):
            class Meta:
                model = User
                include_id = True
                include_type = True

            children = Relation('self')

        class GroupResource(ModelResource):
            class Meta:
                model = Group
                include_id = True
                include_type = True

            members = Relation('user')

        self.api.add_resource(UserResource)
        self.api.add_resource(GroupResource)

    def test_relationship_secondary(self):
        response = self.client.post('/group', data={"name": "Foo"})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'group', "name": "Foo"}, response.json)

        response = self.client.post('/user', data={"name": "Bar"})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'user', "name": "Bar"}, response.json)

        response = self.client.get('/group/1/members')
        self.assert200(response)
        self.assertJSONEqual([], response.json)

        response = self.client.post('/group/1/members', data={"$ref": "/user/1"})
        self.assert200(response)
        self.assertJSONEqual({"$ref": "/user/1"}, response.json)

        response = self.client.get('/group/1/members')
        self.assert200(response)
        self.assertJSONEqual([{"$ref": "/user/1"}], response.json)

    def test_relationship_secondary_delete_missing(self):
        response = self.client.post('/group', data={"name": "Foo"})
        response = self.client.post('/user', data={"name": "Bar"})

        response = self.client.delete('/group/1/members/1')
        self.assertStatus(response, 204)

    def test_relationship_post(self):
        response = self.client.post('/user', data={"name": "Foo"})
        self.assert200(response)
        self.assertJSONEqual({'$id': 1, '$type': 'user', "name": "Foo"}, response.json)

        response = self.client.post('/user', data={"name": "Bar"})
        self.assert200(response)
        self.assertJSONEqual({'$id': 2, '$type': 'user', "name": "Bar"}, response.json)

        response = self.client.post('/user/1/children', data={"$ref": "/user/2"})
        self.assert200(response)
        self.assertJSONEqual({"$ref": "/user/2"}, response.json)

    def test_relationship_get(self):
        self.test_relationship_post()

        response = self.client.get('/user/1/children')
        self.assert200(response)
        self.assertJSONEqual([{"$ref": "/user/2"}], response.json)

    def test_relationship_delete(self):
        self.test_relationship_post()

        response = self.client.delete('/user/1/children/2')
        self.assertStatus(response, 204)

        response = self.client.get('/user/1/children')
        self.assert200(response)
        self.assertJSONEqual([], response.json)

    def test_relationship_delete_missing(self):
        self.test_relationship_post()

        response = self.client.delete('/user/1/children/2')
        self.assertStatus(response, 204)

        response = self.client.delete('/user/1/children/2')
        self.assertStatus(response, 204)

        response = self.client.get('/user/1/children')
        self.assert200(response)
        self.assertJSONEqual([], response.json)

    def test_relationship_pagination(self):
        response = self.client.post('/user', data={"name": "Foo"})
        self.assert200(response)

        for i in range(2, 50):
            response = self.client.post('/user', data={"name": str(i)})
            self.assert200(response)
            response = self.client.post('/user/1/children', data={"$ref": "/user/{}".format(response.json['$id'])})
            self.assert200(response)

        response = self.client.get('/user/1/children')
        self.assert200(response)
        self.assertJSONEqual([{"$ref": "/user/{}".format(i)} for i in range(2, 22)], response.json)

        response = self.client.get('/user/1/children?page=3')
        self.assert200(response)
        self.assertJSONEqual([{"$ref": "/user/{}".format(i)} for i in range(42, 50)], response.json)

        self.assertEqual('48', response.headers['X-Total-Count'])
        self.assertEqual('</user/1/children?page=3&per_page=20>; rel="self",'
                         '</user/1/children?page=1&per_page=20>; rel="first",'
                         '</user/1/children?page=2&per_page=20>; rel="prev",'
                         '</user/1/children?page=3&per_page=20>; rel="last"', response.headers['Link'])
示例#44
0
class FilterTestCase(BaseTestCase):
    def setUp(self):
        super(FilterTestCase, self).setUp()
        app = self.app
        app.config['MONGODB_DB'] = 'potion-test-db'
        app.config['TESTING'] = True

        self.api = Api(self.app, default_manager=MongoEngineManager)
        self.me = me = MongoEngine(app)

        class User(me.Document):
            meta = {
                "collection": "user"
            }

            first_name = StringField(max_length=60, null=False)
            last_name = StringField(max_length=60, null=False)

            gender = StringField(max_length=1)

            age = IntField()

            is_staff = BooleanField(default=None)

        class UserResource(ModelResource):
            class Schema:
                gender = fields.String(enum=['f', 'm'], nullable=True)

            class Meta:
                model = User

        class AllowUserResource(ModelResource):
            class Meta:
                model = User
                name = 'allow-user'
                allowed_filters = {
                    'first_name': ['$eq'],
                    'is_staff': '*'
                }

        self.api.add_resource(UserResource)
        self.api.add_resource(AllowUserResource)

    def post_sample_set_a(self):
        for user in [
            {'first_name': 'John', 'last_name': 'Doe', 'age': 32, 'is_staff': True, 'gender': 'm'},
            {'first_name': 'Jonnie', 'last_name': 'Doe', 'age': 25, 'is_staff': False, 'gender': 'm'},
            {'first_name': 'Jane', 'last_name': 'Roe', 'age': 18, 'is_staff': False, 'gender': 'f'},
            {'first_name': 'Joe', 'last_name': 'Bloggs', 'age': 21, 'is_staff': True, 'gender': 'm'},
            {'first_name': 'Sue', 'last_name': 'Watts', 'age': 25, 'is_staff': True}
        ]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

    def test_equality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": "Doe"}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                ], response.json, without=['$uri', '$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": 25}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe', 'age': 25},
                                    {'first_name': 'Sue', 'last_name': 'Watts', 'age': 25},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'is_staff'])

        response = self.client.get('/user?where={"last_name": "Doe", "age": 25}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_inequality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$ne": "Watts"}, "age": {"$ne": 32}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gt": 25}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gte": 25}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lte": 21}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": 21.0}}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": null}}')
        self.assert400(response)

        response = self.client.get('/user?where={"first_name": {"$gt": "Jo"}}')
        self.assert400(response)

    def test_in(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": {"$in": ["Bloggs", "Watts"]}}')

        self.assertEqualWithout([
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"last_name": {"$in": []}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_startswith(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$startswith": "Jo"}}')

        self.assertEqualWithout([
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"first_name": {"$startswith": "J%e"}}')

        self.assertEqualWithout([], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_text_search(self):
        self.post_sample_set_a()
        response = self.client.get('/user?search=sbc+dedf&rank=1')

    def test_sort(self):
        self.post_sample_set_a()

        response = self.client.get('/user?sort={"last_name": true, "first_name": false}')

        self.assert200(response)
        self.assertEqualWithout([
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'}
                                ], response.json,
                                without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?sort={"age": false, "first_name": false}')

        self.assertEqualWithout([
                                    {'first_name': 'Jane', 'last_name': 'Roe'},
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'},
                                    {'first_name': 'Sue', 'last_name': 'Watts'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                ], response.json,
                                without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])


    def test_sort_and_where(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"first_name": {"$startswith": "Jo"}}&sort={"first_name": false}')

        self.assertEqualWithout([
                                    {'first_name': 'Joe', 'last_name': 'Bloggs'},
                                    {'first_name': 'John', 'last_name': 'Doe'},
                                    {'first_name': 'Jonnie', 'last_name': 'Doe'}
                                ], response.json, without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_sort_pages(self):
        pass

    @unittest.SkipTest
    def test_disallowed_where_filters(self):
        pass

    @unittest.SkipTest
    def test_schema(self):
        pass

    def tearDown(self):
        self.me.connection.drop_database('potion-test-db')
示例#45
0
    def test_route_disabling(self):
        class FooResource(Resource):
            @Route.GET
            def foo(self):
                return 'foo'

            @Route.GET
            def baz(self):
                return 'baz'

            @baz.POST
            def baz(self, value):
                return 'baz: {}'.format(value)

            baz.request_schema = fields.String()

            class Meta:
                name = 'foo'
                exclude_routes = ('readBaz', )

        class BarResource(FooResource):
            class Meta:
                name = 'bar'

        class BazResource(BarResource):
            class Meta:
                name = 'baz'
                exclude_routes = ('readFoo', )

        api = Api(self.app)
        api.add_resource(FooResource)
        api.add_resource(BarResource)
        api.add_resource(BazResource)

        self.assertEqual(
            {
                'describedBy': Resource.described_by,
                'readFoo': FooResource.foo,
                'createBaz': FooResource.baz,
            },
            FooResource.routes,
        )

        self.assertEqual(
            {
                'describedBy': Resource.described_by,
                'readFoo': FooResource.foo,
                'createBaz': FooResource.baz,
            },
            BarResource.routes,
        )

        self.assertIsNone(BazResource.routes.get('readFoo', None))
        self.assertIsNotNone(BazResource.routes.get('readBaz', None))
        self.assertIsNotNone(BazResource.routes.get('createBaz', None))

        response = self.client.get("/foo/foo")
        self.assertEqual('foo', response.json)

        response = self.client.get("/foo/baz")
        self.assert405(response)

        response = self.client.get("/bar/foo")
        self.assert200(response)
        self.assertEqual('foo', response.json)

        response = self.client.get("/bar/baz")
        self.assert405(response)

        response = self.client.post("/bar/baz", data='xyz', force_json=True)
        self.assert200(response)
        self.assertEqual('baz: xyz', response.json)

        response = self.client.get("/baz/foo")
        self.assert404(response)

        response = self.client.get("/baz/baz")
        self.assertEqual('baz', response.json)

        response = self.client.post("/baz/baz", data='123', force_json=True)
        self.assert200(response)
        self.assertEqual('baz: 123', response.json)
示例#46
0
class MongoEngineSignalTestCase(BaseTestCase):
    def setUp(self):
        super(MongoEngineSignalTestCase, self).setUp()
        self.app.config['MONGODB_DB'] = 'potion-test-db'
        self.api = Api(self.app, default_manager=MongoEngineManager)
        self.me = me = MongoEngine(self.app)

        class User(me.Document):
            name = StringField(max_length=60, null=False)
            gender = StringField(max_length=1, null=True)

            children = ListField(ReferenceField("User"))

            def __eq__(self, other):
                return self.name == other.name

            def __repr__(self):
                return 'User({})'.format(self.name)

        class Group(me.Document):
            name = StringField(max_length=60, null=False)

        class GroupMembership(me.Document):
            user = ReferenceField(User)
            group = ReferenceField(Group)

        class UserResource(ModelResource):
            class Meta:
                model = User

            children = Relation('self')

        class GroupResource(ModelResource):
            class Meta:
                model = Group

            members = Relation(UserResource)

        self.User = User
        self.Group = Group
        self.UserResource = UserResource
        self.GroupResource = GroupResource
        self.api.add_resource(UserResource)
        self.api.add_resource(GroupResource)

    def tearDown(self):
        self.me.connection.drop_database('potion-test-db')

    @contextmanager
    def assertSignals(self, expected_events, sender=ANY):
        events = []

        def receiver_(signal, sender, **kwargs):
            events.append((signal, sender, kwargs))

        receivers = {
            signal: partial(receiver_, signal)
            for signal in [
                signals.before_create, signals.after_create, signals.
                before_update, signals.after_update, signals.before_delete,
                signals.after_delete, signals.before_add_to_relation, signals.
                after_add_to_relation, signals.before_remove_from_relation,
                signals.after_remove_from_relation
            ]
        }

        for signal, receiver in receivers.items():
            signal.connect(receiver, sender=sender, weak=False)

        try:
            yield None
        except:
            for signal, receiver in receivers.items():
                signal.disconnect(receiver)
            raise
        else:
            for signal, receiver in receivers.items():
                signal.disconnect(receiver)

            self.assertEqual(events, expected_events)

    def test_create_signal(self):
        with self.assertSignals([(signals.before_create, self.UserResource, {
                'item': self.User(name="Foo")
        }),
                                 (signals.after_create, self.UserResource, {
                                     'item': self.User(name="Foo")
                                 })]):
            response = self.client.post('/user', data={"name": "Foo"})
            self.assert200(response)
            self.assertJSONEqual(
                {
                    '$uri': response.json["$uri"],
                    "name": "Foo",
                    "gender": None
                }, response.json)

    def test_update_signal(self):
        response = self.client.post('/user', data={"name": "Foo"})
        self.assert200(response)

        with self.assertSignals([(signals.before_update, self.UserResource, {
                'changes': {
                    'gender': 'M',
                    'name': 'Bar'
                },
                'item': self.User(name="Bar")
        }),
                                 (signals.after_update, self.UserResource, {
                                     'changes': {
                                         'gender': 'M',
                                         'name': 'Bar'
                                     },
                                     'item': self.User(name="Bar")
                                 })]):
            uri = response.json["$uri"]
            response = self.client.patch(uri,
                                         data={
                                             "name": "Bar",
                                             "gender": "M"
                                         })
            self.assert200(response)
            self.assertJSONEqual({
                '$uri': uri,
                "name": "Bar",
                "gender": "M"
            }, response.json)

    def test_delete_signal(self):
        response = self.client.post('/user', data={"name": "Foo"})
        self.assert200(response)

        with self.assertSignals([(signals.before_delete, self.UserResource, {
                'item': self.User(name="Foo")
        }),
                                 (signals.after_delete, self.UserResource, {
                                     'item': self.User(name="Foo")
                                 })]):
            response = self.client.delete(response.json["$uri"])
            self.assertStatus(response, 204)

    def test_relation_signal(self):

        response = self.client.post('/user', data={"name": "Foo"})
        user1_uri = response.json["$uri"]
        self.assert200(response)

        with self.assertSignals([
            (signals.before_create, self.UserResource, {
                'item': self.User(name="Bar")
            }),
            (signals.after_create, self.UserResource, {
                'item': self.User(name="Bar")
            }),
            (signals.before_add_to_relation, self.UserResource, {
                'item': self.User(name="Foo"),
                'attribute': 'children',
                'child': self.User(name="Bar")
            }),
            (signals.after_add_to_relation, self.UserResource, {
                'item': self.User(name="Foo"),
                'attribute': 'children',
                'child': self.User(name="Bar")
            }),
            (signals.before_remove_from_relation, self.UserResource, {
                'item': self.User(name="Foo"),
                'attribute': 'children',
                'child': self.User(name="Bar")
            }),
            (signals.after_remove_from_relation, self.UserResource, {
                'item': self.User(name="Foo"),
                'attribute': 'children',
                'child': self.User(name="Bar")
            })
        ]):
            response = self.client.post('/user', data={"name": "Bar"})
            user2_uri = response.json["$uri"]
            user2_id = user2_uri.split("/")[-1]
            self.assert200(response)

            response = self.client.post('{}/children'.format(user1_uri),
                                        data={"$ref": user2_uri})

            self.assert200(response)

            response = self.client.delete('{}/children/{}'.format(
                user1_uri, user2_id))
            self.assertStatus(response, 204)
示例#47
0
class FilterTestCase(BaseTestCase):
    def setUp(self):
        super(FilterTestCase, self).setUp()
        app = self.app
        app.config['MONGODB_DB'] = 'potion-test-db'
        app.config['TESTING'] = True

        self.api = Api(self.app, default_manager=MongoEngineManager)
        self.me = me = MongoEngine(app)

        class User(me.Document):
            meta = {"collection": "user"}

            first_name = StringField(max_length=60, null=False)
            last_name = StringField(max_length=60, null=False)

            gender = StringField(max_length=1)

            age = IntField()

            is_staff = BooleanField(default=None)

        class UserResource(ModelResource):
            class Schema:
                gender = fields.String(enum=['f', 'm'], nullable=True)

            class Meta:
                model = User

        class AllowUserResource(ModelResource):
            class Meta:
                model = User
                name = 'allow-user'
                allowed_filters = {'first_name': ['$eq'], 'is_staff': '*'}

        self.api.add_resource(UserResource)
        self.api.add_resource(AllowUserResource)

    def post_sample_set_a(self):
        for user in [{
                'first_name': 'John',
                'last_name': 'Doe',
                'age': 32,
                'is_staff': True,
                'gender': 'm'
        }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe',
                'age': 25,
                'is_staff': False,
                'gender': 'm'
        }, {
                'first_name': 'Jane',
                'last_name': 'Roe',
                'age': 18,
                'is_staff': False,
                'gender': 'f'
        }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs',
                'age': 21,
                'is_staff': True,
                'gender': 'm'
        }, {
                'first_name': 'Sue',
                'last_name': 'Watts',
                'age': 25,
                'is_staff': True
        }]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

    def test_equality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": "Doe"}')

        self.assertEqualWithout([
            {
                'first_name': 'John',
                'last_name': 'Doe'
            },
            {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            },
        ],
                                response.json,
                                without=[
                                    '$uri', '$uri', '$id', '$type', 'gender',
                                    'age', 'is_staff'
                                ])

        response = self.client.get('/user?where={"age": 25}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe',
                    'age': 25
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts',
                    'age': 25
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'is_staff'])

        response = self.client.get(
            '/user?where={"last_name": "Doe", "age": 25}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_inequality(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$ne": "Watts"}, "age": {"$ne": 32}}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Jane',
                    'last_name': 'Roe'
                },
                {
                    'first_name': 'Joe',
                    'last_name': 'Bloggs'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gt": 25}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gte": 25}}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'John',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lte": 21}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Jane',
                'last_name': 'Roe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": 21.0}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Jane',
                'last_name': 'Roe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": null}}')
        self.assert400(response)

        response = self.client.get('/user?where={"first_name": {"$gt": "Jo"}}')
        self.assert400(response)

    def test_in(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$in": ["Bloggs", "Watts"]}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }, {
                'first_name': 'Sue',
                'last_name': 'Watts'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"last_name": {"$in": []}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_startswith(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "Jo"}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "J%e"}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_text_search(self):
        self.post_sample_set_a()
        response = self.client.get('/user?search=sbc+dedf&rank=1')

    def test_sort(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?sort={"last_name": true, "first_name": false}')

        self.assert200(response)
        self.assertEqualWithout(
            [{
                'first_name': 'Sue',
                'last_name': 'Watts'
            }, {
                'first_name': 'Jane',
                'last_name': 'Roe'
            }, {
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?sort={"age": false, "first_name": false}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jane',
                    'last_name': 'Roe'
                },
                {
                    'first_name': 'Joe',
                    'last_name': 'Bloggs'
                },
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts'
                },
                {
                    'first_name': 'John',
                    'last_name': 'Doe'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_sort_and_where(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "Jo"}}&sort={"first_name": false}'
        )

        self.assertEqualWithout(
            [{
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }, {
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_sort_pages(self):
        pass

    @unittest.SkipTest
    def test_disallowed_where_filters(self):
        pass

    @unittest.SkipTest
    def test_schema(self):
        pass

    def tearDown(self):
        self.me.connection.drop_database('potion-test-db')
示例#48
0
class NaturalKeyTestCase(BaseTestCase):
    def setUp(self):
        super(NaturalKeyTestCase, self).setUp()
        self.api = Api(self.app, prefix='/api')

    def test_simple_key(self):
        class Foo(ModelResource):
            class Meta:
                key_converters = [RefKey()]
                model = 'foo'
                manager = MemoryManager

            class Schema:
                inception = fields.ToOne('foo')

        self.api.add_resource(Foo)

        foo_field = fields.ToOne(Foo)

        self.assertJSONEqual(FOO_REFERENCE, foo_field.response)
        self.assertJSONEqual(FOO_REFERENCE, foo_field.request)

    def test_multiple_keys(self):
        with self.assertRaises(RuntimeError) as cx:

            class Bar(ModelResource):
                class Meta:
                    key_converters = (RefKey(), PropertyKey('name'))
                    model = 'bar'
                    natural_key = 'alias'
                    manager = MemoryManager

                class Schema:
                    name = fields.String()
                    alias = fields.String()

            self.api.add_resource(Bar)
        self.assertEqual('Multiple keys of type string defined for bar',
                         cx.exception.args[0])

    def test_property_key(self):
        class Foo(ModelResource):
            class Schema:
                name = fields.String()

            class Meta:
                natural_key = 'name'
                manager = MemoryManager
                model = 'foo'

        self.api.add_resource(Foo)

        foo_field = fields.ToOne(Foo)

        self.assertJSONEqual(FOO_REFERENCE, foo_field.response)
        self.assertJSONEqual(
            {
                "anyOf":
                [FOO_REFERENCE, {
                    "type": "integer"
                }, {
                    "type": "string"
                }]
            }, foo_field.request)

        response = self.client.post('/api/foo', data={"name": "Jane"})
        self.assert200(response)

        response = self.client.post('/api/foo', data={"name": "John"})
        self.assert200(response)

        self.assertEqual({'id': 2, 'name': 'John'}, foo_field.convert(2))

        self.assertEqual({'id': 1, 'name': 'Jane'}, foo_field.convert('Jane'))

        with self.assertRaises(ValidationError):
            foo_field.convert(['John'])

        with self.assertRaises(ItemNotFound) as cx:
            foo_field.convert('Joanne')

        self.assertEqual(
            {
                "message": "Not Found",
                "status": 404,
                "item": {
                    "$type": "foo",
                    "$where": {
                        "name": "Joanne"
                    }
                }
            }, cx.exception.as_dict())

    def test_properties_key(self):
        class Foo(ModelResource):
            class Schema:
                first_name = fields.String()
                last_name = fields.String()

            class Meta:
                natural_key = ['first_name', 'last_name']
                manager = MemoryManager
                model = 'foo'
                name = 'foo'

        self.api.add_resource(Foo)

        foo_field = fields.ToOne(Foo, nullable=True)

        self.assertJSONEqual(FOO_REFERENCE_NULLABLE, foo_field.response)
        self.assertJSONEqual(
            {
                "anyOf": [
                    FOO_REFERENCE, {
                        "type": "integer"
                    }, {
                        "type": "array",
                        "items": [{
                            "type": "string"
                        }, {
                            "type": "string"
                        }],
                        "additionalItems": False
                    }, {
                        "type": "null"
                    }
                ]
            }, foo_field.request)

        response = self.client.post('/api/foo',
                                    data={
                                        "first_name": "Jane",
                                        "last_name": "Doe"
                                    })
        self.assert200(response)

        response = self.client.post('/api/foo',
                                    data={
                                        "first_name": "John",
                                        "last_name": "Doe"
                                    })
        self.assert200(response)

        self.assertEqual({
            'first_name': 'Jane',
            'id': 1,
            'last_name': 'Doe'
        }, foo_field.convert(1))

        self.assertEqual({
            'first_name': 'John',
            'id': 2,
            'last_name': 'Doe'
        }, foo_field.convert(['John', 'Doe']))

        self.assertEqual({
            'first_name': 'John',
            'id': 2,
            'last_name': 'Doe'
        }, foo_field.convert({"$ref": "/api/foo/2"}))

        with self.assertRaises(ItemNotFound) as cx:
            foo_field.convert(['John', 'Joe'])

        self.assertEqual(
            {
                "message": "Not Found",
                "status": 404,
                "item": {
                    "$type": "foo",
                    "$where": {
                        "first_name": "John",
                        "last_name": "Joe"
                    }
                }
            }, cx.exception.as_dict())

        with self.assertRaises(ValidationError):
            foo_field.convert(['John', None])
示例#49
0
class PeeweeSignalTestCase(BaseTestCase):
    def setUp(self):
        super(PeeweeSignalTestCase, self).setUp()
        app = self.app
        app.config['DATABASE'] = 'sqlite://'

        self.db = db = PeeweeTestDB(self.app)
        self.api = Api(self.app, default_manager=PeeweeManager)

        class User(db.Model):
            name = CharField(max_length=60)
            gender = CharField(max_length=1, null=True)

            parent = ForeignKeyField('self', null=True, related_name='children')

            def __eq__(self, other):
                return self.name == other.name

            def __repr__(self):
                return 'User({})'.format(self.name)

        class Group(db.Model):
            name = CharField(max_length=60)

        class GroupMembership(db.Model):
            user = ForeignKeyField(User)
            group = ForeignKeyField(Group)

        db.database.connect()
        db.database.create_tables([User, Group, GroupMembership])


        class UserResource(ModelResource):
            class Meta:
                model = User

            children = Relation('self')

        class GroupResource(ModelResource):
            class Meta:
                model = Group

            members = Relation(UserResource)

        self.User = User
        self.Group = Group
        self.UserResource = UserResource
        self.GroupResource = GroupResource
        self.api.add_resource(UserResource)
        self.api.add_resource(GroupResource)

    @contextmanager
    def assertSignals(self, expected_events, sender=ANY):
        events = []

        def receiver_(signal, sender, **kwargs):
            events.append((signal, sender, kwargs))

        receivers = {
            signal: partial(receiver_, signal) for signal in [
            signals.before_create,
            signals.after_create,
            signals.before_update,
            signals.after_update,
            signals.before_delete,
            signals.after_delete,
            signals.before_add_to_relation,
            signals.after_add_to_relation,
            signals.before_remove_from_relation,
            signals.after_remove_from_relation
        ]
        }

        for signal, receiver in receivers.items():
            signal.connect(receiver, sender=sender, weak=False)

        try:
            yield None
        except:
            for signal, receiver in receivers.items():
                signal.disconnect(receiver)
            raise
        else:
            for signal, receiver in receivers.items():
                signal.disconnect(receiver)

            self.assertEqual(events, expected_events)


    def test_create_signal(self):

        with self.assertSignals([
            (signals.before_create, self.UserResource, {'item': self.User(name="Foo")}),
            (signals.after_create, self.UserResource, {'item': self.User(name="Foo")})
        ]):
            response = self.client.post('/user', data={"name": "Foo"})
            self.assert200(response)
            self.assertJSONEqual({'$uri': '/user/1', "name": "Foo", "gender": None}, response.json)


    def test_update_signal(self):
        response = self.client.post('/user', data={"name": "Foo"})
        self.assert200(response)

        with self.assertSignals([
            (signals.before_update, self.UserResource, {'changes': {'gender': 'M', 'name': 'Bar'},
                                                        'item': self.User(name="Bar")}),
            (signals.after_update, self.UserResource, {'changes': {'gender': 'M', 'name': 'Bar'},
                                                       'item': self.User(name="Bar")})
        ]):
            response = self.client.patch('/user/1', data={"name": "Bar", "gender": "M"})
            self.assert200(response)
            self.assertJSONEqual({'$uri': '/user/1', "name": "Bar", "gender": "M"}, response.json)

    def test_delete_signal(self):
        response = self.client.post('/user', data={"name": "Foo"})
        self.assert200(response)

        with self.assertSignals([
            (signals.before_delete, self.UserResource, {'item': self.User(name="Foo")}),
            (signals.after_delete, self.UserResource, {'item': self.User(name="Foo")})
        ]):
            response = self.client.delete('/user/1')
            self.assertStatus(response, 204)

    def test_relation_signal(self):

        response = self.client.post('/user', data={"name": "Foo"})
        self.assert200(response)

        with self.assertSignals([
            (signals.before_create, self.UserResource, {'item': self.User(name="Bar")}),
            (signals.after_create, self.UserResource, {'item': self.User(name="Bar")}),
            (signals.before_add_to_relation, self.UserResource, {'item': self.User(name="Foo"),
                                                                 'attribute': 'children',
                                                                 'child': self.User(name="Bar")}),
            (signals.after_add_to_relation, self.UserResource, {'item': self.User(name="Foo"),
                                                                'attribute': 'children',
                                                                'child': self.User(name="Bar")}),
            (signals.before_remove_from_relation, self.UserResource, {'item': self.User(name="Foo"),
                                                                      'attribute': 'children',
                                                                      'child': self.User(name="Bar")}),
            (signals.after_remove_from_relation, self.UserResource, {'item': self.User(name="Foo"),
                                                                     'attribute': 'children',
                                                                     'child': self.User(name="Bar")})
        ]):
            response = self.client.post('/user', data={"name": "Bar"})
            self.assert200(response)

            response = self.client.post('/user/1/children', data={"$ref": "/user/2"})
            self.assert200(response)

            response = self.client.delete('/user/1/children/2')
            self.assertStatus(response, 204)
示例#50
0
    class Schema:
        article = fields.ToOne('article')
        author = fields.ToOne('user')

    class Meta:
        model = Comment
        read_only_fields = ['author']
        permissions = {
            'create': 'anybody',
            'update': 'user:author',
            'delete': ['update:article', 'admin']
        }


for resource in (UserResource, ArticleResource, CommentResource):
    api.add_resource(resource)


@signals.before_create.connect_via(ANY)
def before_create_article_comment(sender, item):
    if issubclass(sender, (ArticleResource, CommentResource)):
        item.author_id = current_user.id


db.create_all()

if __name__ == '__main__':
    # Add some example users
    db.session.add(User(username='******', is_editor=True))
    db.session.add(User(username='******', is_editor=True))
    db.session.add(User(username='******', is_admin=True))
class PrincipalTestCase(BaseTestCase):
    def create_app(self):
        app = super(PrincipalTestCase, self).create_app()
        app.test_client_class = AuthorizedApiClient

        self.principal = Principal(app)
        self.sa = sa = SQLAlchemy(app)

        class User(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String())

        class BookStore(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.String())

            owner_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
            owner = sa.relationship(User,
                                    backref=backref('stores', lazy='dynamic'))

        class Book(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            title = sa.Column(sa.String(), nullable=False)

            author_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
            author = sa.relationship(User,
                                     backref=backref('books', lazy='dynamic'))

        class BookSigning(sa.Model):
            id = sa.Column(sa.Integer, primary_key=True)
            book_id = sa.Column(sa.Integer,
                                sa.ForeignKey(Book.id),
                                nullable=False)
            store_id = sa.Column(sa.Integer,
                                 sa.ForeignKey(BookStore.id),
                                 nullable=False)

            book = sa.relationship(Book)
            store = sa.relationship(BookStore)

        sa.create_all()

        for model in (BookStore, User, Book, BookSigning):
            setattr(self, model.__tablename__.upper(), model)

        return app

    def setUp(self):
        super(PrincipalTestCase, self).setUp()
        self.mock_user = None

        @identity_loaded.connect_via(self.app)
        def on_identity_loaded(sender, identity):
            identity.provides.add(UserNeed(identity.id))

            for role in self.mock_user.get('roles', []):
                identity.provides.add(RoleNeed(role))

            for need in self.mock_user.get('needs', []):
                identity.provides.add(need)

        def authenticate(fn):
            @wraps(fn)
            def wrapper(*args, **kwargs):
                auth = request.authorization

                if not auth:
                    raise Unauthorized()

                if auth.password == 'password':
                    identity_changed.send(current_app._get_current_object(),
                                          identity=Identity(
                                              self.mock_user['id']))
                else:
                    raise Unauthorized()
                return fn(*args, **kwargs)

            return wrapper

        self.api = Api(self.app, decorators=[authenticate])

    def test_role(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {'create': 'author'}

        self.api.add_resource(BookResource)

        response = self.client.post('/book', data={'title': 'Foo'}, auth=False)
        self.assert401(response)

        self.mock_user = {'id': 1}
        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert403(response)

        self.mock_user = {'id': 1, 'roles': ['author']}
        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert200(response)
        self.assertEqual({'title': 'Foo', '$uri': '/book/1'}, response.json)

        self.assert200(self.client.patch('/book/1', data={'title': 'Foo I'}))

        self.mock_user = {'id': 1}
        self.assert403(self.client.patch('/book/1', data={'title': 'Bar'}))

        self.assert403(self.client.delete('/book/1'))

        # self.user = {'id': 1, 'roles': ['author']}
        # self.assert200(self.client.delete('/book/1'))

        # response = self.client.post('/book', data={'title': 'Foo'})
        #
        # self.assert200(response)

    def test_access_forbidden_to_resource_collection(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': 'author',
                    'create': 'author',
                }

        self.api.add_resource(BookResource)
        self.mock_user = {'id': 1, 'roles': ['author']}
        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert200(response)
        self.assertEqual({'title': 'Foo', '$uri': '/book/1'}, response.json)
        self.assert200(self.client.get('/book'))
        self.mock_user = {'id': 1}
        self.assert403(self.client.get('/book'))

    def test_inherit_role_to_one_field(self):
        class BookStoreResource(PrincipalResource):
            class Meta:
                model = self.BOOK_STORE
                permissions = {'create': 'admin', 'update': ['admin']}

        class BookSigningResource(PrincipalResource):
            class Schema:
                book = fields.ToOne('book')
                store = fields.ToOne('book_store')

            class Meta:
                model = self.BOOK_SIGNING
                permissions = {'create': 'update:store'}

        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {'create': 'yes'}

        self.api.add_resource(BookStoreResource)
        self.api.add_resource(BookSigningResource)
        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.assert200(
            self.client.post('/book_store', data={'name': 'Foo Books'}))

        self.assert200(self.client.post('/book', data={'title': 'Bar'}))

        self.mock_user = {'id': 2}

        response = self.client.post('/book_signing',
                                    data={
                                        'book': {
                                            '$ref': '/book/1'
                                        },
                                        'store': {
                                            '$ref': '/book_store/1'
                                        }
                                    })
        self.assert403(response)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.assert200(
            self.client.post('/book_signing',
                             data={
                                 'book': {
                                     '$ref': '/book/1'
                                 },
                                 'store': {
                                     '$ref': '/book_store/1'
                                 }
                             }))

    def test_user_need(self):
        class BookStoreResource(PrincipalResource):
            class Schema:
                owner = fields.ToOne('user')

            class Meta:
                model = self.BOOK_STORE
                permissions = {
                    'create': 'admin',
                    'update': ['admin', 'user:owner']
                }

        class UserResource(PrincipalResource):
            class Meta:
                model = self.USER
                permissions = {'create': 'admin'}

        self.api.add_resource(BookStoreResource)
        self.api.add_resource(UserResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        self.assert200(self.client.post('/user', data={'name': 'Admin'}))

        for i, store in enumerate([{
                'name': 'Books & More',
                'owner': {
                    'name': 'Mr. Moore'
                }
        }, {
                'name': 'Foo Books',
                'owner': {
                    'name': 'Foo'
                }
        }]):
            response = self.client.post('/user', data=store['owner'])

            owner = {'$ref': response.json['$uri']}
            response = self.client.post('/book_store',
                                        data={
                                            'name': store['name'],
                                            'owner': owner
                                        })

            self.assertEqual(
                {
                    '$uri': '/book_store/{}'.format(i + 1),
                    'name': store['name'],
                    'owner': owner
                }, response.json)

        response = self.client.patch('/book_store/1',
                                     data={'name': 'books & moore'})
        self.assert200(response)

        self.mock_user = {'id': 3}
        response = self.client.patch('/book_store/1',
                                     data={'name': 'Books & Foore'})
        self.assert403(response)

        self.mock_user = {'id': 2}
        response = self.client.patch('/book_store/1',
                                     data={'name': 'Books & Moore'})

        self.assert200(response)

        self.assertEqual(
            {
                '$uri': '/book_store/1',
                'name': 'Books & Moore',
                'owner': {
                    '$ref': '/user/2'
                }
            }, response.json)

        response = self.client.patch('/book_store/2',
                                     data={'name': 'Moore Books'})
        self.assert403(response)

    def test_item_need_update(self):
        class BookStoreResource(PrincipalResource):
            class Meta:
                model = self.BOOK_STORE
                permissions = {'create': 'admin', 'update': 'update'}

        self.api.add_resource(BookStoreResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        # response = self.client.post('/book_store', data=[
        # {'name': 'Bar Books'},
        #     {'name': 'Foomazon'}
        # ])
        response = self.client.post('/book_store', data={'name': 'Bar Books'})
        self.assert200(response)
        response = self.client.post('/book_store', data={'name': 'Foomazon'})
        self.assert200(response)

        self.mock_user = {
            'id': 1,
            'needs': [ItemNeed('update', 2, 'book_store')]
        }

        self.assert403(self.client.patch('/book_store/1', data={'name':
                                                                'Foo'}))

        response = self.client.patch('/book_store/2', data={'name': 'Foo'})
        self.assert200(response)
        self.assertEqual({
            '$uri': '/book_store/2',
            'name': 'Foo'
        }, response.json)

        # TODO DELETE

    def test_yes_no(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': 'yes',
                    'create': 'admin',
                    'update': 'no'
                }

        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.assert200(self.client.post('/book', data={'title': 'Foo'}))
        self.assert403(self.client.patch('/book/1', data={'title': 'Bar'}))
        self.assert200(self.client.get('/book/1'))
        self.assert200(self.client.get('/book'))

    def test_item_need_read(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': ['owns-copy', 'admin'],
                    'create': 'admin',
                    'owns-copy': 'owns-copy'
                }

        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        # TODO Bulk inserts
        # response = self.client.post('/book', data=[
        # {'title': 'GoT Vol. {}'.format(i + 1)} for i in range(20)
        # ])

        for i in range(20):
            self.client.post('/book',
                             data={'title': 'GoT Vol. {}'.format(i + 1)})

        self.assertEqual(20, len(self.client.get('/book').json))

        self.mock_user = {
            'id':
            2,
            'needs': [
                ItemNeed('owns-copy', i, 'book')
                for i in (1, 4, 6, 8, 11, 15, 19)
            ]
        }
        self.assertEqual(7, len(self.client.get('/book').json))

        self.mock_user = {
            'id': 3,
            'needs': [ItemNeed('owns-copy', i, 'book') for i in (2, 7, 19)]
        }

        self.assertEqual([{
            '$uri': '/book/2',
            'title': 'GoT Vol. 2'
        }, {
            '$uri': '/book/7',
            'title': 'GoT Vol. 7'
        }, {
            '$uri': '/book/19',
            'title': 'GoT Vol. 19'
        }],
                         self.client.get('/book').json)

        self.assert404(self.client.get('/book/15'))
        self.assert200(self.client.get('/book/2'))
        self.assert200(self.client.get('/book/7'))
        self.assert404(self.client.get('/book/1'))
        self.assert404(self.client.get('/book/99'))

        self.mock_user = {'id': 4}
        self.assertEqual([], self.client.get('/book').json)

    def test_relationship(self):
        "should require update permission on parent resource for updating, read permissions on both"

        class BookResource(PrincipalResource):
            class Schema:
                author = fields.ToOne('user', nullable=True)

            class Meta:
                model = self.BOOK
                permissions = {
                    'read': ['owns-copy', 'update', 'admin'],
                    'create': 'writer',
                    'update': 'user:author',
                    'owns-copy': 'owns-copy'
                }

        class UserResource(PrincipalResource):
            books = Relation(BookResource)

            class Meta:
                model = self.USER
                permissions = {'create': 'admin'}

        self.api.add_resource(UserResource)
        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        for user in [{
                'name': 'Admin'
        }, {
                'name': 'Author 1'
        }, {
                'name': 'Author 2'
        }]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert403(response)

        self.mock_user = {'id': 2, 'roles': ['writer']}
        response = self.client.post('/book',
                                    data={
                                        'author': {
                                            '$ref': '/user/2'
                                        },
                                        'title': 'Bar'
                                    })

        self.assert200(response)

        self.mock_user = {'id': 3, 'roles': ['writer']}

        response = self.client.post('/book', data={'title': 'Spying: Novel'})
        self.assert200(response)

        response = self.client.post('/book',
                                    data={'title': 'Spied: The Sequel'})
        self.assert200(response)

        response = self.client.post('/book',
                                    data={'title': 'Spy: The Prequel'})
        self.assert200(response)
        self.assertJSONEqual(
            {
                '$uri': '/book/4',
                'author': None,
                'title': 'Spy: The Prequel'
            }, response.json)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.client.post('/user/3/books', data={'$ref': '/book/2'})
        self.client.post('/user/3/books', data={'$ref': '/book/3'})
        self.client.post('/user/3/books', data={'$ref': '/book/4'})

        self.mock_user = {'id': 3, 'roles': ['writer']}
        self.assert200(response)

        response = self.client.get('/user/3/books')
        self.assert200(response)
        self.assertEqual(3,
                         len(response.json))  # read -> update -> user:author

        self.mock_user = {'id': 4, 'needs': [ItemNeed('owns-copy', 3, 'book')]}

        response = self.client.get('/user/3/books')
        self.assertEqual(1, len(response.json))  # read -> owns-copy

        self.assert200(self.client.get('/book/3'))
        self.assert404(self.client.get('/book/2'))

        self.mock_user = {'id': 5}
        response = self.client.get('/user/3/books')
        self.assertEqual(0, len(response.json))
        self.assert404(self.client.get('/book/2'))

    @unittest.SkipTest
    def test_item_route(self):
        "should require read permission on parent resource plus any additional permissions"
        pass

    def test_permission_circular(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': 'create',
                    'create': 'read',
                    'update': 'create',
                    'delete': 'update'
                }

        self.api.add_resource(BookResource)

        with self.assertRaises(RuntimeError):
            BookResource.manager._needs
示例#52
0
from flask_sqlalchemy import SQLAlchemy, Model
from sqlalchemy import Column, DateTime, BigInteger
from flask_potion import Api, fields
from flask_cors import CORS

from datetime import datetime, date


class TimedModel(Model):
    id = Column(BigInteger, primary_key=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime,
                        default=datetime.utcnow,
                        onupdate=datetime.utcnow,
                        nullable=False)

    def __repr__(self):
        return "<{} #{}>".format(self.__class__.__name__, self.id)


app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app, model_class=TimedModel)
CORS(app, expose_headers=['X-Total-Count', 'Link', 'Date'])

from app.resources import VideoResource, ViewResource, OverrideManger

API = Api(app, default_manager=OverrideManger)
API.add_resource(ViewResource)
API.add_resource(VideoResource)
示例#53
0
from mongoengine import StringField, IntField

from flask_potion import Api, ModelResource, fields
from flask.ext.potion.contrib.mongoengine.manager import MongoEngineManager

app = Flask(__name__)
app.debug = True
app.config['MONGODB_DB'] = 'potion-example'

me = MongoEngine(app)

class Book(me.Document):
    title = StringField(null=False, unique=True)
    year_published = IntField(null=True)


class BookResource(ModelResource):
    class Meta:
        name = 'book'
        model = Book

    class Schema:
        year_published = fields.Integer(minimum=1400)


api = Api(app, default_manager=MongoEngineManager)
api.add_resource(BookResource)

if __name__ == '__main__':
    app.run()
示例#54
0
class NaturalKeyTestCase(BaseTestCase):

    def setUp(self):
        super(NaturalKeyTestCase, self).setUp()
        self.api = Api(self.app, prefix='/api')

    def test_simple_key(self):
        class Foo(ModelResource):
            class Meta:
                key_converters = [
                    RefKey()
                ]
                model = 'foo'
                manager = MemoryManager

            class Schema:
                inception = fields.ToOne('foo')

        self.api.add_resource(Foo)

        foo_field = fields.ToOne(Foo)

        self.assertJSONEqual(FOO_REFERENCE, foo_field.response)
        self.assertJSONEqual(FOO_REFERENCE, foo_field.request)

    def test_multiple_keys(self):
        with self.assertRaises(RuntimeError) as cx:
            class Bar(ModelResource):
                class Meta:
                    key_converters = (
                        RefKey(),
                        PropertyKey('name')
                    )
                    model = 'bar'
                    natural_key = 'alias'
                    manager = MemoryManager

                class Schema:
                    name = fields.String()
                    alias = fields.String()

            self.api.add_resource(Bar)
        self.assertEqual('Multiple keys of type string defined for bar', cx.exception.args[0])


    def test_property_key(self):
        class Foo(ModelResource):
            class Schema:
                name = fields.String()

            class Meta:
                natural_key = 'name'
                manager = MemoryManager
                model = 'foo'

        self.api.add_resource(Foo)

        foo_field = fields.ToOne(Foo)

        self.assertJSONEqual(FOO_REFERENCE, foo_field.response)
        self.assertJSONEqual({
                                 "anyOf": [
                                     FOO_REFERENCE,
                                     {
                                         "type": "integer"
                                     },
                                     {
                                         "type": "string"
                                     }
                                 ]
                             }, foo_field.request)


        response = self.client.post('/api/foo', data={
            "name": "Jane"
        })
        self.assert200(response)

        response = self.client.post('/api/foo', data={
            "name": "John"
        })
        self.assert200(response)

        self.assertEqual(
            {'id': 2, 'name': 'John'},
            foo_field.convert(2)
        )

        self.assertEqual(
            {'id': 1, 'name': 'Jane'},
            foo_field.convert('Jane')
        )

        with self.assertRaises(ValidationError):
            foo_field.convert(['John'])

        with self.assertRaises(ItemNotFound) as cx:
            foo_field.convert('Joanne')

        self.assertEqual({
            "message": "Not Found",
            "status": 404,
            "item": {
                "$type": "foo",
                "$where": {
                    "name": "Joanne"
                }
            }
        }, cx.exception.as_dict())

    def test_properties_key(self):
        class Foo(ModelResource):
            class Schema:
                first_name = fields.String()
                last_name = fields.String()

            class Meta:
                natural_key = ['first_name', 'last_name']
                manager = MemoryManager
                model = 'foo'
                name = 'foo'

        self.api.add_resource(Foo)

        foo_field = fields.ToOne(Foo, nullable=True)

        self.assertJSONEqual(FOO_REFERENCE_NULLABLE, foo_field.response)
        self.assertJSONEqual({
                                 "anyOf": [
                                     FOO_REFERENCE,
                                     {
                                         "type": "integer"
                                     },
                                     {
                                         "type": "array",
                                         "items": [{"type": "string"}, {"type": "string"}],
                                         "additionalItems": False
                                     },
                                     {
                                         "type": "null"
                                     }
                                 ]
                             }, foo_field.request)

        response = self.client.post('/api/foo', data={
            "first_name": "Jane",
            "last_name": "Doe"
        })
        self.assert200(response)

        response = self.client.post('/api/foo', data={
            "first_name": "John",
            "last_name": "Doe"
        })
        self.assert200(response)

        self.assertEqual(
            {'first_name': 'Jane', 'id': 1, 'last_name': 'Doe'},
            foo_field.convert(1)
        )

        self.assertEqual(
            {'first_name': 'John', 'id': 2, 'last_name': 'Doe'},
            foo_field.convert(['John', 'Doe'])
        )

        self.assertEqual(
            {'first_name': 'John', 'id': 2, 'last_name': 'Doe'},
            foo_field.convert({"$ref": "/api/foo/2"})
        )

        with self.assertRaises(ItemNotFound) as cx:
            foo_field.convert(['John', 'Joe'])

        self.assertEqual({
            "message": "Not Found",
            "status": 404,
            "item": {
                "$type": "foo",
                "$where": {
                    "first_name": "John",
                    "last_name": "Joe"
                }
            }
        }, cx.exception.as_dict())

        with self.assertRaises(ValidationError):
            foo_field.convert(['John', None])
示例#55
0
class PeeweeRelationTestCase(BaseTestCase):
    def setUp(self):
        super(PeeweeRelationTestCase, self).setUp()

        self.app.config['DATABASE'] = 'sqlite://'
        self.db = db = PeeweeTestDB(self.app)
        self.api = Api(self.app)

        class User(db.Model):
            parent = pw.ForeignKeyField('self', related_name='children',
                                        null=True)
            name = pw.CharField(max_length=60, null=False)

        class Group(db.Model):
            name = pw.CharField(max_length=60, null=False)
            members = ManyToManyField(User, related_name='memberships')

        db.database.connect()
        db.database.create_tables([
            User,
            Group,
            Group.members.get_through_model()])

        self.User = User
        self.Group = Group

        class UserResource(ModelResource):
            class Meta:
                model = User
                include_id = True
                include_type = True
                manager = PeeweeManager

            children = Relation('self')

        class GroupResource(ModelResource):
            class Meta:
                model = Group
                include_id = True
                include_type = True
                manager = PeeweeManager

            members = Relation('user')

        self.api.add_resource(UserResource)
        self.api.add_resource(GroupResource)

    def tearDown(self):
        self.db.database.drop_tables([
            self.Group.members.get_through_model(),
            self.Group,
            self.User])

        if not self.db.database.is_closed():
            self.db.database.close()

    def test_relationship_secondary(self):
        response = self.client.post('/group', data={'name': 'Foo'})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'group',
            'name': 'Foo'},
            response.json)

        response = self.client.post('/user', data={'name': 'Bar'})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'user',
            'name': 'Bar'},
            response.json)

        response = self.client.get('/group/1/members')
        self.assert200(response)
        self.assertJSONEqual([], response.json)

        response = self.client.post(
            '/group/1/members', data={'$ref': '/user/1'})
        self.assert200(response)
        self.assertJSONEqual({'$ref': '/user/1'}, response.json)

        response = self.client.get('/group/1/members')
        self.assert200(response)
        self.assertJSONEqual([{'$ref': '/user/1'}], response.json)

    def test_relationship_secondary_delete_missing(self):
        response = self.client.post('/group', data={"name": "Foo"})
        response = self.client.post('/user', data={"name": "Bar"})

        response = self.client.delete('/group/1/members/1')
        self.assertStatus(response, 204)

    def test_relationship_post(self):
        response = self.client.post('/user', data={'name': 'Foo'})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 1,
            '$type': 'user',
            'name': 'Foo'},
            response.json)

        response = self.client.post('/user', data={'name': 'Bar'})
        self.assert200(response)
        self.assertJSONEqual({
            '$id': 2,
            '$type': 'user',
            'name': 'Bar'},
            response.json)

        response = self.client.post(
            '/user/1/children', data={'$ref': '/user/2'})
        self.assert200(response)
        self.assertJSONEqual({'$ref': '/user/2'}, response.json)

    def test_relationship_get(self):
        self.test_relationship_post()

        response = self.client.get('/user/1/children')
        self.assert200(response)
        self.assertJSONEqual([{'$ref': '/user/2'}], response.json)

    def test_relationship_delete(self):
        self.test_relationship_post()

        response = self.client.delete('/user/1/children/2')
        self.assertStatus(response, 204)

        response = self.client.get('/user/1/children')
        self.assert200(response)
        self.assertJSONEqual([], response.json)

    def test_relationship_pagination(self):
        response = self.client.post('/user', data={'name': 'Foo'})
        self.assert200(response)

        for i in range(2, 50):
            response = self.client.post('/user', data={'name': str(i)})
            self.assert200(response)
            response = self.client.post(
                '/user/1/children',
                data={'$ref': '/user/{}'.format(response.json['$id'])})
            self.assert200(response)

        response = self.client.get('/user/1/children')
        self.assert200(response)
        self.assertJSONEqual(
            [{'$ref': '/user/{}'.format(i)} for i in range(2, 22)],
            response.json)

        response = self.client.get('/user/1/children?page=3')
        self.assert200(response)
        self.assertJSONEqual(
            [{'$ref': '/user/{}'.format(i)} for i in range(42, 50)],
            response.json)
示例#56
0
    def test_multiple_blueprints(self):
        # Create Blueprints
        api_bp1 = Blueprint("potion1", __name__.split(".")[0])
        api_bp2 = Blueprint("potion2", __name__.split(".")[0], url_prefix="/api")

        # Create Api objects, add resources, and register blueprints with app
        api1 = Api(api_bp1, prefix="/api/v1")
        api2 = Api(api_bp2, prefix="/v2")
        api1.add_resource(self.SampleResource)

        with self.assertRaises(RuntimeError):
           api2.add_resource(self.SampleResource)

        api2.add_resource(self.SampleResource2)
        self.app.register_blueprint(api_bp1)
        self.app.register_blueprint(api_bp2)

        # Test both endpoints
        response = self.client.get("/api/v1/samples")
        self.assert200(response)

        response = self.client.get("/api/v2/samples")
        self.assert200(response)

        response = self.client.get("/api/v1/schema")
        self.assert200(response)
        self.assertEqual('/api/v1/samples/schema#', response.json['properties']['samples']['$ref'])

        response = self.client.get("/api/v2/schema")
        self.assert200(response)
        self.assertEqual('/api/v2/samples/schema#', response.json['properties']['samples']['$ref'])

        response = self.client.get("/api/v1/samples/schema")
        self.assertEqual('^\\/api\\/v1\\/samples\\/[^/]+$', response.json['properties']['$uri']['pattern'])

        response = self.client.get("/api/v2/samples/schema")
        self.assertEqual('^\\/api\\/v2\\/samples\\/[^/]+$', response.json['properties']['$uri']['pattern'])

        # Test that we have two prefix'd schemas
        response = self.client.get("/api/v1/schema")
        self.assert200(response)
        v1_schema = json.loads(response.data)
        response = self.client.get("/api/v2/schema")
        self.assert200(response)
        v2_schema = json.loads(response.data)
        assert v1_schema != v2_schema
        assert v1_schema["properties"]["samples"] != v2_schema["properties"]["samples"]

        # Test that endpoints are linked to same resource
        response = self.client.post('/api/v1/samples', data={
            "name": "to_v1"
        })
        self.assert200(response)
        response = self.client.post('/api/v2/samples', data={
            "name": "to_v2"
        })
        self.assert200(response)
        response = self.client.get("/api/v1/samples/1")
        assert response.json['$uri'] == "/api/v1/samples/1"
        self.assert200(response)
        response = self.client.get("/api/v2/samples/1")
        assert response.json['$uri'] == "/api/v2/samples/1"
        self.assert200(response)
示例#57
0
class RelationTestCase(BaseTestCase):
    def setUp(self):
        super(RelationTestCase, self).setUp()
        self.api = Api(self.app)

    def test_pagination(self):
        class Person(ModelResource):
            class Schema:
                name = fields.String()

            class Meta:
                name = "person"
                model = name
                manager = MemoryManager

        self.api.add_resource(Person)

        response = self.client.get('/person')
        self.assert200(response)

        self.assertEqual('0', response.headers.get('X-Total-Count'))
        self.assertEqual(
            '</person?page=1&per_page=20>; rel="self",'
            '</person?page=1&per_page=20>; rel="last"',
            response.headers['Link'])

        for i in range(1, 51):
            response = self.client.post('/person', data={"name": str(i)})
            self.assert200(response)

        response = self.client.get('/person')
        self.assert200(response)
        self.assertJSONEqual([{
            "$uri": "/person/{}".format(i),
            "name": str(i)
        } for i in range(1, 21)], response.json)

        response = self.client.get('/person?page=3')
        self.assert200(response)

        self.assertEqual('50', response.headers.get('X-Total-Count'))
        self.assertEqual(
            '</person?page=3&per_page=20>; rel="self",'
            '</person?page=1&per_page=20>; rel="first",'
            '</person?page=2&per_page=20>; rel="prev",'
            '</person?page=3&per_page=20>; rel="last"',
            response.headers['Link'])
        self.assertJSONEqual([{
            "$uri": "/person/{}".format(i),
            "name": str(i)
        } for i in range(41, 51)], response.json)

    def test_where_to_one(self):
        class Person(ModelResource):
            class Schema:
                name = fields.String()
                mother = fields.ToOne('person', nullable=True)

            class Meta:
                name = "person"
                model = name
                manager = MemoryManager

        self.api.add_resource(Person)

        response = self.client.post('/person', data={'name':
                                                     'Anna'})  # No. Bad

        self.assert200(response)
        self.assertJSONEqual(
            {
                '$uri': '/person/1',
                'mother': None,
                'name': 'Anna'
            }, response.json)

        self.client.post('/person',
                         data={
                             'name': 'Betty',
                             'mother': {
                                 "$ref": "/person/1"
                             }
                         })

        self.client.post('/person',
                         data={
                             'name': 'Bob',
                             'mother': {
                                 "$ref": "/person/1"
                             }
                         })

        self.client.post('/person',
                         data={
                             'name': 'Foo',
                             'mother': {
                                 "$ref": "/person/2"
                             }
                         })

        self.client.post('/person',
                         data={
                             'name': 'Clare',
                             'mother': {
                                 "$ref": "/person/2"
                             }
                         })

        response = self.client.get('/person?where={"mother": null}')
        self.assertJSONEqual([{
            '$uri': '/person/1',
            'mother': None,
            'name': 'Anna'
        }], response.json)

        response = self.client.get(
            '/person?where={"mother": {"$ref": "/person/1"}}')
        self.assertJSONEqual([{
            '$uri': '/person/2',
            'mother': {
                '$ref': '/person/1'
            },
            'name': 'Betty'
        }, {
            '$uri': '/person/3',
            'mother': {
                '$ref': '/person/1'
            },
            'name': 'Bob'
        }], response.json)

        response = self.client.get(
            '/person?where={"mother": {"$ref": "/person/2"}, "name": {"$startswith": "C"}}'
        )
        self.assertJSONEqual([{
            '$uri': '/person/5',
            'mother': {
                '$ref': '/person/2'
            },
            'name': 'Clare'
        }], response.json)
示例#58
0
class ModelResourceTestCase(BaseTestCase):

    def setUp(self):
        super(ModelResourceTestCase, self).setUp()
        self.api = Api(self.app, default_manager=MemoryManager)

    def test_schema_io(self):

        class FooResource(ModelResource):
            class Schema:
                name = fields.String()
                secret = fields.String(io="c")
                slug = fields.String(io="cr")

            class Meta:
                name = "foo"

        self.api.add_resource(FooResource)

        response = self.client.post("/foo", data={
            "name": "Foo",
            "secret": "mystery",
            "slug": "foo"
        })

        self.assert200(response)
        self.assertEqual({
            "$uri": "/foo/1", 
            "name": "Foo",
            "slug": "foo"
        }, response.json)

        self.assertEqual({
            "id": 1,
            "name": "Foo",
            "slug": "foo",
            "secret": "mystery"
        }, FooResource.manager.items[1])

        response = self.client.patch("/foo/1", data={
            "name": "Bar",
            "secret": "123456"
        })

        self.assert400(response)

        response = self.client.patch("/foo/1", data={
            "name": "Bar"
        })

        self.assert200(response)

        self.assertEqual({
            "$uri": "/foo/1",
            "name": "Bar",
            "slug": "foo"
        }, response.json)

        self.assertEqual({
            "id": 1,
            "name": "Bar",
            "slug": "foo",
            "secret": "mystery"
        }, FooResource.manager.items[1])

    def test_inline_schema(self):
        class FooResource(ModelResource):
            class Meta:
                name = "foo"


        class BarResource(ModelResource):
            class Meta:
                name = "bar"

        self.api.add_resource(FooResource)
        self.api.add_resource(BarResource)

        foo = fields.Inline(FooResource)
        foo.bind(BarResource)

        self.assertEqual({'$ref': '/foo/schema'}, foo.response)

    def test_schema_io_create_flag(self):

        class FooResource(ModelResource):
            class Schema:
                name = fields.String()
                slug = fields.String(io="cr")

            class Meta:
                name = "foo"

        self.api.add_resource(FooResource)
        data, code, headers = FooResource().described_by()
        [create_link] = [
            link for link in data['links'] if link['rel'] == 'create']
        [update_link] = [
            link for link in data['links'] if link['rel'] == 'update']
        self.assertEqual({'$ref': '#'}, create_link['schema'])
        self.assertEqual({
                             "type": "object",
                             "additionalProperties": False,
                             "properties": {
                                 "name": {
                                     "type": "string"
                                 }
                             }
                         }, update_link["schema"])
        self.assertEqual(
            ["$uri", "name", "slug"],  sorted(data["properties"].keys()))
class PeeeeFilterTestCase(BaseTestCase):
    def setUp(self):
        super(PeeeeFilterTestCase, self).setUp()
        app = self.app
        app.config['DATABASE'] = 'sqlite://'

        self.db = db = PeeweeTestDB(self.app)
        self.api = Api(self.app, default_manager=PeeweeManager)
        app.debug = True

        class User(db.Model):
            id = IntegerField(primary_key=True)
            first_name = CharField(max_length=60, null=False)
            last_name = CharField(max_length=60, null=False)

            gender = CharField(max_length=1, null=True)

            age = IntegerField()

            is_staff = BooleanField(default=None)

        db.database.connect()
        db.database.create_tables([User])

        class UserResource(ModelResource):
            class Schema:
                gender = fields.String(enum=['f', 'm'], nullable=True)

            class Meta:
                model = User

        class AllowUserResource(ModelResource):
            class Meta:
                model = User
                name = 'allow-user'
                allowed_filters = {'first_name': ['$eq'], 'is_staff': '*'}

        self.api.add_resource(UserResource)
        self.api.add_resource(AllowUserResource)

    def post_sample_set_a(self):
        for user in [{
                'first_name': 'John',
                'last_name': 'Doe',
                'age': 32,
                'is_staff': True,
                'gender': 'm'
        }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe',
                'age': 25,
                'is_staff': False,
                'gender': 'm'
        }, {
                'first_name': 'Jane',
                'last_name': 'Roe',
                'age': 18,
                'is_staff': False,
                'gender': 'f'
        }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs',
                'age': 21,
                'is_staff': True,
                'gender': 'm'
        }, {
                'first_name': 'Sue',
                'last_name': 'Watts',
                'age': 25,
                'is_staff': True
        }]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

    def test_equality(self):
        self.post_sample_set_a()

        response = self.client.get('/user?where={"last_name": "Doe"}')

        self.assertEqualWithout([
            {
                'first_name': 'John',
                'last_name': 'Doe'
            },
            {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            },
        ],
                                response.json,
                                without=[
                                    '$uri', '$uri', '$id', '$type', 'gender',
                                    'age', 'is_staff'
                                ])

        response = self.client.get('/user?where={"age": 25}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe',
                    'age': 25
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts',
                    'age': 25
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'is_staff'])

        response = self.client.get(
            '/user?where={"last_name": "Doe", "age": 25}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_inequality(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$ne": "Watts"}, "age": {"$ne": 32}}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Jane',
                    'last_name': 'Roe'
                },
                {
                    'first_name': 'Joe',
                    'last_name': 'Bloggs'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gt": 25}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$gte": 25}}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'John',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lte": 21}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Jane',
                'last_name': 'Roe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": 21.0}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Jane',
                'last_name': 'Roe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"age": {"$lt": null}}')
        self.assert400(response)

        response = self.client.get('/user?where={"first_name": {"$gt": "Jo"}}')
        self.assert400(response)

    def test_in(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$in": ["Bloggs", "Watts"]}}')

        self.assertEqualWithout(
            [{
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }, {
                'first_name': 'Sue',
                'last_name': 'Watts'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get('/user?where={"last_name": {"$in": []}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_startswith(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "Jo"}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "J%e"}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_istartswith(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$istartswith": "jo"}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_iendswith(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"last_name": {"$iendswith": "Oe"}}')

        self.assertEqualWithout(
            [{
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jane',
                'last_name': 'Roe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?where={"first_name": {"$istartswith": "j%e"}}')

        self.assertEqualWithout(
            [],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_text_search(self):
        self.post_sample_set_a()

        response = self.client.get('/user?search=sbc+dedf&rank=1')

    def test_sort(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?sort={"last_name": true, "first_name": false}')

        self.assert200(response)
        self.assertEqualWithout(
            [{
                'first_name': 'Sue',
                'last_name': 'Watts'
            }, {
                'first_name': 'Jane',
                'last_name': 'Roe'
            }, {
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }, {
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

        response = self.client.get(
            '/user?sort={"age": false, "first_name": false}')

        self.assertEqualWithout(
            [
                {
                    'first_name': 'Jane',
                    'last_name': 'Roe'
                },
                {
                    'first_name': 'Joe',
                    'last_name': 'Bloggs'
                },
                {
                    'first_name': 'Jonnie',
                    'last_name': 'Doe'
                },
                {
                    'first_name': 'Sue',
                    'last_name': 'Watts'
                },
                {
                    'first_name': 'John',
                    'last_name': 'Doe'
                },
            ],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    def test_sort_and_where(self):
        self.post_sample_set_a()

        response = self.client.get(
            '/user?where={"first_name": {"$startswith": "Jo"}}&sort={"first_name": false}'
        )

        self.assertEqualWithout(
            [{
                'first_name': 'Joe',
                'last_name': 'Bloggs'
            }, {
                'first_name': 'John',
                'last_name': 'Doe'
            }, {
                'first_name': 'Jonnie',
                'last_name': 'Doe'
            }],
            response.json,
            without=['$uri', '$id', '$type', 'gender', 'age', 'is_staff'])

    @unittest.SkipTest
    def test_sort_pages(self):
        pass

    @unittest.SkipTest
    def test_disallowed_where_filters(self):
        pass

    @unittest.SkipTest
    def test_schema(self):
        pass
示例#60
0
    title = db.Column(db.String(), nullable=False)
    year_published = db.Column(db.Integer)

    author = db.relationship(Author, backref=backref('books', lazy='dynamic'))


db.create_all()


class BookResource(ModelResource):
    class Meta:
        model = Book

    class Schema:
        author = fields.ToOne('author')


class AuthorResource(ModelResource):
    books = Relation('book')

    class Meta:
        model = Author
        natural_key = ('first_name', 'last_name')


api = Api(app)
api.add_resource(BookResource)
api.add_resource(AuthorResource)

if __name__ == '__main__':
    app.run()