Ejemplo n.º 1
0
    def posting_to_view(self, fixture):
        """ONLY If a View is writable, may it be POSTed to"""
        def disallowed():
            return False

        class MyForm(Form):
            def __init__(self, view):
                super(MyForm, self).__init__(view, 'myform')
                self.define_event_handler(self.events.an_event)
                self.add_child(ButtonInput(self, self.events.an_event))

            @exposed
            def events(self, events):
                events.an_event = Event(label='Click me')

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                home = self.define_view('/a_view',
                                        'Title',
                                        write_check=disallowed)
                home.set_slot('main', MyForm.factory())

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        browser.open('/a_view')
        browser.click(XPath.button_labelled('Click me'), status=403)
Ejemplo n.º 2
0
def test_i18n_dhtml(web_fixture, dhtml_fixture):
    """Dhtml files can have i18nsed versions, which would be served up if applicable."""
    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/dhtml_ui',
                                       DhtmlUI, {'main_slot': 'main'},
                                       name='test_ui',
                                       static_div_name='astatic')

    fixture = dhtml_fixture

    # Dhtml files should be located in the web.static_root
    web_fixture.config.web.static_root = fixture.static_dir.name

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)

    browser = Browser(wsgi_app)

    # request the file, but get the translated alternative for the locale
    def stubbed_create_context_for_request():
        return LocaleContextStub(locale='af')

    with replaced(wsgi_app.create_context_for_request,
                  stubbed_create_context_for_request):
        browser.open('/dhtml_ui/correctfile.d.html')

    assert browser.title == 'Afrikaans bo!'
Ejemplo n.º 3
0
def test_out_of_bound_widgets(web_fixture):
    """When you need to add a widget to the page, but not as a child/descendant."""

    class MyPanel(Div):
        def __init__(self, view):
            super().__init__(view, css_id='main_panel')
            child_widget = self.add_child(P(view, text='Child Widget'))
            out_of_bound_widget = view.add_out_of_bound_widget(P(view, text='Out Of Bound Widget'))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            home = self.define_view('/', title='Hello')
            home.set_slot('main', MyPanel.factory())

    fixture = web_fixture

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/')

    main_panel = XPath.div().with_id('main_panel')
    assert browser.is_element_present(XPath.paragraph().with_text('Out Of Bound Widget'))
    assert not browser.is_element_present(XPath.paragraph().with_text('Out Of Bound Widget').inside_of(main_panel))
    assert browser.is_element_present(XPath.paragraph().with_text('Child Widget').inside_of(main_panel))
Ejemplo n.º 4
0
def test_check_missing_form(web_fixture):
    """All forms referred to by inputs on a page have to be present on that page."""

    fixture = web_fixture

    class ModelObject(object):
        @exposed
        def fields(self, fields):
            fields.name = Field()

    class MyPanel(Div):
        def __init__(self, view):
            super(MyPanel, self).__init__(view)
            model_object = ModelObject()
            forgotten_form = Form(view, 'myform')
            self.add_child(TextInput(forgotten_form, model_object.fields.name))

    wsgi_app = fixture.new_wsgi_app(child_factory=MyPanel.factory())
    browser = Browser(wsgi_app)

    expected_message = 'Could not find form for <TextInput name=myform-name>. '\
                       'Its form, <Form form id="myform".*> is not present on the current page'

    with expected(ProgrammerError, test=expected_message):
        browser.open('/')
Ejemplo n.º 5
0
def test_views_from_regex(web_fixture):
    """Parameterised Views can also be added based on a regex over the url."""
    class ParameterisedView(UrlBoundView):
        def assemble(self, some_key=None):
            self.title = 'View for: %s' % some_key

    class UIWithParameterisedViews(UserInterface):
        def assemble(self):
            self.define_regex_view('/someurl_(?P<some_key>.*)',
                                   '/someurl_${some_key}',
                                   view_class=ParameterisedView,
                                   some_key=Field(required=True))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page)
            self.define_user_interface('/a_ui',
                                       UIWithParameterisedViews, {},
                                       name='myui')

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    # Parameterised constructing a View from an URL
    browser.open('/a_ui/someurl_test1')
    assert browser.title == 'View for: test1'
Ejemplo n.º 6
0
def test_ui_arguments(web_fixture):
    """UserInterfaces can take exta args and kwargs."""
    class UIWithArguments(UserInterface):
        def assemble(self, kwarg=None):
            self.kwarg = kwarg
            text = self.kwarg
            root = self.define_view('/', title='A view')
            root.set_slot('text', P.factory(text=text))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/a_ui',
                                       UIWithArguments, {'text': 'main'},
                                       name='myui',
                                       kwarg='the kwarg')

    fixture = web_fixture

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/a_ui/')
    [p] = browser.lxml_html.xpath('//p')
    assert p.text == 'the kwarg'
Ejemplo n.º 7
0
def test_ui_slots_map_to_window(web_fixture):
    """The UserInterface uses its own names for Slots. When attaching a UserInterface, you have to specify 
        which of the UserInterface's Slots plug into which of the page's Slots.
    """
    class UIWithSlots(UserInterface):
        def assemble(self):
            root = self.define_view('/', title='UserInterface root view')
            root.set_slot('text',
                          P.factory(text='in user_interface slot named text'))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/a_ui',
                                       UIWithSlots, {'text': 'main'},
                                       name='myui')

    fixture = web_fixture

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/a_ui/')
    assert browser.title == 'UserInterface root view'

    # The widget in the UserInterface's slot named 'text' end up in the HTML5Page slot called main
    [p] = browser.lxml_html.xpath('//div[contains(@class,"column-main")]/p')
    assert p.text == 'in user_interface slot named text'
Ejemplo n.º 8
0
def test_slot_defaults(web_fixture):
    """If a View does not specify contents for a Slot, the Slot will be populated by the window's default
       widget for that slot if specified, else it will be left empty.
    """
    class MainUI(UserInterface):
        def assemble(self):
            main = self.define_page(HTML5Page).use_layout(BasicPageLayout())
            main.add_default_slot('main',
                                  P.factory(text='defaulted slot contents'))
            self.define_view('/', title='Hello')

    fixture = web_fixture

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/')

    # The default widget for the main slot is used
    [p] = browser.xpath('//p')
    assert p.text == 'defaulted slot contents'

    # The header slot has no default, and is thus left empty
    header_contents = browser.xpath('//header/*')
    assert not header_contents
Ejemplo n.º 9
0
    def missing_variable_in_regex(self, fixture):
        """If a variable is missing from the regex, an appropriate error is raised."""
        class ParameterisedView(UrlBoundView):
            def assemble(self, some_key=None):
                self.title = 'View for: %s' % some_key

        class UIWithParameterisedViews(UserInterface):
            def assemble(self):
                self.define_regex_view('/(?P<incorrect_name_for_key>.*)',
                                       '/${key}',
                                       view_class=ParameterisedView,
                                       some_key=Field(required=True))

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page)
                self.define_user_interface('/a_ui',
                                           UIWithParameterisedViews, {},
                                           name='test_ui')

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        def check_message(ex):
            return six.text_type(ex).startswith(
                'The arguments contained in URL')

        with expected(ProgrammerError, test=check_message):
            browser.open('/a_ui/test1/')
Ejemplo n.º 10
0
def test_files_from_list(web_fixture):
    """An explicit list of files can also be added on an URL as if they were in a single
       directory.
    """

    files_dir = temp_dir()
    one_file = files_dir.file_with('any_name_will_do_here', 'one')

    class MainUI(UserInterface):
        def assemble(self):
            list_of_files = [FileOnDisk(one_file.name, 'one_file')]
            self.define_static_files('/morestaticfiles', list_of_files)

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    # How the first file would be accessed
    browser.open('/morestaticfiles/one_file')
    assert browser.raw_html == 'one'

    # The meta-info of the file
    response = browser.last_response
    assert response.content_type == 'application/octet-stream'
    assert response.content_encoding is None
    assert response.content_length == 3
    expected_mtime = datetime.datetime.fromtimestamp(
        int(os.path.getmtime(one_file.name)))
    assert response.last_modified.replace(tzinfo=None) == expected_mtime
    expected_tag = '%s-%s-%s' % (os.path.getmtime(
        one_file.name), 3, abs(hash(one_file.name)))
    assert response.etag == expected_tag

    # When a file does not exist
    browser.open('/morestaticfiles/one_that_does_not_exist', status=404)
Ejemplo n.º 11
0
    def remote_field_validator_handles_GET(self, fixture):
        class ModelObject(object):
            @exposed
            def fields(self, fields):
                fields.field_name = EmailField()

        model_object = ModelObject()

        class MyForm(Form):
            def __init__(self, view, name):
                super(MyForm, self).__init__(view, name)
                self.add_child(TextInput(self, model_object.fields.field_name))

        wsgi_app = fixture.new_wsgi_app(child_factory=MyForm.factory(
            name='some_form'))
        fixture.reahl_server.set_app(wsgi_app)
        browser = Browser(wsgi_app)

        browser.open(six.text_type(fixture.url))
        response = browser.last_response

        vassert(response.unicode_body == fixture.expected_body)
        vassert(response.status == fixture.expected_status)
        vassert(response.content_type == fixture.expected_content_type)
        vassert(response.charset == fixture.expected_charset)
Ejemplo n.º 12
0
def test_concatenated_files(web_fixture, concatenate_scenarios):
    """Files can also be formed by concatenating other files.  Files ending in .css or .js are appropriately
       minified in the process."""

    fixture = concatenate_scenarios

    # Make an egg with a package called packaged_files, and two files in there.
    egg_dir = temp_dir()
    package_dir = egg_dir.sub_dir('packaged_files')
    init_file = package_dir.file_with('__init__.py', '')
    afile = package_dir.file_with('packaged_file', fixture.file1_contents)
    another_file = package_dir.file_with('packaged_file2',
                                         fixture.file2_contents)

    pkg_resources.working_set.add(easter_egg)
    easter_egg.location = egg_dir.name

    class MainUI(UserInterface):
        def assemble(self):
            to_concatenate = [
                PackagedFile('test==1.0', 'packaged_files', 'packaged_file'),
                PackagedFile('test==1.0', 'packaged_files', 'packaged_file2')
            ]
            list_of_files = [
                ConcatenatedFile(fixture.filename, to_concatenate)
            ]
            self.define_static_files('/files', list_of_files)

    web_fixture.config.reahlsystem.debug = False  # To enable minification
    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    # How the first file would be accessed
    browser.open('/files/%s' % fixture.filename)
    assert browser.raw_html == fixture.expected_result
Ejemplo n.º 13
0
def test_packaged_files(web_fixture):
    """Files can also be served straight from a python egg."""

    # Create an egg with package packaged_files, containing the file packaged_file
    egg_dir = temp_dir()
    package_dir = egg_dir.sub_dir('packaged_files')
    init_file = package_dir.file_with('__init__.py', '')
    afile = package_dir.file_with('packaged_file', 'contents')

    easter_egg.clear()
    pkg_resources.working_set.add(easter_egg)
    easter_egg.location = egg_dir.name

    class MainUI(UserInterface):
        def assemble(self):
            list_of_files = [
                PackagedFile(easter_egg.as_requirement_string(),
                             'packaged_files', 'packaged_file')
            ]
            self.define_static_files('/files', list_of_files)

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    # How the file would be accessed
    browser.open('/files/packaged_file')
    assert browser.raw_html == 'contents'
Ejemplo n.º 14
0
def test_files_from_database(web_fixture):
    """Files can also be created on the fly such as from data in a database."""

    content_bytes = ('hôt stuff').encode('utf-8')

    class MainUI(UserInterface):
        def assemble(self):
            mime_type = 'text/html'
            encoding = 'utf-8'
            mtime = 123
            size = len(content_bytes)

            list_of_files = [
                FileFromBlob('database_file', content_bytes, mime_type,
                             encoding, size, mtime)
            ]
            self.define_static_files('/files', list_of_files)

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    # How the file would be accessed
    browser.open('/files/database_file')
    assert browser.raw_html == 'hôt stuff'
    response = browser.last_response

    # The meta-info of the file
    assert response.content_type == 'text/html'
    assert not response.content_encoding
    assert response.content_length == len(content_bytes)
    assert response.last_modified.replace(
        tzinfo=None) == datetime.datetime.fromtimestamp(123)
    expected_etag = '123-%s-%s' % (len(content_bytes),
                                   abs(hash('database_file')))
    assert response.etag == expected_etag
Ejemplo n.º 15
0
def test_bookmarks_from_other_sources(web_fixture):
    """Bookmarks can also be made from ViewFactories, UserInterfaces or UserInterfaceFactories. 
    """
    fixture = web_fixture

    class UIWithRelativeView(UserInterface):
        def assemble(self):
            view_factory = self.define_view('/aview', title='A View title')

            # How you could get a bookmark from a UserInterface or ViewFactory
            fixture.bookmark_from_view_factory = view_factory.as_bookmark(self)
            fixture.bookmark_from_ui = self.get_bookmark(relative_path='/aview')

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page)
            fixture.ui_factory = self.define_user_interface('/a_ui',  UIWithRelativeView,  {}, name='myui')

            # How you could get a bookmark from a UserInterfaceFactory
            fixture.bookmark_from_ui_factory = fixture.ui_factory.get_bookmark(relative_path='/aview')

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    Browser(wsgi_app).open('/a_ui/aview') # To execute the above once

    for bookmark in [fixture.bookmark_from_view_factory, 
                     fixture.bookmark_from_ui, 
                     fixture.bookmark_from_ui_factory]:
        # What the bookmark knows
        assert bookmark.href.path == '/a_ui/aview' 
        assert bookmark.description == 'A View title' 
        assert bookmark.base_path == '/a_ui' 
        assert bookmark.relative_path == '/aview' 
Ejemplo n.º 16
0
def test_remote_field_validator_handles_GET(web_fixture, validation_scenarios):
    fixture = validation_scenarios


    class ModelObject:
        @exposed
        def fields(self, fields):
            fields.field_name = EmailField()

    model_object = ModelObject()

    class MyForm(Form):
        def __init__(self, view, name):
            super().__init__(view, name)
            self.add_child(TextInput(self, model_object.fields.field_name))

    wsgi_app = web_fixture.new_wsgi_app(child_factory=MyForm.factory(name='some_form'))
    web_fixture.reahl_server.set_app(wsgi_app)
    browser = Browser(wsgi_app)

    browser.open(str(fixture.url))
    response = browser.last_response

    assert response.unicode_body == fixture.expected_body 
    assert response.status == fixture.expected_status 
    assert response.content_type == fixture.expected_content_type 
    assert response.charset == fixture.expected_charset 
Ejemplo n.º 17
0
def language_menu(fixture):
    """A Nav can also be constructed to let a user choose to view the same page in 
       another of the supported languages."""
    class PanelWithMenu(Div):
        def __init__(self, view):
            super(PanelWithMenu, self).__init__(view)
            self.add_child(Menu(view).with_languages())
            self.add_child(P(view, text=_('This is an English sentence.')))

    wsgi_app = fixture.new_wsgi_app(child_factory=PanelWithMenu.factory())

    browser = Browser(wsgi_app)
    browser.open('/')

    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('This is an English sentence.')))

    browser.click(XPath.link_with_text('Afrikaans'))
    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('Hierdie is \'n sin in Afrikaans.')))

    browser.click(XPath.link_with_text('English (United Kingdom)'))
    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('This is an English sentence.')))
Ejemplo n.º 18
0
    def i18n_dhtml(self, fixture):
        """Djhtml files can have i18nsed versions, which would be served up if applicable."""
        @stubclass(WebExecutionContext)
        class AfrikaansContext(WebExecutionContext):
            @property
            def interface_locale(self):
                return 'af'

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                self.define_user_interface('/dhtml_ui',
                                           DhtmlUI, {'main_slot': 'main'},
                                           name='test_ui',
                                           static_div_name='astatic')

        # Djhtml files should be located in the web.static_root
        fixture.config.web.static_root = fixture.static_dir.name

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)

        browser = Browser(wsgi_app)

        # request the file, but get the transalated alternative for the locale
        def stubbed_create_context_for_request():
            return AfrikaansContext()

        with replaced(wsgi_app.create_context_for_request,
                      stubbed_create_context_for_request):
            browser.open('/dhtml_ui/correctfile.d.html')

        vassert(browser.title == 'Afrikaans bo!')
Ejemplo n.º 19
0
def test_basic_ui(web_fixture):
    """A UserInterface is a chunk of web app that can be grafted onto the URL hierarchy of any app.

       A UserInterface has its own views. Its Views are relative to the UserInterface itself.
    """
    class UIWithTwoViews(UserInterface):
        def assemble(self):
            self.define_view('/', title='UserInterface root view')
            self.define_view('/other', title='UserInterface other view')

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page)
            self.define_user_interface('/a_ui',
                                       UIWithTwoViews, {},
                                       name='myui')

    fixture = web_fixture
    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/a_ui/')
    assert browser.title == 'UserInterface root view'

    browser.open('/a_ui/other')
    assert browser.title == 'UserInterface other view'
Ejemplo n.º 20
0
def test_simple_sub_resources(web_fixture):
    """During their construction, Widgets can add SubResources to their View.  The SubResource
       will then be available via a special URL underneath the URL of the Widget's View."""

    fixture = web_fixture

    @stubclass(SubResource)
    class ASimpleSubResource(SubResource):
        sub_regex = 'simple_resource'
        sub_path_template = 'simple_resource'

        @exempt
        def handle_get(self, request):
            return Response()

    @stubclass(Widget)
    class WidgetWithSubResource(Widget):
        def __init__(self, view):
            super(WidgetWithSubResource, self).__init__(view)
            view.add_resource(ASimpleSubResource(view, 'uniquename'))

    wsgi_app = fixture.new_wsgi_app(
        child_factory=WidgetWithSubResource.factory())
    browser = Browser(wsgi_app)
    browser.open('/_uniquename_simple_resource')
Ejemplo n.º 21
0
def test_remote_field_formatting(web_fixture):
    """A Form contains a RemoteMethod that can be used to reformat any of its fields via HTTP.
    """

    fixture = web_fixture

    class ModelObject(object):
        @exposed
        def fields(self, fields):
            fields.a_field = DateField()

    model_object = ModelObject()

    class MyForm(Form):
        def __init__(self, view, name):
            super(MyForm, self).__init__(view, name)
            self.add_child(TextInput(self, model_object.fields.a_field))

    wsgi_app = fixture.new_wsgi_app(child_factory=MyForm.factory('myform'))
    browser = Browser(wsgi_app)

    browser.open('/_myform_format_method?myform-a_field=13 November 2012')
    assert browser.raw_html == '13 Nov 2012'

    browser.open('/_myform_format_method?myform-a_field=invaliddate')
    assert browser.raw_html == ''
Ejemplo n.º 22
0
def test_take_and_release_task(web_fixture, task_queue_fixture, workflow_web_fixture):
    fixture = workflow_web_fixture

    browser = Browser(fixture.wsgi_app)
    task = task_queue_fixture.task

    take_task_button = XPath.button_labelled('Take')
    defer_task_button = XPath.button_labelled('Defer')
    release_task_button = XPath.button_labelled('Release')
    go_to_task_button = XPath.button_labelled('Go to')

    web_fixture.log_in(browser=browser)
    browser.open('/inbox/')

    browser.click(take_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(defer_task_button)
    assert browser.current_url.path == '/inbox/'

    browser.click(go_to_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(release_task_button)
    assert browser.current_url.path == '/inbox/'
Ejemplo n.º 23
0
def test_remote_field_validation(web_fixture):
    """A Form contains a RemoteMethod that can be used to validate any of its fields via HTTP.
    """

    fixture = web_fixture

    class ModelObject(object):
        @exposed
        def fields(self, fields):
            fields.a_field = EmailField()

    model_object = ModelObject()

    class MyForm(Form):
        def __init__(self, view, name):
            super(MyForm, self).__init__(view, name)
            self.add_child(TextInput(self, model_object.fields.a_field))

    wsgi_app = fixture.new_wsgi_app(child_factory=MyForm.factory('myform'))
    browser = Browser(wsgi_app)

    browser.open(
        '/_myform_validate_method?myform-a_field=invalid email address')
    assert browser.raw_html == '"a_field should be a valid email address"'

    browser.open('/[email protected]')
    assert browser.raw_html == 'true'
Ejemplo n.º 24
0
def test_take_and_release_task(web_fixture, task_queue_fixture, workflow_web_fixture):
    fixture = workflow_web_fixture

    browser = Browser(fixture.wsgi_app)
    task = task_queue_fixture.task

    take_task_button = '//input[@value="Take"]'
    defer_task_button = '//input[@value="Defer"]'
    release_task_button = '//input[@value="Release"]'
    go_to_task_button = '//input[@value="Go to"]'

    web_fixture.log_in(browser=browser)
    browser.open('/inbox/')

    browser.click(take_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(defer_task_button)
    assert browser.current_url.path == '/inbox/'

    browser.click(go_to_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(release_task_button)
    assert browser.current_url.path == '/inbox/'
Ejemplo n.º 25
0
def test_views_with_parameters(web_fixture, parameterised_scenarios):
    """Views can have arguments that originate from code, or are parsed from the URL."""
    class UIWithParameterisedViews(UserInterface):
        def assemble(self):
            self.define_view('/aview',
                             view_class=fixture.ParameterisedView,
                             some_arg=fixture.argument)

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/a_ui',
                                       UIWithParameterisedViews,
                                       {'main': 'main'},
                                       name='myui')

    fixture = parameterised_scenarios

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    if fixture.should_exist:
        browser.open(fixture.url)
        assert browser.title == 'View for: %s' % fixture.expected_value
        assert browser.is_element_present(XPath.paragraph().including_text(
            'content for %s' % fixture.expected_value))
    else:
        browser.open(fixture.url, status=404)
Ejemplo n.º 26
0
def test_i18n_urls(web_fixture):
    """The current locale is determined by reading the first segment of the path. If the locale is not present in the
    path, web.default_url_locale is used."""
    _ = Catalogue('reahl-web')

    class I18nUI(UserInterface):
        def assemble(self):
            view = self.define_view('/aview', title=_('A View'))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page)
            self.define_user_interface('/a_ui',  I18nUI,  IdentityDictionary(), name='test_ui')

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/a_ui/aview')
    assert browser.title == 'A View'

    browser.open('/af/a_ui/aview')
    assert browser.title == '\'n Oogpunt'

    web_fixture.config.web.default_url_locale = 'af'
    browser.open('/a_ui/aview')
    assert browser.title == '\'n Oogpunt'

    browser.open('/en_gb/a_ui/aview')
    assert browser.title == 'A View'
Ejemplo n.º 27
0
def test_basic_workings(web_fixture, dhtml_fixture):
    """A DhtmlUI provides a UserInterface which maps to the filesystem where there may be
       a combination of .d.html and other files. When a d.html file is requested from
       it, the contents of the specified div from inside the d.html file is inserted
       into the specified Slot. When a normal file is requested, the file is sent verbatim."""
    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/dhtml_ui',
                                       DhtmlUI, {'main_slot': 'main'},
                                       name='test_ui',
                                       static_div_name='astatic')

    fixture = dhtml_fixture

    # Dhtml files should be located in the web.static_root
    web_fixture.config.web.static_root = fixture.static_dir.name

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI, enable_js=True)
    browser = Browser(wsgi_app)

    # A dhtml file: HTML5Page's main_slot now contains the insides of the div in the dhtml file
    browser.open('/dhtml_ui/correctfile.d.html')
    html = fixture.get_inserted_html(browser)
    assert html == fixture.div_internals

    # A non-dhtml file is returned verbatim
    browser.open('/dhtml_ui/otherfile.txt')
    contents = browser.raw_html
    assert contents == 'other'

    # Files that do not exist are reported as such
    browser.open('/dhtml_ui/idonotexist.txt', status=404)
    browser.open('/dhtml_ui/idonotexist.d.html', status=404)
Ejemplo n.º 28
0
def test_basic_working_of_slots(web_fixture):
    """Slots are special Widgets that can be added to the page. The contents of a
       Slot are then supplied (differently) by different Views."""
    class MyPage(Widget):
        def __init__(self, view):
            super(MyPage, self).__init__(view)
            self.add_child(Slot(view, 'slot1'))
            self.add_child(Slot(view, 'slot2'))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(MyPage)

            home = self.define_view('/', title='Home')
            home.set_slot('slot1', P.factory(text='a'))
            home.set_slot('slot2', P.factory(text='b'))

            other = self.define_view('/other', title='Other')
            other.set_slot('slot1', P.factory(text='other'))

    fixture = web_fixture

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/')
    [slot1_p, slot2_p] = browser.lxml_html.xpath('//p')
    assert slot1_p.text == 'a'
    assert slot2_p.text == 'b'

    browser.open('/other')
    [slot1_p] = browser.lxml_html.xpath('//p')
    assert slot1_p.text == 'other'
Ejemplo n.º 29
0
def basic_assembly(fixture):
    """An application is built by extending UserInterface, and defining this UserInterface in an .assemble() method.

    To define the UserInterface, several Views are defined. Views are mapped to URLs. When a user GETs
    the URL of a View, a page is rendered back to the user. How that page is created
    can happen in different ways, as illustrated by each scenario of this test.
    """
    wsgi_app = fixture.new_wsgi_app(site_root=fixture.MainUI)
    browser = Browser(wsgi_app)

    # GETting the URL results in the HTML for that View
    with warnings.catch_warnings(record=True) as caught_warnings:
        warnings.simplefilter('always')
        browser.open('/')
        vassert(browser.title == 'Hello')

    warning_messages = [six.text_type(i.message) for i in caught_warnings]
    vassert(len(warning_messages) == len(fixture.expected_warnings))
    for caught, expected_message in zip_longest(warning_messages,
                                                fixture.expected_warnings):
        vassert(expected_message in caught)

    if fixture.content_includes_p:
        [message] = browser.xpath('//p')
        vassert(message.text == 'Hello world!')

    # The headers are set correctly
    response = browser.last_response
    vassert(response.content_length == fixture.expected_content_length)
    vassert(response.content_type == 'text/html')
    vassert(response.charset == 'utf-8')

    # Invalid URLs do not exist
    with warnings.catch_warnings(record=True):
        browser.open('/nonexistantview/', status=404)
Ejemplo n.º 30
0
    def non_writable_events_are_dealt_with_like_invalid_input(self, fixture):
        """If a form submits an Event with access rights that prohibit writing, a ValidationException is raised."""
        class ModelObject(object):
            @exposed
            def events(self, events):
                events.an_event = Event(
                    label='click me',
                    writable=Allowed(False),
                    disallowed_message='you cannot do this')

        model_object = ModelObject()

        class TestPanel(Div):
            def __init__(self, view):
                super(TestPanel, self).__init__(view)
                form = self.add_child(Form(view, 'some_form'))
                form.define_event_handler(model_object.events.an_event)
                button = form.add_child(
                    ButtonInput(form, model_object.events.an_event))
                if button.validation_error:
                    form.add_child(form.create_error_label(button))
                fixture.form = form

        wsgi_app = fixture.new_wsgi_app(child_factory=TestPanel.factory())
        browser = Browser(wsgi_app)
        browser.open('/')

        browser.post(fixture.form.event_channel.get_url().path,
                     {'event.an_event?': ''})
        browser.follow_response()
        input_id = browser.get_id_of('//input[@name="event.an_event?"]')
        error_label = browser.get_html_for('//label')
        vassert(error_label ==
                '<label for="%s" class="error">you cannot do this</label>' %
                input_id)