Ejemplo n.º 1
0
    def setUp(self):
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=['all'])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table('t0', Field('tt'), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.db.auth_user.insert(first_name='Bart',
                                 last_name='Simpson',
                                 username='******',
                                 email='*****@*****.**',
                                 password='******',
                                 registration_key=None,
                                 registration_id=None)

        self.db.commit()
Ejemplo n.º 2
0
 def setUp(self):
     request = Request(env={})
     request.application = 'a'
     request.controller = 'c'
     request.function = 'f'
     request.folder = 'applications/admin'
     response = Response()
     session = Session()
     T = translator('', 'en')
     session.connect(request, response)
     from gluon.globals import current
     current.request = request
     current.response = response
     current.session = session
     current.T = T
     self.db = DAL(DEFAULT_URI, check_reserved=['all'])
     self.auth = Auth(self.db)
     self.auth.define_tables(username=True, signature=False)
     self.db.define_table('t0', Field('tt'), self.auth.signature)
     self.auth.enable_record_versioning(self.db)
     # Create a user
     self.auth.get_or_create_user(dict(first_name='Bart',
                                       last_name='Simpson',
                                       username='******',
                                       email='*****@*****.**',
                                       password='******',
                                       registration_key='bart',
                                       registration_id=''
                                       ))
Ejemplo n.º 3
0
    def setUp(self):
        request = Request(env={})
        request.application = "a"
        request.controller = "c"
        request.function = "f"
        request.folder = "applications/admin"
        response = Response()
        session = Session()
        T = translator("", "en")
        session.connect(request, response)
        from gluon.globals import current

        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=["all"])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table("t0", Field("tt"), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.db.auth_user.insert(
            first_name="Bart",
            last_name="Simpson",
            username="******",
            email="*****@*****.**",
            password="******",
            registration_key=None,
            registration_id=None,
        )

        self.db.commit()
Ejemplo n.º 4
0
    def testRun(self):
        # setup
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        db = DAL(DEFAULT_URI, check_reserved=['all'])
        auth = Auth(db)
        auth.define_tables(username=True, signature=False)
        self.assertTrue('auth_user' in db)
        self.assertTrue('auth_group' in db)
        self.assertTrue('auth_membership' in db)
        self.assertTrue('auth_permission' in db)
        self.assertTrue('auth_event' in db)
        db.define_table('t0', Field('tt'), auth.signature)
        auth.enable_record_versioning(db)
        self.assertTrue('t0_archive' in db)
        for f in ['login', 'register', 'retrieve_password',
                  'retrieve_username']:
            html_form = getattr(auth, f)().xml()
            self.assertTrue('name="_formkey"' in html_form)

        for f in ['logout', 'verify_email', 'reset_password',
                  'change_password', 'profile', 'groups']:
            self.assertRaisesRegexp(HTTP, "303*", getattr(auth, f))

        self.assertRaisesRegexp(HTTP, "401*", auth.impersonate)

        try:
            for t in ['t0_archive', 't0', 'auth_cas', 'auth_event',
                      'auth_membership', 'auth_permission', 'auth_group',
                      'auth_user']:
                db[t].drop()
        except SyntaxError as e:
            # GAE doesn't support drop
            pass
        return
Ejemplo n.º 5
0
class TestSQLTABLE(unittest.TestCase):
    def setUp(self):
        request = Request(env={})
        request.application = "a"
        request.controller = "c"
        request.function = "f"
        request.folder = "applications/admin"
        response = Response()
        session = Session()
        T = translator("", "en")
        session.connect(request, response)
        from gluon.globals import current

        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=["all"])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table("t0", Field("tt"), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.db.auth_user.insert(
            first_name="Bart",
            last_name="Simpson",
            username="******",
            email="*****@*****.**",
            password="******",
            registration_key=None,
            registration_id=None,
        )

        self.db.commit()

    def test_SQLTABLE(self):
        rows = self.db(self.db.auth_user.id > 0).select(self.db.auth_user.ALL)
        sqltable = SQLTABLE(rows)
        self.assertEqual(
            sqltable.xml(),
            '<table><thead><tr><th>auth_user.id</th><th>auth_user.first_name</th><th>auth_user.last_name</th><th>auth_user.email</th><th>auth_user.username</th><th>auth_user.password</th><th>auth_user.registration_key</th><th>auth_user.reset_password_key</th><th>auth_user.registration_id</th></tr></thead><tbody><tr class="w2p_odd odd"><td>1</td><td>Bart</td><td>Simpson</td><td>[email protected]</td><td>user1</td><td>password_123</td><td>None</td><td></td><td>None</td></tr></tbody></table>',
        )
Ejemplo n.º 6
0
class TestSQLTABLE(unittest.TestCase):
    def setUp(self):
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=['all'])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table('t0', Field('tt'), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.db.auth_user.insert(first_name='Bart',
                                 last_name='Simpson',
                                 username='******',
                                 email='*****@*****.**',
                                 password='******',
                                 registration_key=None,
                                 registration_id=None)

        self.db.commit()

    def test_SQLTABLE(self):
        rows = self.db(self.db.auth_user.id > 0).select(self.db.auth_user.ALL)
        sqltable = SQLTABLE(rows)
        self.assertEqual(
            sqltable.xml(),
            '<table><thead><tr><th>auth_user.id</th><th>auth_user.first_name</th><th>auth_user.last_name</th><th>auth_user.email</th><th>auth_user.username</th><th>auth_user.password</th><th>auth_user.registration_key</th><th>auth_user.reset_password_key</th><th>auth_user.registration_id</th></tr></thead><tbody><tr class="w2p_odd odd"><td>1</td><td>Bart</td><td>Simpson</td><td>[email protected]</td><td>user1</td><td>password_123</td><td>None</td><td></td><td>None</td></tr></tbody></table>'
        )
Ejemplo n.º 7
0
    def testRun(self):
        # setup
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        db = DAL(DEFAULT_URI, check_reserved=['all'])
        auth = Auth(db)
        auth.define_tables(username=True, signature=False)
        self.assertTrue('auth_user' in db)
        self.assertTrue('auth_group' in db)
        self.assertTrue('auth_membership' in db)
        self.assertTrue('auth_permission' in db)
        self.assertTrue('auth_event' in db)
        db.define_table('t0', Field('tt'), auth.signature)
        auth.enable_record_versioning(db)
        self.assertTrue('t0_archive' in db)
        for f in [
                'login', 'register', 'retrieve_password', 'retrieve_username'
        ]:
            html_form = getattr(auth, f)().xml()
            self.assertTrue('name="_formkey"' in html_form)

        for f in [
                'logout', 'verify_email', 'reset_password', 'change_password',
                'profile', 'groups'
        ]:
            self.assertRaisesRegexp(HTTP, "303*", getattr(auth, f))

        self.assertRaisesRegexp(HTTP, "401*", auth.impersonate)

        try:
            for t in [
                    't0_archive', 't0', 'auth_cas', 'auth_event',
                    'auth_membership', 'auth_permission', 'auth_group',
                    'auth_user'
            ]:
                db[t].drop()
        except SyntaxError as e:
            # GAE doesn't support drop
            pass
        return
Ejemplo n.º 8
0
from globals import current
from html import *
from validators import *
from http import redirect, HTTP
from dal import DAL, Field
from sqlhtml import SQLFORM, SQLTABLE
from compileapp import LOAD

# Dummy code to enable code completion in IDE's.
if 0:
    from globals import Request, Response, Session
    from cache import Cache
    from languages import translator
    from tools import Auth, Crud, Mail, Service, PluginManager

    # API objects
    request = Request()
    response = Response()
    session = Session()
    cache = Cache(request)
    T = translator(request)

    # Objects commonly defined in application model files
    # (names are conventions only -- not part of API)
    db = DAL()
    auth = Auth(db)
    crud = Crud(db)
    mail = Mail()
    service = Service()
    plugins = PluginManager()
Ejemplo n.º 9
0
class TestSQLFORM(unittest.TestCase):
    def setUp(self):
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=['all'])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table('t0', Field('tt'), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.db.auth_user.insert(first_name='Bart',
                                 last_name='Simpson',
                                 username='******',
                                 email='*****@*****.**',
                                 password='******',
                                 registration_key=None,
                                 registration_id=None)

        self.db.commit()

    def test_SQLFORM(self):
        form = SQLFORM(self.db.auth_user)
        self.assertEqual(
            form.xml(),
            '<form action="#" enctype="multipart/form-data" method="post"><table><tr id="auth_user_first_name__row"><td class="w2p_fl"><label class="" for="auth_user_first_name" id="auth_user_first_name__label">First name: </label></td><td class="w2p_fw"><input class="string" id="auth_user_first_name" name="first_name" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_last_name__row"><td class="w2p_fl"><label class="" for="auth_user_last_name" id="auth_user_last_name__label">Last name: </label></td><td class="w2p_fw"><input class="string" id="auth_user_last_name" name="last_name" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_email__row"><td class="w2p_fl"><label class="" for="auth_user_email" id="auth_user_email__label">E-mail: </label></td><td class="w2p_fw"><input class="string" id="auth_user_email" name="email" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_username__row"><td class="w2p_fl"><label class="" for="auth_user_username" id="auth_user_username__label">Username: </label></td><td class="w2p_fw"><input class="string" id="auth_user_username" name="username" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_password__row"><td class="w2p_fl"><label class="" for="auth_user_password" id="auth_user_password__label">Password: </label></td><td class="w2p_fw"><input class="password" id="auth_user_password" name="password" type="password" value="" /></td><td class="w2p_fc"></td></tr><tr id="submit_record__row"><td class="w2p_fl"></td><td class="w2p_fw"><input type="submit" value="Submit" /></td><td class="w2p_fc"></td></tr></table></form>'
        )

    # def test_assert_status(self):
    #     pass

    #  def test_createform(self):
    #     pass

    #  def test_accepts(self):
    #     pass

    #  def test_dictform(self):
    #     pass

    #  def test_smartdictform(self):
    #     pass

    def test_factory(self):
        factory_form = SQLFORM.factory(
            Field('field_one', 'string', IS_NOT_EMPTY()),
            Field('field_two', 'string'))
        self.assertEqual(
            factory_form.xml(),
            '<form action="#" enctype="multipart/form-data" method="post"><table><tr id="no_table_field_one__row"><td class="w2p_fl"><label class="" for="no_table_field_one" id="no_table_field_one__label">Field One: </label></td><td class="w2p_fw"><input class="string" id="no_table_field_one" name="field_one" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="no_table_field_two__row"><td class="w2p_fl"><label class="" for="no_table_field_two" id="no_table_field_two__label">Field Two: </label></td><td class="w2p_fw"><input class="string" id="no_table_field_two" name="field_two" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="submit_record__row"><td class="w2p_fl"></td><td class="w2p_fw"><input type="submit" value="Submit" /></td><td class="w2p_fc"></td></tr></table></form>'
        )

    #  def test_build_query(self):
    #     pass

    #  def test_search_menu(self):
    #     pass

    def test_grid(self):
        grid_form = SQLFORM.grid(self.db.auth_user)
        self.assertEqual(
            grid_form.xml(),
            '<div class="web2py_grid "><div class="web2py_console  "><form action="/a/c/f" enctype="multipart/form-data" method="GET"><input class="form-control" id="w2p_keywords" name="keywords" onfocus="jQuery(&#x27;#w2p_query_fields&#x27;).change();jQuery(&#x27;#w2p_query_panel&#x27;).slideDown();" type="text" value="" /><input class="btn btn-default" type="submit" value="Search" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_keywords&#x27;).val(&#x27;&#x27;);" type="submit" value="Clear" /></form><div id="w2p_query_panel" style="display:none;"><select class="form-control" id="w2p_query_fields" onchange="jQuery(&#x27;.w2p_query_row&#x27;).hide();jQuery(&#x27;#w2p_field_&#x27;+jQuery(&#x27;#w2p_query_fields&#x27;).val().replace(&#x27;.&#x27;,&#x27;-&#x27;)).show();" style="float:left"><option value="auth_user.id">Id</option><option value="auth_user.first_name">First name</option><option value="auth_user.last_name">Last name</option><option value="auth_user.email">E-mail</option><option value="auth_user.username">Username</option></select><div class="w2p_query_row" id="w2p_field_auth_user-id" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="in">in</option><option value="not in">not in</option></select><input class="id form-control" id="w2p_value_auth_user-id" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.id&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-first_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-first_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.first_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-last_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-last_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.last_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-email" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-email" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.email&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-username" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-username" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.username&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div></div><script><!--\n\n        jQuery(\'#w2p_query_fields input,#w2p_query_fields select\').css(\n            \'width\',\'auto\');\n        jQuery(function(){web2py_ajax_fields(\'#w2p_query_fields\');});\n        function w2p_build_query(aggregator,a) {\n          var b=a.replace(\'.\',\'-\');\n          var option = jQuery(\'#w2p_field_\'+b+\' select\').val();\n          var value;\n          var $value_item = jQuery(\'#w2p_value_\'+b);\n          if ($value_item.is(\':checkbox\')){\n            if  ($value_item.is(\':checked\'))\n                    value = \'True\';\n            else  value = \'False\';\n          }\n          else\n          { value = $value_item.val().replace(\'"\',\'\\\\"\')}\n          var s=a+\' \'+option+\' "\'+value+\'"\';\n          var k=jQuery(\'#w2p_keywords\');\n          var v=k.val();\n          if(aggregator==\'new\') k.val(s); else k.val((v?(v+\' \'+ aggregator +\' \'):\'\')+s);\n        }\n        \n//--></script><div class="web2py_counter">1 records found</div></div><div class="web2py_table"><div class="web2py_htmltable" style="width:100%;overflow-x:auto;-ms-overflow-x:scroll"><table><colgroup><col data-column="1" id="auth_user-id" /><col data-column="2" id="auth_user-first_name" /><col data-column="3" id="auth_user-last_name" /><col data-column="4" id="auth_user-email" /><col data-column="5" id="auth_user-username" /><col data-column="6" /></colgroup><thead><tr class=""><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.id">Id</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.first_name">First name</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.last_name">Last name</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.email">E-mail</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.username">Username</a></th><th class=""></th></tr></thead><tbody><tr class="w2p_odd odd with_id" id="1"><td>1</td><td>Bart</td><td>Simpson</td><td>[email protected]</td><td>user1</td><td class="row_buttons" nowrap="nowrap"><a class="button btn btn-default" href="/a/c/f/view/auth_user/1"><span class="icon magnifier icon-zoom-in glyphicon glyphicon-zoom-in"></span> <span class="buttontext button" title="View">View</span></a></td></tr></tbody></table></div></div><div class="w2p_export_menu">Export:<a class="btn btn-default" href="/a/c/f?_export_type=csv&amp;keywords=&amp;order=" title="Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows">CSV</a><a class="btn btn-default" href="/a/c/f?_export_type=csv_with_hidden_cols&amp;keywords=&amp;order=" title="Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export">CSV (hidden cols)</a><a class="btn btn-default" href="/a/c/f?_export_type=html&amp;keywords=&amp;order=" title="HTML export of visible columns">HTML</a><a class="btn btn-default" href="/a/c/f?_export_type=json&amp;keywords=&amp;order=" title="JSON export of visible columns">JSON</a><a class="btn btn-default" href="/a/c/f?_export_type=tsv&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.">TSV (Spreadsheets)</a><a class="btn btn-default" href="/a/c/f?_export_type=tsv_with_hidden_cols&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow">TSV (Spreadsheets, hidden cols)</a><a class="btn btn-default" href="/a/c/f?_export_type=xml&amp;keywords=&amp;order=" title="XML export of columns shown">XML</a></div></div>'
        )

    def test_smartgrid(self):
        smartgrid_form = SQLFORM.smartgrid(self.db.auth_user)
        self.assertEqual(
            smartgrid_form.xml(),
            '<div class="web2py_grid "><div class="web2py_breadcrumbs"><ul class=""><li class="active w2p_grid_breadcrumb_elem"><a href="/a/c/f/auth_user">Auth users</a></li></ul></div><div class="web2py_console  "><form action="/a/c/f/auth_user" enctype="multipart/form-data" method="GET"><input class="form-control" id="w2p_keywords" name="keywords" onfocus="jQuery(&#x27;#w2p_query_fields&#x27;).change();jQuery(&#x27;#w2p_query_panel&#x27;).slideDown();" type="text" value="" /><input class="btn btn-default" type="submit" value="Search" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_keywords&#x27;).val(&#x27;&#x27;);" type="submit" value="Clear" /></form><div id="w2p_query_panel" style="display:none;"><select class="form-control" id="w2p_query_fields" onchange="jQuery(&#x27;.w2p_query_row&#x27;).hide();jQuery(&#x27;#w2p_field_&#x27;+jQuery(&#x27;#w2p_query_fields&#x27;).val().replace(&#x27;.&#x27;,&#x27;-&#x27;)).show();" style="float:left"><option value="auth_user.id">Id</option><option value="auth_user.first_name">First name</option><option value="auth_user.last_name">Last name</option><option value="auth_user.email">E-mail</option><option value="auth_user.username">Username</option></select><div class="w2p_query_row" id="w2p_field_auth_user-id" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="in">in</option><option value="not in">not in</option></select><input class="id form-control" id="w2p_value_auth_user-id" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.id&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-first_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-first_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.first_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-last_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-last_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.last_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-email" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-email" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.email&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-username" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-username" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.username&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div></div><script><!--\n\n        jQuery(\'#w2p_query_fields input,#w2p_query_fields select\').css(\n            \'width\',\'auto\');\n        jQuery(function(){web2py_ajax_fields(\'#w2p_query_fields\');});\n        function w2p_build_query(aggregator,a) {\n          var b=a.replace(\'.\',\'-\');\n          var option = jQuery(\'#w2p_field_\'+b+\' select\').val();\n          var value;\n          var $value_item = jQuery(\'#w2p_value_\'+b);\n          if ($value_item.is(\':checkbox\')){\n            if  ($value_item.is(\':checked\'))\n                    value = \'True\';\n            else  value = \'False\';\n          }\n          else\n          { value = $value_item.val().replace(\'"\',\'\\\\"\')}\n          var s=a+\' \'+option+\' "\'+value+\'"\';\n          var k=jQuery(\'#w2p_keywords\');\n          var v=k.val();\n          if(aggregator==\'new\') k.val(s); else k.val((v?(v+\' \'+ aggregator +\' \'):\'\')+s);\n        }\n        \n//--></script><div class="web2py_counter">1 records found</div></div><div class="web2py_table"><div class="web2py_htmltable" style="width:100%;overflow-x:auto;-ms-overflow-x:scroll"><table><colgroup><col data-column="1" id="auth_user-id" /><col data-column="2" id="auth_user-first_name" /><col data-column="3" id="auth_user-last_name" /><col data-column="4" id="auth_user-email" /><col data-column="5" id="auth_user-username" /><col data-column="6" /></colgroup><thead><tr class=""><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.id">Id</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.first_name">First name</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.last_name">Last name</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.email">E-mail</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.username">Username</a></th><th class=""></th></tr></thead><tbody><tr class="w2p_odd odd with_id" id="1"><td>1</td><td>Bart</td><td>Simpson</td><td>[email protected]</td><td>user1</td><td class="row_buttons" nowrap="nowrap"><a href="/a/c/f/auth_user/auth_membership.user_id/1"><span>Auth memberships</span></a><a href="/a/c/f/auth_user/auth_event.user_id/1"><span>Auth events</span></a><a href="/a/c/f/auth_user/auth_cas.user_id/1"><span>Auth cases</span></a><a href="/a/c/f/auth_user/t0.created_by/1"><span>T0s(created_by)</span></a><a href="/a/c/f/auth_user/t0.modified_by/1"><span>T0s(modified_by)</span></a><a href="/a/c/f/auth_user/t0_archive.created_by/1"><span>T0 archives(created_by)</span></a><a href="/a/c/f/auth_user/t0_archive.modified_by/1"><span>T0 archives(modified_by)</span></a><a class="button btn btn-default" href="/a/c/f/auth_user/view/auth_user/1"><span class="icon magnifier icon-zoom-in glyphicon glyphicon-zoom-in"></span> <span class="buttontext button" title="View">View</span></a></td></tr></tbody></table></div></div><div class="w2p_export_menu">Export:<a class="btn btn-default" href="/a/c/f/auth_user?_export_type=csv&amp;keywords=&amp;order=" title="Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows">CSV</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=csv_with_hidden_cols&amp;keywords=&amp;order=" title="Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export">CSV (hidden cols)</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=html&amp;keywords=&amp;order=" title="HTML export of visible columns">HTML</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=json&amp;keywords=&amp;order=" title="JSON export of visible columns">JSON</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=tsv&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.">TSV (Spreadsheets)</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=tsv_with_hidden_cols&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow">TSV (Spreadsheets, hidden cols)</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=xml&amp;keywords=&amp;order=" title="XML export of columns shown">XML</a></div></div>'
        )
Ejemplo n.º 10
0
class TestSQLFORM(unittest.TestCase):
    def setUp(self):
        request = Request(env={})
        request.application = "a"
        request.controller = "c"
        request.function = "f"
        request.folder = "applications/admin"
        response = Response()
        session = Session()
        T = translator("", "en")
        session.connect(request, response)
        from gluon.globals import current

        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=["all"])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table("t0", Field("tt"), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.db.auth_user.insert(
            first_name="Bart",
            last_name="Simpson",
            username="******",
            email="*****@*****.**",
            password="******",
            registration_key=None,
            registration_id=None,
        )

        self.db.commit()

    def test_SQLFORM(self):
        form = SQLFORM(self.db.auth_user)
        self.assertEqual(
            form.xml(),
            '<form action="#" enctype="multipart/form-data" method="post"><table><tr id="auth_user_first_name__row"><td class="w2p_fl"><label class="" for="auth_user_first_name" id="auth_user_first_name__label">First name: </label></td><td class="w2p_fw"><input class="string" id="auth_user_first_name" name="first_name" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_last_name__row"><td class="w2p_fl"><label class="" for="auth_user_last_name" id="auth_user_last_name__label">Last name: </label></td><td class="w2p_fw"><input class="string" id="auth_user_last_name" name="last_name" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_email__row"><td class="w2p_fl"><label class="" for="auth_user_email" id="auth_user_email__label">E-mail: </label></td><td class="w2p_fw"><input class="string" id="auth_user_email" name="email" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_username__row"><td class="w2p_fl"><label class="" for="auth_user_username" id="auth_user_username__label">Username: </label></td><td class="w2p_fw"><input class="string" id="auth_user_username" name="username" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="auth_user_password__row"><td class="w2p_fl"><label class="" for="auth_user_password" id="auth_user_password__label">Password: </label></td><td class="w2p_fw"><input class="password" id="auth_user_password" name="password" type="password" value="" /></td><td class="w2p_fc"></td></tr><tr id="submit_record__row"><td class="w2p_fl"></td><td class="w2p_fw"><input type="submit" value="Submit" /></td><td class="w2p_fc"></td></tr></table></form>',
        )

    # def test_assert_status(self):
    #     pass

    #  def test_createform(self):
    #     pass

    #  def test_accepts(self):
    #     pass

    #  def test_dictform(self):
    #     pass

    #  def test_smartdictform(self):
    #     pass

    def test_factory(self):
        factory_form = SQLFORM.factory(Field("field_one", "string", IS_NOT_EMPTY()), Field("field_two", "string"))
        self.assertEqual(
            factory_form.xml(),
            '<form action="#" enctype="multipart/form-data" method="post"><table><tr id="no_table_field_one__row"><td class="w2p_fl"><label class="" for="no_table_field_one" id="no_table_field_one__label">Field One: </label></td><td class="w2p_fw"><input class="string" id="no_table_field_one" name="field_one" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="no_table_field_two__row"><td class="w2p_fl"><label class="" for="no_table_field_two" id="no_table_field_two__label">Field Two: </label></td><td class="w2p_fw"><input class="string" id="no_table_field_two" name="field_two" type="text" value="" /></td><td class="w2p_fc"></td></tr><tr id="submit_record__row"><td class="w2p_fl"></td><td class="w2p_fw"><input type="submit" value="Submit" /></td><td class="w2p_fc"></td></tr></table></form>',
        )

    #  def test_build_query(self):
    #     pass

    #  def test_search_menu(self):
    #     pass

    def test_grid(self):
        grid_form = SQLFORM.grid(self.db.auth_user)
        self.assertEqual(
            grid_form.xml(),
            '<div class="web2py_grid "><div class="web2py_console  "><form action="/a/c/f" enctype="multipart/form-data" method="GET"><input class="form-control" id="w2p_keywords" name="keywords" onfocus="jQuery(&#x27;#w2p_query_fields&#x27;).change();jQuery(&#x27;#w2p_query_panel&#x27;).slideDown();" type="text" value="" /><input class="btn btn-default" type="submit" value="Search" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_keywords&#x27;).val(&#x27;&#x27;);" type="submit" value="Clear" /></form><div id="w2p_query_panel" style="display:none;"><select class="form-control" id="w2p_query_fields" onchange="jQuery(&#x27;.w2p_query_row&#x27;).hide();jQuery(&#x27;#w2p_field_&#x27;+jQuery(&#x27;#w2p_query_fields&#x27;).val().replace(&#x27;.&#x27;,&#x27;-&#x27;)).show();" style="float:left"><option value="auth_user.id">Id</option><option value="auth_user.first_name">First name</option><option value="auth_user.last_name">Last name</option><option value="auth_user.email">E-mail</option><option value="auth_user.username">Username</option></select><div class="w2p_query_row" id="w2p_field_auth_user-id" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="in">in</option><option value="not in">not in</option></select><input class="id form-control" id="w2p_value_auth_user-id" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.id&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-first_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-first_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.first_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-last_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-last_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.last_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-email" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-email" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.email&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-username" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-username" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.username&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div></div><script><!--\n\n        jQuery(\'#w2p_query_fields input,#w2p_query_fields select\').css(\n            \'width\',\'auto\');\n        jQuery(function(){web2py_ajax_fields(\'#w2p_query_fields\');});\n        function w2p_build_query(aggregator,a) {\n          var b=a.replace(\'.\',\'-\');\n          var option = jQuery(\'#w2p_field_\'+b+\' select\').val();\n          var value;\n          var $value_item = jQuery(\'#w2p_value_\'+b);\n          if ($value_item.is(\':checkbox\')){\n            if  ($value_item.is(\':checked\'))\n                    value = \'True\';\n            else  value = \'False\';\n          }\n          else\n          { value = $value_item.val().replace(\'"\',\'\\\\"\')}\n          var s=a+\' \'+option+\' "\'+value+\'"\';\n          var k=jQuery(\'#w2p_keywords\');\n          var v=k.val();\n          if(aggregator==\'new\') k.val(s); else k.val((v?(v+\' \'+ aggregator +\' \'):\'\')+s);\n        }\n        \n//--></script><div class="web2py_counter">1 records found</div></div><div class="web2py_table"><div class="web2py_htmltable" style="width:100%;overflow-x:auto;-ms-overflow-x:scroll"><table><colgroup><col data-column="1" id="auth_user-id" /><col data-column="2" id="auth_user-first_name" /><col data-column="3" id="auth_user-last_name" /><col data-column="4" id="auth_user-email" /><col data-column="5" id="auth_user-username" /><col data-column="6" /></colgroup><thead><tr class=""><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.id">Id</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.first_name">First name</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.last_name">Last name</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.email">E-mail</a></th><th class=""><a href="/a/c/f?keywords=&amp;order=auth_user.username">Username</a></th><th class=""></th></tr></thead><tbody><tr class="w2p_odd odd with_id" id="1"><td>1</td><td>Bart</td><td>Simpson</td><td>[email protected]</td><td>user1</td><td class="row_buttons" nowrap="nowrap"><a class="button btn btn-default" href="/a/c/f/view/auth_user/1"><span class="icon magnifier icon-zoom-in glyphicon glyphicon-zoom-in"></span> <span class="buttontext button" title="View">View</span></a></td></tr></tbody></table></div></div><div class="w2p_export_menu">Export:<a class="btn btn-default" href="/a/c/f?_export_type=csv&amp;keywords=&amp;order=" title="Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows">CSV</a><a class="btn btn-default" href="/a/c/f?_export_type=csv_with_hidden_cols&amp;keywords=&amp;order=" title="Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export">CSV (hidden cols)</a><a class="btn btn-default" href="/a/c/f?_export_type=html&amp;keywords=&amp;order=" title="HTML export of visible columns">HTML</a><a class="btn btn-default" href="/a/c/f?_export_type=json&amp;keywords=&amp;order=" title="JSON export of visible columns">JSON</a><a class="btn btn-default" href="/a/c/f?_export_type=tsv&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.">TSV (Spreadsheets)</a><a class="btn btn-default" href="/a/c/f?_export_type=tsv_with_hidden_cols&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow">TSV (Spreadsheets, hidden cols)</a><a class="btn btn-default" href="/a/c/f?_export_type=xml&amp;keywords=&amp;order=" title="XML export of columns shown">XML</a></div></div>',
        )

    def test_smartgrid(self):
        smartgrid_form = SQLFORM.smartgrid(self.db.auth_user)
        self.assertEqual(
            smartgrid_form.xml(),
            '<div class="web2py_grid "><div class="web2py_breadcrumbs"><ul class=""><li class="active w2p_grid_breadcrumb_elem"><a href="/a/c/f/auth_user">Auth users</a></li></ul></div><div class="web2py_console  "><form action="/a/c/f/auth_user" enctype="multipart/form-data" method="GET"><input class="form-control" id="w2p_keywords" name="keywords" onfocus="jQuery(&#x27;#w2p_query_fields&#x27;).change();jQuery(&#x27;#w2p_query_panel&#x27;).slideDown();" type="text" value="" /><input class="btn btn-default" type="submit" value="Search" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_keywords&#x27;).val(&#x27;&#x27;);" type="submit" value="Clear" /></form><div id="w2p_query_panel" style="display:none;"><select class="form-control" id="w2p_query_fields" onchange="jQuery(&#x27;.w2p_query_row&#x27;).hide();jQuery(&#x27;#w2p_field_&#x27;+jQuery(&#x27;#w2p_query_fields&#x27;).val().replace(&#x27;.&#x27;,&#x27;-&#x27;)).show();" style="float:left"><option value="auth_user.id">Id</option><option value="auth_user.first_name">First name</option><option value="auth_user.last_name">Last name</option><option value="auth_user.email">E-mail</option><option value="auth_user.username">Username</option></select><div class="w2p_query_row" id="w2p_field_auth_user-id" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="in">in</option><option value="not in">not in</option></select><input class="id form-control" id="w2p_value_auth_user-id" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.id&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.id&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-first_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-first_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.first_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.first_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-last_name" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-last_name" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.last_name&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.last_name&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-email" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-email" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.email&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.email&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div><div class="w2p_query_row" id="w2p_field_auth_user-username" style="display:none"><select class="form-control"><option value="=">=</option><option value="!=">!=</option><option value="&lt;">&lt;</option><option value="&gt;">&gt;</option><option value="&lt;=">&lt;=</option><option value="&gt;=">&gt;=</option><option value="starts with">starts with</option><option value="contains">contains</option><option value="in">in</option><option value="not in">not in</option></select><input class="string form-control" id="w2p_value_auth_user-username" type="text" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;new&#x27;,&#x27;auth_user.username&#x27;)" title="Start building a new search" type="button" value="New Search" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;and&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an AND term" type="button" value="+ And" /><input class="btn btn-default" onclick="w2p_build_query(&#x27;or&#x27;,&#x27;auth_user.username&#x27;)" title="Add this to the search as an OR term" type="button" value="+ Or" /><input class="btn btn-default" onclick="jQuery(&#x27;#w2p_query_panel&#x27;).slideUp()" type="button" value="Close" /></div></div><script><!--\n\n        jQuery(\'#w2p_query_fields input,#w2p_query_fields select\').css(\n            \'width\',\'auto\');\n        jQuery(function(){web2py_ajax_fields(\'#w2p_query_fields\');});\n        function w2p_build_query(aggregator,a) {\n          var b=a.replace(\'.\',\'-\');\n          var option = jQuery(\'#w2p_field_\'+b+\' select\').val();\n          var value;\n          var $value_item = jQuery(\'#w2p_value_\'+b);\n          if ($value_item.is(\':checkbox\')){\n            if  ($value_item.is(\':checked\'))\n                    value = \'True\';\n            else  value = \'False\';\n          }\n          else\n          { value = $value_item.val().replace(\'"\',\'\\\\"\')}\n          var s=a+\' \'+option+\' "\'+value+\'"\';\n          var k=jQuery(\'#w2p_keywords\');\n          var v=k.val();\n          if(aggregator==\'new\') k.val(s); else k.val((v?(v+\' \'+ aggregator +\' \'):\'\')+s);\n        }\n        \n//--></script><div class="web2py_counter">1 records found</div></div><div class="web2py_table"><div class="web2py_htmltable" style="width:100%;overflow-x:auto;-ms-overflow-x:scroll"><table><colgroup><col data-column="1" id="auth_user-id" /><col data-column="2" id="auth_user-first_name" /><col data-column="3" id="auth_user-last_name" /><col data-column="4" id="auth_user-email" /><col data-column="5" id="auth_user-username" /><col data-column="6" /></colgroup><thead><tr class=""><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.id">Id</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.first_name">First name</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.last_name">Last name</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.email">E-mail</a></th><th class=""><a href="/a/c/f/auth_user?keywords=&amp;order=auth_user.username">Username</a></th><th class=""></th></tr></thead><tbody><tr class="w2p_odd odd with_id" id="1"><td>1</td><td>Bart</td><td>Simpson</td><td>[email protected]</td><td>user1</td><td class="row_buttons" nowrap="nowrap"><a href="/a/c/f/auth_user/auth_membership.user_id/1"><span>Auth memberships</span></a><a href="/a/c/f/auth_user/auth_event.user_id/1"><span>Auth events</span></a><a href="/a/c/f/auth_user/auth_cas.user_id/1"><span>Auth cases</span></a><a href="/a/c/f/auth_user/t0.created_by/1"><span>T0s(created_by)</span></a><a href="/a/c/f/auth_user/t0.modified_by/1"><span>T0s(modified_by)</span></a><a href="/a/c/f/auth_user/t0_archive.created_by/1"><span>T0 archives(created_by)</span></a><a href="/a/c/f/auth_user/t0_archive.modified_by/1"><span>T0 archives(modified_by)</span></a><a class="button btn btn-default" href="/a/c/f/auth_user/view/auth_user/1"><span class="icon magnifier icon-zoom-in glyphicon glyphicon-zoom-in"></span> <span class="buttontext button" title="View">View</span></a></td></tr></tbody></table></div></div><div class="w2p_export_menu">Export:<a class="btn btn-default" href="/a/c/f/auth_user?_export_type=csv&amp;keywords=&amp;order=" title="Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows">CSV</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=csv_with_hidden_cols&amp;keywords=&amp;order=" title="Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export">CSV (hidden cols)</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=html&amp;keywords=&amp;order=" title="HTML export of visible columns">HTML</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=json&amp;keywords=&amp;order=" title="JSON export of visible columns">JSON</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=tsv&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.">TSV (Spreadsheets)</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=tsv_with_hidden_cols&amp;keywords=&amp;order=" title="Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow">TSV (Spreadsheets, hidden cols)</a><a class="btn btn-default" href="/a/c/f/auth_user?_export_type=xml&amp;keywords=&amp;order=" title="XML export of columns shown">XML</a></div></div>',
        )
    def __init__(self, client_name, start_config, start_hist=None):
        """
        Whiteboard initialization : we build the GUI using the config file and the potential history of actions made by
         other users. Returns a Whiteboard window ready to use.

        :param client_name: Name of the client who just opened a new whiteboard window (str)
        :param start_config: Whiteboard configuration stored in config.json and loaded as a dict (dict)
        :param start_hist: History of actions by other users (dict)
        """
        pygame.init()

        if not isinstance(client_name, str):
            raise TypeError("Client name must be a string")
        if not isinstance(start_config, dict):
            raise TypeError("Starting configuration file must be a dictionary")
        if start_hist is None:
            start_hist = {"actions": [], "message": [], "auth": []}
        elif not isinstance(start_hist, dict):
            raise TypeError("Starting history file must be a dictionary")

        self._done = False
        self._config = start_config
        self._name = client_name
        self._hist = start_hist
        self.__screen = pygame.display.set_mode([self._config["width"], self._config["length"]])
        self.__screen.fill(self._config["board_background_color"])
        self.__handler = {"line": HandleLine(self),
                          "point": HandlePoint(self),
                          "text": HandleText(self),
                          "rect": HandleRect(self),
                          "circle": HandleCircle(self)}

        pygame.draw.line(self.__screen, self._config["active_color"], [0, self._config["toolbar_y"]],
                         [self._config["width"], self._config["toolbar_y"]], 1)

        # We create a global variable to keep track of the position of the last mode box we create in order to make
        # sure that there is no overlapping between left and right boxes on the toolbar on the toolbar

        """
        Tracé de la box auth, qui permet de donner l'autorisation de modification des textbox
        """

        last_left_position = 0
        last_right_position = self._config["width"] - self._config["mode_box_size"][0]
        self._erasing_auth = False

        try:
            assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                 "toolbar, please increase width in config.json"
            self.__auth_box = Auth((last_left_position, 0), tuple(self._config["auth_box_size"]))
            last_left_position += self._config["mode_box_size"][0]
            self.__auth_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        Tracé de la boite save qui permet d'enregistrer l'image
        """

        try:
            assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                 "toolbar, please increase width in config.json"
            self.__save_box = Save((last_left_position, 0), tuple(self._config["auth_box_size"]))
            last_left_position += self._config["mode_box_size"][0]
            self.__save_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        self.__modes = [Mode("point", (2 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("line", (3 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("text", (4 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("rect", (5 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("circle", (6 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"]))
                        ]
        # If right and left boxes overlap, raise an error and close pygame
        try:
            for mod in self.__modes:
                assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                     "toolbar, please increase width in config.json"
                mod.add(self.__screen)
                last_left_position += self._config["mode_box_size"][0]
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        Choix des couleurs
        """
        self.__colors = []
        try:
            for key, value in self._config["color_palette"].items():
                assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                     "toolbar, please increase width in config.json"
                color_box = ColorBox(value, (last_right_position, 0), tuple(self._config["mode_box_size"]))
                last_right_position -= self._config["mode_box_size"][0]
                self.__colors.append(color_box)
                color_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        Choix des épaisseurs
        """
        self.__font_sizes = []
        try:
            for size in self._config["pen_sizes"]:
                assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                     "toolbar, please increase width in config.json"
                font_size_box = FontSizeBox(size, (last_right_position, 0), tuple(self._config["mode_box_size"]))
                last_right_position -= self._config["mode_box_size"][0]
                self.__font_sizes.append(font_size_box)
                font_size_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        initialisation des variables de dessin
        """
        pygame.display.flip()
        self._draw = False
        self._last_pos = None
        self._mouse_position = (0, 0)

        """
        Initialisation des paramètres des text boxes
        """
        self._text_boxes = []  # Cette liste contiendra les objets de type Textbox

        self.active_box = None

        self.load_actions(self._hist)
        self.__modification_allowed = copy.deepcopy(self._hist["auth"])

        # if some client names are in this list, you will have the authorisation to edit their textboxes

        for action in self._hist["actions"]:
            if action["type"] == "Text_box":
                self.append_text_box(TextBox(**action["params"]))
class WhiteBoard:
    def __init__(self, client_name, start_config, start_hist=None):
        """
        Whiteboard initialization : we build the GUI using the config file and the potential history of actions made by
         other users. Returns a Whiteboard window ready to use.

        :param client_name: Name of the client who just opened a new whiteboard window (str)
        :param start_config: Whiteboard configuration stored in config.json and loaded as a dict (dict)
        :param start_hist: History of actions by other users (dict)
        """
        pygame.init()

        if not isinstance(client_name, str):
            raise TypeError("Client name must be a string")
        if not isinstance(start_config, dict):
            raise TypeError("Starting configuration file must be a dictionary")
        if start_hist is None:
            start_hist = {"actions": [], "message": [], "auth": []}
        elif not isinstance(start_hist, dict):
            raise TypeError("Starting history file must be a dictionary")

        self._done = False
        self._config = start_config
        self._name = client_name
        self._hist = start_hist
        self.__screen = pygame.display.set_mode([self._config["width"], self._config["length"]])
        self.__screen.fill(self._config["board_background_color"])
        self.__handler = {"line": HandleLine(self),
                          "point": HandlePoint(self),
                          "text": HandleText(self),
                          "rect": HandleRect(self),
                          "circle": HandleCircle(self)}

        pygame.draw.line(self.__screen, self._config["active_color"], [0, self._config["toolbar_y"]],
                         [self._config["width"], self._config["toolbar_y"]], 1)

        # We create a global variable to keep track of the position of the last mode box we create in order to make
        # sure that there is no overlapping between left and right boxes on the toolbar on the toolbar

        """
        Tracé de la box auth, qui permet de donner l'autorisation de modification des textbox
        """

        last_left_position = 0
        last_right_position = self._config["width"] - self._config["mode_box_size"][0]
        self._erasing_auth = False

        try:
            assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                 "toolbar, please increase width in config.json"
            self.__auth_box = Auth((last_left_position, 0), tuple(self._config["auth_box_size"]))
            last_left_position += self._config["mode_box_size"][0]
            self.__auth_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        Tracé de la boite save qui permet d'enregistrer l'image
        """

        try:
            assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                 "toolbar, please increase width in config.json"
            self.__save_box = Save((last_left_position, 0), tuple(self._config["auth_box_size"]))
            last_left_position += self._config["mode_box_size"][0]
            self.__save_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        self.__modes = [Mode("point", (2 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("line", (3 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("text", (4 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("rect", (5 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"])),
                        Mode("circle", (6 * self._config["mode_box_size"][0], 0), tuple(self._config["mode_box_size"]))
                        ]
        # If right and left boxes overlap, raise an error and close pygame
        try:
            for mod in self.__modes:
                assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                     "toolbar, please increase width in config.json"
                mod.add(self.__screen)
                last_left_position += self._config["mode_box_size"][0]
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        Choix des couleurs
        """
        self.__colors = []
        try:
            for key, value in self._config["color_palette"].items():
                assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                     "toolbar, please increase width in config.json"
                color_box = ColorBox(value, (last_right_position, 0), tuple(self._config["mode_box_size"]))
                last_right_position -= self._config["mode_box_size"][0]
                self.__colors.append(color_box)
                color_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        Choix des épaisseurs
        """
        self.__font_sizes = []
        try:
            for size in self._config["pen_sizes"]:
                assert last_left_position < last_right_position + 1, "Too many tools to fit in the Whiteboard " \
                                                                     "toolbar, please increase width in config.json"
                font_size_box = FontSizeBox(size, (last_right_position, 0), tuple(self._config["mode_box_size"]))
                last_right_position -= self._config["mode_box_size"][0]
                self.__font_sizes.append(font_size_box)
                font_size_box.add(self.__screen)
        except AssertionError as e:
            print(e)
            pygame.quit()
            sys.exit()

        """
        initialisation des variables de dessin
        """
        pygame.display.flip()
        self._draw = False
        self._last_pos = None
        self._mouse_position = (0, 0)

        """
        Initialisation des paramètres des text boxes
        """
        self._text_boxes = []  # Cette liste contiendra les objets de type Textbox

        self.active_box = None

        self.load_actions(self._hist)
        self.__modification_allowed = copy.deepcopy(self._hist["auth"])

        # if some client names are in this list, you will have the authorisation to edit their textboxes

        for action in self._hist["actions"]:
            if action["type"] == "Text_box":
                self.append_text_box(TextBox(**action["params"]))

    """
    Encapsulation
    """

    def is_done(self):
        return self._done

    def end(self):
        self._done = True

    def get_config(self, maplist):
        """
        Getter of config file. Uses a list of keys to traverse the config dict
        :param maplist: list of keys from parent to child to get the wanted value (list)
        :return: value of a key in the config file (object)
        """
        if not type(maplist) == list:
            maplist = list(maplist)
        try:
            return reduce(operator.getitem, maplist, self._config)
        except (KeyError, TypeError):
            return None

    def set_config(self, maplist, value):
        """
        Setter of config file. Uses the getter and assigns value to a key
        :param maplist: list of keys from parent to child to get the wanted value (list)
        :param value: value to set (object)
        :return: None if failed
        """
        if not type(maplist) == list:
            maplist = list(maplist)
        try:
            self.get_config(maplist[:-1])[maplist[-1]] = value
        except (KeyError, TypeError):
            return None

    def get_hist(self, key=None):
        if key is None:
            return self._hist
        else:
            return self._hist[key]

    def add_to_hist(self, value):
        self._hist["actions"].append(value)

    @property
    def screen(self):
        return self.__screen

    def clear_screen(self):
        """
        Clear the screen by coloring it to background color. Does not color the toolbar
        :return:
        """
        self.__screen.fill(self.get_config(["board_background_color"]), (0, self.get_config(["toolbar_y"]) + 1,
                                                                         self.get_config(["width"]),
                                                                         self.get_config(["length"]) - self.get_config(
                                                                             ["toolbar_y"]) + 1))

    def is_drawing(self):
        return self._draw

    def pen_up(self):
        self._draw = False

    def pen_down(self):
        self._draw = True

    @property
    def name(self):
        return self._name

    @property
    def modification_allowed(self):
        return self.__modification_allowed

    @property
    def last_pos(self):
        return self._last_pos

    def reset_last_pos(self):
        self._last_pos = None

    def update_last_pos(self):
        self._last_pos = self._mouse_position

    def __get_mouse_position(self):
        return self._mouse_position

    def __set_mouse_position(self, value):
        self._mouse_position = value

    mouse_position = property(__get_mouse_position, __set_mouse_position)

    def get_text_boxes(self):
        return self._text_boxes

    def append_text_box(self, textbox):
        self._text_boxes.append(textbox)

    def del_text_box(self, textbox):
        self._text_boxes.remove(textbox)

    def draw(self, obj, timestamp):
        """
        Method to draw figures defined in figures.py. Also adds drawn objects to history.

        :param obj: class of figure to draw
        :param timestamp: timestamp at which the drawing happens
        :return: None
        """

        # Draw object on screen
        obj.draw(self.__screen)

        # Create dict containing object parameters and right timestamp to add to history
        hist_obj = {"type": obj.type, "timestamp": timestamp, "params": obj.fetch_params(), "client": self._name}

        # Special case if it's a Text_box object, we need to get the correct box id
        if hist_obj["type"] == "Text_box":
            hist_obj["id"] = obj.id_counter
            hist_obj["owner"] = self._name
        self.add_to_hist(hist_obj)

    def switch_config(self, event):
        """
        Switch between different modes

        :param event: Action by the user : a mouse click on either modes, colors or font sizes
        :return: None
        """
        if event == "quit":
            self.set_config(["mode"], "quit")

        # We go through each mode, color and font size to see if that mode should be triggered by the event
        else:
            for mod in self.__modes:
                if mod.is_triggered(event):
                    self.set_config(["mode"], mod.name)
            for col in self.__colors:
                if col.is_triggered(event):
                    self.set_config(["text_box", "text_color"], col.color)
                    self.set_config(["active_color"], col.color)
            for font_size_ in self.__font_sizes:
                if font_size_.is_triggered(event):
                    self.set_config(["font_size"], font_size_.font_size)
            if self.__auth_box.is_triggered(event):
                self._erasing_auth = not self._erasing_auth
                self.__auth_box.switch(self.__screen, self._erasing_auth, self.__modification_allowed, self._name)
                self._hist["auth"] = [self._name, self._erasing_auth]
            if self.__save_box.is_triggered(event):
                self.__save_box.save(self.__screen, self)
                print("Le dessin a été sauvegardé dans le dossier")

    def set_active_box(self, box, new=True):
        """
        A method specific to text boxes : select an existing box or one that has just been created to edit. This box is
        thus said to be "active"

        :param box: instance of the TextBox class
        :param new: boolean to specify if the box was just created or already existed
        :return:
        """

        # If the selected box is already the active one, do nothing
        if box == self.active_box:
            return

        # If there is a box that is active we must turn it into "inactive"
        if self.active_box is not None:

            # Change its color to the "inactive color"
            self.active_box.set_textbox_color(self.get_config(["text_box", "inactive_color"]))
            # Select the id of previous active box
            id_counter = self.active_box.id_counter
            # Find the previous active box and change its color in history
            for action in [x for x in self.get_hist('actions') if x['type'] == 'Text_box']:
                if action['id'] == id_counter:
                    action["params"]["text"] = self.active_box.get_textbox_text()
                    action['params']["box_color"] = self.get_config(["text_box", "inactive_color"])
            # Render it
            self.active_box.draw(self.__screen)

        # If selected box already exists on the whiteboard we must turn it into "active"
        if not new:
            id_counter = box.id_counter
            for action in [x for x in self.get_hist('actions') if x['type'] == 'Text_box']:
                if action['id'] == id_counter:
                    action['params']["box_color"] = self.get_config(["text_box", "active_color"])

        # Draw the newly activated box
        self.active_box = box
        self.active_box.draw(self.__screen)
        pygame.display.flip()

    def draw_action(self, action):
        """
        Draw the result of an action by the user on the whiteboard

        :param action: usually a mouse action by the user
        :return:
        """
        if action["type"] == "Point":
            draw_point(action["params"], self.__screen)
        if action["type"] == "Line":
            draw_line(action["params"], self.__screen)
        if action["type"] == "Text_box":
            draw_textbox(action["params"], self.__screen)
        if action["type"] == "rect":
            draw_rect(action["params"], self.__screen)
        if action["type"] == "circle":
            draw_circle(action["params"], self.__screen)

    def load_actions(self, hist):
        """
        Load actions from history

        :param hist: list of dict representing the history of actions in the whiteboard session
        :return:
        """

        # Sort actions chronologically
        sred = sorted(hist["actions"],
                      key=lambda value: value["timestamp"])

        # Go through each action and draw it
        for action in sred:
            self.draw_action(action)
        pygame.display.flip()

    def start(self, connexion_avec_serveur):
        """
        Start and run a whiteboard window

        :param connexion_avec_serveur: socket to connect with server (socket.socket)
        :return:
        """

        # Initialize timestamp
        last_timestamp_sent = 0

        while not self.is_done():

            # Browse all events done by user
            for event in pygame.event.get():
                # If user closes the window, quit the whiteboard
                if self.get_config(["mode"]) == "quit":
                    self.end()
                    break
                # Use specific handling method for current drawing mode
                self.__handler[self.get_config(["mode"])].handle_all(event)

            # msg_a_envoyer["message"] = "CARRY ON"
            # Send dict history to server
            if self._hist["auth"] != [self._name, self._erasing_auth]:
                self._hist["auth"] = []
            new_modifs = [modif for modif in self.get_hist()["actions"] if
                          (modif["timestamp"] > last_timestamp_sent and self._name == modif["client"])]
            message_a_envoyer = {"message": "", 'actions': new_modifs, "auth": self._hist["auth"]}
            connexion_avec_serveur.send(dict_to_binary(message_a_envoyer))

            self._hist["auth"] = []
            # Update last timestamp sent
            if new_modifs:
                last_timestamp_sent = max([modif["timestamp"] for modif in new_modifs])

            # Dict received from server
            try:
                new_hist = binary_to_dict(connexion_avec_serveur.recv(2 ** 24))
            except (ConnectionResetError, ConnectionAbortedError) as e:
                print("Le serveur a été éteint, veuillez le relancer")
                self._done = True
                pass

            # Consider actions made by another client after new_last_timestamp
            new_actions = [action for action in new_hist["actions"] if action["client"] != self._name]
            for action in new_actions:
                # Here there are two cases, a new figure (point, line, rect, circle, new text box) is created or an
                # existing text box is modified. For this second case, we use the variable "matched" as indicator
                matched = False
                if action["type"] == "Text_box":
                    # Find the text box id
                    for textbox in [x for x in self._hist["actions"] if x["type"] == "Text_box"]:
                        if action["id"] == textbox["id"]:
                            # Modify it with the newly acquired parameters from server
                            textbox["params"]["text"], textbox["params"]["w"] = action["params"]["text"], \
                                                                                action["params"]["w"]
                            action_to_update_textbox = action
                            for element in self.get_text_boxes():
                                if element.id_counter == action["id"]:
                                    self.del_text_box(element)
                                    self.append_text_box(TextBox(**action_to_update_textbox["params"]))

                            # Draw the modified text box with updated parameters
                            self.clear_screen()
                            self.load_actions(self._hist)
                            matched = True
                # If we are in the first case, we add the new actions to history and draw them
                if not matched:
                    self.add_to_hist(action)
                    if action["type"] == "Text_box":
                        self.append_text_box(TextBox(**action["params"]))
                    self.draw_action(action)
            if self._name in new_hist["auth"]:
                new_hist["auth"].remove(self._name)
            if new_hist["auth"] != self.__modification_allowed:
                self.__modification_allowed = copy.deepcopy(new_hist["auth"])
            pygame.display.flip()

        # Once we are done, we quit pygame and send end message
        pygame.quit()
        print("Fermeture de la connexion")
        message_a_envoyer["message"] = "END"
        try:
            connexion_avec_serveur.send(dict_to_binary(message_a_envoyer))
        except (ConnectionResetError, BrokenPipeError) as e:
            print("Il n'y a pas de message à envoyer au serveur")
        connexion_avec_serveur.close()

    def start_local(self):
        """
        Starts Whiteboard locally. Used to test stuff and debug.
        :return:
        """
        while not self.is_done():
            for event in pygame.event.get():
                if self.get_config(["mode"]) == "quit":
                    self.end()
                    break
                self.__handler[self.get_config(["mode"])].handle_all(event)
            pygame.display.flip()
        pygame.quit()
Ejemplo n.º 13
0
class TestAuth(unittest.TestCase):

    def setUp(self):
        request = Request(env={})
        request.application = 'a'
        request.controller = 'c'
        request.function = 'f'
        request.folder = 'applications/admin'
        response = Response()
        session = Session()
        T = translator('', 'en')
        session.connect(request, response)
        from gluon.globals import current
        current.request = request
        current.response = response
        current.session = session
        current.T = T
        self.db = DAL(DEFAULT_URI, check_reserved=['all'])
        self.auth = Auth(self.db)
        self.auth.define_tables(username=True, signature=False)
        self.db.define_table('t0', Field('tt'), self.auth.signature)
        self.auth.enable_record_versioning(self.db)
        # Create a user
        self.auth.get_or_create_user(dict(first_name='Bart',
                                          last_name='Simpson',
                                          username='******',
                                          email='*****@*****.**',
                                          password='******',
                                          registration_key='bart',
                                          registration_id=''
                                          ))
        # self.auth.settings.registration_requires_verification = False
        # self.auth.settings.registration_requires_approval = False

    def test_assert_setup(self):
        self.assertEqual(self.db(self.db.auth_user.username == 'bart').select().first()['username'], 'bart')
        self.assertTrue('auth_user' in self.db)
        self.assertTrue('auth_group' in self.db)
        self.assertTrue('auth_membership' in self.db)
        self.assertTrue('auth_permission' in self.db)
        self.assertTrue('auth_event' in self.db)

    def test_enable_record_versioning(self):
        self.assertTrue('t0_archive' in self.db)

    def test_basic_blank_forms(self):
        for f in ['login', 'retrieve_password',
                  'retrieve_username',
                  # 'register'  # register complain about : client_side=self.settings.client_side
                  ]:
            html_form = getattr(self.auth, f)().xml()
            self.assertTrue('name="_formkey"' in html_form)

        # NOTE: Not sure it is the proper way to logout_bare() as there is not methods for that and auth.logout() failed
        self.auth.logout_bare()
        # self.assertTrue(self.auth.is_logged_in())

        for f in ['logout', 'verify_email', 'reset_password',
                  'change_password', 'profile', 'groups']:
            self.assertRaisesRegexp(HTTP, "303*", getattr(self.auth, f))

        self.assertRaisesRegexp(HTTP, "401*", self.auth.impersonate)

        try:
            for t in ['t0_archive', 't0', 'auth_cas', 'auth_event',
                      'auth_membership', 'auth_permission', 'auth_group',
                      'auth_user']:
                self.db[t].drop()
        except SyntaxError as e:
            # GAE doesn't support drop
            pass
        return

    def test_get_or_create_user(self):
        self.db.auth_user.insert(email='*****@*****.**', username='******', password='******')
        self.db.commit()
        # True case
        self.assertEqual(self.auth.get_or_create_user({'email': '*****@*****.**',
                                                       'username': '******',
                                                       'password': '******'
                                                       })['username'], 'user1')
        # user2 doesn't exist yet and get created
        self.assertEqual(self.auth.get_or_create_user({'email': '*****@*****.**',
                                                       'username': '******'})['username'], 'user2')
        # user3 for corner case
        self.assertEqual(self.auth.get_or_create_user({'first_name': 'Omer',
                                                       'last_name': 'Simpson',
                                                       'email': '*****@*****.**',
                                                       'registration_id': 'user3',
                                                       'username': '******'})['username'], 'user3')
        # False case
        self.assertEqual(self.auth.get_or_create_user({'email': ''}), None)
        self.db.auth_user.truncate()
        self.db.commit()

    def test_login_bare(self):
        # The following test case should succeed but failed as I never received the user record but False
        self.auth.login_bare(username='******', password='******')
        self.assertTrue(self.auth.is_logged_in())
        # Failing login because bad_password
        self.assertEqual(self.auth.login_bare(username='******', password='******'), False)
        self.db.auth_user.truncate()

    def test_register_bare(self):
        # corner case empty register call register_bare without args
        self.assertRaises(ValueError, self.auth.register_bare)
        # failing register_bare user already exist
        self.assertEqual(self.auth.register_bare(username='******', password='******'), False)
        # successful register_bare
        self.assertEqual(self.auth.register_bare(username='******',
                                                 email='*****@*****.**',
                                                 password='******')['username'], 'user2')
        # raise ValueError
        self.assertRaises(ValueError, self.auth.register_bare,
                          **dict(wrong_field_name='user3', password='******'))
        # raise ValueError wrong email
        self.assertRaises(ValueError, self.auth.register_bare,
                          **dict(email='user4@', password='******'))
        self.db.auth_user.truncate()
        self.db.commit()

    def test_bulk_register(self):
        self.auth.login_bare(username='******', password='******')
        self.auth.settings.bulk_register_enabled = True
        bulk_register_form = self.auth.bulk_register(max_emails=10).xml()
        self.assertTrue('name="_formkey"' in bulk_register_form)

    def test_change_password(self):
        self.auth.login_bare(username='******', password='******')
        change_password_form = getattr(self.auth, 'change_password')().xml()
        self.assertTrue('name="_formkey"' in change_password_form)

    def test_profile(self):
        self.auth.login_bare(username='******', password='******')
        profile_form = getattr(self.auth, 'profile')().xml()
        self.assertTrue('name="_formkey"' in profile_form)