Example #1
0
def test_abbr_nested():
    class app(morepath.App):
        pass

    class Model(object):
        pass

    @app.path(path='/', model=Model)
    def get_model():
        return Model()

    with app.view(model=Model) as view:

        @view()
        def default(self, request):
            return "Default"

        with view(name='extra') as view:

            @view()
            def get(self, request):
                return "Get"

            @view(request_method='POST')
            def post(self, request):
                return "Post"

    c = Client(app())

    response = c.get('/')
    assert response.body == b'Default'

    response = c.get('/extra')
    assert response.body == b'Get'

    response = c.post('/extra')
    assert response.body == b'Post'
Example #2
0
def test_default_datetime_converter():
    class app(morepath.App):
        pass

    class Model(object):
        def __init__(self, d):
            self.d = d

    from datetime import datetime

    @app.path(model=Model, path='/')
    def get_model(d=datetime(2011, 1, 1, 10, 30)):
        return Model(d)

    @app.view(model=Model)
    def default(self, request):
        return "View: %s" % self.d

    @app.view(model=Model, name='link')
    def link(self, request):
        return request.link(self)

    c = Client(app())

    response = c.get('/?d=20121110T144530')
    assert response.body == b"View: 2012-11-10 14:45:30"

    response = c.get('/')
    assert response.body == b"View: 2011-01-01 10:30:00"

    response = c.get('/link?d=20121110T144500')
    assert response.body == b'http://localhost/?d=20121110T144500'

    response = c.get('/link')
    assert response.body == b'http://localhost/?d=20110101T103000'

    c.get('/?d=broken', status=400)
Example #3
0
def test_defer_view_predicates():
    class Root(morepath.App):
        pass

    class Sub(morepath.App):
        pass

    @Root.path(path='')
    class RootModel(object):
        pass

    @Root.json(model=RootModel)
    def root_model_default(self, request):
        return request.view(SubModel(), name='edit')

    @Sub.path(path='')
    class SubModel(object):
        pass

    @Sub.json(model=SubModel, name='edit')
    def submodel_edit(self, request):
        return {'hello': 'world'}

    @Root.mount(app=Sub, path='sub')
    def mount_sub():
        return Sub()

    @Root.defer_links(model=SubModel)
    def defer_links_sub_model(app, obj):
        return app.child(Sub())

    dectate.commit(Root, Sub)

    c = Client(Root())

    response = c.get('/')
    assert response.json == {'hello': 'world'}
Example #4
0
def test_extra_parameters_with_get_converters():
    class app(morepath.App):
        pass

    class Model(object):
        def __init__(self, extra_parameters):
            self.extra_parameters = extra_parameters

    def get_converters():
        return {
            'a': int,
            'b': type(u""),
        }

    @app.path(model=Model, path='/', get_converters=get_converters)
    def get_model(extra_parameters):
        return Model(extra_parameters)

    @app.view(model=Model)
    def default(self, request):
        return repr(sorted(self.extra_parameters.items()))

    @app.view(model=Model, name='link')
    def link(self, request):
        return request.link(self)

    c = Client(app())

    response = c.get('/?a=1&b=B')
    assert response.body in \
        (b"[(u'a', 1), (u'b', u'B')]", b"[('a', 1), ('b', 'B')]")
    response = c.get('/link?a=1&b=B')
    assert sorted(response.body[len('http://localhost/?'):].split(b"&")) == [
        b'a=1', b'b=B'
    ]

    c.get('/?a=broken&b=B', status=400)
Example #5
0
def test_json_obj_load():
    class app(morepath.App):
        pass

    class Collection(object):
        def __init__(self):
            self.items = []

        def add(self, item):
            self.items.append(item)

    collection = Collection()

    @app.path(path='/', model=Collection)
    def get_collection():
        return collection

    @app.json(model=Collection, request_method='POST')
    def default(self, request):
        self.add(request.body_obj)
        return 'done'

    class Item(object):
        def __init__(self, value):
            self.value = value

    @app.load_json()
    def load_json(json, request):
        return Item(json['x'])

    c = Client(app())

    c.post_json('/', {'x': 'foo'})

    assert len(collection.items) == 1
    assert isinstance(collection.items[0], Item)
    assert collection.items[0].value == 'foo'
def test_defer_link_acquisition_blocking():
    class root(morepath.App):
        pass

    class sub(morepath.App):
        pass

    @root.path(path='model/{id}')
    class Model(object):
        def __init__(self, id):
            self.id = id

    @root.view(model=Model)
    def model_default(self, request):
        return "Hello"

    @sub.path(path='')
    class SubModel(object):
        pass

    @sub.view(model=SubModel)
    def sub_model_default(self, request):
        try:
            return request.link(Model('foo'))
        except LinkError:
            return "link error"

    @root.mount(app=sub, path='sub')
    def mount_sub():
        return sub()

    # no defer_links_to_parent

    c = Client(root())

    response = c.get('/sub')
    assert response.body == b'link error'
Example #7
0
def test_abbr_nested():
    class app(morepath.App):
        pass

    class Model(object):
        pass

    @app.path(path="/", model=Model)
    def get_model():
        return Model()

    with app.view(model=Model) as view:

        @view()
        def default(self, request):
            return "Default"

        with view(name="extra") as view:

            @view()
            def get(self, request):
                return "Get"

            @view(request_method="POST")
            def post(self, request):
                return "Post"

    c = Client(app())

    response = c.get("/")
    assert response.body == b"Default"

    response = c.get("/extra")
    assert response.body == b"Get"

    response = c.post("/extra")
    assert response.body == b"Post"
Example #8
0
def test_mount_named_child_link_name_defaults_to_path():
    class app(morepath.App):
        pass

    class mounted(morepath.App):
        pass

    @mounted.path(path='models/{id}')
    class Model(object):
        def __init__(self, id):
            self.id = id

    @app.path(path='')
    class Root(object):
        pass

    @app.view(model=Root)
    def app_root_default(self, request):
        return request.link(Model('one'), app=request.app.child(mounted))

    @app.view(model=Root, name='extra')
    def app_root_default2(self, request):
        return request.link(Model('one'), app=request.app.child('subapp'))

    @app.mount(path='subapp', app=mounted)
    def get_context():
        return mounted()

    dectate.commit(app, mounted)

    c = Client(app())

    response = c.get('/')
    assert response.body == b'http://localhost/subapp/models/one'

    response = c.get('/extra')
    assert response.body == b'http://localhost/subapp/models/one'
Example #9
0
def test_url_parameter_explicit_converter_get_converters():
    class app(morepath.App):
        pass

    class Model(object):
        def __init__(self, id):
            self.id = id

    def get_converters():
        return dict(id=Converter(int))

    @app.path(model=Model, path='/', get_converters=get_converters)
    def get_model(id):
        return Model(id)

    @app.view(model=Model)
    def default(self, request):
        return "View: %s (%s)" % (self.id, type(self.id))

    @app.view(model=Model, name='link')
    def link(self, request):
        return request.link(self)

    c = Client(app())

    response = c.get('/?id=1')
    assert response.body in \
        (b"View: 1 (<type 'int'>)", b"View: 1 (<class 'int'>)")

    response = c.get('/link?id=1')
    assert response.body == b'http://localhost/?id=1'

    response = c.get('/?id=broken', status=400)

    response = c.get('/')
    assert response.body in \
        (b"View: None (<type 'NoneType'>)", b"View: None (<class 'NoneType'>)")
Example #10
0
def test_class_link_with_subclass():
    class App(morepath.App):
        pass

    class Model(object):
        pass

    class Sub(Model):
        pass

    @App.path(model=Model, path='/foo/{x}')
    def get_model(x):
        return Model()

    @App.view(model=Model)
    def link(self, request):
        return request.class_link(Sub, variables={'x': 'X'})

    dectate.commit(App)

    c = Client(App())

    response = c.get('/foo/3')
    assert response.body == b"http://localhost/foo/X"
Example #11
0
def test_error_when_path_variable_is_none():
    class App(morepath.App):
        pass

    class Model(object):
        def __init__(self, id):
            self.store_id = id

    @App.path(model=Model,
              path='models/{id}',
              variables=lambda m: {'id': None})
    def get_model(id):
        return Model(id)

    @App.view(model=Model)
    def default(self, request):
        return request.link(self)

    dectate.commit(App)

    c = Client(App())

    with pytest.raises(LinkError):
        c.get('/models/1')
Example #12
0
def test_path_explicit_variables_app_arg():
    class App(morepath.App):
        pass

    class Model(object):
        def __init__(self, id):
            self.store_id = id

    def my_variables(app, m):
        assert isinstance(app, App)
        return {'id': m.store_id}

    @App.path(model=Model, path='models/{id}', variables=my_variables)
    def get_model(id):
        return Model(id)

    @App.view(model=Model)
    def default(self, request):
        return request.link(self)

    c = Client(App())

    response = c.get('/models/1')
    assert response.body == b'http://localhost/models/1'
Example #13
0
def test_deferred_loop():
    class root(morepath.App):
        pass

    class alpha(morepath.App):
        pass

    @root.path(path='')
    class RootModel(object):
        pass

    # not actually exposed with path anywhere!
    class Model(object):
        pass

    @root.json(model=RootModel)
    def root_model_default(self, request):
        return request.link(Model())

    @root.mount(app=alpha, path='alpha')
    def mount_alpha():
        return alpha()

    # setup a loop: defer to parent and back to child!
    @alpha.defer_links(model=Model)
    def defer_links_parent(app, obj):
        return app.parent

    @root.defer_links(model=Model)
    def defer_links_alpha(app, obj):
        return app.child(alpha())

    c = Client(root())

    with pytest.raises(LinkError):
        c.get('/')
Example #14
0
def test_view_after_applies_to_some_exceptions(status_code, exception_class):
    class App(morepath.App):
        pass

    class Root(object):
        pass

    @App.path(model=Root, path='')
    def get_root():
        return Root()

    @App.view(model=Root)
    def view(self, request):
        @request.after
        def set_header(response):
            response.headers.add('Foo', 'FOO')
        raise exception_class()

    dectate.commit(App)

    c = Client(App())

    response = c.get('/', status=status_code)
    assert response.headers.get('Foo') == 'FOO'
def test_marshmallow_schema_class():
    class User(object):
        def __init__(self, name, email):
            self.name = name
            self.email = email

    class UserSchema(Schema):
        name = fields.Str(required=True)
        email = fields.Email(required=True)

    class App(MarshmallowApp):
        pass

    user = User('Somebody', '*****@*****.**')

    @App.path(model=User, path='/')
    def get_user():
        return user

    @App.json(model=User, request_method='PUT', load=loader(UserSchema))
    def user_put(self, request, obj):
        for key, value in obj.items():
            setattr(self, key, value)
        return "done"

    c = Client(App())

    r = c.put_json('/', {
        'name': "Somebody else",
        "email": "*****@*****.**"
    })
    assert user.name == 'Somebody else'
    assert user.email == '*****@*****.**'

    r = c.put_json('/', {'name': 'Another'}, status=422)
    assert r.json == {'email': ['Missing data for required field.']}
Example #16
0
def test_reset_unconsumed_path():
    class TestApp(TransactionApp):
        attempts = 0

    @TestApp.path('/foo/bar')
    class Foo(object):
        pass

    @TestApp.view(model=Foo)
    def view_foo(self, request):
        TestApp.attempts += 1

        # on the first attempt raise a conflict error
        if TestApp.attempts == 1:
            raise Conflict

        return 'ok'

    # if the unconsumed path is reset wrongly, it'll accidentally pick
    # up this model instead of Foo
    @TestApp.path('/bar/foo')
    class Bar(object):
        pass

    @TestApp.view(model=Bar)
    def view_bar(self, request):
        return 'error'

    @TestApp.setting(section='transaction', name='attempts')
    def get_retry_attempts():
        return 2

    client = Client(TestApp())
    response = client.get('/foo/bar')
    assert response.text == 'ok'
    assert TestApp.attempts == 2
Example #17
0
def test_mount_directive_with_link_and_absorb():
    class app1(morepath.App):
        pass

    @app1.path(path="")
    class Model1(object):
        pass

    class app2(morepath.App):
        pass

    class Model2(object):
        def __init__(self, absorb):
            self.absorb = absorb

    @app2.path(model=Model2, path='', absorb=True)
    def get_model(absorb):
        return Model2(absorb)

    @app2.view(model=Model2)
    def default(self, request):
        return "A:%s L:%s" % (self.absorb, request.link(self))

    @app1.mount(path="foo", app=app2)
    def get_mount():
        return app2()

    dectate.commit(app1, app2)

    c = Client(app1())

    response = c.get('/foo')
    assert response.body == b'A: L:http://localhost/foo'

    response = c.get('/foo/bla')
    assert response.body == b'A:bla L:http://localhost/foo/bla'
Example #18
0
def test_access_app_through_request():
    class root(morepath.App):
        pass

    class sub(morepath.App):
        def __init__(self, name):
            self.name = name

    @root.path(path='')
    class RootModel(object):
        pass

    @root.view(model=RootModel)
    def root_model_default(self, request):
        child = request.app.child(sub, mount_name='foo')
        return request.link(SubModel('foo'), app=child)

    class SubModel(object):
        def __init__(self, name):
            self.name = name

    @sub.path(path='', model=SubModel)
    def get_sub_model(request):
        return SubModel(request.app.name)

    @root.mount(app=sub, path='{mount_name}',
                variables=lambda a: {'mount_name': a.name})
    def mount_sub(mount_name):
        return sub(name=mount_name)

    dectate.commit(root, sub)

    c = Client(root())

    response = c.get('/')
    assert response.body == b'http://localhost/foo'
Example #19
0
def test_inject_webassets(tempdir):
    client = Client(spawn_test_app(tempdir))

    assert '<head></head>' in client.get('/').text

    with pytest.raises(KeyError):
        assert '<head></head>' in client.get('?bundle=inexistant').text

    # the version of these assets stays the same because it's basically the
    # md5 hash of the javascript files included
    injected_html = (
        '<script type="text/javascript" '
        'src="/assets/common.bundle.js?ddc71aa3"></script></body>')

    assert injected_html in client.get('?bundle=common').text

    injected_html = (
        '<link rel="stylesheet" type="text/css" '
        'href="/assets/theme.bundle.css?32fda411"></head>')

    assert injected_html in client.get('?bundle=theme').text

    page = client.get('/alljs').text
    assert page.find('common.bundle.js') < page.find('extra.bundle.js')
Example #20
0
def test_absorb_class_path_with_variables():
    class App(morepath.App):
        pass

    class Root(object):
        pass

    class Model(object):
        def __init__(self, id, absorb):
            self.id = id
            self.absorb = absorb

    @App.path(model=Root, path='')
    def get_root():
        return Root()

    @App.path(model=Model, path='{id}', absorb=True)
    def get_model(id, absorb):
        return Model(id, absorb)

    @App.view(model=Model)
    def default(self, request):
        return "I:%s A:%s" % (self.id, self.absorb)

    @App.view(model=Root)
    def default_root(self, request):
        return request.class_link(Model,
                                  variables=dict(id='foo', absorb='a/b'))

    dectate.commit(App)

    c = Client(App())

    # link to a/b absorb
    response = c.get('/')
    assert response.body == b'http://localhost/foo/a/b'
Example #21
0
def test_view_after_doesnt_apply_to_exception():
    class App(morepath.App):
        pass

    class Root(object):
        pass

    @App.path(model=Root, path='')
    def get_root():
        return Root()

    @App.view(model=Root)
    def view(self, request):
        @request.after
        def set_header(response):
            response.headers.add('Foo', 'FOO')
        raise HTTPNotFound()

    dectate.commit(App)

    c = Client(App())

    response = c.get('/', status=404)
    assert response.headers.get('Foo') is None
Example #22
0
def test_defer_view_acquisition_blocking():
    class root(morepath.App):
        pass

    class sub(morepath.App):
        pass

    @root.path(path='model/{id}')
    class Model(object):
        def __init__(self, id):
            self.id = id

    @root.json(model=Model)
    def model_default(self, request):
        return {"Hello": "World"}

    @sub.path(path='')
    class SubModel(object):
        pass

    @sub.json(model=SubModel)
    def sub_model_default(self, request):
        return request.view(Model('foo')) is None

    @root.mount(app=sub, path='sub')
    def mount_sub():
        return sub()

    # no defer_links_to_parent

    dectate.commit(root, sub)

    c = Client(root())

    response = c.get('/sub')
    assert response.json is True
Example #23
0
def test_defer_view_acquisition():
    class root(morepath.App):
        pass

    class sub(morepath.App):
        pass

    @root.path(path='model/{id}')
    class Model(object):
        def __init__(self, id):
            self.id = id

    @root.json(model=Model)
    def model_default(self, request):
        return {"Hello": "World"}

    @sub.path(path='')
    class SubModel(object):
        pass

    @sub.json(model=SubModel)
    def sub_model_default(self, request):
        return request.view(Model('foo'))

    @root.mount(app=sub, path='sub')
    def mount_sub(obj, app):
        return app.child(sub())

    @sub.defer_links(model=Model)
    def get_parent(app, obj):
        return app.parent

    c = Client(root())

    response = c.get('/sub')
    assert response.json == {"Hello": "World"}
Example #24
0
def test_reset_unconsumed_path():
    class TestApp(TransactionApp):
        attempts = 0

    @TestApp.path("/foo/bar")
    class Foo:
        pass

    @TestApp.view(model=Foo)
    def view_foo(self, request):
        TestApp.attempts += 1

        # on the first attempt raise a conflict error
        if TestApp.attempts == 1:
            raise Conflict

        return "ok"

    # if the unconsumed path is reset wrongly, it'll accidentally pick
    # up this model instead of Foo
    @TestApp.path("/bar/foo")
    class Bar:
        pass

    @TestApp.view(model=Bar)
    def view_bar(self, request):
        return "error"

    @TestApp.setting(section="transaction", name="attempts")
    def get_retry_attempts():
        return 2

    client = Client(TestApp())
    response = client.get("/foo/bar")
    assert response.text == "ok"
    assert TestApp.attempts == 2
def test_delete_todo():
    c = Client(App())

    response = c.delete("/todos/2")
    todo_list = {
        "todos": [
            {
                "@id": "http://localhost/todos/0",
                "title": "Code",
                "completed": True
            },
            {
                "@id": "http://localhost/todos/1",
                "title": "Test",
                "completed": False
            },
            {
                "@id": "http://localhost/todos/3",
                "title": "Release",
                "completed": False
            },
        ]
    }
    assert response.json == todo_list
Example #26
0
def test_injector_does_not_fail_for_401_responses_with_no_content_type():
    bower = bowerstatic.Bower()

    components = bower.components(
        'components',
        os.path.join(os.path.dirname(__file__), 'bower_components'))

    def wsgi(environ, start_response):
        # Can not use 401 here as webtest only accepts 200 or 3xx, which is ok
        # as we want to test the behaviour if no content type is given
        start_response('302', [('Content-Type', None)])
        include = components.includer(environ)
        with pytest.raises(bowerstatic.Error):
            include('jquery/nonexistent.js')
        return [b'<html><head></head><body>Hello!</body></html>']

    injector = bower.injector(wsgi)

    c = Client(injector)

    # webtest checks, in contracy to pyramid, the headers and breaks if one of
    # them is not a string.
    with mock.patch('webtest.lint.check_headers'):
        c.get('/')
Example #27
0
def test_no_permission():
    class app(morepath.App):
        pass

    class Model(object):
        def __init__(self, id):
            self.id = id

    class Permission(object):
        pass

    @app.path(
        model=Model, path="{id}", variables=lambda model: {"id": model.id}
    )
    def get_model(id):
        return Model(id)

    @app.view(model=Model, permission=Permission)
    def default(self, request):
        return "Model: %s" % self.id

    c = Client(app())

    c.get("/foo", status=403)
Example #28
0
def test_local_external_dependencies():
    bower = bowerstatic.Bower()

    components = bower.components('components', os.path.join(
        os.path.dirname(__file__), 'bower_components'))

    local = bower.local_components('local', components)

    path = os.path.join(
        os.path.dirname(__file__), 'local_component')

    local.component(path, version='2.0')

    local.resource('local_component/local.js', dependencies=[
        'jquery'])

    def wsgi(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html;charset=UTF-8')])
        include = local.includer(environ)
        include('local_component/local.js')
        return [b'<html><head></head><body>Hello!</body></html>']

    wrapped = bower.wrap(wsgi)

    c = Client(wrapped)

    response = c.get('/')

    assert response.body == (
        b'<html><head>'
        b'<script type="text/javascript" '
        b'src="/bowerstatic/components/jquery/2.1.1/dist/jquery.js">'
        b'</script>\n'
        b'<script type="text/javascript" '
        b'src="/bowerstatic/local/local_component/2.0/local.js"></script>'
        b'</head><body>Hello!</body></html>')
Example #29
0
def test_POST_functionality_allows_POST_with_GET_operation_name():
    wsgi = graphql_wsgi(TestSchema)

    c = Client(wsgi)

    response = c.post(
        '/?operationName=helloWorld', {
            'query':
            b'''
              query helloYou { test(who: "You"), ...shared }
              query helloWorld { test(who: "World"), ...shared }
              query helloDolly { test(who: "Dolly"), ...shared }
              fragment shared on Root {
                shared: test(who: "Everyone")
              }
            '''
        })

    assert response.json == {
        'data': {
            'test': 'Hello World',
            'shared': 'Hello Everyone'
        }
    }
Example #30
0
def test_injector_endpoint_depends_on_main_missing():
    bower = bowerstatic.Bower()

    components = bower.components(
        'components',
        os.path.join(os.path.dirname(__file__), 'bower_components'))

    def wsgi(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html;charset=UTF-8')])
        include = components.includer(environ)
        include('depends_on_missing_main')
        return [b'<html><head></head><body>Hello!</body></html>']

    injector = bower.injector(wsgi)

    c = Client(injector)

    response = c.get('/')

    # without a main, it should just include nothing
    assert response.body == (
        b'<html><head><script type="text/javascript" '
        b'src="/bowerstatic/components/depends_on_missing_main/'
        b'2.1.1/resource.js"></script></head><body>Hello!</body></html>')