Exemple #1
0
def test_init_db(db: SQLAlchemy, config: Config):
    """Tests :meth:`teal.resource.Resource.init_db` with one inventory."""

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

    class FooDef(Resource):
        __type__ = 'Foo'

        def init_db(self, db: SQLAlchemy, exclude_schema=None):
            db.session.add(Foo())

    config.RESOURCE_DEFINITIONS = FooDef,
    app = Teal(config=config, db=db)
    with app.app_context():
        app.init_db()
    with app.app_context():
        # If no commit happened in init_db() or anything else
        # this would not exist
        assert Foo.query.filter_by(id=1).one()

    # Test again but executing init-db through the command-line
    runner = app.test_cli_runner()
    runner.invoke('init-db')
    with app.app_context():
        assert Foo.query.filter_by(id=2).one()

    # Test with --erase option
    runner.invoke('init-db', '--erase')
    with app.app_context():
        assert Foo.query.count() == 1
Exemple #2
0
def test_etag_secondary(client: Client, app: Teal):
    """Tests creating, linking and accessing an ETag through
    its secondary (NFC) id."""
    with app.app_context():
        et = ETag(secondary='NFCID')
        db.session.add(et)
        db.session.commit()
    client.get('/', item='NFCID', accept=ANY, status=400)
    with app.app_context():
        tag = ETag.query.filter_by(secondary='NFCID').one()
        tag.devicehub = URL('https://dh.com')
        db.session.commit()
    _, r = client.get('/', item='NFCID', accept=ANY, status=302)
    assert r.location == 'https://dh.com/tags/FO-3MP5M/device'
Exemple #3
0
def test_tag_export(runner: FlaskCliRunner, app: Teal):
    with app.app_context():
        t = ETag()
        db.session.add(t)
        db.session.commit()
    with NamedTemporaryFile('r+') as f:
        result = runner.invoke(args=('export', f.name), catch_exceptions=False)
        assert result.exit_code == 0
        result = runner.invoke(args=('import', f.name), catch_exceptions=False)
        assert result.exit_code == 0
    with app.app_context():
        t = Tag()
        db.session.add(t)
        db.session.commit()
        assert Tag.decode(t.id) == 2
Exemple #4
0
def test_json_encoder(app: Teal):
    """
    Ensures that Teal is using the custom JSON Encoder through Flask's
    json.
    """
    with app.app_context():
        # Try to dump a type flask's json encoder cannot handle
        json.dumps({'foo': StrictVersion('1.3')})
Exemple #5
0
def test_get_not_linked_tag(app: Teal, client: Client):
    """Tests getting a tag that has not been linked yet to a Devicehub."""
    with app.app_context():
        t = Tag()
        db.session.add(t)
        db.session.commit()
        id = t.id
    client.get(res=Tag.t, item=id, status=NoRemoteTag)
Exemple #6
0
def test_not_found(app: Teal):
    """
    When not finding a resource, the db should raise a ``NotFound``
    exception instead of the built-in for SQLAlchemy.
    """
    with app.app_context():
        Device = app.resources['Device'].MODEL
        with pytest.raises(NotFound):
            Device.query.one()
Exemple #7
0
def test_validator_is_type(app: Teal):
    """Checks the validator IsType"""
    with app.app_context():
        is_type = IsType()
        is_type('Device')
        is_type('Component')
        with pytest.raises(ValidationError):
            is_type('Foo')

        is_subtype = IsType('Component')
        is_subtype('Component')
        with pytest.raises(ValidationError):
            is_subtype('Computer')
Exemple #8
0
def test_models(app: Teal, db: SQLAlchemy):
    """Checks that the models used in the fixture work."""
    DeviceDef, ComponentDef, ComputerDef = \
        app.config['RESOURCE_DEFINITIONS']  # type: Tuple[ResourceDef]
    Component = ComponentDef.MODEL
    Computer = ComputerDef.MODEL

    component = Component(id=1, model='foo')
    pc = Computer(id=2, model='bar', components=[component])
    with app.app_context():
        db.session.add(pc)
        queried_pc = Computer.query.first()
        assert pc == queried_pc
Exemple #9
0
def test_nested_on(fconfig: Config, db: SQLAlchemy):
    """Tests the NestedOn marshmallow field."""
    DeviceDef, ComponentDef, ComputerDef = fconfig.RESOURCE_DEFINITIONS

    class GraphicCardSchema(ComponentDef.SCHEMA):
        speed = Integer()

    class GraphicCard(ComponentDef.MODEL):
        speed = db.Column(db.Integer)

    class GraphicCardDef(ComponentDef):
        SCHEMA = GraphicCardSchema
        MODEL = GraphicCard

    fconfig.RESOURCE_DEFINITIONS += (GraphicCardDef,)

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

    pc_template = {
        'id': 1,
        'components': [
            {'id': 2, 'type': 'Component'},
            {'id': 3, 'type': 'GraphicCard', 'speed': 4}
        ]
    }
    with app.app_context():
        schema = app.resources['Computer'].SCHEMA()
        result = schema.load(pc_template)
        assert pc_template['id'] == result['id']
        assert isinstance(result['components'][0], ComponentDef.MODEL)
        assert isinstance(result['components'][1], GraphicCardDef.MODEL)
        # Let's add the graphic card's speed field to the component
        with pytest.raises(ValidationError, message={'components': {'speed': ['Unknown field']}}):
            pc = deepcopy(pc_template)
            pc['components'][0]['speed'] = 4
            schema.load(pc)
        # Let's remove the 'type'
        with pytest.raises(ValidationError,
                           message={
                               'components': ['\'Type\' field required to disambiguate resources.']
                           }):
            pc = deepcopy(pc_template)
            del pc['components'][0]['type']
            del pc['components'][1]['type']
            schema.load(pc)
        # Let's set a 'type' that is not a Component
        with pytest.raises(ValidationError,
                           message={'components': ['Computer is not a sub-type of Component']}):
            pc = deepcopy(pc_template)
            pc['components'][0]['type'] = 'Computer'
            schema.load(pc)
Exemple #10
0
def test_tag_creation(app: Teal):
    with app.app_context():
        t = Tag()
        db.session.add(t)
        db.session.commit()
        assert t.id
        assert t.devicehub is None
        assert t.id == '3MP5M'

        et = ETag()
        db.session.add(et)
        db.session.commit()
        assert et.id == 'FO-WNBRM'
        assert et.id.split('-')[0] == 'FO'
        assert len(et.id.split('-')[1]) == 5
        assert et.devicehub is None
Exemple #11
0
def test_query_sort(app: Teal):
    """Tests sorting params."""
    with app.app_context():
        Device = app.resources['Device'].MODEL

        class Sorting(Sort):
            models = SortField(Device.model)
            ids = SortField(Device.id)

        schema = Sorting()
        sort = tuple(
            str(s) for s in schema.load({
                'models': True,
                'ids': False
            }))
        assert len(sort) == 2
        assert 'device.model ASC' in sort
        assert 'device.id DESC' in sort
Exemple #12
0
def test_query_join(app: Teal):
    """Checks that nested queries work."""
    with app.app_context():
        Device = app.resources['Device'].MODEL
        Computer = app.resources['Computer'].MODEL

        class Inner(Query):
            foo = ILike(Device.model)

        class Q(Query):
            idq = Between(Device.id, Integer())
            componentq = Join(Device.id == Computer.id, Inner)

        schema = Q()
        query = schema.load({'idq': [1, 4], 'componentq': {'foo': 'bar'}})
        s, params = compiled(Device, query)
        assert 'device.id BETWEEN %(id_1)s AND %(id_2)s' in s
        assert 'device.model ILIKE %(model_1)s' in s
        assert params == {'id_1': 1, 'model_1': 'bar%', 'id_2': 4}
Exemple #13
0
def test_query(app: Teal):
    with app.app_context():
        Device = app.resources['Device'].MODEL

        class Q(Query):
            idq = Or(Equal(Device.id, Str()))
            modelq = ILike(Device.model)

        schema = Q()
        query = schema.load({'idq': ['a', 'b', 'c'], 'modelq': 'foobar'})
        s, params = compiled(Device, query)
        # Order between query clauses can change
        assert 'device.model ILIKE %(model_1)s' in s
        assert '(device.id = %(id_1)s OR device.id = %(id_2)s OR device.id = %(id_3)s' in s
        assert params == {
            'id_2': 'b',
            'id_3': 'c',
            'id_1': 'a',
            'model_1': 'foobar%'
        }
Exemple #14
0
def app_context(app: Teal):
    with app.app_context():
        yield
Exemple #15
0
def app(fconfig: Config, db: SQLAlchemy) -> Teal:
    app = Teal(config=fconfig, db=db)
    with app.app_context():
        app.init_db()
    yield app