Esempio n. 1
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!'
Esempio n. 2
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'
Esempio n. 3
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'
Esempio 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('/')
Esempio n. 5
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!')
Esempio n. 6
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'
Esempio n. 7
0
def test_widget_factory_creates_widget_with_layout(web_fixture,
                                                   widget_creation_scenarios):
    """A Layout can be specified to any WidgetFactory or to UserInterface.define_page"""
    class MyLayout(Layout):
        def customise_widget(self):
            self.widget.add_child(
                P(self.view, text='This widget is using Mylayout'))

    layout_for_widget = MyLayout()

    class MainUI(UserInterface):
        def assemble(self):
            self.define_view(
                '/',
                title='Hello',
                page=HTML5Page.factory(use_layout=layout_for_widget))

    fixture = widget_creation_scenarios

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

    browser.open('/')
    [p] = browser.lxml_html.xpath('//p')
    assert p.text == 'This widget is using Mylayout'
Esempio n. 8
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/')
Esempio n. 9
0
def test_activating_javascript(web_fixture):
    """The JavaScript snippets of all Widgets are collected in a jQuery.ready() function by"""
    """ an automatically inserted Widget in the slot named reahl_footer.  Duplicate snippets are removed."""
    @stubclass(Widget)
    class WidgetWithJavaScript(Widget):
        def __init__(self, view, fake_js):
            super().__init__(view)
            self.fake_js = fake_js

        def get_js(self, context=None):
           return [self.fake_js]

    class MyPage(Widget):
        def __init__(self, view):
            super().__init__(view)
            self.add_child(WidgetWithJavaScript(view, 'js1'))
            self.add_child(WidgetWithJavaScript(view, 'js2'))
            self.add_child(WidgetWithJavaScript(view, 'js1'))#intended duplicate
            self.add_child(Slot(view, 'reahl_footer'))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(MyPage)
            self.define_view('/', title='Home')

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

    browser.open('/')
    rendered_js = [i.text for i in browser.lxml_html.xpath('//script[@id="reahl-jqueryready"]')][0]
    assert rendered_js == '\njQuery(document).ready(function($){\n$(\'body\').addClass(\'enhanced\');\njs1\njs2\n\n});\n'

    number_of_duplicates = rendered_js.count('js1') - 1
    assert number_of_duplicates == 0
Esempio n. 10
0
    def internal_redirects(self, fixture):
        """During request handling, an InternalRedirect exception can be thrown. This is handled by
           restarting the request loop from scratch to handle the same request again, using a freshly
           constructed resource just as though the request was submitted again by the browser
           save for the browser round trip."""

        fixture.requests_handled = []
        fixture.handling_resources = []

        @stubclass(Resource)
        class ResourceStub(object):
            def handle_request(self, request):
                fixture.requests_handled.append(request)
                fixture.handling_resources.append(self)
                if hasattr(request, 'internal_redirect'):
                    return Response(body='response given after internal redirect')
                raise InternalRedirect(None, None)

        @stubclass(ReahlWSGIApplication)
        class ReahlWSGIApplicationStub2(ReahlWSGIApplicationStub):
            def resource_for(self, request):
                return ResourceStub()

        browser = Browser(ReahlWSGIApplicationStub2(fixture.config))

        browser.open('/')

        vassert( browser.raw_html == 'response given after internal redirect' )
        vassert( fixture.requests_handled[0] is fixture.requests_handled[1] )
        vassert( fixture.handling_resources[0] is not fixture.handling_resources[1] )
Esempio n. 11
0
def test_missing_variable_in_ui_regex(web_fixture):
    class RegexUserInterface(UserInterface):
        def assemble(self, ui_key=None):
            self.name = 'user_interface-%s' % ui_key

    class UIWithParameterisedUserInterfaces(UserInterface):
        def assemble(self):
            self.define_regex_user_interface('/(?P<xxx>[^/]*)',
                                             'N/A',
                                             RegexUserInterface, {},
                                             ui_key=Field(required=True))

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

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)

    browser = Browser(wsgi_app)

    with expected(RequiredConstraint):
        browser.open('/a_ui/test1/')
Esempio n. 12
0
def test_immutable_remote_methods(web_fixture, remote_method_fixture,
                                  sql_alchemy_fixture):
    """The database is always rolled back at the end of an immutable RemoteMethod."""
    class TestObject(Base):
        __tablename__ = 'test_remotemethods_test_object'
        id = Column(Integer, primary_key=True)
        name = Column(UnicodeText)

    with sql_alchemy_fixture.persistent_test_classes(TestObject):

        def callable_object():
            Session.add(TestObject(name='new object'))
            assert Session.query(TestObject).count() == 1
            return 'value returned from method'

        remote_method = RemoteMethod(web_fixture.view,
                                     'amethod',
                                     callable_object,
                                     MethodResult(),
                                     immutable=True)

        assert remote_method.idempotent  # Immutable methods are idempotent

        wsgi_app = remote_method_fixture.new_wsgi_app(
            remote_method=remote_method)
        browser = Browser(wsgi_app)

        browser.open('/_amethod_method')
        assert browser.raw_html == 'value returned from method'

        # The database is rolled back to ensure immutability
        assert Session.query(TestObject).count() == 0
Esempio n. 13
0
def test_inline_form_layouts(web_fixture, form_layout_fixture):
    """An InlineFormLayout adds the Label and Input of each added input next to each other, with some space between them."""
    fixture = form_layout_fixture

    class FormWithInlineFormLayout(Form):
        def __init__(self, view):
            super().__init__(view, 'aform')
            self.use_layout(InlineFormLayout())
            self.layout.add_input(TextInput(
                self, fixture.domain_object.fields.an_attribute),
                                  help_text='some help')

    browser = Browser(
        web_fixture.new_wsgi_app(
            child_factory=FormWithInlineFormLayout.factory()))
    browser.open('/')

    [label, input_, help_text] = fixture.get_form_group_children(browser)

    #check spacing specified between label, input and help_text
    assert label.tag == 'label'
    assert 'mr-2' == label.attrib['class']

    assert input_.tag == 'input'

    assert help_text.tag == 'span'
    assert 'ml-2' in help_text.attrib['class'].split(' ')
Esempio n. 14
0
def test_grid_form_layouts(web_fixture, form_layout_fixture):
    """A GridFormLayout adds the Label and Input of each added input in separate columns sized like you specify"""
    fixture = form_layout_fixture

    class FormWithGridFormLayout(Form):
        def __init__(self, view):
            super().__init__(view, 'aform')
            self.use_layout(
                GridFormLayout(ResponsiveSize(lg=4), ResponsiveSize(lg=8)))
            self.layout.add_input(TextInput(
                self, fixture.domain_object.fields.an_attribute),
                                  help_text='some help')

    browser = Browser(
        web_fixture.new_wsgi_app(
            child_factory=FormWithGridFormLayout.factory()))
    browser.open('/')

    [label_column, input_column] = fixture.get_form_group_children(browser)
    assert label_column.tag == 'div'
    assert 'col-lg-4' in label_column.attrib['class'].split(' ')
    assert 'column-label' in label_column.attrib['class'].split(' ')

    [label] = fixture.get_label_in_form_group(browser)
    assert 'col-form-label' in label.attrib['class'].split(' ')

    assert input_column.tag == 'div'
    assert 'col-lg-8' in input_column.attrib['class'].split(' ')
    assert 'column-input' in input_column.attrib['class'].split(' ')

    [input_, help_text] = input_column.getchildren()
    assert input_.tag == 'input'
    assert help_text.tag == 'p'
    assert 'form-text' in help_text.attrib['class'].split(' ')
Esempio n. 15
0
def test_query_string_prepopulates_form(web_fixture, value_scenarios):
    """Widget query string arguments can be used on forms to pre-populate inputs based on the query string."""

    fixture = value_scenarios

    class ModelObject:
        @exposed
        def fields(self, fields):
            fields.arg_on_other_object = fixture.field

    class FormWithQueryArguments(Form):
        def __init__(self, view):
            self.model_object = ModelObject()
            super().__init__(view, 'name')
            self.use_layout(FormLayout())
            self.layout.add_input(TextInput(self, self.model_object.fields.arg_on_other_object))

        @exposed
        def query_fields(self, fields):
            fields.arg_on_other_object = self.model_object.fields.arg_on_other_object

    wsgi_app = web_fixture.new_wsgi_app(enable_js=True, child_factory=FormWithQueryArguments.factory())
    browser = Browser(wsgi_app)

    browser.open('/?%s' % fixture.field_on_query_string.format(field_name='name-arg_on_other_object'))
    assert browser.get_value(XPath.input_labelled('field')) == fixture.field_value_as_string
Esempio n. 16
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)
Esempio n. 17
0
    def query_string_prepopulates_form(self, fixture):
        """Widget query string arguments can be used on forms to pre-populate inputs based on the query string."""
        class ModelObject(object):
            @exposed
            def fields(self, fields):
                fields.arg_on_other_object = Field()

        class FormWithQueryArguments(Form):
            def __init__(self, view):
                self.model_object = ModelObject()
                super(FormWithQueryArguments, self).__init__(view, 'name')
                self.add_child(
                    TextInput(self,
                              self.model_object.fields.arg_on_other_object))

            @exposed
            def query_fields(self, fields):
                fields.arg_on_other_object = self.model_object.fields.arg_on_other_object

        wsgi_app = fixture.new_wsgi_app(
            widget_factory=FormWithQueryArguments.factory())
        browser = Browser(wsgi_app)

        browser.open('/?arg_on_other_object=metoo')
        vassert(browser.lxml_html.xpath('//input')[0].value == 'metoo')
Esempio n. 18
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 
Esempio n. 19
0
def adding_basic_input(fixture):
    """Adding an input to a FormLayout, adds it in a bootstrap form-group with Some input."""
    class FormWithInputAddedUsingDefaults(Form):
        def __init__(self, view):
            super(FormWithInputAddedUsingDefaults,
                  self).__init__(view, 'aform')
            self.use_layout(FormLayout())
            self.layout.add_input(
                TextInput(self, fixture.domain_object.fields.an_attribute))

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

    vassert(fixture.form_contains_form_group(browser))

    [label, input_widget] = fixture.get_form_group_children(browser)

    # form-group has a label, correctly set up for bootstrap
    vassert(label.tag == 'label')
    vassert(label.attrib['for'] == input_widget.attrib['id'])
    vassert(label.text == 'Some input')

    # form-group has an input, correctly set up for bootstrap
    vassert(input_widget.tag == 'input')
    vassert(input_widget.attrib['name'] == 'an_attribute')
Esempio 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')
Esempio n. 21
0
def adding_checkboxes(fixture):
    """CheckboxInputs are added non-inlined, and by default without labels."""
    class DomainObjectWithBoolean(object):
        @exposed
        def fields(self, fields):
            fields.an_attribute = BooleanField(label='Some input',
                                               required=True)

    fixture.domain_object = DomainObjectWithBoolean()

    class FormWithInputWithCheckbox(Form):
        def __init__(self, view):
            super(FormWithInputWithCheckbox, self).__init__(view, 'aform')
            self.use_layout(FormLayout())
            self.layout.add_input(
                CheckboxInput(self, fixture.domain_object.fields.an_attribute))

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

    vassert(not any(child.tag == 'label'
                    for child in fixture.get_form_group_children(browser)))
    [div] = fixture.get_form_group_children(browser)
    [checkbox] = div.getchildren()
    vassert(checkbox.attrib['class'] == 'checkbox')
Esempio n. 22
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)
Esempio n. 23
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)
Esempio n. 24
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'
Esempio n. 25
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
Esempio n. 26
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'
Esempio n. 27
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
Esempio n. 28
0
def test_linking_to_views_marked_as_detour(web_fixture):
    """A View can be marked as the start of a Detour. Where used, a Bookmark for such a View
       will automatically include a returnTo in the its query string. This allows an
       eventual return_transition (or similar) to return to where, eg, a link was clicked from.
       This mechanism works for returning across UserInterfaces."""
    class UIWithLink(UserInterface):
        def assemble(self, bookmark=None):
            self.bookmark = bookmark
            self.define_view('/initial', title='View a').set_slot(
                'main', A.factory_from_bookmark(self.bookmark))

    class UIWithDetour(UserInterface):
        def assemble(self):
            event = Event(label='Click me')
            event.bind('anevent', None)

            step1 = self.define_view('/firstStepOfDetour',
                                     title='Step 1',
                                     detour=True)
            step1.set_slot('main', FormWithButton.factory(event))
            step2 = self.define_view('/lastStepOfDetour', title='Step 2')
            step2.set_slot('main', FormWithButton.factory(event))

            self.define_transition(event, step1, step2)
            self.define_return_transition(event, step2)

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            detour_ui = self.define_user_interface('/uiWithDetour',
                                                   UIWithDetour,
                                                   IdentityDictionary(),
                                                   name='second_ui')
            bookmark = detour_ui.get_bookmark(
                relative_path='/firstStepOfDetour')
            self.define_user_interface('/uiWithLink',
                                       UIWithLink,
                                       IdentityDictionary(),
                                       name='first_ui',
                                       bookmark=bookmark)

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

    browser.open('/uiWithLink/initial')
    browser.click('//a')
    assert browser.current_url.path == '/uiWithDetour/firstStepOfDetour'

    browser.click('//input[@type="submit"]')
    assert browser.current_url.path == '/uiWithDetour/lastStepOfDetour'

    browser.click('//input[@type="submit"]')
    assert browser.current_url.path == '/uiWithLink/initial'

    # The query string is cleared after such a return (it is used to remember where to return to)
    assert browser.current_url.query == ''
Esempio n. 29
0
def slots(fixture):
    """A View modifies the page by populating named Slots in the page with Widgets."""
    wsgi_app = fixture.new_wsgi_app(site_root=fixture.MainUI)
    browser = Browser(wsgi_app)

    browser.open('/')
    vassert(browser.title == 'Hello')
    [main_p, footer_p] = browser.xpath('//p')
    vassert(main_p.text == 'Hello world')
    vassert(footer_p.text == 'I am the footer')
Esempio n. 30
0
    def detour_to_login(self, fixture):
        browser = Browser(fixture.wsgi_app)

        browser.open('/inbox/')
        vassert(browser.location_path == '/accounts/login')
        browser.type('//input[@name="email"]', fixture.system_account.email)
        browser.type('//input[@name="password"]',
                     fixture.system_account.password)
        browser.click('//input[@value="Log in"]')
        vassert(browser.location_path == '/inbox/')