def test_is_spam_for_admin(users): users.return_value = [c.user, ] d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') t.post('This is a post') post = M.Post.query.get(text='This is a post') assert not t.is_spam(post), t.is_spam(post)
def test_thread_subject_not_included_in_text_checked(spam_checker): spam_checker.check.return_value = False d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') t.post('Hello') assert_equal(spam_checker.check.call_count, 1) assert_equal(spam_checker.check.call_args[0][0], 'Hello')
def test_post_methods(): d = M.Discussion(shortname='test', name='test') t = M.Thread(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 p.attachments.count() == 0 assert 'Test Admin' in p.summary() 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 ss.index()['title_s'] assert '#' in ss.shorthand_id() jsn = p.__json__() assert jsn["thread_id"] == t._id (p.approve() for p in (p, p2)) assert t.num_replies == 1 p2.spam() assert t.num_replies == 0 p.spam() assert t.num_replies == 0 p.delete() assert t.num_replies == 0
def test_post_count(): d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') p1 = M.Post(discussion_id=d._id, thread_id=t._id, status='spam') p2 = M.Post(discussion_id=d._id, thread_id=t._id, status='ok') p3 = M.Post(discussion_id=d._id, thread_id=t._id, status='pending') ThreadLocalORMSession.flush_all() assert_equal(t.post_count, 2)
def test_thread_subject_not_included_in_text_checked(spam_checker): spam_checker.check.return_value = False d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') admin = M.User.by_username('test-admin') post = t.post('Hello') spam_checker.check.assert_called_once() assert_equal(spam_checker.check.call_args[0][0], 'Hello')
def test_spam_num_replies(spam_checker): d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread', num_replies=2) M.Post(discussion_id=d._id, thread_id=t._id, status='ok') ThreadLocalORMSession.flush_all() p1 = M.Post(discussion_id=d._id, thread_id=t._id, status='spam') p1.spam() assert_equal(t.num_replies, 1)
def test_is_spam(role): d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') role.return_value = [] with mock.patch('allura.controllers.discuss.g.spam_checker') as spam_checker: spam_checker.check.return_value = True post = mock.Mock() assert t.is_spam(post), t.is_spam(post) assert spam_checker.check.call_count == 1, spam_checker.call_count
def test_is_spam(self, spam_checker): spam_checker.check.return_value = True c.user = M.User.query.get(username="******") role = M.ProjectRole(project_id=c.project._id, name='TestRole') M.ProjectRole.by_user(c.user, upsert=True).roles.append(role._id) ThreadLocalORMSession.flush_all() t = M.Thread() p = M.Post(thread=t) assert_in('TestRole', [r.name for r in c.project.named_roles]) assert_false(t.is_spam(p))
def test_post_permission_check(): d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') c.user = M.User.anonymous() try: p1 = t.post('This post will fail the check.') assert False, "Expected an anonymous post to fail." except exc.HTTPUnauthorized: pass p2 = t.post('This post will pass the check.', ignore_security=True)
def test_post_delete(): d = M.Discussion(shortname='test', name='test') t = M.Thread(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 test_not_spam_but_has_no_unmoderated_post_permission(notify_moderators, spam_checker): spam_checker.check.return_value = False d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') role = M.ProjectRole.by_name('*anonymous')._id post_permission = M.ACE.allow(role, 'post') t.acl.append(post_permission) with h.push_config(c, user=M.User.anonymous()): post = t.post('Hey') assert_equal(post.status, 'pending') assert_equal(notify_moderators.call_count, 1)
def save(self, **kw): require_access(c.app, 'write') post = BM.BlogPost() for k, v in kw.iteritems(): setattr(post, k, v) post.neighborhood_id = c.project.neighborhood_id post.make_slug() post.commit() M.Thread(discussion_id=post.app_config.discussion_id, ref_id=post.index_id(), subject='%s discussion' % post.title) redirect(h.really_unicode(post.url()).encode('utf-8'))
def test_should_update_index(self): p = M.Thread() assert_false(p.should_update_index({}, {})) old = {'num_views': 1} new = {'num_views': 2} assert_false(p.should_update_index(old, new)) old = {'num_views': 1, 'a': 1} new = {'num_views': 2, 'a': 1} assert_false(p.should_update_index(old, new)) old = {'num_views': 1, 'a': 1} new = {'num_views': 2, 'a': 2} assert_true(p.should_update_index(old, new))
def test_deleted_thread_index(): d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') p = M.Post(discussion_id=d._id, thread_id=t._id, status='ok') t.delete() ThreadLocalORMSession.flush_all() # re-query, so relationships get reloaded ThreadLocalORMSession.close_all() p = M.Post.query.get(_id=p._id) # just make sure this doesn't fail p.index()
def test_attachment_methods(): d = M.Discussion(shortname='test', name='test') t = M.Thread(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(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_equals( u'test message\n\n\nAttachment: fake.txt (37 Bytes; text/plain)', n.text)
def test_post_url_paginated(): d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') p = [] # posts in display order ts = datetime.utcnow() - timedelta(days=1) for i in range(5): ts += timedelta(minutes=1) p.append(t.post('This is a post #%s' % i, timestamp=ts)) ts += timedelta(minutes=1) p.insert(1, t.post( 'This is reply #0 to post #0', parent_id=p[0]._id, timestamp=ts)) ts += timedelta(minutes=1) p.insert(2, t.post( 'This is reply #1 to post #0', parent_id=p[0]._id, timestamp=ts)) ts += timedelta(minutes=1) p.insert(4, t.post( 'This is reply #0 to post #1', parent_id=p[3]._id, timestamp=ts)) ts += timedelta(minutes=1) p.insert(6, t.post( 'This is reply #0 to post #2', parent_id=p[5]._id, timestamp=ts)) ts += timedelta(minutes=1) p.insert(7, t.post( 'This is reply #1 to post #2', parent_id=p[5]._id, timestamp=ts)) ts += timedelta(minutes=1) p.insert(8, t.post( 'This is reply #0 to reply #1 to post #2', parent_id=p[7]._id, timestamp=ts)) # with default paging limit for _p in p: url = t.url() + '?limit=25#' + _p.slug assert _p.url_paginated() == url, _p.url_paginated() # with user paging limit limit = 3 c.user.set_pref('results_per_page', limit) for i, _p in enumerate(p): page = i // limit url = t.url() + '?limit=%s' % limit if page > 0: url += '&page=%s' % page url += '#' + _p.slug assert_equal(_p.url_paginated(), url)
def test_thread_methods(): d = M.Discussion(shortname='test', name='test') t = M.Thread(discussion_id=d._id, subject='Test Thread') assert t.discussion_class() == M.Discussion assert t.post_class() == M.Post assert t.attachment_class() == M.DiscussionAttachment p0 = t.post('This is a post') p1 = t.post('This is another post') time.sleep(0.25) p2 = t.post('This is a reply', parent_id=p0._id) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() d = M.Discussion.query.get(shortname='test') t = d.threads[0] assert d.last_post is not None assert t.last_post is not None t.create_post_threads(t.posts) posts0 = t.find_posts(page=0, limit=10, style='threaded') posts1 = t.find_posts(page=0, limit=10, style='timestamp') assert posts0 != posts1 ts = p0.timestamp.replace( microsecond=int(p0.timestamp.microsecond // 1000) * 1000) posts2 = t.find_posts(page=0, limit=10, style='threaded', timestamp=ts) assert len(posts2) > 0 assert 'wiki/_discuss/' in t.url() assert t.index()['views_i'] == 0 assert not t.subscription t.subscription = True assert t.subscription t.subscription = False assert not t.subscription assert t.top_level_posts().count() == 2 assert t.post_count == 3 jsn = t.__json__() assert '_id' in jsn assert_equals(len(jsn['posts']), 3) (p.approve() for p in (p0, p1)) assert t.num_replies == 2 t.spam() assert t.num_replies == 0 ThreadLocalORMSession.flush_all() assert len(t.find_posts()) == 0 t.delete()
def import_news(project, pid, frs_mapping, sf_project_shortname, nbhd): from forgeblog import model as BM posts = os.listdir(os.path.join(options.output_dir, pid, 'news')) if len(posts): news_app = project.app_instance('news') if not news_app: news_app = project.install_app('blog', 'news', mount_label='News') h.set_context(project.shortname, 'news', neighborhood=nbhd) # make all the blog posts for post in posts: if '.json' == post[-5:]: post_data = loadjson(pid, 'news', post) create_date = datetime.strptime(post_data.createdOn, '%Y-%m-%d %H:%M:%S') p = BM.BlogPost.query.get(title=post_data.title, timestamp=create_date, app_config_id=news_app.config._id) if not p: p = BM.BlogPost(title=post_data.title, timestamp=create_date, app_config_id=news_app.config._id) p.text = convert_post_content(frs_mapping, sf_project_shortname, post_data.body, nbhd) p.mod_date = create_date p.state = 'published' if not p.slug: p.make_slug() if not p.history().first(): p.commit() ThreadLocalORMSession.flush_all() M.Thread(discussion_id=p.app_config.discussion_id, ref_id=p.index_id(), subject='%s discussion' % p.title) user = get_user(post_data.createdByUsername) p.history().first().author = dict( id=user._id, username=user.username, display_name=user.get_pref('display_name')) ThreadLocalORMSession.flush_all()
def do_request_merge(self, **kw): kw = self.mr_widget.to_python(kw) downstream=dict( project_id=c.project._id, mount_point=c.app.config.options.mount_point, commit_id=c.app.repo.commit(kw['source_branch'])._id) with c.app.repo.push_upstream_context(): mr = M.MergeRequest.upsert( downstream=downstream, target_branch=kw['target_branch'], summary=kw['summary'], description=kw['description']) M.Notification.post( mr, 'merge_request', subject='Merge request: ' + mr.summary) t = M.Thread( discussion_id=c.app.config.discussion_id, artifact_reference=mr.index_id(), subject='Discussion for Merge Request #:%s: %s' % ( mr.request_number, mr.summary)) session(t).flush() redirect(mr.url())