示例#1
0
def test_item_path(fconfig: Config, db: SQLAlchemy):
    """
    Tests that the URL converter works for the item endpoints of
    the resources.

    The following test has set an URL converter of type int, and will
    allow only integers using the flask rules.
    """
    DeviceDef, *_ = fconfig.RESOURCE_DEFINITIONS  # type: Tuple[ResourceDef, ...]

    def cannot_find(id):
        assert id == 1
        return Response(status=200)

    DeviceDef.VIEW.one = MagicMock(side_effect=cannot_find)
    app = Teal(config=fconfig, db=db)
    client = app.test_client()  # type: Client
    with populated_db(db, app):
        # All ok, we expect an int and got an int
        client.get(res=DeviceDef.type, item=1)
        DeviceDef.VIEW.one.assert_called_once_with(1)
        # Conversion of 'int' works in here
        client.get(res=DeviceDef.type, item='1')
        assert DeviceDef.VIEW.one.call_count == 2
        # Anything else fails and our function is directly not executed
        client.get(res=DeviceDef.type, item='foo', status=NotFound)
        assert DeviceDef.VIEW.one.call_count == 2
示例#2
0
def test_post(fconfig: Config, db: SQLAlchemy):
    """
    Tests posting resources, going through API (Marshmallow) and DB
    (SQLAlchemy) validation, and retrieving and returning a result.
    """
    DeviceDef, ComponentDef, ComputerDef = fconfig.RESOURCE_DEFINITIONS  # type: Tuple[ResourceDef]
    Computer = ComputerDef.MODEL
    Component = ComponentDef.MODEL
    PC = {
        'id': 1,
        'model': 'foo',
        'components': [{'id': 2, 'type': 'Component'}, {'id': 3, 'type': 'Component'}]
    }

    def post():
        pc = request.get_json()
        pc = Computer(**pc)
        db.session.add(pc)
        db.session.commit()
        return Response(status=201)

    def _one(id):
        pc = Computer.query.filter_by(id=id).first()
        return_pc = {
            'id': pc.id,
            'model': pc.model,
            'type': pc.type,
        }
        # todo convert components to JSON
        return return_pc

    def one(id: int):
        return jsonify(_one(id))

    def find(_):
        return jsonify([_one(1)])

    ComputerDef.VIEW.post = MagicMock(side_effect=post)
    ComputerDef.VIEW.one = MagicMock(side_effect=one)
    ComputerDef.VIEW.find = MagicMock(side_effect=find)

    app = Teal(config=fconfig, db=db)

    client = app.test_client()  # type: Client
    with populated_db(db, app):
        client.post(res=ComputerDef.type, data=PC)
        # Wrong data
        data, _ = client.post(res=ComputerDef.type, data={'id': 'foo'}, status=ValidationError)
        assert data == {
            'code': 422,
            'type': 'ValidationError',
            'message': {'id': ['Not a valid integer.']}
        }
        # Get the first data
        data, _ = client.get(res=ComputerDef.type, item=1)
        assert data == {'id': 1, 'model': 'foo', 'type': 'Computer'}
        # Get all data
        data, _ = client.get(res=ComputerDef.type)
        assert data == [{'id': 1, 'model': 'foo', 'type': 'Computer'}]
示例#3
0
def test_token_auth_view(db: SQLAlchemy):
    """
    Ensures that an authorization endpoint correctly protects against
    wrong credentials (this case tokens), allowing the endpoint
    to only specific cases.
    """

    class TestTokenAuth(TokenAuth):
        authenticate = MagicMock(side_effect=Unauthorized)

    class FooSchema(Schema):
        pass

    class FooView(View):
        get = MagicMock(side_effect=lambda id: jsonify({'did': 'it!'}))

    class Foo(db.Model):
        id = db.Column(db.Integer, primary_key=True)

    class FooDef(Resource):
        SCHEMA = FooSchema
        VIEW = FooView
        MODEL = Foo
        AUTH = True

    class TestConfig(Config):
        RESOURCE_DEFINITIONS = [FooDef]

    app = Teal(config=TestConfig(), Auth=TestTokenAuth, db=db)
    client = app.test_client()

    # No token
    # No auth header sent
    client.get(res=FooSchema.t, status=Unauthorized)
    assert TestTokenAuth.authenticate.call_count == 0

    # Wrong format
    # System couldn't parse Auth header
    client.get(res=FooSchema.t, token='this is wrong', status=Unauthorized)
    assert TestTokenAuth.authenticate.call_count == 0

    # Wrong credentials
    # System can parse credentials but they are incorrect
    client.get(res=FooSchema.t, token=b64encode(b'nok:').decode(), status=Unauthorized)
    # Authenticate method was hit
    assert TestTokenAuth.authenticate.call_count == 1

    # OK
    # Our authenticate method now returns some dummy user instead of
    # raising Unauthorized
    TestTokenAuth.authenticate = MagicMock(return_value={'id': '1'})
    data, _ = client.get(res=FooSchema.t, token=b64encode(b'ok:').decode())
    TestTokenAuth.authenticate.assert_called_once_with('ok', '')
    # The endpoint was hit
    assert data == {'did': 'it!'}
    FooView.get.assert_called_once_with(id=None)
示例#4
0
文件: conftest.py 项目: eReuse/teal
def client(app: Teal) -> Client:
    return app.test_client()