def test_make_app_admin_only(): h.set_context('test', 'wiki', neighborhood='Projects') anon = M.User.anonymous() dev = M.User.query.get(username='******') admin = M.User.query.get(username='******') c.project.add_user(dev, ['Developer']) ThreadLocalORMSession.flush_all() Credentials.get().clear() assert has_access(c.app, 'read', user=anon)() assert has_access(c.app, 'read', user=dev)() assert has_access(c.app, 'read', user=admin)() assert not has_access(c.app, 'create', user=anon)() assert has_access(c.app, 'create', user=dev)() assert has_access(c.app, 'create', user=admin)() assert c.app.is_visible_to(anon) assert c.app.is_visible_to(dev) assert c.app.is_visible_to(admin) h.make_app_admin_only(c.app) ThreadLocalORMSession.flush_all() Credentials.get().clear() assert not has_access(c.app, 'read', user=anon)() assert not has_access(c.app, 'read', user=dev)() assert has_access(c.app, 'read', user=admin)() assert not has_access(c.app, 'create', user=anon)() assert not has_access(c.app, 'create', user=dev)() assert has_access(c.app, 'create', user=admin)() assert not c.app.is_visible_to(anon) assert not c.app.is_visible_to(dev) assert c.app.is_visible_to(admin)
def test_export_with_attachments(self): project = M.Project.query.get(shortname='test') discussion = project.app_instance('discussion') post = Forum.query.get(shortname='general').sorted_threads[0].first_post test_file1 = FieldStorage() test_file1.name = 'file_info' test_file1.filename = 'test_file' test_file1.file = StringIO('test file1\n') post.add_attachment(test_file1) ThreadLocalORMSession.flush_all() f = tempfile.TemporaryFile() temp_dir = tempfile.mkdtemp() discussion.bulk_export(f, temp_dir, True) f.seek(0) discussion = json.loads(f.read()) forums = sorted(discussion['forums'], key=lambda x: x['name']) threads = sorted(forums[0]['threads'], key=lambda x: x['subject']) file_path = os.path.join( 'discussion', str(post.discussion_id), str(post.thread_id), post.slug, 'test_file' ) assert_equal(threads[0]['posts'][0]['attachments'][0]['path'], file_path) os.path.exists(file_path)
def main(options): log.addHandler(logging.StreamHandler(sys.stdout)) log.setLevel(getattr(logging, options.log_level.upper())) g.solr = mock.Mock() preamble = options.dry_run and "Would delete" or "Deleting" options.preamble = preamble for nbhd in M.Neighborhood.query.find(): q = {'neighborhood_id': nbhd._id} for projects in utils.chunked_find(M.Project, q): for p in projects: scrub_project(p, options) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() log.info('%s %s EmailAddress documents' % (preamble, M.EmailAddress.query.find().count())) log.info('%s email addresses from %s User documents' % (preamble, M.User.query.find().count())) log.info('%s monitoring_email addresses from %s Forum documents' % (preamble, DM.Forum.query.find({"monitoring_email": {"$nin": [None, ""]}}).count())) if not options.dry_run: M.EmailAddress.query.remove() M.User.query.update({}, {"$set": {"email_addresses": []}}, multi=True) DM.Forum.query.update({"monitoring_email": {"$nin": [None, ""]}}, {"$set": {"monitoring_email": None}}, multi=True) return 0
def test_refresh(self): ci = mock.Mock() ci.count_revisions=mock.Mock(return_value=100) ci.authored.name = 'Test Committer' ci.author_url = '/u/test-committer/' self.repo._impl.commit = mock.Mock(return_value=ci) self.repo._impl.new_commits = mock.Mock(return_value=['foo%d' % i for i in range(100) ]) self.repo._impl.all_commit_ids = mock.Mock(return_value=['foo%d' % i for i in range(100) ]) self.repo.symbolics_for_commit = mock.Mock(return_value=[['master', 'branch'], []]) def refresh_commit_info(oid, seen, lazy=False): M.repo.CommitDoc(dict( authored=dict( name='Test Committer', email='*****@*****.**'), _id=oid)).m.insert() def set_heads(): self.repo.heads = [ ming.base.Object(name='head', object_id='foo0', count=100) ] self.repo._impl.refresh_commit_info = refresh_commit_info self.repo._impl.refresh_heads = mock.Mock(side_effect=set_heads) self.repo.shorthand_for_commit = lambda oid: '[' + str(oid) + ']' self.repo.url_for_commit = lambda oid: '/ci/' + str(oid) + '/' self.repo.refresh() ThreadLocalORMSession.flush_all() notifications = M.Notification.query.find().all() for n in notifications: if '100 new commits' in n.subject: assert "master,branch: by Test Committer http://localhost/#" in n.text break else: assert False, 'Did not find notification' assert M.Feed.query.find(dict( title='New commit', author_name='Test Committer')).count()
def test_email(self): self._subscribe() # as current user: test-admin user2 = M.User.query.get(username='******') self._subscribe(user=user2) self._post_notification() ThreadLocalORMSession.flush_all() assert_equal(M.Notification.query.get()['from_address'], '"Test Admin" <*****@*****.**>') assert_equal(M.Mailbox.query.find().count(), 2) M.MonQTask.run_ready() # sends the notification out into "mailboxes", and from mailboxes into email tasks mboxes = M.Mailbox.query.find().all() assert_equal(len(mboxes), 2) assert_equal(len(mboxes[0].queue), 1) assert not mboxes[0].queue_empty assert_equal(len(mboxes[1].queue), 1) assert not mboxes[1].queue_empty email_tasks = M.MonQTask.query.find({'state': 'ready'}).all() assert_equal(len(email_tasks), 2) # make sure both subscribers will get an email first_destinations = [e.kwargs['destinations'][0] for e in email_tasks] assert_in(str(c.user._id), first_destinations) assert_in(str(user2._id), first_destinations) assert_equal(email_tasks[0].kwargs['fromaddr'], '"Test Admin" <*****@*****.**>') assert_equal(email_tasks[1].kwargs['fromaddr'], '"Test Admin" <*****@*****.**>') assert_equal(email_tasks[0].kwargs['sender'], '*****@*****.**') assert_equal(email_tasks[1].kwargs['sender'], '*****@*****.**') assert email_tasks[0].kwargs['text'].startswith('Home modified by Test Admin') assert 'you indicated interest in ' in email_tasks[0].kwargs['text']
def fork(self, project_id=None, mount_point=None, mount_label=None): # this shows the form and handles the submission security.require_authenticated() if not c.app.forkable: raise exc.HTTPNotFound from_repo = c.app.repo ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() from_project = c.project to_project = M.Project.query.get(_id=ObjectId(project_id)) mount_label = mount_label or '%s - %s' % (c.project.name, c.app.config.options.mount_label) mount_point = (mount_point or from_project.shortname) if request.method != 'POST' or not mount_point: return dict(from_repo=from_repo, user_project=c.user.private_project(), mount_point=mount_point, mount_label=mount_label) else: with h.push_config(c, project=to_project): if not to_project.database_configured: to_project.configure_project(is_user_project=True) security.require(security.has_access(to_project, 'admin')) try: to_project.install_app( ep_name=from_repo.tool_name, mount_point=mount_point, mount_label=mount_label, cloned_from_project_id=from_project._id, cloned_from_repo_id=from_repo._id) redirect(to_project.url()+mount_point+'/') except exc.HTTPRedirection: raise except Exception, ex: flash(str(ex), 'error') redirect(request.referer)
def test_attachment_methods(): d = M.Discussion(shortname='test', name='test') t = M.Thread.new(discussion_id=d._id, subject='Test Thread') p = t.post('This is a post') p_att = p.attach('foo.text', StringIO('Hello, world!'), discussion_id=d._id, thread_id=t._id, post_id=p._id) t_att = p.attach('foo2.text', StringIO('Hello, thread!'), discussion_id=d._id, thread_id=t._id) d_att = p.attach('foo3.text', StringIO('Hello, discussion!'), discussion_id=d._id) ThreadLocalORMSession.flush_all() assert p_att.post == p assert p_att.thread == t assert p_att.discussion == d for att in (p_att, t_att, d_att): assert 'wiki/_discuss' in att.url() assert 'attachment/' in att.url() # Test notification in mail t = M.Thread.new(discussion_id=d._id, subject='Test comment notification') fs = FieldStorage() fs.name = 'file_info' fs.filename = 'fake.txt' fs.type = 'text/plain' fs.file = StringIO('this is the content of the fake file\n') p = t.post(text=u'test message', forum=None, subject='', file_info=fs) ThreadLocalORMSession.flush_all() n = M.Notification.query.get( subject=u'[test:wiki] Test comment notification') assert '\nAttachment: fake.txt (37 Bytes; text/plain)' in n.text
def test_permissions(self): # Notification should only be delivered if user has read perms on the # artifact. The perm check happens just before the mail task is # posted. u = M.User.query.get(username='******') self._subscribe(user=u) # Simulate a permission check failure. def patched_has_access(*args, **kw): def predicate(*args, **kw): return False return predicate from allura.model.notification import security orig = security.has_access security.has_access = patched_has_access try: # this will create a notification task self._post_notification() ThreadLocalORMSession.flush_all() # running the notification task will create a mail task if the # permission check passes... M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() # ...but in this case it doesn't create a mail task since we # forced the perm check to fail assert M.MonQTask.get() == None finally: security.has_access = orig
def main(): dbs = dict((p.database_uri, p) for p in M.Project.query.find()) for db, p in sorted(dbs.items()): log.info('=== Making attachments in %s polymorphic ===', db) c.project = p log.info('Fixing %d discussions', M.Discussion.query.find().count()) for d in M.Discussion.query.find(): for a in M.DiscussionAttachment.query.find(dict( discussion_id=d._id)): log.info('%s: %s', d.url(), a.filename) log.info('Fixing %d forums', DM.Forum.query.find().count()) for d in DM.Forum.query.find(): for a in DM.ForumAttachment.query.find(dict( discussion_id=d._id)): log.info('%s: %s', d.url(), a.filename) log.info('Fixing %d tickets', TM.Ticket.query.find().count()) for t in TM.Ticket.query.find(): for a in TM.TicketAttachment.query.find(dict( artifact_id=t._id)): log.info('%s: %s', t.url(), a.filename) log.info('Fixing %d wikis', WM.Page.query.find().count()) for p in WM.Page.query.find(): for a in WM.WikiAttachment.query.find(dict( artifact_id=p._id)): log.info('%s: %s', p.url(), a.filename) ThreadLocalORMSession.flush_all()
def test_direct_sub(self): self._subscribe() self._post_notification(text='A') self._post_notification(text='B') ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() M.Mailbox.fire_ready()
def setup_with_tools(self): setup_global_objects() _clear_subscriptions() _clear_notifications() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() M.notification.MAILBOX_QUIESCENT=None # disable message combining
def test_refresh(self): committer_name = 'Test Committer' committer_email = '*****@*****.**' ci = mock.Mock() ci.authored.name = committer_name ci.committed.name = committer_name ci.committed.email = committer_email ci.author_url = '/u/test-committer/' self.repo._impl.commit = mock.Mock(return_value=ci) self.repo._impl.new_commits = mock.Mock(return_value=['foo%d' % i for i in range(100) ]) self.repo._impl.all_commit_ids = mock.Mock(return_value=['foo%d' % i for i in range(100) ]) self.repo.symbolics_for_commit = mock.Mock(return_value=[['master', 'branch'], []]) def refresh_commit_info(oid, seen, lazy=False): M.repo.CommitDoc(dict( authored=dict( name=committer_name, email=committer_email), _id=oid)).m.insert() self.repo._impl.refresh_commit_info = refresh_commit_info _id = lambda oid: getattr(oid, '_id', str(oid)) self.repo.shorthand_for_commit = lambda oid: '[' + _id(oid) + ']' self.repo.url_for_commit = lambda oid: '/ci/' + _id(oid) + '/' self.repo.refresh() ThreadLocalORMSession.flush_all() notifications = M.Notification.query.find().all() for n in notifications: if '100 new commits' in n.subject: assert "master,branch: by %s http://localhost/ci/foo99" % committer_name in n.text break else: assert False, 'Did not find notification' assert M.Feed.query.find(dict( author_name=committer_name)).count() == 100
def main(): for chunk in utils.chunked_find(M.Project): for p in chunk: p.install_app('activity') ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def add_page_with_attachmetns(self): self.page = WM.Page.upsert('ZTest_title') self.page.text = 'test_text' self.page.mod_date = datetime.datetime(2013, 7, 5) self.page.labels = ['test_label1', 'test_label2'] self.page.attach('some/path/test_file', StringIO('test string')) ThreadLocalORMSession.flush_all()
def test_post_delete(): d = M.Discussion(shortname="test", name="test") t = M.Thread.new(discussion_id=d._id, subject="Test Thread") p = t.post("This is a post") p.attach("foo.text", StringIO(""), discussion_id=d._id, thread_id=t._id, post_id=p._id) ThreadLocalORMSession.flush_all() p.delete()
def notice(self, out, message): self.say('NOTICE %s :%s' % (out, message)) CM.ChatMessage( sender=self.nick, channel=out, text=message) ThreadLocalORMSession.flush_all()
def test_attachment_methods(): d = M.Discussion(shortname="test", name="test") t = M.Thread.new(discussion_id=d._id, subject="Test Thread") p = t.post("This is a post") p_att = p.attach("foo.text", StringIO("Hello, world!"), discussion_id=d._id, thread_id=t._id, post_id=p._id) t_att = p.attach("foo2.text", StringIO("Hello, thread!"), discussion_id=d._id, thread_id=t._id) d_att = p.attach("foo3.text", StringIO("Hello, discussion!"), discussion_id=d._id) ThreadLocalORMSession.flush_all() assert p_att.post == p assert p_att.thread == t assert p_att.discussion == d for att in (p_att, t_att, d_att): assert "wiki/_discuss" in att.url() assert "attachment/" in att.url() # Test notification in mail t = M.Thread.new(discussion_id=d._id, subject="Test comment notification") fs = FieldStorage() fs.name = "file_info" fs.filename = "fake.txt" fs.type = "text/plain" fs.file = StringIO("this is the content of the fake file\n") p = t.post(text=u"test message", forum=None, subject="", file_info=fs) ThreadLocalORMSession.flush_all() n = M.Notification.query.get(subject=u"[test:wiki] Test comment notification") assert "\nAttachment: fake.txt (37 Bytes; text/plain)" in n.text
def test_user_search_for_disabled_user(self): user = M.User.by_username('test-admin') user.disabled = True ThreadLocalORMSession.flush_all() r = self.app.get('/p/test/user_search?term=test', status=200) j = json.loads(r.body) assert j == {'users': []}
def test_post_methods(): d = M.Discussion(shortname='test', name='test') t = M.Thread.new(discussion_id=d._id, subject='Test Thread') p = t.post('This is a post') p2 = t.post('This is another post') assert p.discussion_class() == M.Discussion assert p.thread_class() == M.Thread assert p.attachment_class() == M.DiscussionAttachment p.commit() assert p.parent is None assert p.subject == 'Test Thread' assert_equals(p.attachments, []) assert 'wiki/_discuss' in p.url() assert p.reply_subject() == 'Re: Test Thread' assert p.link_text() == p.subject ss = p.history().first() assert 'version' in h.get_first(ss.index(), 'title') assert '#' in ss.shorthand_id() jsn = p.__json__() assert jsn["thread_id"] == t._id (p.approve() for p in (p, p2)) ThreadLocalORMSession.flush_all() assert t.num_replies == 2 p.spam() assert t.num_replies == 1 p.undo('ok') assert t.num_replies == 2 p.delete() assert t.num_replies == 1
def test_macro_include_extra_br(): p_nbhd = M.Neighborhood.query.get(name="Projects") p_test = M.Project.query.get(shortname="test", neighborhood_id=p_nbhd._id) wiki = p_test.app_instance("wiki") with h.push_context(p_test._id, app_config_id=wiki.config._id): p = WM.Page.upsert(title="Include_1") p.text = "included page 1" p.commit() p = WM.Page.upsert(title="Include_2") p.text = "included page 2" p.commit() p = WM.Page.upsert(title="Include_3") p.text = "included page 3" p.commit() ThreadLocalORMSession.flush_all() md = "[[include ref=Include_1]]\n[[include ref=Include_2]]\n[[include ref=Include_3]]" html = g.markdown_wiki.convert(md) expected_html = """ <div class="markdown_content"> <p> <div><div class="markdown_content"><p>included page 1</p></div></div> <div><div class="markdown_content"><p>included page 2</p></div></div> <div><div class="markdown_content"><p>included page 3</p></div></div> </p> </div> """.strip().replace( "\n", "" ) assert html.strip().replace("\n", "") == expected_html, html
def test_export_with_attachments(self): project = M.Project.query.get(shortname='test') blog = project.app_instance('blog') with h.push_context('test', 'blog', neighborhood='Projects'): post = BM.BlogPost.new( title='Test title', text='test post', labels=['the firstlabel', 'the second label'], delete=None ) ThreadLocalORMSession.flush_all() test_file1 = FieldStorage() test_file1.name = 'file_info' test_file1.filename = 'test_file' test_file1.file = StringIO('test file1\n') p = post.discussion_thread.add_post(text='test comment') p.add_multiple_attachments(test_file1) ThreadLocalORMSession.flush_all() f = tempfile.TemporaryFile() temp_dir = tempfile.mkdtemp() blog.bulk_export(f, temp_dir, True) f.seek(0) blog = json.loads(f.read()) blog['posts'] = sorted( blog['posts'], key=lambda x: x['title'], reverse=True) file_path = 'blog/{}/{}/{}/test_file'.format( post._id, post.discussion_thread._id, list(post.discussion_thread.post_class().query.find())[0].slug ) assert_equal(blog['posts'][0]['discussion_thread']['posts'][0] ['attachments'][0]['path'], file_path) assert os.path.exists(os.path.join(temp_dir, file_path))
def test_macro_include_permissions(): p_nbhd = M.Neighborhood.query.get(name='Projects') p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) wiki = p_test.app_instance('wiki') wiki2 = p_test.app_instance('wiki2') with h.push_context(p_test._id, app_config_id=wiki.config._id): p = WM.Page.upsert(title='CanRead') p.text = 'Can see this!' p.commit() ThreadLocalORMSession.flush_all() with h.push_context(p_test._id, app_config_id=wiki2.config._id): role = M.ProjectRole.by_name('*anonymous')._id read_perm = M.ACE.allow(role, 'read') acl = c.app.config.acl if read_perm in acl: acl.remove(read_perm) p = WM.Page.upsert(title='CanNotRead') p.text = 'Can not see this!' p.commit() ThreadLocalORMSession.flush_all() with h.push_context(p_test._id, app_config_id=wiki.config._id): c.user = M.User.anonymous() md = '[[include ref=CanRead]]\n[[include ref=wiki2:CanNotRead]]' html = g.markdown_wiki.convert(md) assert_in('Can see this!', html) assert_not_in('Can not see this!', html) assert_in("[[include: you don't have a read permission for wiki2:CanNotRead]]", html)
def test_macro_include_no_extra_br(): p_nbhd = M.Neighborhood.query.get(name='Projects') p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) wiki = p_test.app_instance('wiki') with h.push_context(p_test._id, app_config_id=wiki.config._id): p = WM.Page.upsert(title='Include_1') p.text = 'included page 1' p.commit() p = WM.Page.upsert(title='Include_2') p.text = 'included page 2' p.commit() p = WM.Page.upsert(title='Include_3') p.text = 'included page 3' p.commit() ThreadLocalORMSession.flush_all() md = '[[include ref=Include_1]]\n[[include ref=Include_2]]\n[[include ref=Include_3]]' html = g.markdown_wiki.convert(md) expected_html = '''<div class="markdown_content"><p></p><div> <div class="markdown_content"><p>included page 1</p></div> </div> <div> <div class="markdown_content"><p>included page 2</p></div> </div> <div> <div class="markdown_content"><p>included page 3</p></div> </div> <p></p></div>''' assert_equal(squish_spaces(html), squish_spaces(expected_html))
def test_hideawards_macro(): p_nbhd = M.Neighborhood.query.get(name='Projects') app_config_id = ObjectId() award = M.Award(app_config_id=app_config_id) award.short = u'Award short' award.full = u'Award full' award.created_by_neighborhood_id = p_nbhd._id project = M.Project.query.get( neighborhood_id=p_nbhd._id, shortname=u'test') M.AwardGrant( award=award, award_url='http://award.org', comment='Winner!', granted_by_neighborhood=p_nbhd, granted_to_project=project) ThreadLocalORMSession.flush_all() with h.push_context(p_nbhd.neighborhood_project._id): r = g.markdown_wiki.convert('[[projects]]') assert_in('<div class="feature"> <a href="http://award.org" rel="nofollow" title="Winner!">' 'Award short</a> </div>', squish_spaces(r)) r = g.markdown_wiki.convert('[[projects show_awards_banner=False]]') assert_not_in('Award short', r)
def test_paged_diffs_with_detect_copies(self): # setup h.set_context('test', 'src-weird', neighborhood='Projects') repo_dir = pkg_resources.resource_filename( 'forgegit', 'tests/data') repo = GM.Repository( name='weird-chars.git', fs_path=repo_dir, url_path='/src-weird/', tool='git', status='creating') repo.refresh() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() diffs = repo.paged_diffs('346c52c1dddc729e2c2711f809336401f0ff925e') # Test copy expected = { 'added': [], 'removed': [], 'copied': [{'new': u'README.copy', 'old': u'README', 'ratio': 1.0}], 'renamed': [], 'changed': [u'README'], 'total': 2, } assert_equals(diffs, expected) diffs = repo.paged_diffs('3cb2bbcd7997f89060a14fe8b1a363f01883087f') # Test rename expected = { 'added': [], 'removed': [], 'copied': [], 'renamed': [{'new': u'README', 'old': u'README-copy.md', 'ratio': 1.0}], 'changed': [], 'total': 1, } assert_equals(diffs, expected)
def test_macro_neighborhood_feeds(): p_nbhd = M.Neighborhood.query.get(name='Projects') p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) with h.push_context('--init--', 'wiki', neighborhood='Projects'): r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') assert 'Home modified by' in r, r orig_len = len(r) # Make project private & verify we don't see its new feed items anon = M.User.anonymous() p_test.acl.insert(0, M.ACE.deny( M.ProjectRole.anonymous(p_test)._id, 'read')) ThreadLocalORMSession.flush_all() pg = WM.Page.query.get(title='Home', app_config_id=c.app.config._id) pg.text = 'Change' with h.push_config(c, user=M.User.by_username('test-admin')): pg.commit() r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') new_len = len(r) assert new_len == orig_len p = BM.BlogPost(title='test me', neighborhood_id=p_test.neighborhood_id) p.text = 'test content' p.state = 'published' p.make_slug() with h.push_config(c, user=M.User.by_username('test-admin')): p.commit() ThreadLocalORMSession.flush_all() with h.push_config(c, user=anon): r = g.markdown_wiki.convert('[[neighborhood_blog_posts]]') assert 'test content' in r
def test_sendsimplemail_with_disabled_user(self): c.user = M.User.by_username('test-admin') with mock.patch.object(mail_tasks.smtp_client, '_client') as _client: mail_tasks.sendsimplemail( fromaddr=str(c.user._id), toaddr='*****@*****.**', text=u'This is a test', reply_to=g.noreply, subject=u'Test subject', message_id=h.gen_message_id()) assert_equal(_client.sendmail.call_count, 1) return_path, rcpts, body = _client.sendmail.call_args[0] body = body.split('\n') assert_in('From: "Test Admin" <*****@*****.**>', body) c.user.disabled = True ThreadLocalORMSession.flush_all() mail_tasks.sendsimplemail( fromaddr=str(c.user._id), toaddr='*****@*****.**', text=u'This is a test', reply_to=g.noreply, subject=u'Test subject', message_id=h.gen_message_id()) assert_equal(_client.sendmail.call_count, 2) return_path, rcpts, body = _client.sendmail.call_args[0] body = body.split('\n') assert_in('From: %s' % g.noreply, body)
def fix_for_project(self, project): c.project = project base.log.info( 'Checking discussion instances for each tracker in project %s' % project.shortname) trackers = [ac for ac in project.app_configs if ac.tool_name.lower() == 'tickets'] for tracker in trackers: base.log.info('Found tracker %s' % tracker) for ticket in Ticket.query.find({'app_config_id': tracker._id}): base.log.info('Processing ticket %s [#%s] %s' % (ticket._id, ticket.ticket_num, ticket.summary)) if ticket.discussion_thread.discussion.app_config_id != tracker._id: # Some tickets were moved from this tracker, # and Discussion instance for entire tracker was moved too. # Should move it back. base.log.info("Some tickets were moved from this tracker. " "Moving tracker's discussion instance back.") ticket.discussion_thread.discussion.app_config_id = tracker._id if ticket.discussion_thread.discussion_id != tracker.discussion_id: # Ticket was moved from another tracker. # Should bind his comment thread to tracker's Discussion base.log.info("Ticket was moved from another tracker. " "Bind ticket's comment thread to tracker's Discussion instance.") ticket.discussion_thread.discussion_id = tracker.discussion_id for post in ticket.discussion_thread.posts: post.discussion_id = tracker.discussion_id ThreadLocalORMSession.flush_all()
def test_members(self): nbhd = M.Neighborhood.query.get(name='Projects') self.app.post('/admin/groups/create', params={'name': 'B_role'}) test_project = M.Project.query.get( shortname='test', neighborhood_id=nbhd._id) test_project.add_user(M.User.by_username('test-user-1'), ['B_role']) test_project.add_user(M.User.by_username('test-user'), ['Developer']) test_project.add_user(M.User.by_username('test-user-0'), ['Member']) test_project.add_user(M.User.by_username('test-user-2'), ['Member']) test_project.add_user(M.User.by_username('test-user-3'), ['Member']) test_project.add_user(M.User.by_username('test-user-3'), ['Developer']) test_project.add_user(M.User.by_username('test-user-4'), ['Admin']) ThreadLocalORMSession.flush_all() r = self.app.get('/p/test/_members/') assert '<td>Test Admin</td>' in r assert '<td><a href="/u/test-admin/">test-admin</a></td>' in r assert '<td>Admin</td>' in r tr = r.html.findAll('tr') assert "<td>Test Admin</td>" in str(tr[1]) assert "<td>Test User 4</td>" in str(tr[2]) assert "<td>Test User</td>" in str(tr[3]) assert "<td>Test User 3</td>" in str(tr[4]) assert "<td>Test User 0</td>" in str(tr[5]) assert "<td>Test User 1</td>" in str(tr[6]) assert "<td>Test User 2</td>" in str(tr[7])
def refresh_repo_lcds(cls, commit_ids, options): tree_cache = {} timings = [] if options.diffs: print 'Processing diffs' for i, commit_id in enumerate(commit_ids): commit = M.repo.Commit.query.get(_id=commit_id) with time(timings): M.repo_refresh.compute_diffs(c.app.repo._id, tree_cache, commit) if i % 1000 == 0: cls._print_stats(i, timings, 1000) model_cache = M.repo.ModelCache( max_instances={M.repo.LastCommit: 4000}, max_queries={M.repo.LastCommit: 4000}, ) lcid_cache = {} timings = [] print 'Processing last commits' for i, commit_id in enumerate(commit_ids): commit = M.repo.Commit.query.get(_id=commit_id) if commit is None: print "Commit missing, skipping: %s" % commit_id continue commit.set_context(c.app.repo) with time(timings): M.repo_refresh.compute_lcds(commit, model_cache, lcid_cache) ThreadLocalORMSession.flush_all() if i % 100 == 0: cls._print_stats(i, timings, 100) if options.limit and i >= options.limit: break ThreadLocalORMSession.flush_all()
def test_macro_project_admins_one_br(): p_nbhd = M.Neighborhood.query.get(name='Projects') p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) p_test.add_user(M.User.by_username('test-user'), ['Admin']) ThreadLocalORMSession.flush_all() with h.push_config(c, project=p_test): r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]') assert '</a><br/><br/><a href=' not in r, r assert '</a></li><li><a href=' in r, r
def test_delivery(self): self._subscribe() self._post_notification() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() assert M.Mailbox.query.find().count() == 1 mbox = M.Mailbox.query.get() assert len(mbox.queue) == 1
def test_post_delete(): d = M.Discussion(shortname='test', name='test') t = M.Thread.new(discussion_id=d._id, subject='Test Thread') p = t.post('This is a post') p.attach('foo.text', BytesIO(b''), discussion_id=d._id, thread_id=t._id, post_id=p._id) ThreadLocalORMSession.flush_all() p.delete()
def setup_with_tools(self): h.set_context('test', 'src-git', neighborhood='Projects') repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data') c.app.repo.fs_path = repo_dir c.app.repo.status = 'ready' c.app.repo.name = 'testrename.git' ThreadLocalORMSession.flush_all() h.set_context('test', 'src-git', neighborhood='Projects') c.app.repo.refresh() ThreadLocalORMSession.flush_all()
def setup_with_tools(self): setup_global_objects() h.set_context('test', 'src-git', neighborhood='Projects') repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data') c.app.repo.fs_path = repo_dir c.app.repo.name = 'testgit.git' self.repo = c.app.repo self.repo.refresh() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def reclone(*args, **kwargs): from allura import model as M from ming.orm import ThreadLocalORMSession repo = c.app.repo if repo is not None: shutil.rmtree(repo.full_fs_path, ignore_errors=True) M.MergeRequest.query.remove(dict( app_config_id=c.app.config._id)) ThreadLocalORMSession.flush_all() clone(*args, **kwargs)
def uninstall(**kwargs): from allura import model as M repo = c.app.repo if repo is not None: shutil.rmtree(repo.full_fs_path, ignore_errors=True) repo.delete() M.MergeRequest.query.remove(dict(app_config_id=c.app.config._id)) super(RepositoryApp, c.app).uninstall(c.project) from ming.orm import ThreadLocalORMSession ThreadLocalORMSession.flush_all()
def import_project_info(project_name): from forgeimporters.google.project import GoogleCodeProjectImporter importer = GoogleCodeProjectImporter(None) with ImportErrorHandler(importer, project_name, c.project) as handler: extractor = GoogleCodeProjectExtractor(project_name, 'project_info') extractor.get_short_description(c.project) extractor.get_icon(c.project) extractor.get_license(c.project) ThreadLocalORMSession.flush_all() g.post_event('project_updated')
def test_commit(self): assert self.rev.primary() is self.rev assert self.rev.index_id().startswith('allura/model/repo/Commit#') self.rev.author_url self.rev.committer_url assert self.rev.tree._id == self.rev.tree_id assert self.rev.summary == self.rev.message.splitlines()[0] assert self.rev.shorthand_id() == '[1e146e]' assert self.rev.symbolic_ids == ( ['master'], ['foo']), self.rev.symbolic_ids assert self.rev.url() == ( '/p/test/src-git/ci/' '1e146e67985dcd71c74de79613719bef7bddca4a/') all_cis = list(self.repo.log(self.rev._id, id_only=True)) assert len(all_cis) == 4 c.lcid_cache = {} self.rev.tree.ls() # print self.rev.tree.readme() assert_equal(self.rev.tree.readme(), ( 'README', 'This is readme\nAnother Line\n')) assert self.rev.tree.path() == '/' assert self.rev.tree.url() == ( '/p/test/src-git/ci/' '1e146e67985dcd71c74de79613719bef7bddca4a/' 'tree/') self.rev.tree.by_name['README'] assert self.rev.tree.is_blob('README') == True ThreadLocalORMSession.close_all() c.app = None converted = g.markdown.convert('[1e146e]') assert '1e146e' in converted, converted h.set_context('test', 'wiki', neighborhood='Projects') pg = WM.Page( title='Test Page', text='This is a commit reference: [1e146e]') ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() for ci in pg.related_artifacts(): assert ci.shorthand_id() == '[1e146e]', ci.shorthand_id() assert ci.url() == ( '/p/test/src-git/ci/' '1e146e67985dcd71c74de79613719bef7bddca4a/') assert_equal(self.rev.authored_user, None) assert_equal(self.rev.committed_user, None) user = M.User.upsert('rick') email = user.claim_address('*****@*****.**') email.confirmed = True session(email).flush(email) rev = self.repo.commit(self.rev._id) # to update cached values of LazyProperty assert_equal(rev.authored_user, user) assert_equal(rev.committed_user, user) assert_equal( sorted(rev.webhook_info.keys()), sorted(['id', 'url', 'timestamp', 'message', 'author', 'committer', 'added', 'removed', 'renamed', 'modified', 'copied']))
def import_tool(self, project, user, project_name, mount_point=None, mount_label=None, **kw): import_id_converter = ImportIdConverter.get() project_name = '%s/%s' % (kw['user_name'], project_name) extractor = GitHubProjectExtractor(project_name, user=user) if not extractor.has_tracker(): return app = project.install_app('tickets', mount_point, mount_label, EnableVoting=False, open_status_names='open', closed_status_names='closed', import_id={ 'source': self.source, 'project_name': project_name, }) self.github_markdown_converter = GitHubMarkdownConverter( kw['user_name'], project_name) ThreadLocalORMSession.flush_all() try: M.session.artifact_orm_session._get().skip_mod_date = True with h.push_config(c, user=M.User.anonymous(), app=app): for ticket_num, issue in extractor.iter_issues(): self.max_ticket_num = max(ticket_num, self.max_ticket_num) ticket = TM.Ticket(app_config_id=app.config._id, custom_fields=dict(), ticket_num=ticket_num, import_id=import_id_converter.expand( ticket_num, app)) self.process_fields(extractor, ticket, issue) self.process_comments(extractor, ticket, issue) self.process_events(extractor, ticket, issue) self.process_milestones(ticket, issue) session(ticket).flush(ticket) session(ticket).expunge(ticket) app.globals.custom_fields = self.postprocess_milestones() app.globals.last_ticket_num = self.max_ticket_num ThreadLocalORMSession.flush_all() M.AuditLog.log( 'import tool %s from %s on %s' % (app.config.options.mount_point, project_name, self.source), project=project, user=user, url=app.url) g.post_event('project_updated') app.globals.invalidate_bin_counts() return app finally: M.session.artifact_orm_session._get().skip_mod_date = False
def main(): for chunk in utils.chunked_find(SM.Repository): for r in chunk: print 'Processing {0}'.format(r) all_commit_ids = r._impl.all_commit_ids() if all_commit_ids: for commit in M.repo.Commit.query.find({'_id':{'$in':all_commit_ids}}): if commit.tree_id and M.repo.Tree.query.get(_id=commit.tree_id): kill_tree(r._impl, commit._id, '', commit.tree) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def test_notification_email_multiple_commits(self): send_notifications(self.repo, [ 'df30427c488aeab84b2352bdf88a3b19223f9d7a', '1e146e67985dcd71c74de79613719bef7bddca4a', ]) ThreadLocalORMSession.flush_all() n = M.Notification.query.find( dict(subject='[test:src-git] 2 new commits to Git')).first() assert n assert n.text.startswith('\n## Branch: master'), n.text assert n.text.find('Add README') < n.text.find('Change README'), n.text
def setUp(self): super(TestMergeRequest, self).setUp() c.project.install_app('svn', 'test2') h.set_context('test', 'test2', neighborhood='Projects') self.repo2 = M.Repository(name='test2', tool='svn') self.repo2._impl = mock.Mock(spec=M.RepositoryImplementation()) self.repo2._impl.log = lambda *a, **kw: (['foo'], []) self.repo2._impl._repo = self.repo2 self.repo2.init_as_clone('/p/test/', 'test1', '/p/test/test1/') ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def _make_app(self, mount_point, name): h.set_context('test', mount_point, neighborhood='Projects') repo_dir = pkg_resources.resource_filename('forgesvn', 'tests/data/') c.app.repo.fs_path = repo_dir c.app.repo.status = 'ready' c.app.repo.name = name c.app.repo.refresh() if os.path.isdir(c.app.repo.tarball_path): shutil.rmtree(c.app.repo.tarball_path.encode('utf-8')) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def configure_project(self, users=None, apps=None, is_user_project=False, is_private_project=False): from allura import model as M self.notifications_disabled = True if users is None: users = [c.user] if apps is None: if is_user_project: apps = [('Wiki', 'wiki', 'Wiki'), ('profile', 'profile', 'Profile'), ('admin', 'admin', 'Admin'), ('search', 'search', 'Search'), ('activity', 'activity', 'Activity')] else: apps = [('admin', 'admin', 'Admin'), ('search', 'search', 'Search'), ('activity', 'activity', 'Activity')] with h.push_config(c, project=self, user=users[0]): # Install default named roles (#78) root_project_id = self.root_project._id role_admin = M.ProjectRole.upsert(name='Admin', project_id=root_project_id) role_developer = M.ProjectRole.upsert(name='Developer', project_id=root_project_id) role_member = M.ProjectRole.upsert(name='Member', project_id=root_project_id) role_auth = M.ProjectRole.upsert(name='*authenticated', project_id=root_project_id) role_anon = M.ProjectRole.upsert(name='*anonymous', project_id=root_project_id) # Setup subroles role_admin.roles = [role_developer._id] role_developer.roles = [role_member._id] self.acl = [ ACE.allow(role_developer._id, 'read'), ACE.allow(role_member._id, 'read') ] self.acl += [ M.ACE.allow(role_admin._id, perm) for perm in self.permissions ] self.private = is_private_project for user in users: pr = user.project_role() pr.roles = [role_admin._id] session(self).flush(self) # Setup apps for i, (ep_name, mount_point, label) in enumerate(apps): self.install_app(ep_name, mount_point, label, ordinal=i) self.database_configured = True self.notifications_disabled = False ThreadLocalORMSession.flush_all()
def test_post_event_explicit_flush(self): g.post_event('my_event1', flush_immediately=True) assert M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=['my_event1']) g.post_event('my_event2', flush_immediately=False) assert not M.MonQTask.query.get( task_name='allura.tasks.event_tasks.event', args=['my_event2']) ThreadLocalORMSession.flush_all() assert M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=['my_event2'])
def scrub_project(p, options): log.info('Scrubbing project "%s"' % p.shortname) preamble = options.preamble if not public(p): log.info('%s project "%s"' % (preamble, p.shortname)) if not options.dry_run: p.delete() return for ac in p.app_configs: ac.project = p c.app = p.app_instance(ac) mount_point = ac.options.get('mount_point') tool_name = ac.tool_name.lower() if tool_name in ('admin', 'search', 'profile'): continue if not public(ac, project=p): log.info('%s tool %s/%s on project "%s"' % ( preamble, tool_name, mount_point, p.shortname)) if not options.dry_run: p.uninstall_app(mount_point) continue q = dict(app_config_id=ac._id) ace = dict(access='DENY', permission='*', role_id=None) q['acl'] = {'$in': [ace]} counter = 0 if tool_name == 'tickets': if ac.options.get('TicketMonitoringEmail'): log.info('%s options.TicketMonitoringEmail from the %s/%s ' 'tool on project "%s"' % (preamble, tool_name, mount_point, p.shortname)) if not options.dry_run: ac.options['TicketMonitoringEmail'] = None for tickets in utils.chunked_find(TM.Ticket, q): for t in tickets: counter += 1 if not options.dry_run: t.discussion_thread.delete() t.delete() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() if counter > 0: log.info('%s %s tickets from the %s/%s tool on ' 'project "%s"' % (preamble, counter, tool_name, mount_point, p.shortname)) elif tool_name == 'discussion': for forums in utils.chunked_find(DM.Forum, q): for f in forums: counter += 1 if not options.dry_run: f.delete() if counter > 0: log.info('%s %s forums from the %s/%s tool on ' 'project "%s"' % (preamble, counter, tool_name, mount_point, p.shortname))
def setup_with_tools(self): setup_global_objects() h.set_context('test', 'src', neighborhood='Projects') repo_dir = pkg_resources.resource_filename('forgesvn', 'tests/data/') c.app.repo.name = 'testsvn' c.app.repo.fs_path = repo_dir self.repo = c.app.repo self.repo.refresh() self.rev = self.repo.commit('HEAD') ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def setup_with_tools(self): setup_global_objects() g.set_app('wiki') _clear_subscriptions() _clear_notifications() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() self.pg = WM.Page.query.get(app_config_id=c.app.config._id) M.notification.MAILBOX_QUIESCENT = None # disable message combining while M.MonQTask.run_ready('setup'): ThreadLocalORMSession.flush_all()
def test_markdown_user_mention_in_code(self): u1 = M.User.register(dict(username='******'), make_project=True) ThreadLocalORMSession.flush_all() output = g.markdown.convert('Hello.. `@admin-user-4, how` are you?') assert 'class="user-mention"' not in output assert '<code>' in output assert ('href="%s"' % u1.url()) not in output output = g.markdown.convert('Hello.. This is code \n~~~python\nprint("@admin-user-4")\n~~~') assert 'class="user-mention"' not in output assert '<div class="codehilite">' in output assert ('href="%s"' % u1.url()) not in output
def execute(cls, options): query = {'tool_name': {'$regex': '^svn$', '$options': 'i'}, 'options.checkout_url': ''} for chunk in utils.chunked_find(M.AppConfig, query): for config in chunk: repo = Repository.query.get(app_config_id=config._id) trunk_path = "file://{0}{1}/trunk".format(repo.fs_path, repo.name) if svn_path_exists(trunk_path): config.options['checkout_url'] = "trunk" log.info("Update checkout_url for: %s", trunk_path) ThreadLocalORMSession.flush_all()
def log_channel(self, sender, cmd, rcpt, rest): if cmd not in ('NOTICE', 'PRIVMSG'): self.logger.debug('IGN: %s %s %s %s', sender, cmd, rcpt, rest) return if cmd == 'NOTICE': text = '--' + rest else: text = rest CM.ChatMessage(sender='!'.join(sender), channel=rcpt, text=text) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def execute(cls, options): q_project = {} if options.nbhd: nbhd = M.Neighborhood.query.get(url_prefix=options.nbhd) if not nbhd: return "Invalid neighborhood url prefix." q_project['neighborhood_id'] = nbhd._id if options.project: q_project['shortname'] = options.project elif options.project_regex: q_project['shortname'] = {'$regex': options.project_regex} log.info('Refreshing last commit data') for chunk in chunked_find(M.Project, q_project): for p in chunk: log.info("Refreshing last commit data for project '%s'." % p.shortname) if options.dry_run: continue c.project = p if options.mount_point: mount_points = [options.mount_point] else: mount_points = [ac.options.mount_point for ac in M.AppConfig.query.find(dict(project_id=p._id))] for app in (p.app_instance(mp) for mp in mount_points): c.app = app if not hasattr(app, 'repo'): continue if c.app.repo.tool.lower() not in options.repo_types: log.info("Skipping %r: wrong type (%s)", c.app.repo, c.app.repo.tool.lower()) continue c.app.repo.status = 'analyzing' session(c.app.repo).flush(c.app.repo) try: ci_ids = list(reversed(list(c.app.repo.all_commit_ids()))) if options.clean: cls._clean(ci_ids, options.diffs) log.info('Refreshing all last commits in %r', c.app.repo) cls.refresh_repo_lcds(ci_ids, options) new_commit_ids = app.repo.unknown_commit_ids() if len(new_commit_ids) > 0: refresh.post() except: log.exception('Error refreshing %r', c.app.repo) raise finally: c.app.repo.status = 'ready' session(c.app.repo).flush(c.app.repo) ThreadLocalORMSession.flush_all()
def test_notification_email(self): send_notifications(self.repo, ['1e146e67985dcd71c74de79613719bef7bddca4a', ]) ThreadLocalORMSession.flush_all() notifications = M.Notification.query.find().sort('pubdate') n = notifications.all()[2] assert_equal(n.subject, '[test:src-git] [1e146e] - Rick Copeland: Change README') assert 'master,zz: ' in n.text send_notifications(self.repo, ['1e146e67985dcd71c74de79613719bef7bddca4a', 'df30427c488aeab84b2352bdf88a3b19223f9d7a']) ThreadLocalORMSession.flush_all() notifications = M.Notification.query.find().sort('pubdate') n = notifications.all()[3] assert_equal(n.subject, '[test:src-git] 2 new commits to test Git')
def test_status_html(self): resp = self.app.get('/src-git/').follow().follow() # repo status not displayed if 'ready' assert None == resp.html.find('div', dict(id='repo_status')) h.set_context('test', 'src-git', neighborhood='Projects') c.app.repo.status = 'analyzing' ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() # repo status displayed if not 'ready' resp = self.app.get('/src-git/').follow().follow() div = resp.html.find('div', dict(id='repo_status')) assert div.span.text == 'analyzing'
def test_post_user_notification(self): u = M.User.query.get(username='******') M.Notification.post_user(u, self.pg, 'metadata') ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() flash_msgs = list(h.pop_user_notifications(u)) assert len(flash_msgs) == 1, flash_msgs msg = flash_msgs[0] assert msg['text'].startswith('Home modified by Test Admin') assert msg['subject'].startswith('[test:wiki]') flash_msgs = list(h.pop_user_notifications(u)) assert not flash_msgs, flash_msgs
def setup_with_tools(self): setup_global_objects() h.set_context('test', 'src-git', neighborhood='Projects') repo_dir = pkg_resources.resource_filename('forgegit', 'tests/data') self.repo = GM.Repository(name='testgit.git', fs_path=repo_dir, url_path='/test/', tool='git', status='creating') self.repo.refresh() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def test_post_undo(): d = M.Discussion(shortname='test', name='test') t = M.Thread.new(discussion_id=d._id, subject='Test Thread') p = t.post('This is a post') t.post('This is a post2') t.post('This is a post3') ThreadLocalORMSession.flush_all() assert t.num_replies == 3 p.spam() assert t.num_replies == 2 p.undo('ok') assert t.num_replies == 3
def test_notification_email(self): send_notifications(self.repo, [ '1e146e67985dcd71c74de79613719bef7bddca4a', ]) ThreadLocalORMSession.flush_all() n = M.Notification.query.find({ 'subject': '[test:src-git] New commit [1e146e] by Rick Copeland' }).first() assert n assert_in('Change README', n.text)
def test_notification_email_max_commits(self): send_notifications(self.repo, ['9a7df788cf800241e3bb5a849c8870f2f8259d98', '6a45885ae7347f1cac5103b0050cc1be6a1496c8', 'df30427c488aeab84b2352bdf88a3b19223f9d7a', '1e146e67985dcd71c74de79613719bef7bddca4a', ]) ThreadLocalORMSession.flush_all() n = M.Notification.query.find( dict(subject='[test:src-git] 4 new commits to Git')).first() assert n assert n.text.startswith('\n## Branch: master'), n.text assert n.text.endswith('And 1 more commits.\n'), n.text