Skip to content

Comments

Search: Add breadcrumbs to search results in order to provide more context#2282

Open
Tschuppi81 wants to merge 63 commits intomasterfrom
feature/ogc-2880-search-results-with-path
Open

Search: Add breadcrumbs to search results in order to provide more context#2282
Tschuppi81 wants to merge 63 commits intomasterfrom
feature/ogc-2880-search-results-with-path

Conversation

@Tschuppi81
Copy link
Contributor

@Tschuppi81 Tschuppi81 commented Jan 6, 2026

Search: Add breadcrumbs to search results in order to provide more context

TYPE: Feature
LINK: ogc-2880

@linear
Copy link

linear bot commented Jan 6, 2026

@codecov
Copy link

codecov bot commented Jan 6, 2026

❌ 11 Tests Failed:

Tests completed Failed Passed Skipped
2629 11 2618 17
View the top 3 failed test(s) by shortest run time
tests/onegov/town6/test_views_search.py::test_search_hashtags
Stack Traces | 3.14s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f831ddd9090>

    def test_search_hashtags(client_with_fts: Client) -> None:
    
        client = client_with_fts
        client.login_admin()
    
        page = client.get('/news').click("Nachricht")
        page.form['title'] = "We have a new homepage"
        page.form['lead'] = "It is very good"
        page.form['text'] = "It is lots of fun #newhomepage"
    
        assert page.form.submit().follow().status_code == 200
    
>       assert 'We have a new homepage' in client.get(
            '/search?q=%23newhomepage')

.../onegov/town6/test_views_search.py:237: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f831db33ed0 GET http:.../localhost/search?q=%23newhomepage>
model = News(name='we-have-a-new-homepage', id=6, parent_id=4)

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views_search.py::test_search_publication_files
Stack Traces | 3.15s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f8148561950>

    def test_search_publication_files(client_with_fts: Client) -> None:
        client = client_with_fts
        client.login_admin()
    
        path = module_path('tests.onegov.org', 'fixtures/sample.pdf')
        with (open(path, 'rb') as f):
            page = client.get('/files')
            page.form['file'] = [Upload(
                'Sample.pdf', f.read(), 'application/pdf')]
            page.form.submit()
    
>       assert 'Sample' in client.get('/search?q=Adobe')
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views_search.py:213: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:31050: in render_search_result_files
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f8144c33150 GET http:.../localhost/search?q=Adobe>
model = <onegov.org.models.file.GeneralFile object at 0x7f8144fb9e50>

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views.py::test_search_in_header
Stack Traces | 3.28s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f24e825e850>

    def test_search_in_header(client_with_fts: Client) -> None:
        page = client_with_fts.get("/")
        assert "Suchbegriff" in page
        page.form['q'] = 'aktuell'
>       page = page.form.submit()
               ^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views.py:159: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.................................................../app/lib/python3.11.../site-packages/webtest/forms.py:633: in submit
    return self.response.goto(self.action, method=self.method,
.................................................../app/lib/python3.11.../site-packages/webtest/response.py:275: in goto
    return method(href, **args)
           ^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
.................................................../app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f24e20725d0 GET http:.../localhost/search?q=aktuell>
model = News(name='news', id=4, parent_id=None)

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views_search.py::test_ticket_chat_search
Stack Traces | 3.49s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f24d895bed0>

    def test_ticket_chat_search(client_with_fts: Client) -> None:
        client = client_with_fts
    
        collection = FormCollection(client.app.session())
        collection.definitions.add('Profile', definition=textwrap.dedent("""
            First name * = ___
            Last name * = ___
            E-Mail * = @@@
        """), type='custom')
    
        transaction.commit()
    
        # submit a form
        client.login_admin()
    
        page = client.get('/forms').click('Profile')
        page.form['first_name'] = 'Foo'
        page.form['last_name'] = 'Bar'
        page.form['e_mail'] = 'foo@bar.baz'
        page = page.form.submit().follow().form.submit().follow()
    
        # send a message that should be findable through the search
        page.form['text'] = "I spelt my name wrong: it's deadbeef"
        assert page.form.submit().follow().status_code == 200
    
        # at this point logged in users should find the ticket by 'deadbeef'
>       page = client.get('/search?q=deadbeef')
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views_search.py:269: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:31351: in render_search_result_tickets
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f24da4ab650 GET http:.../localhost/search?q=deadbeef>
model = <onegov.org.models.ticket.FormSubmissionTicket object at 0x7f24db3da510>

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views_search.py::test_search_recently_published_object
Stack Traces | 3.63s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f831aa0ff50>

    def test_search_recently_published_object(client_with_fts: Client) -> None:
        client = client_with_fts
        client.login_admin()
        anom = client.spawn()
        session = client.app.session()
    
        # Create objects, not yet published
        start = datetime.now() + timedelta(days=1)
    
        add_news = client.get('/news').click('Nachricht')
        add_news.form['title'] = "Now supporting fulltext search"
        add_news.form['lead'] = "It is pretty awesome"
        add_news.form['text'] = "Much <em>wow</em>"
        add_news.form['publication_start'] = start.isoformat()
        add_news.form.submit()
    
        page = session.query(Page).filter(
            Page.title == "Now supporting fulltext search"
        ).one()
        assert isinstance(page, News)
        assert page.access == 'public'
        assert page.published == False
    
>       assert 'fulltext' in client.get('/search?q=wow')
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views_search.py:121: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f831e5c7990 GET http:.../localhost/search?q=wow>
model = News(name='now-supporting-fulltext-search', id=6, parent_id=4)

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views_search.py::test_view_search_is_limiting
Stack Traces | 3.71s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f24e22adc10>

    def test_view_search_is_limiting(client_with_fts: Client) -> None:
        # ensures that the search doesn't just return all results
        # a regression that occurred for anonymous uses only
    
        client = client_with_fts
        client.login_admin()
    
        add_news = client.get('/news').click('Nachricht')
        add_news.form['title'] = "Foobar"
        add_news.form['lead'] = "Foobar"
        add_news.form.submit()
    
        add_news = client.get('/news').click('Nachricht')
        add_news.form['title'] = "Deadbeef"
        add_news.form['lead'] = "Deadbeef"
        add_news.form.submit()
    
        root_page = client.get('/')
        root_page.form['q'] = "Foobar"
>       search_page = root_page.form.submit()
                      ^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views_search.py:85: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.................................................../app/lib/python3.11.../site-packages/webtest/forms.py:633: in submit
    return self.response.goto(self.action, method=self.method,
.................................................../app/lib/python3.11.../site-packages/webtest/response.py:275: in goto
    return method(href, **args)
           ^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
.................................................../app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f24daaf7850 GET http:.../localhost/search?q=Foobar>
model = News(name='foobar', id=6, parent_id=4)

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views_search.py::test_search_for_page_with_member_access
Stack Traces | 3.79s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f81489003d0>

    def test_search_for_page_with_member_access(client_with_fts: Client) -> None:
        client = client_with_fts
        client.login_admin()
        anom = client.spawn()
        member = client.spawn()
        member.login_member()
    
        new_page = client.get('/topics/organisation').click('Thema')
        new_page.form['title'] = "Test"
        new_page.form['lead'] = "Memberius testius"
        new_page.form['access'] = 'member'
        new_page.form.submit().follow()
    
>       assert 'Test' in client.get('/search?q=Memberius')
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views_search.py:182: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f81484ff750 GET http:.../localhost/search?q=Memberius>
model = Topic(name='test', id=6, parent_id=1)

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views_search.py::test_basic_search
Stack Traces | 4.05s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f8149d7f0d0>

    def test_basic_search(client_with_fts: Client) -> None:
        client = client_with_fts
        client.login_admin()
        anom = client.spawn()
    
        add_news = client.get('/news').click('Nachricht')
        add_news.form['title'] = "Now supporting fulltext search"
        add_news.form['lead'] = "It is pretty awesome"
        add_news.form['text'] = "Much <em>wow</em>"
        news = add_news.form.submit().follow()
    
        root_page = client.get('/')
        root_page.form['q'] = "fulltext"
    
>       search_page = root_page.form.submit()
                      ^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views_search.py:36: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.................................................../app/lib/python3.11.../site-packages/webtest/forms.py:633: in submit
    return self.response.goto(self.action, method=self.method,
.................................................../app/lib/python3.11.../site-packages/webtest/response.py:275: in goto
    return method(href, **args)
           ^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
.................................................../app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
.................................................../app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f814978e510 GET http:.../localhost/search?q=fulltext>
model = News(name='now-supporting-fulltext-search', id=6, parent_id=4)

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/town6/test_views_search.py::test_search_future_events_are_sorted_by_occurrence_date
Stack Traces | 5.69s run time
client_with_fts = <tests.onegov.town6.conftest.Client object at 0x7f1f16afd910>

    def test_search_future_events_are_sorted_by_occurrence_date(
        client_with_fts: Client
    ) -> None:
    
        client = client_with_fts
        client.login_admin()
        anom = client.spawn()
        member = client.spawn()
        member.login_member()
    
        event_data: list[dict[str, Any]] = [
            {
                "email": "test@example.org",
                "title": "Not sorted Concert",
                "location": "Location0",
                "organizer": "Organizer0",
                "start_date": date.today() - timedelta(days=10),
            },
            {
                "email": "test2@example.org",
                "title": "Second Concert",
                "location": "Location2",
                "organizer": "Organizer2",
                "start_date": date.today() + timedelta(days=20),
            },
            {
                "email": "test1@example.org",
                "title": "First Concert",
                "location": "Location1",
                "organizer": "Organizer1",
                "start_date": date.today() + timedelta(days=1),
            },
            {
                "email": "test4@example.org",
                "title": "Fourth Concert",
                "location": "Location4",
                "organizer": "Organizer4",
                "start_date": date.today() + timedelta(days=111),
            },
            {
                "email": "test3@example.org",
                "title": "Third Concert",
                "location": "Location3",
                "organizer": "Organizer3",
                "start_date": date.today() + timedelta(days=35),
            },
    
        ]
    
        # Create a couple of events
        for data in event_data:
            form_page = client.get('/events/enter-event')
            form_page.form['email'] = data['email']
            form_page.form['title'] = data['title']
            form_page.form['location'] = data['location']
            form_page.form['organizer'] = data['organizer']
            form_page.form['start_date'] = data['start_date'].isoformat()
            form_page.form['start_time'] = "18:00"
            form_page.form['end_time'] = "22:00"
            form_page.form['repeat'] = 'without'
    
            events_redirect = form_page.form.submit().follow().follow()
            assert "erfolgreich erstellt" in events_redirect
    
        for current_client in (client, member, anom):
>           results = current_client.get('/search?q=Concert')
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/town6/test_views_search.py:342: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:31768: in render_search_result_events
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <OrgRequest at 0x7f1f1932fed0 GET http:.../localhost/search?q=Concert>
model = <onegov.event.models.occurrence.Occurrence object at 0x7f1f0c081ad0>

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/feriennet/test_views.py::test_activity_search
Stack Traces | 6.37s run time
client_with_fts = <tests.onegov.feriennet.conftest.Client object at 0x7f4375e8fa10>
scenario = <tests.onegov.activity.conftest.Scenario object at 0x7f4374008ed0>

    def test_activity_search(client_with_fts: Client, scenario: Scenario) -> None:
        client = client_with_fts
    
        scenario.add_period()
        scenario.add_activity(
            title="Learn How to Program",
            lead="Using a Raspberry Pi we will learn Python",
            username='editor@example.org'
        )
        scenario.add_occasion()
        scenario.commit()
    
        admin = client.spawn()
        admin.login_admin()
    
        editor = client.spawn()
        editor.login_editor()
    
        # in preview, activities can't be found
        assert 'search-result-activities' not in admin.get('/search?q=Learn')
        assert 'search-result-activities' not in editor.get('/search?q=Learn')
        assert 'search-result-activities' not in client.get('/search?q=Learn')
    
        url = '/activity/learn-how-to-program'
        editor.get(url).click("Publikation beantragen")
    
        # once proposed, activities can be found by the admin only
>       assert 'search-result-activities' in admin.get('/search?q=Learn')
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/feriennet/test_views.py:324: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <FeriennetRequest at 0x7f4374e00210 GET http:.../localhost/search?q=Learn>
model = <onegov.feriennet.models.activity.VacationActivity object at 0x7f43751d8510>

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError
tests/onegov/pas/test_views.py::test_views_manage
Stack Traces | 11.7s run time
client_with_fts = <tests.shared.client.Client object at 0x7f9aa033bd50>

    def test_views_manage(client_with_fts: Client[TestPasApp]) -> None:
        client = client_with_fts
        client.login_admin()
    
        settings = client.get('/').follow().click('PAS Einstellungen')
        delete: list[ExtendedResponse] = []
    
        add_rate_set(settings, delete)
    
        # Settlement Runs
        page = settings.click('Abrechnungsläufe')
        page = page.click(href='new')
        page.form['name'] = 'Q1'
        page.form['start'] = '2024-01-01'
        page.form['end'] = '2024-12-31'
        page.form['closed'] = False
        page = page.form.submit().follow()
        assert '31.12.2024' in page
    
        page = page.click('Bearbeiten')
        page.form['end'] = '2024-03-31'
        page = page.form.submit().follow()
        assert '31.03.2024' in page
    
        delete.append(page)
    
        # parties
        page = settings.click('Parteien')
        page = page.click(href='new')
        page.form['name'] = 'BB'
        page = page.form.submit().follow()
        assert 'BB' in page
    
        page = page.click('Bearbeiten')
        page.form['name'] = 'AA'
        page = page.form.submit().follow()
        assert 'AA' in page
    
        delete.append(page)
    
        # Parliamentarian Group
        page = settings.click('Fraktionen')
        page = page.click(href='new')
        page.form['name'] = 'CC'
        page = page.form.submit().follow()
        assert 'CC' in page
    
        page = page.click('Bearbeiten')
        page.form['name'] = 'BB'
        page = page.form.submit().follow()
        assert 'BB' in page
    
        delete.append(page)
    
        # Parliamentarian
        page = settings.click('Parlamentarier:innen')
        page = page.click(href='new')
        page.form['gender'] = 'male'
        page.form['first_name'] = 'First'
        page.form['last_name'] = 'Last'
        page.form['shipping_method'] = 'a'
        page.form['shipping_address'] = 'Address'
        page.form['shipping_address_zip_code'] = 'ZIP'
        page.form['shipping_address_city'] = 'City'
        page.form['email_primary'] = 'first.last@example.org'
        page = page.form.submit().follow()
        assert 'First Last' in page
        assert ' Das Parlamentsmitglied wurde automatisch für den' in page
    
        page = page.click('Bearbeiten')
        page.form['gender'] = 'female'
        page = page.form.submit().follow()
        assert 'weiblich' in page
    
        delete.append(page)
    
        # Role
        page = page.click(href='new')
        page.form['role'] = 'member'
        page.form['start'] = '2020-01-01'
        page = page.form.submit().follow()
        assert 'Mitglied Parlament' in page
    
        page = page.click('Mitglied Parlament').click('Bearbeiten')
        page.form['role'] = 'president'
        page = page.form.submit().follow()
        assert 'Präsident:in Parlament' in page
    
        # Commission
        page = settings.click('Kommissionen')
        page = page.click(href='new')
        page.form['name'] = 'DD'
        page = page.form.submit().follow()
        assert 'DD' in page
    
        page = page.click('Bearbeiten')
        page.form['name'] = 'CC'
        page = page.form.submit().follow()
        assert 'CC' in page
    
        delete.append(page)
    
        # Commission Membership
        page = page.click(href='new-membership')
        page.form['role'] = 'member'
        page.form['start'] = '2020-01-01'
        page = page.form.submit().follow()
        assert 'Mitglied' in page
    
        page = page.click('Mitglied').click('Bearbeiten')
        page.form['role'] = 'president'
        page = page.form.submit().follow()
        assert 'Präsident:in' in page
    
        # Attendences
        # ... commission
        page = page.click(href='add-attendence')
        page.form['date'] = '2024-02-02'
        page.form['duration'] = '1'
        page.form['type'] = 'commission'
        page = page.form.submit().follow()
        assert 'Kommissionsitzung hinzugefügt' in page
    
        # ... attendence
        page = client.get('/').follow().click('Anwesenheiten').click(
            href='new', index=0
        )
        page.form['date'] = '2024-02-03'
        page.form['duration'] = '2'
        page.form['type'] = 'study'
        page.form['commission_id'].select(text='CC')
        page = page.form.submit().follow()
        assert 'Neue Anwesenheit hinzugefügt' in page
    
        page = page.click('Bearbeiten')
        page.form['duration'] = '0.5'
        page = page.form.submit().follow()
        assert '0.50h' in page
    
        delete.insert(0, page)
    
        # ... plenary
        page = client.get('/').follow().click('Anwesenheiten').click(
            href='new', index=1
        )
        page.form['date'] = '2024-02-04'
        page.form['duration'] = '3'
        page = page.form.submit().follow()
        assert 'Plenarsitzung hinzugefügt' in page
    
        page = client.get('/').follow().click('Anwesenheiten')
        assert '02.02.2024' in page
        assert '03.02.2024' in page
        assert '04.02.2024' in page
    
        # Changes
        page = client.get('/').follow().click('Aktivitäten')
        assert '02.02.2024' in page
        assert '03.02.2024' in page
        assert '04.02.2024' in page
        assert 'Anwesenheit bearbeitet' in page
    
        page = page.click(href='/change/', index=0)
        assert 'admin@example.org' in page
    
        # Test search results
        client = client.spawn()
    
        assert '0 Resultate' in client.get('/search?q=aa')
        assert '0 Resultate' in client.get('/search?q=bb')
        assert '0 Resultate' in client.get('/search?q=cc')
        assert '0 Resultate' in client.get('/search?q=first')
        assert '0 Resultate' in client.get('/search?q=Q1')
    
        client.login_admin()
    
>       assert '1 Resultat' in client.get('/search?q=aa')
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^

.../onegov/pas/test_views.py:238: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
............................................./app/lib/python3.11....../site-packages/webtest/app.py:328: in get
    return self.do_request(req, status=status,
tests/shared/client.py:167: in do_request
    return self.extend_response(super().do_request(*args, **kwargs))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webtest/app.py:627: in do_request
    res = req.get_response(app, catch_exc_info=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/webob/request.py:1309: in send
    status, headers, app_iter, exc_info = self.call_application(
............................................./app/lib/python3.11....../site-packages/webob/request.py:1278: in call_application
    app_iter = application(self.environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/webtest/lint.py:196: in lint_app
    iterator = application(environ, start_response_wrapper)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:224: in with_request_cache_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:239: in with_print_exceptions_wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/app.py:138: in __call__
    response = self.publish(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:201: in poisoned_host_header_protection_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1767: in http_conflict_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1792: in activate_session_manager
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1810: in close_session_after_request
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/file/integration.py:450: in configure_depot_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/transaction/main.py:67: in transaction_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1630: in fix_webassets_url
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/user/integration.py:312: in auto_login_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:132: in __call__
    return self.handler(request)
           ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/webassets/tweens.py:84: in __call__
    response = self.handler(request)
               ^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/core.py:157: in excview_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../more/content_security/core.py:99: in content_security_policy_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1835: in current_language_tween
    return handler(request)
           ^^^^^^^^^^^^^^^^
.../onegov/core/framework.py:1877: in set_cache_control_header_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/gis/integration.py:139: in inject_mapbox_api_token_tween
    response = handler(request)
               ^^^^^^^^^^^^^^^^
.../onegov/websockets/integration.py:151: in websocket_csp_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
.../onegov/org/app.py:707: in enable_iframes_tween
    result = handler(request)
             ^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:38: in publish
    return resolve_response(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11....../site-packages/morepath/publish.py:93: in resolve_response
    return request.app.get_view(obj, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<generated code: def call(self, obj, request):
    _key = _registry_key(self=self, obj=obj, request=request)
    return (_component_lookup(_key) or
            _fallback_lookup(_key) or
            _fallback)(self, obj, request)
>:3: in call
    ???
.../onegov/org/app.py:946: in wrapped
    response = func(self, obj, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
............................................./app/lib/python3.11.../site-packages/morepath/view.py:82: in __call__
    content = self.func(obj, request)
              ^^^^^^^^^^^^^^^^^^^^^^^
.../town6/views/search.py:21: in town_search
    return search(self, request, DefaultLayout(self, request))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../org/views/search.py:77: in search
    results_html = self.highlight_results(render_macro(
.../onegov/core/templates.py:294: in render_macro
    macro.include(stream, Scope(variables), {})
macros_aa3ce8b40459e78d416430034ad2a129.py:30333: in render_search_results
    ???
macros_aa3ce8b40459e78d416430034ad2a129.py:33504: in render_search_result_default
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <PasRequest at 0x7f9a9e0d2d90 GET http:.../localhost/search?q=aa>
model = <Party AA>

    def get_layout(self, model: object) -> Layout | DefaultLayout:
        """
        Get the registered layout for a model instance.
        """
    
>       layout_class = self.app.get_layout(model)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: Framework.get_layout() missing 1 required positional argument: 'request'

.../onegov/org/request.py:294: TypeError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@Tschuppi81
Copy link
Contributor Author

Tschuppi81 commented Jan 9, 2026

Also i switched the red color in the results to primary and italic

left: previous, right: now
image

@Tschuppi81
Copy link
Contributor Author

Not sure if the breadcrumbs color in search shall be primary or oil, what do you think?

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds breadcrumb navigation to search results for various content types (Topics, News, People, Files, Tickets, Events, Directory Entries, etc.) to provide better context when viewing search results. The implementation includes:

Changes:

  • Renamed PageLayout to TopicLayout throughout the codebase for clarity
  • Added a new get_layout() method to the request object to retrieve layouts for model instances
  • Implemented a layout registry system via a new Layout directive
  • Updated search result templates to display breadcrumbs for various content types
  • Added breadcrumb styling and fixed CSS issues related to z-index stacking
  • Added file ID anchors and highlight styling for targeted files
  • Updated test selectors to use regex anchors for more precise matching

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/onegov/winterthur/test_search.py Updated click selectors to use regex anchors for precise matching
tests/onegov/town6/test_views_directory.py Updated click selectors to use regex anchors for precise matching
tests/onegov/org/test_views_ticket.py Updated click selectors to use regex anchors for precise matching
tests/onegov/org/test_views_directory.py Updated click selectors to use regex anchors for precise matching
tests/onegov/org/test_layout.py Updated imports from PageLayout to TopicLayout
src/onegov/town6/theme/styles/town6.scss Added z-index reset for breadcrumb links
src/onegov/town6/theme/styles/search.scss Added breadcrumb styling and updated search preview styles
src/onegov/town6/theme/styles/files.scss Added highlight and scroll margin for targeted file rows
src/onegov/town6/templates/macros.pt Added breadcrumbs to search result macros, changed p to div tags for consistency
src/onegov/town6/layout.py Renamed PageLayout to TopicLayout, added layout decorators for multiple models, implemented breadcrumbs for GeneralFile and various RIS models
src/onegov/org/views/page.py Updated imports and references from PageLayout to TopicLayout
src/onegov/org/views/editor.py Updated imports and references from PageLayout to TopicLayout
src/onegov/org/request.py Added get_layout() method to retrieve layouts for model instances
src/onegov/org/layout.py Renamed PageLayout to TopicLayout, added FormDefinitionLayout, DirectoryLayout, improved breadcrumbs for various layouts
src/onegov/org/exports/base.py Fixed import to use onegov.org instead of onegov.town6
src/onegov/org/directives.py Added Layout directive for registering layouts to models
src/onegov/org/app.py Added layout directive to OrgApp
src/onegov/agency/views/page.py Updated imports and references from PageLayout to TopicLayout
src/onegov/agency/layout.py Updated imports and class name from PageLayout to TopicLayout

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@BreathingFlesh BreathingFlesh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would give the breadcrumbs a light background so they look more like a separate element

Copy link
Member

@Daverball Daverball left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there was some confusion, request is not a predicate it's just a regular parameter on get_layout, so you get back a layout instance for the given obj and request, you don't get a layout class back anymore.

Copy link
Member

@Daverball Daverball left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I forgot, that the first parameter to the dispatch_method for the app instance is required for all implementations, we still want the request parameter though, just not as a predicate and we want to return a layout instance, not a class.

@Tschuppi81 Tschuppi81 requested a review from Daverball February 23, 2026 12:48
Copy link
Member

@Daverball Daverball left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're getting pretty close, but the request parameter is still missing and some of the type annotations aren't quite correct.

You also made some changes to the breadcrumb links I'm not sure are a good idea, I'd rather you make that transformation when rendering the search result, since # should generally be able to be replaced by request.link(result). If that isn't the case for some models, I think I'd prefer if you added a new self_url property to Layout, which defaults to return self.request.link(self.model) and can be changed for any layouts where it's different.

Comment on lines +426 to +429
except RegistrationError as e:
# ignore `already have registration for key` error
if 'Already have registration for key' not in str(e):
raise
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very suspect to me. The View action does not need to do a song and dance like this, so I'm pretty sure registering a different layout for the same predicate is fine, as long it's not on the same app class, i.e. registering for Page on OrgApp and then again for TownApp is fine, but registering Page twice on OrgApp isn't.

We may need to set the filter_convert and filter_compare attributes on the action to, so the perform calls happen correctly:

    filter_convert = {
        "model": dectate.convert_dotted_name
    }
    filter_compare = {
        "model": morepath.directive.isbaseclass,
    }

You may also need to change self.identifier to {'model': self.model} or just self.model, but I'm not sure about that one.

Framework.get_layout,
name='model',
default=None,
index=ClassIndex # type: ignore[arg-type]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably my mistake, this type: ignore can go away if you change PredicateAction.__init__ stubs/morepath/directive.pyi, the index parameter should be type[KeyIndex] | str instead of KeyIndex | str.

Comment on lines +1819 to +1820
Link(self.model.number, self.request.link(
TicketCollection(self.request.session).by_id(self.model.id)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you change this for the search results, so the final breadcrumb points somewhere? I think I would prefer if you detected breadcrumb links with href # and replaced them with request.link(model) in the search view, not in the original layout. I'm also not sure why you're querying for the ticket, when you already have it as self.model, you should just do self.request.link(self).

I think in general we want the breadcrumb link to remain #, since it should generally point to where we currently are. The search view is the exception, so the search view can deal with that. So please revert any changes from # to an absolute link.

Comment on lines +294 to +297
layout_class = self.app.get_layout(model)
assert layout_class is not None

return layout_class(model, self)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
layout_class = self.app.get_layout(model)
assert layout_class is not None
return layout_class(model, self)
layout= self.app.get_layout(model, self)
assert layout is not None
return layout

This should now become just this with the new signature.

Tschuppi81 and others added 5 commits February 24, 2026 15:31
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants