class PlatformBuildTestCase(unittest.TestCase): """Tests that involve Builds, TargetPlatforms and BuildSteps""" def setUp(self): self.env = EnvironmentStub() self.env.path = tempfile.mkdtemp() logs_dir = self.env.config.get("bitten", "logs_dir") if os.path.isabs(logs_dir): raise ValueError("Should not have absolute logs directory for temporary test") logs_dir = os.path.join(self.env.path, logs_dir) os.makedirs(logs_dir) db = self.env.get_db_cnx() cursor = db.cursor() connector, _ = DatabaseManager(self.env)._get_connector() for schema in [Build._schema, TargetPlatform._schema, BuildStep._schema]: for table in schema: for stmt in connector.to_sql(table): cursor.execute(stmt) db.commit() def test_delete_platform_with_pending_builds(self): """Check that deleting a platform with pending builds removes those pending builds""" db = self.env.get_db_cnx() platform = TargetPlatform(self.env, config='test', name='Linux') platform.insert() build = Build(self.env, config='test', platform=platform.id, rev='42', rev_time=12039) build.insert() platform.delete() pending = list(build.select(self.env, config='test', status=Build.PENDING)) self.assertEqual(0, len(pending))
class AnnouncementSystemSendTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(enable=['trac.*', 'announcer.*']) self.env.path = tempfile.mkdtemp() self.db_mgr = DatabaseManager(self.env) self.db = self.env.get_db_cnx() self.an_sys = AnnouncementSystem(self.env) def tearDown(self): self.db.close() # Really close db connections. self.env.shutdown() shutil.rmtree(self.env.path) # Tests def test_filter_added(self): class DummySubscriptionFilter(Component): """Test implementation for checking the filter ExtensionPoint.""" implements(IAnnouncementSubscriptionFilter) def filter_subscriptions(self, event, subscriptions): """Just a pass-through.""" return subscriptions dummy = DummySubscriptionFilter(self.env) self.assertTrue(dummy in self.an_sys.subscription_filters)
class VersionControlAdminTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() def tearDown(self): self.env.reset_db() def test_render_admin_with_alias_to_default_repos(self): with self.env.db_transaction as db: # Add aliases to non-existent default repository db.executemany( "INSERT INTO repository (id, name, value) VALUES (%s, %s, %s)", [(1, 'name', ''), (1, 'dir', None), (1, 'alias', ''), (2, 'name', 'blah'), (2, 'dir', None), (2, 'alias', '')]) panel = RepositoryAdminPanel(self.env) req = Mock(method='GET', chrome={}, args={}, session={}, abs_href=Href('/'), href=Href('/'), locale=None, perm=MockPerm(), authname='anonymous', tz=utc) template, data = panel.render_admin_panel(req, 'versioncontrol', 'repository', '') repositories = data['repositories'] self.assertNotEqual({}, repositories) self.assertEqual('', repositories['']['name']) self.assertEqual('', repositories['']['alias']) self.assertEqual('blah', repositories['blah']['name']) self.assertEqual('', repositories['blah']['alias'])
class _BaseTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) self.env.path = tempfile.mkdtemp() self.perms = PermissionSystem(self.env) self.req = Mock(authname='editor') self.actions = ['TAGS_ADMIN', 'TAGS_MODIFY', 'TAGS_VIEW'] self.db = self.env.get_db_cnx() setup = TagSetup(self.env) # Current tractags schema is setup with enabled component anyway. # Revert these changes for getting default permissions inserted. self._revert_tractags_schema_init() setup.upgrade_environment(self.db) self.tag_s = tractags.api.TagSystem(self.env) def tearDown(self): self.db.close() # Really close db connections. self.env.shutdown() shutil.rmtree(self.env.path) # Helpers def _revert_tractags_schema_init(self): cursor = self.db.cursor() cursor.execute("DROP TABLE IF EXISTS tags") cursor.execute("DROP TABLE IF EXISTS tags_change") cursor.execute("DELETE FROM system WHERE name='tags_version'") cursor.execute("DELETE FROM permission WHERE action %s" % self.db.like(), ('TAGS_%',))
class TicketFieldTimelineFilterTests(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() t1 = self._insert_and_load_ticket("foo") self.filter = TicketFieldTimelineFilter(self.env) self.context = Mock(resource=t1.resource) def tearDown(self): self.env.reset_db() def test_returns_none_for_invalid_ticket_id(self): event = ['ticket', None, None, ['88']] result = self.filter.filter_event(self.context, None, event, None) self.assertIsNone(result) def test_long_resource_id(self): """Test resource with long id (#547)""" resource = self.context.resource resource.id = long(resource.id) event = ['ticket', None, None, [resource]] result = self.filter.filter_event(self.context, None, event, None) self.assertEqual(result, event) def _insert_and_load_ticket(self, summary, **kw): ticket = Ticket(self.env) ticket["summary"] = summary for k, v in kw.items(): ticket[k] = v return Ticket(self.env, ticket.insert())
def make_trac_environment_with_plugin(): env = EnvironmentStub( enable=["ticketref.*", TicketRefsPlugin, TicketRefsTemplate]) TicketRefsPlugin(env).upgrade_environment(env.get_db_cnx()) tref = TicketRefsPlugin(env) tmpl = TicketRefsTemplate(env) return env, tref, tmpl
def create_trac_ctx(self, website_url, author_name, timezone_str, uri): req = Mock(href=Href(uri), abs_href=Href(website_url), authname=author_name, perm=MockPerm(), tz=timezone_str, args={}) context = Context.from_request(req, 'wiki', 'WikiStart') env = EnvironmentStub(enable=['trac.*']) # + additional components # -- macros support env.path = '' # -- intertrac support env.config.set('intertrac', 'trac.title', "Trac's Trac") env.config.set('intertrac', 'trac.url', website_url) env.config.set('intertrac', 't', 'trac') env.config.set('intertrac', 'th.title', "Trac Hacks") env.config.set('intertrac', 'th.url', "http://trac-hacks.org") env.config.set('intertrac', 'th.compat', 'false') # -- safe schemes env.config.set('wiki', 'safe_schemes', 'file,ftp,http,https,svn,svn+ssh,git,' 'rfc-2396.compatible,rfc-2396+under_score') env.href = req.href env.abs_href = req.abs_href return (env, context)
class _BaseTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) self.env.path = tempfile.mkdtemp() self.db = self.env.get_db_cnx() setup = TagSetup(self.env) # Current tractags schema is setup with enabled component anyway. # Revert these changes for getting default permissions inserted. self._revert_tractags_schema_init() setup.upgrade_environment(self.db) def tearDown(self): self.db.close() # Really close db connections. self.env.shutdown() shutil.rmtree(self.env.path) # Helpers def _revert_tractags_schema_init(self): cursor = self.db.cursor() cursor.execute("DROP TABLE IF EXISTS tags") cursor.execute("DROP TABLE IF EXISTS tags_change") cursor.execute("DELETE FROM system WHERE name='tags_version'") cursor.execute("DELETE FROM permission WHERE action %s" % self.db.like(), ('TAGS_%',)) def _insert_tags(self, tagspace, name, tags): cursor = self.db.cursor() args = [(tagspace, name, tag) for tag in tags] cursor.executemany("INSERT INTO tags (tagspace,name,tag) " "VALUES (%s,%s,%s)", args)
class ComponentTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True) def tearDown(self): self.env.reset_db() def test_exists_negative(self): def get_fake_component(): return Component(self.env, "Shrubbery") self.assertRaises(TracError, get_fake_component) def test_exists(self): """ http://trac.edgewall.org/ticket/4247 """ for c in Component.select(self.env): self.assertEqual(c.exists, True) def test_create_and_update(self): component = Component(self.env) component.name = 'Test' component.insert() self.assertEqual([('Test', None, None)], self.env.db_query(""" SELECT name, owner, description FROM component WHERE name='Test'""")) # Use the same model object to update the component component.owner = 'joe' component.update() self.assertEqual([('Test', 'joe', None)], self.env.db_query( "SELECT name, owner, description FROM component WHERE name='Test'"))
class TargetPlatformTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.env.path = tempfile.mkdtemp() logs_dir = self.env.config.get("bitten", "logs_dir") if os.path.isabs(logs_dir): raise ValueError("Should not have absolute logs directory for temporary test") logs_dir = os.path.join(self.env.path, logs_dir) os.makedirs(logs_dir) db = self.env.get_db_cnx() cursor = db.cursor() connector, _ = DatabaseManager(self.env)._get_connector() for table in TargetPlatform._schema: for stmt in connector.to_sql(table): cursor.execute(stmt) db.commit() def test_new(self): platform = TargetPlatform(self.env) self.assertEqual(False, platform.exists) self.assertEqual([], platform.rules) def test_insert(self): platform = TargetPlatform(self.env, config='test', name='Windows XP') platform.rules += [(Build.OS_NAME, 'Windows'), (Build.OS_VERSION, 'XP')] platform.insert() assert platform.exists db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT config,name FROM bitten_platform " "WHERE id=%s", (platform.id,)) self.assertEqual(('test', 'Windows XP'), cursor.fetchone()) cursor.execute("SELECT propname,pattern,orderno FROM bitten_rule " "WHERE id=%s", (platform.id,)) self.assertEqual((Build.OS_NAME, 'Windows', 0), cursor.fetchone()) self.assertEqual((Build.OS_VERSION, 'XP', 1), cursor.fetchone()) def test_fetch(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO bitten_platform (config,name) " "VALUES (%s,%s)", ('test', 'Windows')) id = db.get_last_id(cursor, 'bitten_platform') platform = TargetPlatform.fetch(self.env, id) assert platform.exists self.assertEqual('test', platform.config) self.assertEqual('Windows', platform.name) def test_select(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.executemany("INSERT INTO bitten_platform (config,name) " "VALUES (%s,%s)", [('test', 'Windows'), ('test', 'Mac OS X')]) platforms = list(TargetPlatform.select(self.env, config='test')) self.assertEqual(2, len(platforms))
class ConnectionTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.db = self.env.get_db_cnx() def tearDown(self): self.env.reset_db() def test_get_last_id(self): c = self.db.cursor() q = "INSERT INTO report (author) VALUES ('anonymous')" c.execute(q) # Row ID correct before... id1 = self.db.get_last_id(c, 'report') self.assertNotEqual(0, id1) self.db.commit() c.execute(q) self.db.commit() # ... and after commit() id2 = self.db.get_last_id(c, 'report') self.assertEqual(id1 + 1, id2) def test_update_sequence(self): cursor = self.db.cursor() cursor.execute(""" INSERT INTO report (id, author) VALUES (42, 'anonymous') """) self.db.commit() self.db.update_sequence(cursor, 'report', 'id') self.db.commit() cursor.execute("INSERT INTO report (author) VALUES ('next-id')") self.db.commit() cursor.execute("SELECT id FROM report WHERE author='next-id'") self.assertEqual(43, cursor.fetchall()[0][0])
class StringsTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() def test_insert_unicode(self): self.env.db_transaction( "INSERT INTO system (name,value) VALUES (%s,%s)", ('test-unicode', u'ünicöde')) self.assertEqual([(u'ünicöde',)], self.env.db_query( "SELECT value FROM system WHERE name='test-unicode'")) def test_insert_empty(self): from trac.util.text import empty self.env.db_transaction( "INSERT INTO system (name,value) VALUES (%s,%s)", ('test-empty', empty)) self.assertEqual([(u'',)], self.env.db_query( "SELECT value FROM system WHERE name='test-empty'")) def test_insert_markup(self): from genshi.core import Markup self.env.db_transaction( "INSERT INTO system (name,value) VALUES (%s,%s)", ('test-markup', Markup(u'<em>märkup</em>'))) self.assertEqual([(u'<em>märkup</em>',)], self.env.db_query( "SELECT value FROM system WHERE name='test-markup'")) def test_quote(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute('SELECT 1 AS %s' % \ db.quote(r'alpha\`\"\'\\beta``gamma""delta')) self.assertEqual(r'alpha\`\"\'\\beta``gamma""delta', get_column_names(cursor)[0])
class PluginAdminPanelTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.req = Mock( args={}, chrome={"notices": []}, href=self.env.href, lc_time=locale_en, method=None, perm=MockPerm(), session={}, tz=utc, ) def tearDown(self): self.env.reset_db() def test_abstract_component_not_visible(self): class AbstractComponent(Component): abstract = True class NotAbstractComponent(Component): abstract = False panel = PluginAdminPanel(self.env) data = panel.render_admin_panel(self.req, "general", "plugin", None)[1] module = self.__class__.__module__ components = [] for plugin in data["plugins"]: if module in plugin["modules"].keys(): components = plugin["modules"][module]["components"].keys() self.assertNotIn("AbstractComponent", components) self.assertIn("NotAbstractComponent", components)
class TracHoursByCommentTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'trachours.*']) self.env.path = tempfile.mkdtemp() setup = SetupTracHours(self.env) setup.upgrade_environment(db=self.env.get_db_cnx()) self.hours_thp = TracHoursPlugin(self.env) self.hours_thbc = TracHoursByComment(self.env) self.ticket_system = TicketSystem(self.env) def tearDown(self): self.env.reset_db() revert_trachours_schema_init(db=self.env.get_db_cnx()) shutil.rmtree(self.env.path) def test_ticket_delete(self): ticket = Ticket(self.env) ticket['summary'] = 'ticket summary' ticket.insert() self.hours_thp.add_ticket_hours(ticket.id, 'user', 160) self.hours_thp.add_ticket_hours(ticket.id, 'user', 1200) ticket.delete() hours = self.hours_thp.get_ticket_hours(ticket.id) self.assertEqual([], hours)
class GetBlogPostsTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() if hasattr(self.env, "db_transaction"): with self.env.db_transaction as db: FullBlogSetup(self.env).upgrade_environment(db) else: FullBlogSetup(self.env).upgrade_environment(self.env.get_db_cnx()) def tearDown(self): self.env.destroy_db() del self.env def test_get_by_category(self): bp = BlogPost(self.env, "one") bp.update_fields({"title": "one", "body": "body", "author": "user", "categories": "about stuff"}) self.assertEquals([], bp.save("user")) posts = get_blog_posts(self.env) self.assertEquals(1, len(posts)) self.assertEquals("one", posts[0][0]) posts = get_blog_posts(self.env, category="non-existing") self.assertEquals(0, len(posts)) posts = get_blog_posts(self.env, category="stuff") self.assertEquals(1, len(posts)) self.assertEquals("one", posts[0][0]) self.assertEquals(get_blog_posts(self.env, category="about"), get_blog_posts(self.env, category="stuff"))
class VersionTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True) self.db = self.env.get_db_cnx() def tearDown(self): self.env.reset_db() def test_exists_negative(self): def get_fake_version(): return Version(self.env, "-1") self.assertRaises(TracError, get_fake_version) def test_exists(self): """ http://trac.edgewall.org/ticket/4247 """ for v in Version.select(self.env): self.assertEqual(v.exists, True) def test_create_and_update(self): version = Version(self.env) version.name = "Test" version.insert() cursor = self.db.cursor() cursor.execute("SELECT name,time,description FROM version " "WHERE name='Test'") self.assertEqual(("Test", 0, None), cursor.fetchone()) # Use the same model object to update the version version.description = "Some text" version.update() cursor.execute("SELECT name,time,description FROM version " "WHERE name='Test'") self.assertEqual(("Test", 0, "Some text"), cursor.fetchone())
class _BaseTestCase(unittest.TestCase): def setUp(self): #self.basedir = os.path.realpath(tempfile.mkdtemp()) self.env = EnvironmentStub(enable=['trac.*', 'acct_mgr.*']) self.env.config.set('account-manager', 'password_store', 'SessionStore') self.store = SessionStore(self.env) #self.env.path = os.path.join(self.basedir, 'trac-tempenv') #os.mkdir(self.env.path) def test_get_users(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.executemany("INSERT INTO session_attribute " "(sid,authenticated,name,value) " "VALUES (%s,1,'password',%s)", [('a', 'a'), ('b', 'b'), ('c', 'c')]) self.assertEqual(set(['a', 'b', 'c']), set(self.store.get_users())) def test_has_user(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO session_attribute " "(sid,authenticated,name,value) " "VALUES (%s,1,'password',%s)", ('bar', 'bar')) self.assertFalse(self.store.has_user('foo')) self.assertTrue(self.store.has_user('bar')) def test_create_user(self): self.assertFalse(self.store.has_user('foo')) self.store.set_password('foo', 'password') self.assertTrue(self.store.has_user('foo')) def test_update_password(self): self.store.set_password('foo', 'pass1') self.assertFalse(self.store.check_password('foo', 'pass2')) self.store.set_password('foo', 'pass2') self.assertTrue(self.store.check_password('foo', 'pass2')) self.store.set_password('foo', 'pass3', 'pass2') self.assertTrue(self.store.check_password('foo', 'pass3')) def test_delete_user(self): self.store.set_password('foo', 'password') self.assertTrue(self.store.has_user('foo')) self.assertTrue(self.store.delete_user('foo')) self.assertFalse(self.store.has_user('foo')) def test_delete_nonexistant_user(self): self.assertFalse(self.store.has_user('foo')) self.assertFalse(self.store.delete_user('foo')) def test_unicode_username_and_password(self): username = u'\u4e60' password = u'\u4e61' self.store.set_password(username, password) self.assertTrue(self.store.check_password(username, password))
class ComponentTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True) self.db = self.env.get_db_cnx() def tearDown(self): self.env.reset_db() def test_exists_negative(self): def get_fake_component(): return Component(self.env, "Shrubbery") self.assertRaises(TracError, get_fake_component) def test_exists(self): """ http://trac.edgewall.org/ticket/4247 """ for c in Component.select(self.env): self.assertEqual(c.exists, True) def test_create_and_update(self): component = Component(self.env) component.name = "Test" component.insert() cursor = self.db.cursor() cursor.execute("SELECT name,owner,description FROM component " "WHERE name='Test'") self.assertEqual(("Test", None, None), cursor.fetchone()) # Use the same model object to update the component component.owner = "joe" component.update() cursor.execute("SELECT name,owner,description FROM component " "WHERE name='Test'") self.assertEqual(("Test", "joe", None), cursor.fetchone())
class GetBlogPostsTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() FullBlogSetup(self.env).upgrade_environment(self.env.get_db_cnx()) def tearDown(self): self.env.destroy_db() del self.env def test_get_by_category(self): bp = BlogPost(self.env, 'one') bp.update_fields({'title': 'one', 'body': 'body', 'author': 'user', 'categories': 'about stuff'}) self.assertEquals([], bp.save('user')) posts = get_blog_posts(self.env) self.assertEquals(1, len(posts)) self.assertEquals('one', posts[0][0]) posts = get_blog_posts(self.env, category='non-existing') self.assertEquals(0, len(posts)) posts = get_blog_posts(self.env, category='stuff') self.assertEquals(1, len(posts)) self.assertEquals('one', posts[0][0]) self.assertEquals(get_blog_posts(self.env, category='about'), get_blog_posts(self.env, category='stuff'))
class GroupPostsByMonthTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() FullBlogSetup(self.env).upgrade_environment(self.env.get_db_cnx()) def tearDown(self): self.env.destroy_db() del self.env def test_many_posts(self): # 2 posts in one period one = BlogPost(self.env, 'one') one.update_fields({'title': 'one', 'body': 'body', 'author': 'user'}) self.assertEquals([], one.save('user')) two = BlogPost(self.env, 'two') two.update_fields({'title': 'two', 'body': 'body', 'author': 'user'}) self.assertEquals([], two.save('user')) grouped = group_posts_by_month(get_blog_posts(self.env)) self.assertEquals(1, len(grouped)) # Add 1 post in another period three = BlogPost(self.env, 'three') three.update_fields({'title': 'three', 'body': 'body', 'author': 'user', 'publish_time': three.publish_time - datetime.timedelta(days=-100)}) self.assertEquals([], three.save('user')) grouped = group_posts_by_month(get_blog_posts(self.env)) self.assertEquals(2, len(grouped)) self.assertEquals(1, len(grouped[0][1])) self.assertEquals(2, len(grouped[1][1])) self.assertEquals(type(grouped[0][0]), datetime.datetime) self.assertEquals((one.name, one.version, one.publish_time, one.author, one.title, one.body, []), grouped[1][1][0]) def test_no_posts(self): grouped = group_posts_by_month(get_blog_posts(self.env)) self.assertEquals([], grouped)
class VersionTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True) def tearDown(self): self.env.reset_db() def test_exists_negative(self): def get_fake_version(): return Version(self.env, "-1") self.assertRaises(TracError, get_fake_version) def test_exists(self): """ http://trac.edgewall.org/ticket/4247 """ for v in Version.select(self.env): self.assertEqual(v.exists, True) def test_create_and_update(self): version = Version(self.env) version.name = 'Test' version.insert() self.assertEqual([('Test', 0, None)], self.env.db_query( "SELECT name, time, description FROM version WHERE name='Test'")) # Use the same model object to update the version version.description = 'Some text' version.update() self.assertEqual([('Test', 0, 'Some text')], self.env.db_query( "SELECT name, time, description FROM version WHERE name='Test'"))
class CommitTicketUpdaterTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(enable=['trac.*', 'tracopt.ticket.commit_updater.*']) self.env.config.set('ticket', 'commit_ticket_update_check_perms', False) self.repos = Mock(Repository, 'repos1', {'name': 'repos1', 'id': 1}, self.env.log, normalize_rev=lambda rev: 1) self.updater = CommitTicketUpdater(self.env) def tearDown(self): self.env.reset_db() def _make_tickets(self, num): self.tickets = [] for i in xrange(0, num): ticket = Ticket(self.env) ticket['reporter'] = 'someone' ticket['summary'] = random_sentence() ticket.insert() self.tickets.append(ticket) def test_changeset_added(self): self._make_tickets(1) message = 'This is the first comment. Refs #1.' chgset = Mock(repos=self.repos, rev=1, message=message, author='joe', date=datetime(2001, 1, 1, 1, 1, 1, 0, utc)) self.updater.changeset_added(self.repos, chgset) self.assertEqual("""\ In [changeset:"1/repos1" 1/repos1]: {{{ #!CommitTicketReference repository="repos1" revision="1" This is the first comment. Refs #1. }}}""", self.tickets[0].get_change(cnum=1)['fields']['comment']['new']) def test_changeset_modified(self): self._make_tickets(2) message = 'This is the first comment. Refs #1.' old_chgset = Mock(repos=self.repos, rev=1, message=message, author='joe', date=datetime(2001, 1, 1, 1, 1, 1, 0, utc)) message = 'This is the first comment after an edit. Refs #1, #2.' new_chgset = Mock(repos=self.repos, rev=1, message=message, author='joe', date=datetime(2001, 1, 2, 1, 1, 1, 0, utc)) self.updater.changeset_added(self.repos, old_chgset) self.updater.changeset_modified(self.repos, new_chgset, old_chgset) self.assertEqual("""\ In [changeset:"1/repos1" 1/repos1]: {{{ #!CommitTicketReference repository="repos1" revision="1" This is the first comment. Refs #1. }}}""", self.tickets[0].get_change(cnum=1)['fields']['comment']['new']) self.assertEqual("""\ In [changeset:"1/repos1" 1/repos1]: {{{ #!CommitTicketReference repository="repos1" revision="1" This is the first comment after an edit. Refs #1, #2. }}}""", self.tickets[1].get_change(cnum=1)['fields']['comment']['new'])
class CrashDumpModelTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(enable=['trac.*', 'crashdump.*']) self.env.path = tempfile.mkdtemp() self.db_mgr = DatabaseManager(self.env) self.env.upgrade() #self.db = self.env.get_db_cnx() self.crashdump_module = CrashDumpModule(self.env) def tearDown(self): #self.db.close() self.env.shutdown() shutil.rmtree(self.env.path) def _insert_crashdump(self, **kw): """Helper for inserting a ticket into the database""" crash = CrashDump(env=self.env) for k, v in kw.items(): crash[k] = v crash.insert() return crash def test_new_crash(self): crash = CrashDump(env=self.env) crash.insert() self.assertIsNotNone(crash) self.assertIsNone(crash.uuid) self.assertIsNotNone(crash.id) def test_existing_crash(self): crash = CrashDump(env=self.env, uuid='67cbc89f-1001-4691-a2c2-c1bb40aac806', must_exist=False) crash.insert() self.assertIsNotNone(crash.uuid) self.assertEqual(crash.uuid, '67cbc89f-1001-4691-a2c2-c1bb40aac806') crash2 = CrashDump(id=crash.id, env=self.env) self.assertIsNotNone(crash2.uuid) self.assertEqual(crash.id, crash2.id) self.assertEqual(crash.uuid, crash2.uuid) crash3 = CrashDump(uuid=crash.uuid, env=self.env) self.assertEqual(crash.uuid, crash3.uuid) self.assertEqual(crash.id, crash3.id) crash4 = CrashDump(id=' #%i ' % crash.id, env=self.env) self.assertEqual(crash.uuid, crash4.uuid) self.assertEqual(crash.id, crash4.id) def test_non_existing_crash(self): self.assertRaises(ResourceNotFound, CrashDump, id='#1742', env=self.env) self.assertRaises(ResourceNotFound, CrashDump, id='42', env=self.env)
def destroy(self): """Remove all of the test environment data.""" env = EnvironmentStub(path=self.tracdir, destroying=True) env.destroy_db() self.destroy_repo() if os.path.exists(self.dirname): rmtree(self.dirname)
def test_sub_var_mysql(self): env = EnvironmentStub() env.db = MockMySQLConnection() # ditto sql, values, missing_args = ReportModule(env).sql_sub_vars( "'$VAR'", {'VAR': 'value'}) self.assertEqual("concat('', %s, '')", sql) self.assertEqual(['value'], values) self.assertEqual([], missing_args)
def test_sub_var_mysql(self): req = Mock(hdf=dict()) env = EnvironmentStub() env.db = MockMySQLConnection() sql, args = ReportModule(env).sql_sub_vars(req, "'$VAR'", {'VAR': 'value'}) self.assertEqual("concat('', %s, '')", sql) self.assertEqual(['value'], args)
class DefaultPermissionStoreTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(enable=[perm.DefaultPermissionStore, perm.DefaultPermissionGroupProvider]) self.store = perm.DefaultPermissionStore(self.env) def test_simple_actions(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.executemany("INSERT INTO permission VALUES (%s,%s)", [ ('john', 'WIKI_MODIFY'), ('john', 'REPORT_ADMIN'), ('kate', 'TICKET_CREATE')]) self.assertEquals(['WIKI_MODIFY', 'REPORT_ADMIN'], self.store.get_user_permissions('john')) self.assertEquals(['TICKET_CREATE'], self.store.get_user_permissions('kate')) def test_simple_group(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.executemany("INSERT INTO permission VALUES (%s,%s)", [ ('dev', 'WIKI_MODIFY'), ('dev', 'REPORT_ADMIN'), ('john', 'dev')]) self.assertEquals(['WIKI_MODIFY', 'REPORT_ADMIN'], self.store.get_user_permissions('john')) def test_nested_groups(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.executemany("INSERT INTO permission VALUES (%s,%s)", [ ('dev', 'WIKI_MODIFY'), ('dev', 'REPORT_ADMIN'), ('admin', 'dev'), ('john', 'admin')]) self.assertEquals(['WIKI_MODIFY', 'REPORT_ADMIN'], self.store.get_user_permissions('john')) def test_builtin_groups(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.executemany("INSERT INTO permission VALUES (%s,%s)", [ ('authenticated', 'WIKI_MODIFY'), ('authenticated', 'REPORT_ADMIN'), ('anonymous', 'TICKET_CREATE')]) self.assertEquals(['WIKI_MODIFY', 'REPORT_ADMIN', 'TICKET_CREATE'], self.store.get_user_permissions('john')) self.assertEquals(['TICKET_CREATE'], self.store.get_user_permissions('anonymous')) def test_get_all_permissions(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.executemany("INSERT INTO permission VALUES (%s,%s)", [ ('dev', 'WIKI_MODIFY'), ('dev', 'REPORT_ADMIN'), ('john', 'dev')]) expected = [('dev', 'WIKI_MODIFY'), ('dev', 'REPORT_ADMIN'), ('john', 'dev')] for res in self.store.get_all_permissions(): self.failIf(res not in expected)
def destroy(self): """Remove all of the test environment data.""" env = EnvironmentStub() env.destroy_db() env.shutdown() self.destroy_repo() if os.path.exists(self.dirname): rmtree(self.dirname)
def env_stub_with_tables(): env = EnvironmentStub() db = env.get_db_cnx() cursor = db.cursor() connector, _ = DatabaseManager(env)._get_connector() for table in schema: for stmt in connector.to_sql(table): cursor.execute(stmt) return env
class PermissionCacheTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(enable=[perm.DefaultPermissionStore, perm.DefaultPermissionPolicy, TestPermissionRequestor]) self.env.config.set('trac', 'permission_policies', 'DefaultPermissionPolicy') self.perm_system = perm.PermissionSystem(self.env) # by-pass DefaultPermissionPolicy cache: perm.DefaultPermissionPolicy.CACHE_EXPIRY = -1 self.perm_system.grant_permission('testuser', 'TEST_MODIFY') self.perm_system.grant_permission('testuser', 'TEST_ADMIN') self.perm = perm.PermissionCache(self.env, 'testuser') def tearDown(self): self.env.reset_db() def test_contains(self): self.assertTrue('TEST_MODIFY' in self.perm) self.assertTrue('TEST_ADMIN' in self.perm) self.assertFalse('TRAC_ADMIN' in self.perm) def test_has_permission(self): self.assertTrue(self.perm.has_permission('TEST_MODIFY')) self.assertTrue(self.perm.has_permission('TEST_ADMIN')) self.assertFalse(self.perm.has_permission('TRAC_ADMIN')) def test_require(self): self.perm.require('TEST_MODIFY') self.perm.require('TEST_ADMIN') self.assertRaises(perm.PermissionError, self.perm.require, 'TRAC_ADMIN') def test_assert_permission(self): self.perm.assert_permission('TEST_MODIFY') self.perm.assert_permission('TEST_ADMIN') self.assertRaises(perm.PermissionError, self.perm.assert_permission, 'TRAC_ADMIN') def test_cache(self): self.perm.assert_permission('TEST_MODIFY') self.perm.assert_permission('TEST_ADMIN') self.perm_system.revoke_permission('testuser', 'TEST_ADMIN') # Using cached GRANT here self.perm.assert_permission('TEST_ADMIN') def test_cache_shared(self): # we need to start with an empty cache here (#7201) perm1 = perm.PermissionCache(self.env, 'testcache') perm1 = perm1('ticket', 1) perm2 = perm1('ticket', 1) # share internal cache self.perm_system.grant_permission('testcache', 'TEST_ADMIN') perm1.assert_permission('TEST_ADMIN') self.perm_system.revoke_permission('testcache', 'TEST_ADMIN') # Using cached GRANT here (from shared cache) perm2.assert_permission('TEST_ADMIN')
class MySQLConnectionTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.schema = [ Table('test_simple', key='id')[Column('id', auto_increment=True), Column('username'), Column('email'), Column('enabled', type='int'), Column('extra'), Index(['username'], unique=True), Index(['email'], unique=False), ], Table('test_composite', key=['id', 'name'])[Column('id', type='int'), Column('name'), Column('value'), Column('enabled', type='int'), Index(['name', 'value'], unique=False), Index(['name', 'enabled'], unique=True), ], ] self.dbm = DatabaseManager(self.env) self.dbm.drop_tables(self.schema) self.dbm.create_tables(self.schema) self.dbm.insert_into_tables([ ('test_simple', ('username', 'email', 'enabled'), [('joe', '*****@*****.**', 1), (u'joé', '*****@*****.**', 0)]), ('test_composite', ('id', 'name', 'value', 'enabled'), [(1, 'foo', '42', 1), (1, 'bar', '42', 1), (2, 'foo', '43', 0), (2, 'bar', '43', 0)]), ]) def tearDown(self): DatabaseManager(self.env).drop_tables(self.schema) self.env.reset_db() def _show_index(self, table): with self.env.db_query as db: cursor = db.cursor() cursor.execute("SHOW INDEX FROM " + db.quote(table)) columns = get_column_names(cursor) rows = [dict(zip(columns, row)) for row in cursor] results = {} for index, group in itertools.groupby(rows, lambda v: v['Key_name']): group = list(group) results[index] = { 'unique': not group[0]['Non_unique'], 'columns': [row['Column_name'] for row in group], } return results def _drop_column(self, table, column): with self.env.db_transaction as db: db.drop_column(table, column) def _query(self, stmt, *args): return self.env.db_query(stmt, args) def test_remove_simple_keys(self): indices_0 = self._show_index('test_simple') self.assertEqual( ['PRIMARY', 'test_simple_email_idx', 'test_simple_username_idx'], sorted(indices_0)) self.assertEqual({ 'unique': True, 'columns': ['id'] }, indices_0['PRIMARY']) self.assertEqual({ 'unique': True, 'columns': ['username'] }, indices_0['test_simple_username_idx']) self.assertEqual({ 'unique': False, 'columns': ['email'] }, indices_0['test_simple_email_idx']) self._drop_column('test_simple', 'enabled') self.assertEqual(indices_0, self._show_index('test_simple')) self._drop_column('test_simple', 'username') indices_1 = self._show_index('test_simple') self.assertEqual(['PRIMARY', 'test_simple_email_idx'], sorted(indices_1)) self._drop_column('test_simple', 'email') indices_2 = self._show_index('test_simple') self.assertEqual(['PRIMARY'], sorted(indices_2)) self._drop_column('test_simple', 'id') indices_3 = self._show_index('test_simple') self.assertEqual({}, indices_3) def test_remove_composite_keys(self): indices_0 = self._show_index('test_composite') self.assertEqual([ 'PRIMARY', 'test_composite_name_enabled_idx', 'test_composite_name_value_idx' ], sorted(indices_0)) self.assertEqual({ 'unique': True, 'columns': ['id', 'name'] }, indices_0['PRIMARY']) self.assertEqual({ 'unique': False, 'columns': ['name', 'value'] }, indices_0['test_composite_name_value_idx']) self.assertEqual({ 'unique': True, 'columns': ['name', 'enabled'] }, indices_0['test_composite_name_enabled_idx']) self._drop_column('test_composite', 'id') indices_1 = self._show_index('test_composite') self.assertEqual([ 'test_composite_name_enabled_idx', 'test_composite_name_value_idx' ], sorted(indices_1)) self.assertEqual(indices_0['test_composite_name_value_idx'], indices_1['test_composite_name_value_idx']) self.assertEqual(indices_0['test_composite_name_enabled_idx'], indices_1['test_composite_name_enabled_idx']) rows = self._query("""SELECT * FROM test_composite ORDER BY name, value, enabled""") self.assertEqual([('bar', '42', 1), ('bar', '43', 0), ('foo', '42', 1), ('foo', '43', 0)], rows) self._drop_column('test_composite', 'name') self.assertEqual({}, self._show_index('test_composite')) rows = self._query("""SELECT * FROM test_composite ORDER BY value, enabled""") self.assertEqual([('42', 1), ('42', 1), ('43', 0), ('43', 0)], rows)
def setUp(self): self.env = EnvironmentStub(path=mkdtemp()) os.mkdir(self.env.templates_dir) filepath = os.path.join(self.env.templates_dir, self.filename) create_file(filepath, self.template) self.chrome = Chrome(self.env)
def setUp(self): self.env = EnvironmentStub(enable=self.system_info_providers)
class UnicodeNameTestCase(unittest.TestCase, GitCommandMixin): def setUp(self): self.env = EnvironmentStub() self.repos_path = mkdtemp() # create git repository and master branch self._git('init') self._git('config', 'core.quotepath', 'true') # ticket:11198 self._git('config', 'user.name', "Joé") # passing utf-8 bytes self._git('config', 'user.email', "*****@*****.**") create_file(os.path.join(self.repos_path, '.gitignore')) self._git('add', '.gitignore') self._git_commit('-a', '-m', 'test', date=datetime(2013, 1, 1, 9, 4, 57)) def tearDown(self): self.env.reset_db() if os.path.isdir(self.repos_path): rmtree(self.repos_path) def _storage(self): path = os.path.join(self.repos_path, '.git') return Storage(path, self.env.log, self.git_bin, 'utf-8') def test_unicode_verifyrev(self): storage = self._storage() self.assertIsNotNone(storage.verifyrev(u'master')) self.assertIsNone(storage.verifyrev(u'tété')) def test_unicode_filename(self): create_file(os.path.join(self.repos_path, 'tickét.txt')) self._git('add', 'tickét.txt') self._git_commit('-m', 'unicode-filename', date='1359912600 +0100') storage = self._storage() filenames = sorted(fname for mode, type, sha, size, fname in storage.ls_tree('HEAD')) self.assertEqual(unicode, type(filenames[0])) self.assertEqual(unicode, type(filenames[1])) self.assertEqual(u'.gitignore', filenames[0]) self.assertEqual(u'tickét.txt', filenames[1]) # check commit author, for good measure self.assertEqual(u'Joé <*****@*****.**> 1359912600 +0100', storage.read_commit(storage.head())[1]['author'][0]) def test_unicode_branches(self): self._git('checkout', '-b', 'tickɇt10980', 'master') storage = self._storage() branches = sorted(storage.get_branches()) self.assertEqual(unicode, type(branches[0][0])) self.assertEqual(unicode, type(branches[1][0])) self.assertEqual(u'master', branches[0][0]) self.assertEqual(u'tickɇt10980', branches[1][0]) contains = sorted(storage.get_branch_contains(branches[1][1], resolve=True)) self.assertEqual(unicode, type(contains[0][0])) self.assertEqual(unicode, type(contains[1][0])) self.assertEqual(u'master', contains[0][0]) self.assertEqual(u'tickɇt10980', contains[1][0]) def test_unicode_tags(self): self._git('tag', 'tɐg-t10980', 'master') self._git_commit('-m', 'blah', '--allow-empty') self._git('tag', 'v0.42.1', 'master') storage = self._storage() tags = storage.get_tags() self.assertEqual(unicode, type(tags[0])) self.assertEqual([u'tɐg-t10980', 'v0.42.1'], tags) rev = storage.verifyrev(u'tɐg-t10980') self.assertIsNotNone(rev) self.assertEqual([u'tɐg-t10980'], storage.get_tags(rev)) rev = storage.verifyrev('v0.42.1') self.assertIsNotNone(rev) self.assertEqual(['v0.42.1'], storage.get_tags(rev)) def test_ls_tree(self): paths = [u'normal-path.txt', u'tickét.tx\\t', u'\a\b\t\n\v\f\r\x1b"\\.tx\\t'] for path in paths: path_utf8 = path.encode('utf-8') create_file(os.path.join(self.repos_path, path_utf8)) self._git('add', path_utf8) self._git_commit('-m', 'ticket:11180 and ticket:11198', date=datetime(2013, 4, 30, 13, 48, 57)) storage = self._storage() rev = storage.head() entries = storage.ls_tree(rev, '/') self.assertEqual(4, len(entries)) self.assertEqual(u'\a\b\t\n\v\f\r\x1b"\\.tx\\t', entries[0][4]) self.assertEqual(u'.gitignore', entries[1][4]) self.assertEqual(u'normal-path.txt', entries[2][4]) self.assertEqual(u'tickét.tx\\t', entries[3][4]) def test_get_historian(self): paths = [u'normal-path.txt', u'tickét.tx\\t', u'\a\b\t\n\v\f\r\x1b"\\.tx\\t'] for path in paths: path_utf8 = path.encode('utf-8') create_file(os.path.join(self.repos_path, path_utf8)) self._git('add', path_utf8) self._git_commit('-m', 'ticket:11180 and ticket:11198', date=datetime(2013, 4, 30, 17, 48, 57)) def validate(path, quotepath): self._git('config', 'core.quotepath', quotepath) storage = self._storage() rev = storage.head() with storage.get_historian('HEAD', path) as historian: hrev = storage.last_change('HEAD', path, historian) self.assertEqual(rev, hrev) validate(paths[0], 'true') validate(paths[0], 'false') validate(paths[1], 'true') validate(paths[1], 'false') validate(paths[2], 'true') validate(paths[2], 'false')
def setUp(self): self.env = EnvironmentStub(path=mkdtemp()) self.chrome = Chrome(self.env)
def _destroy_db(self): EnvironmentStub(path=self.path, destroying=True).destroy_db()
class WikiPageTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.env.path = tempfile.mkdtemp(prefix='trac-tempenv-') def tearDown(self): self.env.reset_db_and_disk() def test_new_page(self): page = WikiPage(self.env) self.assertFalse(page.exists) self.assertIsNone(page.name) self.assertEqual(0, page.version) self.assertEqual('', page.text) self.assertEqual(0, page.readonly) self.assertEqual('', page.author) self.assertEqual('', page.comment) self.assertIsNone(page.time) self.assertEqual('<WikiPage None>', repr(page)) def test_existing_page(self): t = datetime(2001, 1, 1, 1, 1, 1, 0, utc) self.env.db_transaction( "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", ('TestPage', 1, to_utimestamp(t), 'joe', '::1', 'Bla bla', 'Testing', 0)) page = WikiPage(self.env, 'TestPage') self.assertTrue(page.exists) self.assertEqual('TestPage', page.name) self.assertEqual(1, page.version) self.assertIsNone(page.resource.version) self.assertEqual('Bla bla', page.text) self.assertEqual(0, page.readonly) self.assertEqual('joe', page.author) self.assertEqual('Testing', page.comment) self.assertEqual(t, page.time) self.assertEqual("<WikiPage u'TestPage@1'>", repr(page)) history = list(page.get_history()) self.assertEqual(1, len(history)) self.assertEqual((1, t, 'joe', 'Testing', '::1'), history[0]) page = WikiPage(self.env, 'TestPage', 1) self.assertEqual(1, page.resource.version) self.assertEqual(1, page.version) resource = Resource('wiki', 'TestPage') page = WikiPage(self.env, resource, 1) self.assertEqual(1, page.version) def test_create_page(self): page = WikiPage(self.env) page.name = 'TestPage' page.text = 'Bla bla' t = datetime(2001, 1, 1, 1, 1, 1, 0, utc) page.save('joe', 'Testing', '::1', t) self.assertTrue(page.exists) self.assertEqual(1, page.version) self.assertIsNone(page.resource.version) self.assertEqual(0, page.readonly) self.assertEqual('joe', page.author) self.assertEqual('Testing', page.comment) self.assertEqual(t, page.time) self.assertEqual( [(1, to_utimestamp(t), 'joe', '::1', 'Bla bla', 'Testing', 0)], self.env.db_query( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s """, ('TestPage', ))) listener = TestWikiChangeListener(self.env) self.assertEqual(page, listener.added[0]) def test_update_page(self): t = datetime(2001, 1, 1, 1, 1, 1, 0, utc) t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc) self.env.db_transaction( "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", ('TestPage', 1, to_utimestamp(t), 'joe', '::1', 'Bla bla', 'Testing', 0)) page = WikiPage(self.env, 'TestPage') page.text = 'Bla' page.save('kate', 'Changing', '192.168.0.101', t2) self.assertEqual(2, page.version) self.assertIsNone(page.resource.version) self.assertEqual(0, page.readonly) self.assertEqual('kate', page.author) self.assertEqual('Changing', page.comment) self.assertEqual(t2, page.time) with self.env.db_query as db: rows = db( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s ORDER BY version """, ('TestPage', )) self.assertEqual(2, len(rows)) self.assertEqual( (1, to_utimestamp(t), 'joe', '::1', 'Bla bla', 'Testing', 0), rows[0]) self.assertEqual((2, to_utimestamp(t2), 'kate', '192.168.0.101', 'Bla', 'Changing', 0), rows[1]) listener = TestLegacyWikiChangeListener(self.env) self.assertEqual((page, 2, t2, 'Changing', 'kate', '192.168.0.101'), listener.changed[0]) listener = TestWikiChangeListener(self.env) self.assertEqual((page, 2, t2, 'Changing', 'kate'), listener.changed[0]) page = WikiPage(self.env, 'TestPage') history = list(page.get_history()) self.assertEqual(2, len(history)) self.assertEqual((2, t2, 'kate', 'Changing', '192.168.0.101'), history[0]) self.assertEqual((1, t, 'joe', 'Testing', '::1'), history[1]) def test_delete_page(self): self.env.db_transaction( "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", ('TestPage', 1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0)) page = WikiPage(self.env, 'TestPage') page.delete() self.assertFalse(page.exists) self.assertEqual([], self.env.db_query( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s """, ('TestPage', ))) listener = TestWikiChangeListener(self.env) self.assertEqual(page, listener.deleted[0]) def test_delete_page_version(self): self.env.db_transaction.executemany( "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", [('TestPage', 1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0), ('TestPage', 2, 43, 'kate', '192.168.0.11', 'Bla', 'Changing', 0) ]) page = WikiPage(self.env, 'TestPage') page.delete(version=2) self.assertTrue(page.exists) self.assertEqual([(1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0)], self.env.db_query( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s """, ('TestPage', ))) listener = TestWikiChangeListener(self.env) self.assertEqual(page, listener.deleted_version[0]) def test_delete_page_last_version(self): self.env.db_transaction( "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", ('TestPage', 1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0)) page = WikiPage(self.env, 'TestPage') page.delete(version=1) self.assertFalse(page.exists) self.assertEqual([], self.env.db_query( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s """, ('TestPage', ))) listener = TestWikiChangeListener(self.env) self.assertEqual(page, listener.deleted[0]) def test_rename_page(self): data = (1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0) self.env.db_transaction( "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", ('TestPage', ) + data) attachment = Attachment(self.env, 'wiki', 'TestPage') attachment.insert('foo.txt', StringIO(), 0, 1) page = WikiPage(self.env, 'TestPage') page.rename('PageRenamed') self.assertEqual('PageRenamed', page.name) self.assertEqual('PageRenamed', page.resource.id) self.assertEqual([data], self.env.db_query( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s """, ('PageRenamed', ))) attachments = Attachment.select(self.env, 'wiki', 'PageRenamed') self.assertEqual('foo.txt', attachments.next().filename) self.assertRaises(StopIteration, attachments.next) Attachment.delete_all(self.env, 'wiki', 'PageRenamed') old_page = WikiPage(self.env, 'TestPage') self.assertFalse(old_page.exists) self.assertEqual([], self.env.db_query( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s """, ('TestPage', ))) listener = TestWikiChangeListener(self.env) self.assertEqual((page, 'TestPage'), listener.renamed[0]) def test_edit_comment_of_page_version(self): self.env.db_transaction.executemany( "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", [('TestPage', 1, 42, 'joe', '::1', 'Bla bla', 'old 1', 0), ('TestPage', 2, 43, 'kate', '::11', 'Bla', 'old 2', 0)]) page = WikiPage(self.env, 'TestPage') page.edit_comment('edited comment two') old_page = WikiPage(self.env, 'TestPage', 1) old_page.edit_comment('new comment one') self.assertEqual('edited comment two', page.comment) self.assertEqual('new comment one', old_page.comment) self.assertEqual( [(1, 42, 'joe', '::1', 'Bla bla', 'new comment one', 0), (2, 43, 'kate', '::11', 'Bla', 'edited comment two', 0)], self.env.db_query( """ SELECT version, time, author, ipnr, text, comment, readonly FROM wiki WHERE name=%s ORDER BY version """, ('TestPage', ))) listener = TestWikiChangeListener(self.env) self.assertEqual((page, 'old 2'), listener.comment_modified[0]) self.assertEqual((old_page, 'old 1'), listener.comment_modified[1]) def test_invalid_page_name(self): invalid_names = ('../Page', 'Page/..', 'Page/////SubPage', 'Page/./SubPage', '/PagePrefix', 'PageSuffix/') for name in invalid_names: page = WikiPage(self.env) page.name = name page.text = 'Bla bla' t = datetime(2001, 1, 1, 1, 1, 1, 0, utc) self.assertRaises(TracError, page.save, 'joe', 'Testing', '::1', t) page = WikiPage(self.env) page.name = 'TestPage' page.text = 'Bla bla' t = datetime(2001, 1, 1, 1, 1, 1, 0, utc) page.save('joe', 'Testing', '::1', t) for name in invalid_names: page = WikiPage(self.env, 'TestPage') self.assertRaises(TracError, page.rename, name) def test_invalid_version(self): data = [(1, 42, 'joe', '::1', 'First revision', 'Rev1', 0), (2, 42, 'joe', '::1', 'Second revision', 'Rev2', 0)] with self.env.db_transaction as db: for d in data: db("INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", ('TestPage', ) + d) page = WikiPage(self.env, 'TestPage', '1abc') self.assertEqual(2, page.version) resource = Resource('wiki', 'TestPage') page = WikiPage(self.env, resource, '1abc') self.assertEqual(2, page.version) resource = Resource('wiki', 'TestPage', '1abc') page = WikiPage(self.env, resource) self.assertEqual(2, page.version) resource = Resource('wiki', 'TestPage', 1) page = WikiPage(self.env, resource) self.assertEqual(1, page.version) resource = Resource('wiki', 'TestPage', 2) page = WikiPage(self.env, resource, 1) self.assertEqual(1, page.version)
def _destroy_db(self): EnvironmentStub(path=self.path).destroy_db()
def setUp(self): self.env = EnvironmentStub(enable=('trac.web.chrome.*', ))
class EnvironmentUpgradeTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() def tearDown(self): self.env.reset_db() def test_multiple_upgrade_participants(self): class Participant1(Component): implements(IEnvironmentSetupParticipant) def environment_created(self): pass def environment_needs_upgrade(self): return True def upgrade_environment(self): insert_value('value1', 1) class Participant2(Component): implements(IEnvironmentSetupParticipant) def environment_created(self): pass def environment_needs_upgrade(self): return True def upgrade_environment(self): insert_value('value2', 2) def insert_value(name, value): with self.env.db_transaction as db: db( """ INSERT INTO {0} (name, value) VALUES (%s, %s) """.format(db.quote('system')), (name, value)) def select_value(name): with self.env.db_query as db: for value, in db( """ SELECT value FROM {0} WHERE name=%s """.format(db.quote('system')), (name, )): return value self.env.enable_component(Participant1) self.env.enable_component(Participant2) self.assertTrue(self.env.needs_upgrade()) self.assertTrue(self.env.upgrade()) self.assertEqual('1', select_value('value1')) self.assertEqual('2', select_value('value2')) def test_upgrade_environment(self): """EnvironmentSetupParticipants are called only if environment_needs_upgrade returns True for the participant. """ class SetupParticipantA(Component): implements(IEnvironmentSetupParticipant) called = False def environment_created(self): pass def environment_needs_upgrade(self): return True def upgrade_environment(self): self.called = True class SetupParticipantB(Component): implements(IEnvironmentSetupParticipant) called = False def environment_created(self): pass def environment_needs_upgrade(self): return False def upgrade_environment(self): self.called = True self.env.enable_component(SetupParticipantA) self.env.enable_component(SetupParticipantB) participant_a = SetupParticipantA(self.env) participant_b = SetupParticipantB(self.env) self.assertTrue(self.env.needs_upgrade()) self.env.upgrade() self.assertTrue(participant_a.called) self.assertFalse(participant_b.called)
def setUp(self): self.env = EnvironmentStub() self.env.config.set('trac', 'base_url', 'https://trac.edgewall.org/some/path')
class TagSystemTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) self.env.path = tempfile.mkdtemp() self.perms = PermissionSystem(self.env) self.req = Mock() self.actions = ['TAGS_ADMIN', 'TAGS_MODIFY', 'TAGS_VIEW'] self.tag_s = TagSystem(self.env) self.db = self.env.get_db_cnx() setup = TagSetup(self.env) # Current tractags schema is setup with enabled component anyway. # Revert these changes for getting default permissions inserted. self._revert_tractags_schema_init() setup.upgrade_environment(self.db) def tearDown(self): self.db.close() # Really close db connections. self.env.shutdown() shutil.rmtree(self.env.path) # Helpers def _revert_tractags_schema_init(self): cursor = self.db.cursor() cursor.execute("DROP TABLE IF EXISTS tags") cursor.execute("DELETE FROM system WHERE name='tags_version'") cursor.execute( "DELETE FROM permission WHERE action %s" % self.db.like(), ('TAGS_%', )) # Tests def test_available_actions(self): for action in self.actions: self.failIf(action not in self.perms.get_actions()) def test_available_providers(self): # Standard implementations of DefaultTagProvider should be registered. seen = [] for provider in [ TicketTagProvider(self.env), WikiTagProvider(self.env) ]: self.failIf(provider not in self.tag_s.tag_providers) # Ensure unique provider references, a possible bug in Trac-0.11. self.failIf(provider in seen) seen.append(provider) def test_set_tags_no_perms(self): resource = Resource('wiki', 'WikiStart') tags = ['tag1'] # Mock an anonymous request. self.req.perm = PermissionCache(self.env) self.assertRaises(PermissionError, self.tag_s.set_tags, self.req, resource, tags) def test_set_tags(self): resource = Resource('wiki', 'WikiStart') tags = ['tag1'] self.req.perm = PermissionCache(self.env, username='******') # Shouldn't raise an error with appropriate permission. self.tag_s.set_tags(self.req, resource, tags) def test_query_no_args(self): # Regression test for query without argument, # reported as th:ticket:7857. # Mock an anonymous request. self.req.perm = PermissionCache(self.env) self.assertEquals( [(res, tags) for res, tags in self.tag_s.query(self.req, query='')], [])
def setUp(self): self.basedir = os.path.realpath(tempfile.mkdtemp()) self.env = EnvironmentStub() self.env.path = os.path.join(self.basedir, 'trac-tempenv') os.mkdir(self.env.path)
def setUp(self): self.env = EnvironmentStub()
def setUp(self): self.env = EnvironmentStub() self.env.path = tempfile.mkdtemp(prefix='trac-tempenv-')
class KnownUsersTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() users = [ ('123', None, '*****@*****.**', 0), ('jane', 'Jane', None, 1), ('joe', None, '*****@*****.**', 1), ('tom', 'Tom', '*****@*****.**', 1) ] self.env.insert_users(users) self.expected = [user[:3] for user in users if user[3] == 1] def tearDown(self): self.env.reset_db() def test_get_known_users_as_list_of_tuples(self): users = list(self.env.get_known_users()) i = 0 for i, user in enumerate(users): self.assertEqual(self.expected[i], user) else: self.assertEqual(2, i) def test_get_known_users_as_dict(self): users = self.env.get_known_users(as_dict=True) self.assertEqual(3, len(users)) for exp in self.expected: self.assertEqual(exp[1:], users[exp[0]]) def test_get_known_users_is_cached(self): self.env.get_known_users() self.env.get_known_users(as_dict=True) self.env.insert_users([('user4', None, None)]) users_list = list(self.env.get_known_users()) users_dict = self.env.get_known_users(as_dict=True) i = 0 for i, user in enumerate(users_list): self.assertEqual(self.expected[i], user) self.assertIn(self.expected[i][0], users_dict) else: self.assertEqual(2, i) self.assertEqual(3, len(users_dict)) def test_invalidate_known_users_cache(self): self.env.get_known_users() self.env.get_known_users(as_dict=True) user = ('user4', 'User Four', '*****@*****.**') self.env.insert_users([user]) self.expected.append(user[:3]) self.env.invalidate_known_users_cache() users_list = self.env.get_known_users() users_dict = self.env.get_known_users(as_dict=True) i = 0 for i, user in enumerate(users_list): self.assertEqual(self.expected[i], user) self.assertIn(self.expected[i][0], users_dict) else: self.assertEqual(3, i) self.assertEqual(4, len(users_dict))
class CommitTicketUpdaterTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub( enable=['trac.*', 'tracopt.ticket.commit_updater.*']) self.env.config.set('ticket', 'commit_ticket_update_check_perms', False) self.repos = Mock(Repository, 'repos1', { 'name': 'repos1', 'id': 1 }, self.env.log, normalize_rev=lambda rev: 1) self.updater = CommitTicketUpdater(self.env) def tearDown(self): self.env.reset_db() def _make_tickets(self, num): self.tickets = [] for i in xrange(num): ticket = insert_ticket(self.env, reporter='someone', summary=random_sentence()) self.tickets.append(ticket) def test_changeset_added(self): self._make_tickets(1) message = 'This is the first comment. Refs #1.' chgset = Mock(repos=self.repos, rev=1, message=message, author='joe', date=datetime(2001, 1, 1, 1, 1, 1, 0, utc)) self.updater.changeset_added(self.repos, chgset) changes = self.tickets[0].get_change(cnum=1) self.assertEqual( textwrap.dedent("""\ In [changeset:"1/repos1" 1/repos1]: {{{ #!CommitTicketReference repository="repos1" revision="1" This is the first comment. Refs #1. }}}"""), changes['fields']['comment']['new']) def test_changeset_modified(self): self._make_tickets(2) message = 'This is the first comment. Refs #1.' old_chgset = Mock(repos=self.repos, rev=1, message=message, author='joe', date=datetime(2001, 1, 1, 1, 1, 1, 0, utc)) message = 'This is the first comment after an edit. Refs #1, #2.' new_chgset = Mock(repos=self.repos, rev=1, message=message, author='joe', date=datetime(2001, 1, 2, 1, 1, 1, 0, utc)) self.updater.changeset_added(self.repos, old_chgset) self.updater.changeset_modified(self.repos, new_chgset, old_chgset) changes = self.tickets[0].get_change(cnum=1) self.assertEqual( textwrap.dedent("""\ In [changeset:"1/repos1" 1/repos1]: {{{ #!CommitTicketReference repository="repos1" revision="1" This is the first comment. Refs #1. }}}"""), changes['fields']['comment']['new']) changes = self.tickets[1].get_change(cnum=1) self.assertEqual( textwrap.dedent("""\ In [changeset:"1/repos1" 1/repos1]: {{{ #!CommitTicketReference repository="repos1" revision="1" This is the first comment after an edit. Refs #1, #2. }}}"""), changes['fields']['comment']['new']) def test_commands_refs(self): commands = { (1, ): 'Refs #1', (2, ): 'refs #2', (3, ): 'refs ticket:3#comment:1', (4, 5): 'refs ticket:4#comment:description and ' 'ticket:5#comment:1' } self._make_tickets(5) rev = 0 for tkts, cmd in commands.items(): rev += 1 message = "This is the first comment. %s." % cmd chgset = Mock(repos=self.repos, rev=rev, message=message, author='joe', date=datetime(2001, 1, 1, 1, 1, 1, 0, utc)) self.updater.changeset_added(self.repos, chgset) comment = self.updater.make_ticket_comment(self.repos, chgset) for tkt in tkts: change = self.tickets[tkt - 1].get_change(cnum=1) self.assertEqual(comment, change['fields']['comment']['new'])
def setUp(self): self.env = EnvironmentStub(enable=self.navigation_contributors)
def setUp(self): tmpdir = mkdtemp() self.authz_file = os.path.join(tmpdir, 'trac-authz') create_file(self.authz_file, textwrap.dedent("""\ [groups] group1 = user group2 = @group1 cycle1 = @cycle2 cycle2 = @cycle3 cycle3 = @cycle1, user alias1 = &jekyll alias2 = @alias1 [aliases] jekyll = Mr Hyde # Read / write permissions [/readonly] user = r [/writeonly] user = w [/readwrite] user = rw [/empty] user = # Trailing slashes [/trailing_a] user = r [/trailing_b/] user = r # Sub-paths [/sub/path] user = r # Module usage [module:/module_a] user = r [other:/module_b] user = r [/module_c] user = r [module:/module_d] user = [/module_d] user = r # Wildcards [/wildcard] * = r # Special tokens [/special/anonymous] $anonymous = r [/special/authenticated] $authenticated = r # Groups [/groups_a] @group1 = r [/groups_b] @group2 = r [/cyclic] @cycle1 = r # Precedence [module:/precedence_a] user = [/precedence_a] user = r [/precedence_b] user = r [/precedence_b/sub] user = [/precedence_b/sub/test] user = r [/precedence_c] user = @group1 = r [/precedence_d] @group1 = r user = # Aliases [/aliases_a] &jekyll = r [/aliases_b] @alias2 = r # Scoped repository [scoped:/scope/dir1] joe = r [scoped:/scope/dir2] Jane = r # multiple entries [/multiple] $authenticated = r [/multiple/foo] joe = $authenticated = * = r [/multiple/bar] * = john = r Jane = r $anonymous = r [/multiple/baz] $anonymous = r * = Jane = r [module:/multiple/bar] joe = r john = # multiple entries with module and parent directory [/multiple/1] user = r @group1 = r $authenticated = r * = r [module:/multiple/1/user] user = [module:/multiple/1/group] @group1 = [module:/multiple/1/auth] $authenticated = [module:/multiple/1/star] * = [/multiple/2] user = @group1 = $authenticated = * = [module:/multiple/2/user] user = r [module:/multiple/2/group] @group1 = r [module:/multiple/2/auth] $authenticated = r [module:/multiple/2/star] * = r """)) self.env = EnvironmentStub(enable=[AuthzSourcePolicy], path=tmpdir) self.env.config.set('trac', 'permission_policies', 'AuthzSourcePolicy, DefaultPermissionPolicy') self.env.config.set('svn', 'authz_file', self.authz_file) # Monkey-subclass RepositoryManager to serve mock repositories rm = RepositoryManager(self.env) class TestRepositoryManager(rm.__class__): def get_real_repositories(self): return {Mock(reponame='module'), Mock(reponame='other'), Mock(reponame='scoped')} def get_repository(self, reponame): if reponame == 'scoped': def get_changeset(rev): if rev == 123: def get_changes(): yield ('/dir1/file',) elif rev == 456: def get_changes(): yield ('/dir2/file',) else: def get_changes(): return iter([]) return Mock(get_changes=get_changes) return Mock(scope='/scope', get_changeset=get_changeset) return Mock(scope='/') rm.__class__ = TestRepositoryManager
def setUp(self): self.env = EnvironmentStub(default_data=True) self.env.config.set('ldap', 'enable', 'true') self.env.config.set('ldap', 'basedn', 'dc=example,dc=org') self.env.config.set('ldap', 'host', 'xebian')
class AuthzSourcePolicyTestCase(unittest.TestCase): def setUp(self): tmpdir = mkdtemp() self.authz_file = os.path.join(tmpdir, 'trac-authz') create_file(self.authz_file, textwrap.dedent("""\ [groups] group1 = user group2 = @group1 cycle1 = @cycle2 cycle2 = @cycle3 cycle3 = @cycle1, user alias1 = &jekyll alias2 = @alias1 [aliases] jekyll = Mr Hyde # Read / write permissions [/readonly] user = r [/writeonly] user = w [/readwrite] user = rw [/empty] user = # Trailing slashes [/trailing_a] user = r [/trailing_b/] user = r # Sub-paths [/sub/path] user = r # Module usage [module:/module_a] user = r [other:/module_b] user = r [/module_c] user = r [module:/module_d] user = [/module_d] user = r # Wildcards [/wildcard] * = r # Special tokens [/special/anonymous] $anonymous = r [/special/authenticated] $authenticated = r # Groups [/groups_a] @group1 = r [/groups_b] @group2 = r [/cyclic] @cycle1 = r # Precedence [module:/precedence_a] user = [/precedence_a] user = r [/precedence_b] user = r [/precedence_b/sub] user = [/precedence_b/sub/test] user = r [/precedence_c] user = @group1 = r [/precedence_d] @group1 = r user = # Aliases [/aliases_a] &jekyll = r [/aliases_b] @alias2 = r # Scoped repository [scoped:/scope/dir1] joe = r [scoped:/scope/dir2] Jane = r # multiple entries [/multiple] $authenticated = r [/multiple/foo] joe = $authenticated = * = r [/multiple/bar] * = john = r Jane = r $anonymous = r [/multiple/baz] $anonymous = r * = Jane = r [module:/multiple/bar] joe = r john = # multiple entries with module and parent directory [/multiple/1] user = r @group1 = r $authenticated = r * = r [module:/multiple/1/user] user = [module:/multiple/1/group] @group1 = [module:/multiple/1/auth] $authenticated = [module:/multiple/1/star] * = [/multiple/2] user = @group1 = $authenticated = * = [module:/multiple/2/user] user = r [module:/multiple/2/group] @group1 = r [module:/multiple/2/auth] $authenticated = r [module:/multiple/2/star] * = r """)) self.env = EnvironmentStub(enable=[AuthzSourcePolicy], path=tmpdir) self.env.config.set('trac', 'permission_policies', 'AuthzSourcePolicy, DefaultPermissionPolicy') self.env.config.set('svn', 'authz_file', self.authz_file) # Monkey-subclass RepositoryManager to serve mock repositories rm = RepositoryManager(self.env) class TestRepositoryManager(rm.__class__): def get_real_repositories(self): return {Mock(reponame='module'), Mock(reponame='other'), Mock(reponame='scoped')} def get_repository(self, reponame): if reponame == 'scoped': def get_changeset(rev): if rev == 123: def get_changes(): yield ('/dir1/file',) elif rev == 456: def get_changes(): yield ('/dir2/file',) else: def get_changes(): return iter([]) return Mock(get_changes=get_changes) return Mock(scope='/scope', get_changeset=get_changeset) return Mock(scope='/') rm.__class__ = TestRepositoryManager def tearDown(self): self.env.reset_db_and_disk() def test_get_authz_file_notfound_raises(self): """ConfigurationError exception is raised if file not found.""" authz_file = os.path.join(self.env.path, 'some-nonexistent-file') self.env.config.set('svn', 'authz_file', authz_file) policy = AuthzSourcePolicy(self.env) self.assertRaises(ConfigurationError, policy.check_permission, 'BROWSER_VIEW', 'user', None, None) def test_get_authz_file_notdefined_raises(self): """ConfigurationError exception is raised if the option `[svn] authz_file` is not specified in trac.ini.""" self.env.config.remove('svn', 'authz_file') policy = AuthzSourcePolicy(self.env) self.assertRaises(ConfigurationError, policy.check_permission, 'BROWSER_VIEW', 'user', None, None) def test_get_authz_file_empty_raises(self): """ConfigurationError exception is raised if the option `[svn] authz_file` is empty.""" self.env.config.set('svn', 'authz_file', '') policy = AuthzSourcePolicy(self.env) self.assertRaises(ConfigurationError, policy.check_permission, 'BROWSER_VIEW', 'user', None, None) def test_get_authz_file_removed_raises(self): """ConfigurationError exception is raised if file is removed.""" policy = AuthzSourcePolicy(self.env) os.remove(self.authz_file) self.assertRaises(ConfigurationError, policy.check_permission, 'BROWSER_VIEW', 'user', None, None) def test_parse_error_raises(self): """ConfigurationError exception is raised when exception occurs parsing the `[svn authz_file`.""" create_file(self.authz_file, textwrap.dedent("""\ [/somepath joe = r """)) policy = AuthzSourcePolicy(self.env) self.assertRaises(ConfigurationError, policy.check_permission, 'BROWSER_VIEW', 'user', None, None) def assertPathPerm(self, result, user, reponame=None, path=None): """Assert that `user` is granted access `result` to `path` within the repository `reponame`. """ policy = AuthzSourcePolicy(self.env) resource = None if reponame is not None: resource = Resource('source', path, parent=Resource('repository', reponame)) for perm in ('BROWSER_VIEW', 'FILE_VIEW', 'LOG_VIEW'): check = policy.check_permission(perm, user, resource, None) self.assertEqual(result, check) def assertRevPerm(self, result, user, reponame=None, rev=None): """Assert that `user` is granted access `result` to `rev` within the repository `reponame`. """ policy = AuthzSourcePolicy(self.env) resource = None if reponame is not None: resource = Resource('changeset', rev, parent=Resource('repository', reponame)) check = policy.check_permission('CHANGESET_VIEW', user, resource, None) self.assertEqual(result, check) def test_coarse_permissions(self): policy = AuthzSourcePolicy(self.env) # Granted to all due to wildcard self.assertPathPerm(True, 'unknown') self.assertPathPerm(True, 'joe') self.assertRevPerm(True, 'unknown') self.assertRevPerm(True, 'joe') # Granted if at least one fine permission is granted policy._mtime = 0 create_file(self.authz_file, textwrap.dedent("""\ [/somepath] joe = r denied = [module:/otherpath] Jane = r $anonymous = r [inactive:/not-in-this-instance] unknown = r """)) self.assertPathPerm(None, 'unknown') self.assertRevPerm(None, 'unknown') self.assertPathPerm(None, 'denied') self.assertRevPerm(None, 'denied') self.assertPathPerm(True, 'joe') self.assertRevPerm(True, 'joe') self.assertPathPerm(True, 'Jane') self.assertRevPerm(True, 'Jane') self.assertPathPerm(True, 'anonymous') self.assertRevPerm(True, 'anonymous') def test_default_permission(self): # By default, permissions are undecided self.assertPathPerm(None, 'joe', '', '/not_defined') self.assertPathPerm(None, 'Jane', 'repo', '/not/defined/either') def test_read_write(self): # Allow 'r' and 'rw' entries, deny 'w' and empty entries self.assertPathPerm(True, 'user', '', '/readonly') self.assertPathPerm(True, 'user', '', '/readwrite') self.assertPathPerm(False, 'user', '', '/writeonly') self.assertPathPerm(False, 'user', '', '/empty') def test_trailing_slashes(self): # Combinations of trailing slashes in the file and in the path self.assertPathPerm(True, 'user', '', '/trailing_a') self.assertPathPerm(True, 'user', '', '/trailing_a/') self.assertPathPerm(True, 'user', '', '/trailing_b') self.assertPathPerm(True, 'user', '', '/trailing_b/') def test_sub_path(self): # Permissions are inherited from containing directories self.assertPathPerm(True, 'user', '', '/sub/path') self.assertPathPerm(True, 'user', '', '/sub/path/test') self.assertPathPerm(True, 'user', '', '/sub/path/other/sub') def test_module_usage(self): # If a module name is specified, the rules are specific to the module self.assertPathPerm(True, 'user', 'module', '/module_a') self.assertPathPerm(None, 'user', 'module', '/module_b') # If a module is specified, but the configuration contains a non-module # path, the non-module path can still apply self.assertPathPerm(True, 'user', 'module', '/module_c') # The module-specific rule takes precedence self.assertPathPerm(True, 'user', '', '/module_d') self.assertPathPerm(False, 'user', 'module', '/module_d') def test_wildcard(self): # The * wildcard matches all users, including anonymous self.assertPathPerm(True, 'anonymous', '', '/wildcard') self.assertPathPerm(True, 'joe', '', '/wildcard') self.assertPathPerm(True, 'Jane', '', '/wildcard') def test_special_tokens(self): # The $anonymous token matches only anonymous users self.assertPathPerm(True, 'anonymous', '', '/special/anonymous') self.assertPathPerm(None, 'user', '', '/special/anonymous') # The $authenticated token matches all authenticated users self.assertPathPerm(None, 'anonymous', '', '/special/authenticated') self.assertPathPerm(True, 'joe', '', '/special/authenticated') self.assertPathPerm(True, 'Jane', '', '/special/authenticated') def test_groups(self): # Groups are specified in a separate section and used with an @ prefix self.assertPathPerm(True, 'user', '', '/groups_a') # Groups can also be members of other groups self.assertPathPerm(True, 'user', '', '/groups_b') # Groups should not be defined cyclically, but they are still handled # correctly to avoid infinite loops self.assertPathPerm(True, 'user', '', '/cyclic') def test_precedence(self): # Module-specific sections take precedence over non-module sections self.assertPathPerm(False, 'user', 'module', '/precedence_a') # The most specific section applies self.assertPathPerm(True, 'user', '', '/precedence_b/sub/test') # ... intentional deviation from SVN's rules as we need to # make '/precedence_b/sub' browseable so that the user can see # '/precedence_b/sub/test': self.assertPathPerm(True, 'user', '', '/precedence_b/sub') self.assertPathPerm(True, 'user', '', '/precedence_b') # Ordering isn't significant; any entry could grant permission self.assertPathPerm(True, 'user', '', '/precedence_c') self.assertPathPerm(True, 'user', '', '/precedence_d') def test_aliases(self): # Aliases are specified in a separate section and used with an & prefix self.assertPathPerm(True, 'Mr Hyde', '', '/aliases_a') # Aliases can also be used in groups self.assertPathPerm(True, 'Mr Hyde', '', '/aliases_b') def test_scoped_repository(self): # Take repository scope into account self.assertPathPerm(True, 'joe', 'scoped', '/dir1') self.assertPathPerm(None, 'joe', 'scoped', '/dir2') self.assertPathPerm(True, 'joe', 'scoped', '/') self.assertPathPerm(None, 'Jane', 'scoped', '/dir1') self.assertPathPerm(True, 'Jane', 'scoped', '/dir2') self.assertPathPerm(True, 'Jane', 'scoped', '/') def test_multiple_entries(self): self.assertPathPerm(True, 'anonymous', '', '/multiple/foo') self.assertPathPerm(True, 'joe', '', '/multiple/foo') self.assertPathPerm(True, 'anonymous', '', '/multiple/bar') self.assertPathPerm(False, 'joe', '', '/multiple/bar') self.assertPathPerm(True, 'john', '', '/multiple/bar') self.assertPathPerm(True, 'anonymous', '', '/multiple/baz') self.assertPathPerm(True, 'Jane', '', '/multiple/baz') self.assertPathPerm(False, 'joe', '', '/multiple/baz') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/foo') self.assertPathPerm(True, 'joe', 'module', '/multiple/foo') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/bar') self.assertPathPerm(True, 'joe', 'module', '/multiple/bar') self.assertPathPerm(False, 'john', 'module', '/multiple/bar') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/baz') self.assertPathPerm(True, 'Jane', 'module', '/multiple/baz') self.assertPathPerm(False, 'joe', 'module', '/multiple/baz') def test_multiple_entries_with_module_and_parent_directory(self): self.assertPathPerm(True, 'anonymous', '', '/multiple/1') self.assertPathPerm(True, 'user', '', '/multiple/1') self.assertPathPerm(True, 'someone', '', '/multiple/1') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/1') self.assertPathPerm(True, 'user', 'module', '/multiple/1') self.assertPathPerm(True, 'someone', 'module', '/multiple/1') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/1/user') self.assertPathPerm(False, 'user', 'module', '/multiple/1/user') self.assertPathPerm(True, 'someone', 'module', '/multiple/1/user') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/1/group') self.assertPathPerm(False, 'user', 'module', '/multiple/1/group') self.assertPathPerm(True, 'someone', 'module', '/multiple/1/group') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/1/auth') self.assertPathPerm(False, 'user', 'module', '/multiple/1/auth') self.assertPathPerm(False, 'someone', 'module', '/multiple/1/auth') self.assertPathPerm(False, 'anonymous', 'module', '/multiple/1/star') self.assertPathPerm(False, 'user', 'module', '/multiple/1/star') self.assertPathPerm(False, 'someone', 'module', '/multiple/1/star') self.assertPathPerm(False, 'anonymous', '', '/multiple/2') self.assertPathPerm(False, 'user', '', '/multiple/2') self.assertPathPerm(False, 'someone', '', '/multiple/2') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/2') self.assertPathPerm(True, 'user', 'module', '/multiple/2') self.assertPathPerm(True, 'someone', 'module', '/multiple/2') self.assertPathPerm(False, 'anonymous', 'module', '/multiple/2/user') self.assertPathPerm(True, 'user', 'module', '/multiple/2/user') self.assertPathPerm(False, 'someone', 'module', '/multiple/2/user') self.assertPathPerm(False, 'anonymous', 'module', '/multiple/2/group') self.assertPathPerm(True, 'user', 'module', '/multiple/2/group') self.assertPathPerm(False, 'someone', 'module', '/multiple/2/group') self.assertPathPerm(False, 'anonymous', 'module', '/multiple/2/auth') self.assertPathPerm(True, 'user', 'module', '/multiple/2/auth') self.assertPathPerm(True, 'someone', 'module', '/multiple/2/auth') self.assertPathPerm(True, 'anonymous', 'module', '/multiple/2/star') self.assertPathPerm(True, 'user', 'module', '/multiple/2/star') self.assertPathPerm(True, 'someone', 'module', '/multiple/2/star') def test_changesets(self): # Changesets are allowed if at least one changed path is allowed, or # if the changeset is empty self.assertRevPerm(True, 'joe', 'scoped', 123) self.assertRevPerm(None, 'joe', 'scoped', 456) self.assertRevPerm(True, 'joe', 'scoped', 789) self.assertRevPerm(None, 'Jane', 'scoped', 123) self.assertRevPerm(True, 'Jane', 'scoped', 456) self.assertRevPerm(True, 'Jane', 'scoped', 789) self.assertRevPerm(None, 'user', 'scoped', 123) self.assertRevPerm(None, 'user', 'scoped', 456) self.assertRevPerm(True, 'user', 'scoped', 789)
def setUp(self): self.env = EnvironmentStub(default_data=True) self.env.path = os.path.join(tempfile.gettempdir(), 'trac-tempenv') os.mkdir(self.env.path)
class NormalTestCase(unittest.TestCase, GitCommandMixin): def setUp(self): self.env = EnvironmentStub() self.repos_path = mkdtemp() # create git repository and master branch self._git('init') self._git('config', 'core.quotepath', 'true') # ticket:11198 self._git('config', 'user.name', "Joe") self._git('config', 'user.email', "*****@*****.**") create_file(os.path.join(self.repos_path, '.gitignore')) self._git('add', '.gitignore') self._git_commit('-a', '-m', 'test', date=datetime(2013, 1, 1, 9, 4, 56)) def tearDown(self): RepositoryManager(self.env).reload_repositories() StorageFactory._clean() self.env.reset_db() if os.path.isdir(self.repos_path): rmtree(self.repos_path) def _factory(self, weak, path=None): if path is None: path = os.path.join(self.repos_path, '.git') return StorageFactory(path, self.env.log, weak) def _storage(self, path=None): if path is None: path = os.path.join(self.repos_path, '.git') return Storage(path, self.env.log, self.git_bin, 'utf-8') def test_control_files_detection(self): # Exception not raised when path points to ctrl file dir self.assertIsInstance(self._storage().repo, GitCore) # Exception not raised when path points to parent of ctrl files dir self.assertIsInstance(self._storage(self.repos_path).repo, GitCore) # Exception raised when path points to dir with no ctrl files path = tempfile.mkdtemp(dir=self.repos_path) self.assertRaises(GitError, self._storage, path) # Exception raised if a ctrl file is missing os.remove(os.path.join(self.repos_path, '.git', 'HEAD')) self.assertRaises(GitError, self._storage, self.repos_path) def test_get_branches_with_cr_in_commitlog(self): # regression test for #11598 message = 'message with carriage return'.replace(' ', '\r') create_file(os.path.join(self.repos_path, 'ticket11598.txt')) self._git('add', 'ticket11598.txt') self._git_commit('-m', message, date=datetime(2013, 5, 9, 11, 5, 21)) storage = self._storage() branches = sorted(storage.get_branches()) self.assertEqual('master', branches[0][0]) self.assertEqual(1, len(branches)) if os.name == 'nt': del test_get_branches_with_cr_in_commitlog def test_rev_is_anchestor_of(self): # regression test for #11215 path = os.path.join(self.repos_path, '.git') DbRepositoryProvider(self.env).add_repository('gitrepos', path, 'git') repos = RepositoryManager(self.env).get_repository('gitrepos') parent_rev = repos.youngest_rev create_file(os.path.join(self.repos_path, 'ticket11215.txt')) self._git('add', 'ticket11215.txt') self._git_commit('-m', 'ticket11215', date=datetime(2013, 6, 27, 18, 26, 2)) repos.sync() rev = repos.youngest_rev self.assertNotEqual(rev, parent_rev) self.assertFalse(repos.rev_older_than(None, None)) self.assertFalse(repos.rev_older_than(None, rev[:7])) self.assertFalse(repos.rev_older_than(rev[:7], None)) self.assertTrue(repos.rev_older_than(parent_rev, rev)) self.assertTrue(repos.rev_older_than(parent_rev[:7], rev[:7])) self.assertFalse(repos.rev_older_than(rev, parent_rev)) self.assertFalse(repos.rev_older_than(rev[:7], parent_rev[:7])) def test_node_get_history_with_empty_commit(self): # regression test for #11328 path = os.path.join(self.repos_path, '.git') DbRepositoryProvider(self.env).add_repository('gitrepos', path, 'git') repos = RepositoryManager(self.env).get_repository('gitrepos') parent_rev = repos.youngest_rev self._git_commit('-m', 'ticket:11328', '--allow-empty', date=datetime(2013, 10, 15, 9, 46, 27)) repos.sync() rev = repos.youngest_rev node = repos.get_node('', rev) self.assertEqual(rev, repos.git.last_change(rev, '')) history = list(node.get_history()) self.assertEqual(u'', history[0][0]) self.assertEqual(rev, history[0][1]) self.assertEqual(Changeset.EDIT, history[0][2]) self.assertEqual(u'', history[1][0]) self.assertEqual(parent_rev, history[1][1]) self.assertEqual(Changeset.ADD, history[1][2]) self.assertEqual(2, len(history)) def test_sync_after_removing_branch(self): self._git('checkout', '-b', 'b1', 'master') self._git('checkout', 'master') create_file(os.path.join(self.repos_path, 'newfile.txt')) self._git('add', 'newfile.txt') self._git_commit('-m', 'added newfile.txt to master', date=datetime(2013, 12, 23, 6, 52, 23)) storage = self._storage() storage.sync() self.assertEqual(['b1', 'master'], sorted(b[0] for b in storage.get_branches())) self._git('branch', '-D', 'b1') self.assertTrue(storage.sync()) self.assertEqual(['master'], sorted(b[0] for b in storage.get_branches())) self.assertFalse(storage.sync()) def test_turn_off_persistent_cache(self): # persistent_cache is enabled parent_rev = self._factory(False).getInstance().youngest_rev() create_file(os.path.join(self.repos_path, 'newfile.txt')) self._git('add', 'newfile.txt') self._git_commit('-m', 'test_turn_off_persistent_cache', date=datetime(2014, 1, 29, 13, 13, 25)) # persistent_cache is disabled rev = self._factory(True).getInstance().youngest_rev() self.assertNotEqual(rev, parent_rev)
def setUp(self): self.env = EnvironmentStub(enable=self.navigation_contributors + ['trac.perm.*']) self.env.config.set('trac', 'permission_policies', 'DefaultPermissionPolicy')
def setUp(self): self.env = EnvironmentStub(path=mkdtemp()) self.env.config.filename = os.path.join(self.env.path, 'trac.ini')
def setUp(self): self.env = EnvironmentStub() self.log = self.env.log self.env.db_transaction.executemany( "INSERT INTO repository (id, name, value) VALUES (%s, %s, %s)", [(1, 'name', 'test-repos'), (1, 'youngest_rev', '')])
def setUp(self): self.env = EnvironmentStub(default_data=True)
class CacheTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.log = self.env.log self.env.db_transaction.executemany( "INSERT INTO repository (id, name, value) VALUES (%s, %s, %s)", [(1, 'name', 'test-repos'), (1, 'youngest_rev', '')]) def tearDown(self): self.env.reset_db() # Helpers def get_repos(self, get_changeset=None, youngest_rev=1): if get_changeset is None: def no_changeset(rev): raise NoSuchChangeset(rev) get_changeset = no_changeset return Mock( Repository, 'test-repos', { 'name': 'test-repos', 'id': 1 }, self.log, get_changeset=get_changeset, get_oldest_rev=lambda: 0, get_youngest_rev=lambda: youngest_rev, normalize_rev=lambda x: get_changeset(x).rev, next_rev=(lambda x: int(x) < youngest_rev and x + 1 or None)) def preset_cache(self, *args): """Each arg is a (rev tuple, changes list of tuples) pair.""" with self.env.db_transaction as db: for rev, changes in args: db( """INSERT INTO revision (repos, rev, time, author, message) VALUES (1,%s,%s,%s,%s) """, rev) if changes: db.executemany( """ INSERT INTO node_change (repos, rev, path, node_type, change_type, base_path, base_rev) VALUES (1, %s, %s, %s, %s, %s, %s) """, [(rev[0], ) + change for change in changes]) db( """UPDATE repository SET value=%s WHERE id=1 AND name='youngest_rev' """, (args[-1][0][0], )) # Tests def test_repr(self): repos = self.get_repos() cache = CachedRepository(self.env, repos, self.log) self.assertEqual("<CachedRepository 1 'test-repos' '/'>", repr(cache)) def test_initial_sync_with_empty_repos(self): repos = self.get_repos() cache = CachedRepository(self.env, repos, self.log) cache.sync() with self.env.db_query as db: self.assertEqual( [], db("SELECT rev, time, author, message FROM revision")) self.assertEqual(0, db("SELECT COUNT(*) FROM node_change")[0][0]) def test_initial_sync(self): t1 = datetime(2001, 1, 1, 1, 1, 1, 0, utc) t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc) repos = self.get_repos(get_changeset=lambda x: changesets[int(x)], youngest_rev=1) changes = [('trunk', Node.DIRECTORY, Changeset.ADD, None, None), ('trunk/README', Node.FILE, Changeset.ADD, None, None)] changesets = [ Mock(Changeset, repos, 0, '', '', t1, get_changes=lambda: []), Mock(Changeset, repos, 1, 'Import', 'joe', t2, get_changes=lambda: iter(changes)) ] cache = CachedRepository(self.env, repos, self.log) cache.sync() with self.env.db_query as db: rows = db("SELECT rev, time, author, message FROM revision") self.assertEqual(len(rows), 2) self.assertEqual(('0', to_utimestamp(t1), '', ''), rows[0]) self.assertEqual(('1', to_utimestamp(t2), 'joe', 'Import'), rows[1]) rows = db(""" SELECT rev, path, node_type, change_type, base_path, base_rev FROM node_change""") self.assertEqual(len(rows), 2) self.assertEqual(('1', 'trunk', 'D', 'A', None, None), rows[0]) self.assertEqual(('1', 'trunk/README', 'F', 'A', None, None), rows[1]) def test_update_sync(self): t1 = datetime(2001, 1, 1, 1, 1, 1, 0, utc) t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc) t3 = datetime(2003, 1, 1, 1, 1, 1, 0, utc) self.preset_cache( (('0', to_utimestamp(t1), '', ''), []), (('1', to_utimestamp(t2), 'joe', 'Import'), [ ('trunk', 'D', 'A', None, None), ('trunk/README', 'F', 'A', None, None) ]), ) repos = self.get_repos(get_changeset=lambda x: changesets[int(x)], youngest_rev=2) changes = [('trunk/README', Node.FILE, Changeset.EDIT, 'trunk/README', 1)] changesets = [ None, Mock(Changeset, repos, 1, '', '', t2, get_changes=lambda: []), Mock(Changeset, repos, 2, 'Update', 'joe', t3, get_changes=lambda: iter(changes)) ] cache = CachedRepository(self.env, repos, self.log) cache.sync() with self.env.db_query as db: self.assertEqual( [(to_utimestamp(t3), 'joe', 'Update')], db("SELECT time, author, message FROM revision WHERE rev='2'")) self.assertEqual( [('trunk/README', 'F', 'E', 'trunk/README', '1')], db("""SELECT path, node_type, change_type, base_path, base_rev FROM node_change WHERE rev='2'""")) def test_clean_sync(self): t1 = datetime(2001, 1, 1, 1, 1, 1, 0, utc) t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc) t3 = datetime(2003, 1, 1, 1, 1, 1, 0, utc) self.preset_cache( (('0', to_utimestamp(t1), '', ''), []), (('1', to_utimestamp(t2), 'joe', 'Import'), [ ('trunk', 'D', 'A', None, None), ('trunk/README', 'F', 'A', None, None) ]), ) repos = self.get_repos(get_changeset=lambda x: changesets[int(x)], youngest_rev=2) changes1 = [('trunk', Node.DIRECTORY, Changeset.ADD, None, None), ('trunk/README', Node.FILE, Changeset.ADD, None, None)] changes2 = [('trunk/README', Node.FILE, Changeset.EDIT, 'trunk/README', 1)] changesets = [ Mock(Changeset, repos, 0, '**empty**', 'joe', t1, get_changes=lambda: []), Mock(Changeset, repos, 1, 'Initial Import', 'joe', t2, get_changes=lambda: iter(changes1)), Mock(Changeset, repos, 2, 'Update', 'joe', t3, get_changes=lambda: iter(changes2)) ] cache = CachedRepository(self.env, repos, self.log) cache.sync(clean=True) rows = self.env.db_query(""" SELECT time, author, message FROM revision ORDER BY rev """) self.assertEqual(3, len(rows)) self.assertEqual((to_utimestamp(t1), 'joe', '**empty**'), rows[0]) self.assertEqual((to_utimestamp(t2), 'joe', 'Initial Import'), rows[1]) self.assertEqual((to_utimestamp(t3), 'joe', 'Update'), rows[2]) rows = self.env.db_query(""" SELECT rev, path, node_type, change_type, base_path, base_rev FROM node_change ORDER BY rev, path""") self.assertEqual(3, len(rows)) self.assertEqual(('1', 'trunk', 'D', 'A', None, None), rows[0]) self.assertEqual(('1', 'trunk/README', 'F', 'A', None, None), rows[1]) self.assertEqual(('2', 'trunk/README', 'F', 'E', 'trunk/README', '1'), rows[2]) def test_sync_changeset(self): t1 = datetime(2001, 1, 1, 1, 1, 1, 0, utc) t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc) self.preset_cache( (('0', to_utimestamp(t1), '', ''), []), (('1', to_utimestamp(t2), 'joe', 'Import'), [ ('trunk', 'D', 'A', None, None), ('trunk/README', 'F', 'A', None, None) ]), ) repos = self.get_repos(get_changeset=lambda x: changesets[int(x)], youngest_rev=1) changes1 = [('trunk', Node.DIRECTORY, Changeset.ADD, None, None), ('trunk/README', Node.FILE, Changeset.ADD, None, None)] changesets = [ Mock(Changeset, repos, 0, '**empty**', 'joe', t1, get_changes=lambda: []), Mock(Changeset, repos, 1, 'Initial Import', 'joe', t2, get_changes=lambda: iter(changes1)), ] cache = CachedRepository(self.env, repos, self.log) cache.sync_changeset(0) rows = self.env.db_query( "SELECT time, author, message FROM revision ORDER BY rev") self.assertEqual(2, len(rows)) self.assertEqual((to_utimestamp(t1), 'joe', '**empty**'), rows[0]) self.assertEqual((to_utimestamp(t2), 'joe', 'Import'), rows[1]) def test_sync_changeset_if_not_exists(self): t = [ datetime(2001, 1, 1, 1, 1, 1, 0, utc), # r0 datetime(2002, 1, 1, 1, 1, 1, 0, utc), # r1 datetime(2003, 1, 1, 1, 1, 1, 0, utc), # r2 datetime(2004, 1, 1, 1, 1, 1, 0, utc), # r3 ] self.preset_cache( (('0', to_utimestamp(t[0]), 'joe', '**empty**'), []), (('1', to_utimestamp(t[1]), 'joe', 'Import'), [ ('trunk', 'D', 'A', None, None), ('trunk/README', 'F', 'A', None, None) ]), # not exists r2 (('3', to_utimestamp(t[3]), 'joe', 'Add COPYING'), [ ('trunk/COPYING', 'F', 'A', None, None) ]), ) repos = self.get_repos(get_changeset=lambda x: changesets[int(x)], youngest_rev=3) changes = [ None, # r0 [ ('trunk', Node.DIRECTORY, Changeset.ADD, None, None), # r1 ('trunk/README', Node.FILE, Changeset.ADD, None, None) ], [ ('branches', Node.DIRECTORY, Changeset.ADD, None, None), # r2 ('tags', Node.DIRECTORY, Changeset.ADD, None, None) ], [('trunk/COPYING', Node.FILE, Changeset.ADD, None, None)], # r3 ] changesets = [ Mock(Changeset, repos, 0, '**empty**', 'joe', t[0], get_changes=lambda: []), Mock(Changeset, repos, 1, 'Initial Import', 'joe', t[1], get_changes=lambda: iter(changes[1])), Mock(Changeset, repos, 2, 'Created directories', 'john', t[2], get_changes=lambda: iter(changes[2])), Mock(Changeset, repos, 3, 'Add COPYING', 'joe', t[3], get_changes=lambda: iter(changes[3])), ] cache = CachedRepository(self.env, repos, self.log) self.assertRaises(NoSuchChangeset, cache.get_changeset, 2) cache.sync() self.assertRaises(NoSuchChangeset, cache.get_changeset, 2) self.assertIsNone(cache.sync_changeset(2)) cset = cache.get_changeset(2) self.assertEqual('john', cset.author) self.assertEqual('Created directories', cset.message) self.assertEqual(t[2], cset.date) cset_changes = cset.get_changes() self.assertEqual( ('branches', Node.DIRECTORY, Changeset.ADD, None, None), next(cset_changes)) self.assertEqual(('tags', Node.DIRECTORY, Changeset.ADD, None, None), next(cset_changes)) self.assertRaises(StopIteration, next, cset_changes) rows = self.env.db_query( "SELECT time,author,message FROM revision ORDER BY rev") self.assertEqual(4, len(rows)) self.assertEqual((to_utimestamp(t[0]), 'joe', '**empty**'), rows[0]) self.assertEqual((to_utimestamp(t[1]), 'joe', 'Import'), rows[1]) self.assertEqual((to_utimestamp(t[2]), 'john', 'Created directories'), rows[2]) self.assertEqual((to_utimestamp(t[3]), 'joe', 'Add COPYING'), rows[3]) def test_sync_changeset_with_string_rev(self): # ticket:11660 class MockCachedRepository(CachedRepository): def db_rev(self, rev): return '%010d' % rev t1 = datetime(2001, 1, 1, 1, 1, 1, 0, utc) t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc) repos = self.get_repos(get_changeset=lambda x: changesets[int(x)], youngest_rev=1) changesets = [ Mock(Changeset, repos, 0, 'empty', 'joe', t1, get_changes=lambda: []), Mock(Changeset, repos, 1, 'first', 'joe', t2, get_changes=lambda: []), ] cache = MockCachedRepository(self.env, repos, self.log) cache.sync_changeset('0') # not cached yet cache.sync_changeset(u'1') # not cached yet rows = self.env.db_query( "SELECT rev,author FROM revision ORDER BY rev") self.assertEqual(2, len(rows)) self.assertEqual(('0000000000', 'joe'), rows[0]) self.assertEqual(('0000000001', 'joe'), rows[1]) cache.sync_changeset(u'0') # cached cache.sync_changeset('1') # cached rows = self.env.db_query( "SELECT rev,author FROM revision ORDER BY rev") self.assertEqual(2, len(rows)) self.assertEqual(('0000000000', 'joe'), rows[0]) self.assertEqual(('0000000001', 'joe'), rows[1]) def test_get_changes(self): t1 = datetime(2001, 1, 1, 1, 1, 1, 0, utc) t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc) self.preset_cache( (('0', to_utimestamp(t1), '', ''), []), (('1', to_utimestamp(t2), 'joe', 'Import'), [ ('trunk', 'D', 'A', None, None), ('trunk/RDME', 'F', 'A', None, None) ]), ) repos = self.get_repos() cache = CachedRepository(self.env, repos, self.log) self.assertEqual('1', cache.youngest_rev) changeset = cache.get_changeset(1) self.assertEqual('joe', changeset.author) self.assertEqual('Import', changeset.message) self.assertEqual(t2, changeset.date) changes = changeset.get_changes() self.assertEqual(('trunk', Node.DIRECTORY, Changeset.ADD, None, None), next(changes)) self.assertEqual(('trunk/RDME', Node.FILE, Changeset.ADD, None, None), next(changes)) self.assertRaises(StopIteration, next, changes)
class FormatAuthorTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(enable=[ 'trac.web.chrome.*', 'trac.perm.*', 'tracopt.perm.authz_policy' ]) self.env.config.set('trac', 'permission_policies', 'AuthzPolicy, DefaultPermissionPolicy') fd, self.authz_file = tempfile.mkstemp() with os.fdopen(fd, 'w') as f: f.write( textwrap.dedent("""\ [wiki:WikiStart] user2 = EMAIL_VIEW [wiki:TracGuide] user2 = """)) PermissionSystem(self.env).grant_permission('user1', 'EMAIL_VIEW') self.env.config.set('authz_policy', 'authz_file', self.authz_file) def tearDown(self): os.remove(self.authz_file) def test_subject_is_anonymous(self): format_author = Chrome(self.env).format_author self.assertEqual('anonymous', format_author(None, 'anonymous')) def test_subject_is_none(self): format_author = Chrome(self.env).format_author self.assertEqual('(none)', format_author(None, None)) def test_actor_has_email_view(self): req = MockRequest(self.env, authname='user1') author = Chrome(self.env).format_author(req, '*****@*****.**') self.assertEqual('*****@*****.**', author) def test_actor_no_email_view(self): req = MockRequest(self.env, authname='user2') author = Chrome(self.env).format_author(req, '*****@*****.**') self.assertEqual(u'user@\u2026', author) def test_actor_no_email_view_show_email_addresses(self): self.env.config.set('trac', 'show_email_addresses', True) req = MockRequest(self.env, authname='user2') author = Chrome(self.env).format_author(req, '*****@*****.**') self.assertEqual('*****@*****.**', author) def test_actor_no_email_view_no_req(self): author = Chrome(self.env).format_author(None, '*****@*****.**') self.assertEqual(u'user@\u2026', author) def test_actor_has_email_view_for_resource(self): format_author = Chrome(self.env).format_author req = MockRequest(self.env, authname='user2') resource = Resource('wiki', 'WikiStart') author = format_author(req, '*****@*****.**', resource) self.assertEqual('*****@*****.**', author) def test_actor_has_email_view_for_resource_negative(self): format_author = Chrome(self.env).format_author req = MockRequest(self.env, authname='user2') resource = Resource('wiki', 'TracGuide') author = format_author(req, '*****@*****.**', resource) self.assertEqual(u'user@\u2026', author) def test_show_full_names_true(self): format_author = Chrome(self.env).format_author self.env.config.set('trac', 'show_full_names', True) self.env.insert_users([('user1', 'User One', '*****@*****.**'), ('user2', None, None)]) self.assertEqual('User One', format_author(None, 'user1')) self.assertEqual('user2', format_author(None, 'user2')) def test_show_full_names_false(self): format_author = Chrome(self.env).format_author self.env.config.set('trac', 'show_full_names', False) self.assertEqual('user1', format_author(None, 'user1')) self.assertEqual('user2', format_author(None, 'user2')) def test_show_email_true(self): format_author = Chrome(self.env).format_author req = MockRequest(self.env, authname='user2') author = format_author(None, '*****@*****.**', show_email=True) self.assertEqual('*****@*****.**', author) author = format_author(req, '*****@*****.**', show_email=True) self.assertEqual('*****@*****.**', author) def test_show_email_false(self): format_author = Chrome(self.env).format_author req = MockRequest(self.env, authname='user1') author = format_author(None, '*****@*****.**', show_email=False) self.assertEqual(u'user@\u2026', author) author = format_author(req, '*****@*****.**', show_email=False) self.assertEqual(u'user@\u2026', author) def test_show_full_names_true_actor_has_email_view(self): format_author = Chrome(self.env).format_author self.env.config.set('trac', 'show_full_names', True) self.env.insert_users([('user1', 'User One', '*****@*****.**'), ('user2', None, None)]) self.assertEqual('User One', format_author(None, 'user1')) self.assertEqual('user2', format_author(None, 'user2')) def test_show_full_names_false_actor_has_email_view(self): req = MockRequest(self.env, authname='user1') format_author = Chrome(self.env).format_author self.env.config.set('trac', 'show_full_names', False) self.assertEqual('user1', format_author(req, 'user1')) self.assertEqual('user2', format_author(req, 'user2')) def test_show_email_addresses_true(self): req = MockRequest(self.env) format_author = Chrome(self.env).format_author self.env.config.set('trac', 'show_email_addresses', True) self.assertEqual('*****@*****.**', format_author(None, '*****@*****.**')) self.assertEqual('*****@*****.**', format_author(req, '*****@*****.**')) def test_show_email_addresses_false(self): req = MockRequest(self.env) format_author = Chrome(self.env).format_author self.env.config.set('trac', 'show_email_addresses', False) self.assertEqual(u'user3@\u2026', format_author(None, '*****@*****.**')) self.assertEqual('*****@*****.**', format_author(req, '*****@*****.**')) def test_format_emails(self): format_emails = Chrome(self.env).format_emails to_format = '[email protected], user2; [email protected]' self.assertEqual(u'user1@\u2026, user2, user3@\u2026', format_emails(None, to_format)) def test_format_emails_actor_has_email_view(self): req = MockRequest(self.env, authname='user1') context = web_context(req) format_emails = Chrome(self.env).format_emails to_format = '[email protected], user2; [email protected]' self.assertEqual('[email protected], user2, [email protected]', format_emails(context, to_format)) def test_format_emails_actor_no_email_view(self): req = MockRequest(self.env, authname='user2') context = web_context(req) format_emails = Chrome(self.env).format_emails to_format = '[email protected], user2; [email protected]' self.assertEqual(u'user1@\u2026, user2, user3@\u2026', format_emails(context, to_format))
class ChromeTemplateRenderingTestCase(unittest.TestCase): filename = 'test_chrome.html' template = textwrap.dedent("""\ <!DOCTYPE html> <html> <body> <h1>${greeting}</h1> </body> </html> """) def setUp(self): self.env = EnvironmentStub(path=mkdtemp()) os.mkdir(self.env.templates_dir) filepath = os.path.join(self.env.templates_dir, self.filename) create_file(filepath, self.template) self.chrome = Chrome(self.env) def tearDown(self): self.env.reset_db_and_disk() def test_load_template(self): t1 = self.chrome.load_template(self.filename) self.assertTrue(isinstance(t1, jinja2.Template)) t1_text = self.chrome.load_template(self.filename, text=True) self.assertTrue(isinstance(t1_text, jinja2.Template)) # testing template cache t2 = self.chrome.load_template(self.filename) t2_text = self.chrome.load_template(self.filename, text=True) self.assertIs(t1, t2) self.assertIs(t1_text, t2_text) self.assertIsNot(t1, t1_text) def test_render_template_string(self): t = self.chrome.load_template(self.filename) self.assertIsNotNone(t) t_text = self.chrome.load_template(self.filename, text=True) self.assertIsNotNone(t_text) data = {'greeting': u"Hell&ö"} content = self.chrome.render_template_string(t, data) self.assertIsInstance(content, Markup) self.assertEqual( textwrap.dedent(u"""\ <!DOCTYPE html> <html> <body> <h1>Hell&ö</h1> </body> </html>"""), content) content_text = self.chrome.render_template_string(t_text, data, text=True) self.assertFalse(isinstance(content_text, Markup)) self.assertIsInstance(content_text, unicode) self.assertEqual( textwrap.dedent(u"""\ <!DOCTYPE html> <html> <body> <h1>Hell&ö</h1> </body> </html>"""), content_text) def test_render_template(self): data = {'greeting': u"Hell&ö"} content = self.chrome.render_template(MockRequest(self.env), self.filename, data, {'fragment': True}) self.assertIsInstance(content, str) self.assertEqual( textwrap.dedent("""\ <!DOCTYPE html> <html> <body> <h1>Hell&ö</h1> </body> </html>"""), content) def test_render_template_late_data(self): def fn(): add_stylesheet(req, 'common/css/blahblah.css') add_script(req, 'common/js/blahblah.js') add_script_data(req, blahblah=42) return 'blahblah' template = textwrap.dedent("""\ # extends 'layout.html' <!DOCTYPE html> <html> <body> # block content <div>${fn()}</div> ${ super() } # endblock content </body> </html> """) filename = 'test_render_template_late_data.html' filepath = os.path.join(self.env.templates_dir, filename) create_file(filepath, template) req = MockRequest(self.env) data = {'fn': fn} content = self.chrome.render_template(req, filename, data, {'fragment': True}) self.assertIsInstance(content, str) self.assertIn('<div>blahblah</div>', content) self.assertIn( ' jQuery.loadScript("/trac.cgi/chrome/' 'common/js/blahblah.js", "");', content) self.assertIn( ' jQuery.loadStyleSheet("/trac.cgi/chrome/' 'common/css/blahblah.css", "text/css");', content) self.assertIn(' var blahblah=42;', content)