def test_remote_methods_via_ajax(web_fixture, remote_method_fixture): """A RemoteMethod can be called via AJAX with CSRF protection built-in.""" fixture = remote_method_fixture def callable_object(): return 'value returned from method' remote_method = RemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(), disable_csrf_check=False) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method, enable_js=True) web_fixture.reahl_server.set_app(wsgi_app) browser = web_fixture.driver_browser # Case: using jquery to POST to the method includes the necessary xsrf info automatically browser.open('/') browser.execute_script( '$.post("/_amethod_method", success=function(data){ $("body").attr("data-result", data) })' ) results = browser.execute_script('return $("body").attr("data-result")') assert results == 'value returned from method' # Case: POSTing without a csrf token breaks browser = Browser(wsgi_app) browser.post('/_amethod_method', {}, status=403)
def test_checked_arguments(web_fixture, remote_method_fixture, argument_scenarios): """A CheckedRemoteMethod checks and marshalls its parameters using Fields.""" fixture = argument_scenarios def callable_object(anint=None, astring=None): fixture.method_kwargs = {'anint': anint, 'astring': astring} return '' remote_method = CheckedRemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(), idempotent=fixture.idempotent, anint=IntegerField(), astring=Field(), disable_csrf_check=True) wsgi_app = remote_method_fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) if fixture.idempotent: browser.open( '/_amethod_method?anint=5&astring=SupercalifraGilisticexpialidocious' ) else: browser.post('/_amethod_method', { 'anint': '5', 'astring': 'SupercalifraGilisticexpialidocious' }) assert fixture.method_kwargs == { 'anint': 5, 'astring': 'SupercalifraGilisticexpialidocious' }
def test_remote_methods(web_fixture, remote_method_fixture): """A RemoteMethod is a SubResource representing a method on the server side which can be invoked via POSTing to an URL.""" fixture = remote_method_fixture def callable_object(): return 'value returned from method' encoding = 'koi8_r' # Deliberate remote_method = RemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(mime_type='ttext/hhtml', encoding=encoding), disable_csrf_check=True) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) # By default you cannot GET, since the method is not immutable browser.open('/_amethod_method', status=405) # POSTing to the URL, returns the result of the method browser.post('/_amethod_method', {}) assert browser.raw_html == 'value returned from method' assert browser.last_response.charset == encoding assert browser.last_response.content_type == 'ttext/hhtml'
def test_immutable_remote_methods(web_fixture, remote_method_fixture, sql_alchemy_fixture): """The database is always rolled back at the end of an immutable RemoteMethod.""" class TestObject(Base): __tablename__ = 'test_remotemethods_test_object' id = Column(Integer, primary_key=True) name = Column(UnicodeText) with sql_alchemy_fixture.persistent_test_classes(TestObject): def callable_object(): Session.add(TestObject(name='new object')) assert Session.query(TestObject).count() == 1 return 'value returned from method' remote_method = RemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(), immutable=True, disable_csrf_check=True) assert remote_method.idempotent # Immutable methods are idempotent wsgi_app = remote_method_fixture.new_wsgi_app( remote_method=remote_method) browser = Browser(wsgi_app) browser.open('/_amethod_method') assert browser.raw_html == 'value returned from method' # The database is rolled back to ensure immutability assert Session.query(TestObject).count() == 0
def test_arguments_to_remote_methods(web_fixture, remote_method_fixture, argument_scenarios): """A RemoteMethod can get arguments from a query string or submitted form values, depending on the scenario.""" fixture = argument_scenarios def callable_object(**kwargs): fixture.method_kwargs = kwargs return '' remote_method = RemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(), idempotent=fixture.idempotent, disable_csrf_check=True) wsgi_app = remote_method_fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) kwargs_sent = {'a': 'AAA', 'b': 'BBB'} if fixture.idempotent: browser.open('/_amethod_method?a=AAA&b=BBB') else: browser.post('/_amethod_method', kwargs_sent) assert fixture.method_kwargs == kwargs_sent
def remote_methods(self, fixture): """A RemoteMethod is a SubResource representing a method on the server side which can be invoked via POSTing to an URL.""" def callable_object(): return 'value returned from method' encoding = 'koi8_r' # Deliberate remote_method = RemoteMethod( 'amethod', callable_object, MethodResult(mime_type='ttext/hhtml', encoding=encoding)) @stubclass(Widget) class WidgetWithRemoteMethod(Widget): def __init__(self, view): super(WidgetWithRemoteMethod, self).__init__(view) view.add_resource(remote_method) wsgi_app = fixture.new_wsgi_app( view_slots={'main': WidgetWithRemoteMethod.factory()}) browser = Browser(wsgi_app) # By default you cannot GET, since the method is not immutable browser.open('/_amethod_method', status=405) # POSTing to the URL, returns the result of the method browser.post('/_amethod_method', {}) vassert(browser.raw_html == 'value returned from method') vassert(browser.last_response.charset == encoding) vassert(browser.last_response.content_type == 'ttext/hhtml')
def checked_arguments(self, fixture): """A CheckedRemoteMethod checks and marshalls its parameters using Fields.""" def callable_object(anint=None, astring=None): fixture.method_kwargs = {'anint': anint, 'astring': astring} return '' remote_method = CheckedRemoteMethod('amethod', callable_object, MethodResult(), immutable=fixture.immutable, anint=IntegerField(), astring=Field()) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) if fixture.immutable: browser.open( '/_amethod_method?anint=5&astring=SupercalifraGilisticexpialidocious' ) else: browser.post('/_amethod_method', { 'anint': '5', 'astring': 'SupercalifraGilisticexpialidocious' }) vassert(fixture.method_kwargs == { 'anint': 5, 'astring': 'SupercalifraGilisticexpialidocious' })
def exception_handling(self, fixture): """The RemoteMethod sends back the six.text_type() of an exception raised for the specified exception class.""" def fail(): raise Exception('I failed') remote_method = RemoteMethod('amethod', fail, MethodResult(catch_exception=Exception)) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) browser.post('/_amethod_method', {}) vassert(browser.raw_html == 'I failed')
def test_exception_handling(web_fixture, remote_method_fixture): """The RemoteMethod sends back the str() of an exception raised for the specified exception class.""" def fail(): raise Exception('I failed') remote_method = RemoteMethod(web_fixture.view, 'amethod', fail, MethodResult(catch_exception=Exception)) wsgi_app = remote_method_fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) browser.post('/_amethod_method', {}) assert browser.raw_html == 'I failed'
def immutable_remote_methods(self, fixture): """A RemoteMethod that is immutable is accessible via GET (instead of POST).""" def callable_object(): return 'value returned from method' remote_method = RemoteMethod('amethod', callable_object, MethodResult(), immutable=True) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) # GET, since the method is immutable browser.open('/_amethod_method') vassert(browser.raw_html == 'value returned from method') # POSTing to the URL, is not supported browser.post('/_amethod_method', {}, status=405)
def arguments_to_remote_methods(self, fixture): """A RemoteMethod can get arguments from a query string or submitted form values, depending on the scenario.""" def callable_object(**kwargs): fixture.method_kwargs = kwargs return '' remote_method = RemoteMethod('amethod', callable_object, MethodResult(), immutable=fixture.immutable) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) kwargs_sent = {'a': 'AAA', 'b': 'BBB'} if fixture.immutable: browser.open('/_amethod_method?a=AAA&b=BBB') else: browser.post('/_amethod_method', kwargs_sent) vassert(fixture.method_kwargs == kwargs_sent)
def test_idempotent_remote_methods(web_fixture, remote_method_fixture): """A RemoteMethod that is idempotent is accessible via GET (instead of POST).""" def callable_object(): return 'value returned from method' remote_method = RemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(), idempotent=True) wsgi_app = remote_method_fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) # GET, since the method is idempotent browser.open('/_amethod_method') assert browser.raw_html == 'value returned from method' # POSTing to the URL, is not supported browser.post('/_amethod_method', {}, status=405)