def create_types(env, type_names, db=None): db, handle_ta = get_db_for_write(env, db) # Query definitions sql_select_type = "SELECT count(*) FROM enum WHERE type = 'ticket_type' AND name = '%s'" sql_select_max_value = "SELECT max(value) FROM enum WHERE type = 'ticket_type'" sql_insert_type = "INSERT INTO enum (type,name,value) VALUES('ticket_type','%s',%d)" # For every default type check, if already in db, otherwise insert it. # To consistently insert, we need to know the value of the highest ticket_type entry first. cursor = db.cursor() cursor.execute(sql_select_max_value) ticket_type_max_value = int(cursor.fetchone()[0]) for t in type_names: try: cursor.execute(sql_select_type % t) if cursor.fetchone()[0] == 0: ticket_type_max_value += 1 debug(env, "ticket_type '%s' not found within table 'enum' - will " \ "insert it with value %d..." % (t,ticket_type_max_value)) # If the type is not present already insert with the next value available cursor.execute(sql_insert_type % (t,ticket_type_max_value)) if handle_ta: db.commit() else: debug(env, "Found ticket_type '%s' within table 'enum'" % (t)) except Exception, e: if handle_ta: db.rollback() exception_to_unicode(e)
def create_types(env, type_names, db=None): db, handle_ta = get_db_for_write(env, db) # Query definitions sql_select_type = "SELECT count(*) FROM enum WHERE type = 'ticket_type' AND name = '%s'" sql_select_max_value = "SELECT max(value) FROM enum WHERE type = 'ticket_type'" sql_insert_type = "INSERT INTO enum (type,name,value) VALUES('ticket_type','%s',%d)" # For every default type check, if already in db, otherwise insert it. # To consistently insert, we need to know the value of the highest ticket_type entry first. cursor = db.cursor() cursor.execute(sql_select_max_value) ticket_type_max_value = int(cursor.fetchone()[0]) for t in type_names: try: cursor.execute(sql_select_type % t) if cursor.fetchone()[0] == 0: ticket_type_max_value += 1 debug(env, "ticket_type '%s' not found within table 'enum' - will " \ "insert it with value %d..." % (t,ticket_type_max_value)) # If the type is not present already insert with the next value available cursor.execute(sql_insert_type % (t, ticket_type_max_value)) if handle_ta: db.commit() else: debug(env, "Found ticket_type '%s' within table 'enum'" % (t)) except Exception, e: if handle_ta: db.rollback() exception_to_unicode(e)
def delete_ticket(self, t_id): """Deletes the ticket with the given ticket id""" atm = AgiloTicketModelManager(self.env) ticket = atm.get(tkt_id=t_id) try: atm.delete(ticket) except Exception, e: print exception_to_unicode(e)
def delete_all_tickets(self): """Delete all the tickets in the environment""" atm = AgiloTicketModelManager(self.env) tickets = atm.select() for t in tickets: try: atm.delete(t) except Exception, e: print exception_to_unicode(e)
def store_data_in_session(self, req, data): """Stores the data in the session for reuse during a failed post or an exception. This will allow to refill a form in case of wrong data without having the user to retype everything in""" if hasattr(req, 'session'): try: session_data = cPickle.dumps(data) req.session[AGILO_PAGE_DATA] = url_encode(session_data) except Exception, e: exception_to_unicode(e)
def get_data_from_session(self, req): """Retrieves data from the session, and delete it""" if hasattr(req, 'session') and req.session.has_key(AGILO_PAGE_DATA): try: session_data = url_decode(req.session[AGILO_PAGE_DATA]) data = cPickle.loads(session_data) del req.session[AGILO_PAGE_DATA] return data except Exception, e: exception_to_unicode(e)
def test_raises_on_component_set_if_filter_by_component_is_not_enabled( self): error = self.assert_raises(AssertionError, self.change.set_component_marker, 'fnord') self.assert_true( "should_reload_burndown_on_filter_change_when_filtering_by_component" in exception_to_unicode(error)) self.assert_true( "backlog_filter_attribute" in exception_to_unicode(error)) self.teh.enable_burndown_filter() self.change.set_component_marker('fnord')
def do_post(self, req, args): # FIXME(AT): in this method the same ticket is loaded twice it is an expensive # operation that we could limit. The resource is loading the ticket using the # Trac introspection, and later in the _simulate_sta... it is loaded again. As # the ticket is also a Resource of itself this can be changed by loading it # directly from here and pass it through instead of ticket_id ticket_id = self.get_ticket_id(args) ticket_resource = Resource(Realm.TICKET)(id=ticket_id) req.perm.assert_permission(Action.TICKET_VIEW, ticket_resource) self.wait_if_last_change_was_within_this_second(req, ticket_id, args) # we pack all changes in one transaction to minimize waiting times if 'simple_status' in args: if not req.perm.has_permission(Action.TICKET_EDIT, ticket_resource): error = 'AGILO_TICKET_EDIT privileges are required to perform this operation on Ticket #%s' % ticket_id self._send_error(req, ticket_id, [error], 403) status = args['simple_status'] if self.is_unknown_status(status): error_message = 'Invalid status: %s. Try to configure a workflow that includes this status.' % status self._send_error(req, ticket_id, [error_message]) self._simulate_status_change_and_update_request_parameters(req, args, ticket_id) try: success, errors = self._modify_ticket_attributes(req, args) # REFACT: mixing success boolean and exception is confusing except TracError, e: success = False errors = [exception_to_unicode(e)]
def process_request(self, req): call_handler = False if req.method in ('PUT', 'DELETE', 'POST'): if self._contains_data(req): http_body = req.read() data = dict(req.args) body_data = self._load_json_data(http_body) if body_data is not None: # REFACT: consider to make the whole body available under a special key # so we can send other types than dictionaries directly to the server and so # we can distinguish between parameters from the url and parameters that where # sent from the body without reparsing it. (not sure if that would even be possible) data.update(body_data) call_handler = True else: # AT: we need to take even with data 0 cause the command # Get on /json/<models>/ is valid, has to return the list # of models data = req.args call_handler = (len(data) >= 0) if call_handler: code = 200 try: response = self.get_handler(req)(req, data) if isinstance(response, tuple): response, code = response self.respond(req, response, code=code) except Exception, e: if isinstance(e, RequestDone): raise msg = exception_to_unicode(e) log.error(self, msg) self.error_response(req, {}, [msg])
def initialize_agilo(self, project_name, db_url, svn_repo, demo=False): try: self.do_initenv('%s %s %s %s' % (project_name, db_url, 'svn', svn_repo or 'somewhere')) # Now add agilo and the template path env = Environment(self.envname) ac = AgiloConfig(env) if not svn_repo: # remove the fake from the config ac.change_option('repository_dir', '', 'trac') # sets the restric_owner option ac.change_option('restrict_owner', 'true', 'ticket') # this is also saving the config ac.enable_agilo() # update wiki wiki = WikiPage(env, name='WikiStart') wiki.text = agilo_wiki wiki.save('admin', 'Updated to Agilo', '127.0.0.1') # reset the env self.env_set(envname=self.envname, env=env) # Now initialize Agilo self.do_upgrade('upgrade --no-backup') # Now create the demo if needed if demo: try: from create_demo_data import _create_demo_data _create_demo_data(env) except ImportError, e: env.log.error(exception_to_unicode(e)) except: pass
def create_milestone(self, name, due=None, duration=20, db=None): """ Creates a milestone with the given name and due date, the latter should be a datetime object """ db, handle_ta = get_db_for_write(self.env, db) # Try to load the milestone first try: m = Milestone(self.env, name=name, db=db) except ResourceNotFound: # than we create it m = Milestone(self.env, db=db) m.name = name if due is not None and isinstance(due, datetime): dueo = due.toordinal() + duration m.due = mktime(datetime.fromordinal(dueo).timetuple()) m.insert() if handle_ta: try: db.commit() # workaround for the fact that trac in 0.11.1 doesn't set exists correctly... m._old_name = m.name except Exception, e: self.env.log.warning(exception_to_unicode(e)) db.rollback()
def do_post(self, req, args): # FIXME(AT): in this method the same ticket is loaded twice it is an expensive # operation that we could limit. The resource is loading the ticket using the # Trac introspection, and later in the _simulate_sta... it is loaded again. As # the ticket is also a Resource of itself this can be changed by loading it # directly from here and pass it through instead of ticket_id ticket_id = self.get_ticket_id(args) ticket_resource = Resource(Realm.TICKET)(id=ticket_id) req.perm.assert_permission(Action.TICKET_VIEW, ticket_resource) self.wait_if_last_change_was_within_this_second(req, ticket_id, args) # we pack all changes in one transaction to minimize waiting times if 'simple_status' in args: if not req.perm.has_permission(Action.TICKET_EDIT, ticket_resource): error = 'AGILO_TICKET_EDIT privileges are required to perform this operation on Ticket #%s' % ticket_id self._send_error(req, ticket_id, [error], 403) status = args['simple_status'] if self.is_unknown_status(status): error_message = 'Invalid status: %s. Try to configure a workflow that includes this status.' % status self._send_error(req, ticket_id, [error_message]) self._simulate_status_change_and_update_request_parameters( req, args, ticket_id) try: success, errors = self._modify_ticket_attributes(req, args) # REFACT: mixing success boolean and exception is confusing except TracError, e: success = False errors = [exception_to_unicode(e)]
def initialize_agilo(self, project_name, db_url, svn_repo, demo=False): try: self.do_initenv( '%s %s %s %s' % (project_name, db_url, 'svn', svn_repo or 'somewhere')) # Now add agilo and the template path env = Environment(self.envname) ac = AgiloConfig(env) if not svn_repo: # remove the fake from the config ac.change_option('repository_dir', '', 'trac') # sets the restric_owner option ac.change_option('restrict_owner', 'true', 'ticket') # this is also saving the config ac.enable_agilo() # update wiki wiki = WikiPage(env, name='WikiStart') wiki.text = agilo_wiki wiki.save('admin', 'Updated to Agilo', '127.0.0.1') # reset the env self.env_set(envname=self.envname, env=env) # Now initialize Agilo self.do_upgrade('upgrade --no-backup') # Now create the demo if needed if demo: try: from create_demo_data import _create_demo_data _create_demo_data(env) except ImportError, e: env.log.error(exception_to_unicode(e)) except: pass
def test_will_throw_if_save_doesnt_affect_any_rows(self): first = MyPO(self.env, name="foo") first.save() first.name = 'bar' first._old['name'] = 'bar' # this should generate wrong WHERE clause on saving exception = self.assert_raises(UnableToSaveObjectError, first.save) self.assert_true(r'0 rows affected' in exception_to_unicode(exception))
def create_table(env, table, conn=None): """ Creates a the given table in the given environment. The Table has to be of type trac.db.Table, and the Environment a trac.env.Environment. """ assert isinstance(env, Environment), \ "[DB]: env should be an instance of trac.env.Environment, got %s" % type(env) assert isinstance(table, Table), \ "[DB]: table should be an instance of trac.sb.Table, got %s" % type(table) # Get The Databse Manager dbm = DatabaseManager(env) # Get the Connector Object for the current DB schema connector, args = dbm._get_connector() # Ask the connector to generate the proper DDL for the table ddl_gen = connector.to_sql(table) # Get a DB Connection from the pool, create a cursor and the table conn, handle_ta = get_db_for_write(env, conn) try: cursor = conn.cursor() for statement in ddl_gen: debug(env, "[DB]: Table: %s\n%s" % (table.name, statement)) cursor.execute(statement) if handle_ta: conn.commit() debug(env, "[DB]: Successfully Created Table %s" % table.name) except Exception, e: if handle_ta: conn.rollback() error(env, "[DB]: Unable to Create Table %s, an error occurred: %s" % \ (table.name, exception_to_unicode(e))) raise
def _sprint(self, req, sprint_name): try: get_sprint = SprintController.GetSprintCommand(self.env, sprint=sprint_name) get_sprint.native = True return SprintController(self.env).process_command(get_sprint) except ICommand.NotValidError, e: self.error_response(req, {}, [exception_to_unicode(e)])
def validate(self, sprint_name): if not sprint_name: return None try: return self._get_sprint(sprint_name) except Exception, e: self.message = exception_to_unicode(e) self.error(sprint_name)
def _load_json_data(self, http_body): try: data = json.loads(http_body) except Exception, e: msg = u'Received invalid JSON request %s' % \ exception_to_unicode(e) log.warning(self, msg) data = None
def test_will_throw_if_save_doesnt_affect_any_rows(self): first = MyPO(self.env, name="foo") first.save() first.name = 'bar' first._old[ 'name'] = 'bar' # this should generate wrong WHERE clause on saving exception = self.assert_raises(UnableToSaveObjectError, first.save) self.assert_true(r'0 rows affected' in exception_to_unicode(exception))
def do_post(self, req): req.perm.assert_permission(Action.CONTINGENT_ADMIN) name = req.args.get('cont_name') amount = req.args.get('cont_amount') sprint = self._get_sprint(req) params = dict(sprint=sprint.name, name=name, amount=amount) try: cmd = ContingentController.AddContingentCommand(self.env, **params) ContingentController(self.env).process_command(cmd) except Exception, e: raise TracError(exception_to_unicode(e))
def interesting_fieldnames(self): fieldnames = [] for field in AgiloTicketSystem(self.env).get_ticket_fields(): fieldname = field[Key.NAME] # AT: here key must be a string or will break the call # afterwards try: fieldname = str(fieldname) except ValueError, e: warning(self, "Fieldname: %s is not a string... %s" % \ (repr(fieldname), exception_to_unicode(e))) continue fieldnames.append(fieldname)
def get_users_last_visits(env, db=None): """Returns a list of tuples (username, lastvisit) from the session table""" db, handle_ta = get_db_for_write(env, db) users = [] try: cursor = db.cursor() cursor.execute("SELECT sid, last_visit FROM session WHERE authenticated = 1") for row in cursor.fetchall(): if row and len(row) == 2: users.append((row[0], row[1])) return users except Exception, e: warning(env, _("Could not load users from session table: %s" % \ exception_to_unicode(e)))
def _iterate(self, data, key=None, command=None): """ Operator to iterate over a sequence and return the items matching the given condition. If no condition is supplied an Alias replacing will be attempted on the whole list. The operator returns a list """ # Check if the key contains also a condition condition = realkey = None if key is not None and isinstance(key, tuple): realkey, condition = key else: realkey = key #debug(self, "[Iterate]: Processing %s with %s, command: #%s#" % \ # (repr(data), key, command)) # Now process the data, take the analyzed data that should be pointers to the # real ones, so that the real_data gets modified too if data is not None and hasattr(data, '__iter__'): for i, item in enumerate(data): #debug(self, "[Iterate]: Command left: %s\ni: %d\ndata[%d] = %s" % \ # (command, i, i, data[i])) if (condition is not None and eval(condition)) or condition is None: if realkey is not None: try: if not command: #debug(self, "[Iterate]: No command left, " \ # "calculating aliases...") data[i][realkey] = self._aliasize( item[realkey]) else: #debug(self, "[Iterate]: Processing next " \ # "command... %s" % command) # The command in this case is not consumed, # because we are in a cycle and the same command # has to be used to evaluate all items. acc, newkey, newcommand = self._parse_command( command) if acc is not None: #debug(self, "[Iterate]: calling\nacc: %s\n" \ # "data[%s], data: %s\nkey: %s\n\n" % \ # (acc, realkey, data[i], newkey)) acc(data[i][realkey], newkey, newcommand) except KeyError, e: warning( self, "[Iterate]: Warning %s" % exception_to_unicode(e)) else: data[i] = self._aliasize(item)
def get_users_last_visits(env, db=None): """Returns a list of tuples (username, lastvisit) from the session table""" db, handle_ta = get_db_for_write(env, db) users = [] try: cursor = db.cursor() cursor.execute( "SELECT sid, last_visit FROM session WHERE authenticated = 1") for row in cursor.fetchall(): if row and len(row) == 2: users.append((row[0], row[1])) return users except Exception, e: warning(env, _("Could not load users from session table: %s" % \ exception_to_unicode(e)))
def runTest(self): # User "TeamMember" is not part of the team. This is why the test fails self.json_tester.login_as(Usernames.team_member) self.ensure_min_one_second_passed() exception = self.assert_raises(GenericHTTPException, \ lambda: self.json_tester.edit_ticket(self.task_id, simple_status='in_progress')) self.assert_contains("doesn't belong to the team", exception_to_unicode(exception)) response_json = json.loads(exception.detail) self.assertEqual(1, len(response_json['errors'])) ticket = ValueObject(response_json['current_data']) self.assertEqual(Status.NEW, ticket.status) self.assertEqual('', ticket.owner) task_owner = self.tester.get_owner_of_ticket(self.task_id) self.assertEqual('', task_owner)
def get_user_attribute_from_session(env, attr, username, db=None): """ Returns the given attribute value if present in the session_attribute table, for this team members """ db = get_db_for_read(env, db) try: cursor = db.cursor() cursor.execute("SELECT value FROM session_attribute WHERE sid=%s AND name=%s", [username, attr]) value = cursor.fetchone() if value is not None: return value[0] except Exception, e: warning(env, _("Could not load attribute: %s for TeamMember: %s => %s" % \ (attr, username, exception_to_unicode(e))))
def _process(prop_type): """ Process the final property """ try: if prop_type in self._type_to_alias: #debug(self, "[Aliasize]: Returning %s for %s" % \ # (self._type_to_alias[prop_type], prop_type)) return self._type_to_alias[prop_type] elif prop_type in self._alias_mapping: #debug(self, "[Aliasize]: Returning %s for %s" % \ # (self._alias_mapping[prop_type], prop_type)) return self._alias_mapping[prop_type] # else: # warning(self, "No alias found for %s..." % prop_type) except TypeError, e: warning(self, "[Aliasize]: Error, %s" % exception_to_unicode(e))
def get_user_attribute_from_session(env, attr, username, db=None): """ Returns the given attribute value if present in the session_attribute table, for this team members """ db = get_db_for_read(env, db) try: cursor = db.cursor() cursor.execute( "SELECT value FROM session_attribute WHERE sid=%s AND name=%s", [username, attr]) value = cursor.fetchone() if value is not None: return value[0] except Exception, e: warning(env, _("Could not load attribute: %s for TeamMember: %s => %s" % \ (attr, username, exception_to_unicode(e))))
def set_user_attribute_in_session(env, attr, value, username, db=None): db, handle_ta = get_db_for_write(env, db) try: cursor = db.cursor() if get_user_attribute_from_session(env, attr, username, db=db) is not None: cursor.execute("UPDATE session_attribute SET value=%s WHERE sid=%s" \ " AND name=%s", [value, username, attr]) else: cursor.execute("INSERT INTO session_attribute (sid, authenticated, name, value)" \ " VALUES (%s, %s, %s, %s)", [username, 1, attr, value]) if handle_ta: db.commit() except Exception, e: if handle_ta: db.rollback() warning(env, _("Could not store attribute: %s=%s for TeamMember: %s => %s" % \ (attr, value, username, exception_to_unicode(e))))
def _process_ticket_request(self, req): if not AgiloConfig(self.env).is_agilo_enabled: return super(AgiloTicketModule, self)._process_ticket_request(req) from agilo.scrum.workflow.api import RuleValidationException # Compute the back_to_url self._set_back_to_url(req) # Check if the delete has been called if 'delete' in req.args: # load the ticket, delete it and change the ID to another one before # sending it to trac self._do_delete(req) # Process the Ticket the TRAC way template = data = content_type = None try: template, data, content_type = super(AgiloTicketModule, self)._process_ticket_request(req) except RuleValidationException, e: raise TracError(exception_to_unicode(e))
def _iterate(self, data, key=None, command=None): """ Operator to iterate over a sequence and return the items matching the given condition. If no condition is supplied an Alias replacing will be attempted on the whole list. The operator returns a list """ # Check if the key contains also a condition condition = realkey = None if key is not None and isinstance(key, tuple): realkey, condition = key else: realkey = key #debug(self, "[Iterate]: Processing %s with %s, command: #%s#" % \ # (repr(data), key, command)) # Now process the data, take the analyzed data that should be pointers to the # real ones, so that the real_data gets modified too if data is not None and hasattr(data, '__iter__'): for i, item in enumerate(data): #debug(self, "[Iterate]: Command left: %s\ni: %d\ndata[%d] = %s" % \ # (command, i, i, data[i])) if (condition is not None and eval(condition)) or condition is None: if realkey is not None: try: if not command: #debug(self, "[Iterate]: No command left, " \ # "calculating aliases...") data[i][realkey] = self._aliasize(item[realkey]) else: #debug(self, "[Iterate]: Processing next " \ # "command... %s" % command) # The command in this case is not consumed, # because we are in a cycle and the same command # has to be used to evaluate all items. acc, newkey, newcommand = self._parse_command(command) if acc is not None: #debug(self, "[Iterate]: calling\nacc: %s\n" \ # "data[%s], data: %s\nkey: %s\n\n" % \ # (acc, realkey, data[i], newkey)) acc(data[i][realkey], newkey, newcommand) except KeyError, e: warning(self, "[Iterate]: Warning %s" % exception_to_unicode(e)) else: data[i] = self._aliasize(item)
def _process_ticket_request(self, req): if not AgiloConfig(self.env).is_agilo_enabled: return super(AgiloTicketModule, self)._process_ticket_request(req) from agilo.scrum.workflow.api import RuleValidationException # Compute the back_to_url self._set_back_to_url(req) # Check if the delete has been called if 'delete' in req.args: # load the ticket, delete it and change the ID to another one before # sending it to trac self._do_delete(req) # Process the Ticket the TRAC way template = data = content_type = None try: template, data, content_type = super( AgiloTicketModule, self)._process_ticket_request(req) except RuleValidationException, e: raise TracError(exception_to_unicode(e))
def _do_create(self, req, ticket): if not AgiloConfig(self.env).is_agilo_enabled: return super(AgiloTicketModule, self)._do_create(req, ticket) # AT: to have full control of the flow we need to rewrite the # do create, in this way we will be able to add options to the # redirect, rather than only intervening once the request as # already been sent out from trac. This needs to be kept under # control in case of changes :-) from agilo.scrum.workflow.api import RuleValidationException try: ticket.insert() req.perm(ticket.resource).require('TICKET_VIEW') # Notify try: tn = TicketNotifyEmail(self.env) tn.notify(ticket, newticket=True) except Exception, e: self.log.error( "Failure sending notification on creation of " "ticket #%s: %s", ticket.id, exception_to_unicode(e)) # AT: if the source of a link is there, means we are # coming from the edit panel of a ticket, and that is # where we want to go back to after linking if 'src' in req.args: if self._add_links_for_ticket(req, ticket) and \ not 'redirected' in req.args: # redirect to the calling ticket, in edit pane # after creating the link successfully req.redirect( req.href.ticket(req.args['src'], {'pane': 'edit'})) # Redirect the user to the newly created ticket or add attachment if 'attachment' in req.args: req.redirect( req.href.attachment('ticket', ticket.id, action='new')) # if no option is there, than redirect to the normal view # page of the ticket req.redirect(req.href.ticket(ticket.id))
def _do_create(self, req, ticket): if not AgiloConfig(self.env).is_agilo_enabled: return super(AgiloTicketModule, self)._do_create(req, ticket) # AT: to have full control of the flow we need to rewrite the # do create, in this way we will be able to add options to the # redirect, rather than only intervening once the request as # already been sent out from trac. This needs to be kept under # control in case of changes :-) from agilo.scrum.workflow.api import RuleValidationException try: ticket.insert() req.perm(ticket.resource).require('TICKET_VIEW') # Notify try: tn = TicketNotifyEmail(self.env) tn.notify(ticket, newticket=True) except Exception, e: self.log.error("Failure sending notification on creation of " "ticket #%s: %s", ticket.id, exception_to_unicode(e)) # AT: if the source of a link is there, means we are # coming from the edit panel of a ticket, and that is # where we want to go back to after linking if 'src' in req.args: if self._add_links_for_ticket(req, ticket) and \ not 'redirected' in req.args: # redirect to the calling ticket, in edit pane # after creating the link successfully req.redirect(req.href.ticket(req.args['src'], {'pane': 'edit'})) # Redirect the user to the newly created ticket or add attachment if 'attachment' in req.args: req.redirect(req.href.attachment('ticket', ticket.id, action='new')) # if no option is there, than redirect to the normal view # page of the ticket req.redirect(req.href.ticket(ticket.id))
def emulate_login(self, username, when=None): """Emulates a login for the given username, by setting an entry in the session table, if when is specified will be also set the datetime of the login to when, otherwise to now""" if when is None: when = now() db = self.env.get_db_cnx() try: cursor = db.cursor() cursor.execute("SELECT sid FROM session WHERE sid='%s'" % username) last_visit = to_timestamp(when) if cursor.fetchone(): cursor.execute("UPDATE session SET last_visit=%s WHERE sid='%s'" % \ (last_visit, username)) else: cursor.execute("INSERT INTO session (sid, authenticated, last_visit) " \ "VALUES ('%s', 1, %s)" % (username, last_visit)) db.commit() self.add_user_to_known_users(username) except Exception, e: db.rollback() assert False, "Unable to complete login for user: %s (%)" % \ (username, exception_to_unicode(e))
def test_raises_on_component_set_if_filter_by_component_is_not_enabled(self): error = self.assert_raises(AssertionError, self.change.set_component_marker, 'fnord') self.assert_true("should_reload_burndown_on_filter_change_when_filtering_by_component" in exception_to_unicode(error)) self.assert_true("backlog_filter_attribute" in exception_to_unicode(error)) self.teh.enable_burndown_filter() self.change.set_component_marker('fnord')
def test_raises_on_sorting_non_comparable_elements(self): exception = self.assert_raises(ValueError, sorted, [v(1), v('foo')], By(Attribute('foo'))) self.assert_true( 'Elements are not comparable' in exception_to_unicode(exception))
def exception_response(self, req, current_data, exception): self.error_response(req, current_data, [exception_to_unicode(exception)])
def test_raises_on_sorting_non_comparable_elements(self): exception = self.assert_raises(ValueError, sorted, [v(1), v('foo')], By(Attribute('foo'))) self.assert_true('Elements are not comparable' in exception_to_unicode(exception))