def init_group(container, admin_email, emailDomain): '''Initialise the first group.''' acl_users = container.site_root().acl_users site = getattr(container.Content, SITE_ID, None) if not site: m = 'No site "{0}" found in "{1}"'.format(SITE_ID, container) raise ValueError(m) siteInfo = createObject('groupserver.SiteInfo', site) starter = MoiraeForGroup(siteInfo) groupId = 'example_group' # We want the userInfo in the context of the site admin = acl_users.get_userByEmail(admin_email) adminInfo = createObject('groupserver.UserFromId', site, admin.getId()) try: groupInfo = starter.create('Example group', groupId, 'public', emailDomain, adminInfo) except BadRequest: mumble_exists_mumble('init_group', 'groups/%s' % groupId) m = 'init_group: Skipping the rest of the group configuration.' log.warning(m) else: ju = JoiningUser(adminInfo) # Silent Join is used so if the SMTP config is borken everything # still works. ju.silent_join(groupInfo)
def handle_get_groups(self, action, data): '''The form action for the *Leave group* page. :param action: The button that was clicked. :param dict data: The form data.''' r = OrderedDict() groupInfo = createObject('groupserver.GroupInfo', self.context, data['groupId']) userInfo = createObject('groupserver.UserFromId', self.context, data['userId']) if groupInfo.groupObj is None: r['status'] = self.NO_GROUP r['message'] = 'No such group "{0}"'.format(data['groupId']) elif userInfo.anonymous: r['status'] = self.NO_USER r['message'] = 'No such user "{0}"'.format(data['userId']) elif user_member_of_group(userInfo, groupInfo): leave_group(groupInfo, userInfo, self.request) r['status'] = self.SUCCESS r['message'] = '{0} has left {1}'.format(userInfo.name, groupInfo.name) else: r['status'] = self.NOT_MEMBER r['message'] = '{0} is not a member {1}'.format(userInfo.name, groupInfo.name) r['groupId'] = data['groupId'] r['userId'] = data['userId'] retval = to_json(r) return retval
def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) # Create a conversation. conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') comment1.text = 'Comment Text' comment1.creator = "jim" comment1.author_username = "******" comment1.creation_date = datetime(2006, 9, 17, 14, 18, 12) comment1.modification_date = datetime(2006, 9, 17, 14, 18, 12) self.new_id1 = conversation.addComment(comment1) comment2 = createObject('plone.Comment') comment2.text = 'Comment Text' comment2.creator = "emma" comment2.author_username = "******" comment2.creation_date = datetime(2007, 12, 13, 4, 18, 12) comment2.modification_date = datetime(2007, 12, 13, 4, 18, 12) self.new_id2 = conversation.addComment(comment2) comment3 = createObject('plone.Comment') comment3.text = 'Comment Text' comment3.creator = "lukas" comment3.author_username = "******" comment3.creation_date = datetime(2009, 4, 12, 11, 12, 12) comment3.modification_date = datetime(2009, 4, 12, 11, 12, 12) self.new_id3 = conversation.addComment(comment3) self.conversation = conversation
def test_conversations_method(self): self.topic.invokeFactory( 'conversation', id='conv1', title='Conversation 1' ) conversation = IConversation(self.topic.conv1) comment1 = createObject('plone.Comment') comment1.creation_date = datetime.utcnow() comment1.author_name = u'John Doe' conversation.addComment(comment1) comment2 = createObject('plone.Comment') comment2.creation_date = datetime.utcnow() comment2.author_name = u'Jane Doe' conversation.addComment(comment2) from collective.ploneboard.browser.topic import TopicView view = TopicView(self.topic, self.request) conversations = view.conversations() self.assertEqual(len(conversations), 1) self.assertEqual( conversations, [ { 'title': u'Conversation 1', 'url': 'http://nohost/plone/board/topic1/conv1', 'total_comments': 2, 'last_commenter': u'Jane Doe', 'last_comment_date': comment2.creation_date, } ] )
def test_delete_comment(self): # Add and remove a comment to a CommentReplies adapter # Create a conversation. In this case we doesn't assign it to an # object, as we just want to check the Conversation object API. conversation = IConversation(self.portal.doc1) # Add a comment to the conversation replies = IReplies(conversation) comment = createObject('plone.Comment') comment.text = 'Comment text' new_id = replies.addComment(comment) comment = self.portal.doc1.restrictedTraverse( '++conversation++default/{0}'.format(new_id) ) # Add a reply to the CommentReplies adapter of the first comment re_comment = createObject('plone.Comment') re_comment.text = 'Comment text' replies = IReplies(comment) new_re_id = replies.addComment(re_comment) # Remove the reply to the CommentReplies adapter del replies[new_re_id] # Make sure there is no comment left in CommentReplies self.assertEqual(len(replies), 0) # Make sure the first comment is still in the conversation self.assertEqual(conversation.total_comments(), 1)
def __init__(self, page): """Create an edit auditor. DESCRIPTION The constructor for an auditor is passed all the data that will be the same for the events that are created during one use of the auditor by a Zope 3 page-view. ARGUMENTS "page" A IGSContentFolder representing the page being edited. SIDE EFFECTS The page is set to the page that is passed in, and used as the context for the auditor. The user (who is acting on the page) is set after determining the logged-in user, using the page as the context. The site that all this is occurring on is set, after being determined by a similar mechanism to the user. A page-edit audit event factory is instantiated. """ self.page = page self.userInfo = createObject('groupserver.LoggedInUser', page) self.siteInfo = createObject('groupserver.SiteInfo', page) self.queries = AuditQuery() self.factory = EditPageAuditEventFactory()
def __call__(self): siteInfo = createObject('groupserver.SiteInfo', self.context) auditor = Auditor(self.context, siteInfo) if len(self.traverse_subpath) == 1: # The reset ID is specified resetId = self.traverse_subpath[0] try: passwordResetUser = \ createObject('groupserver.PasswordResetUser', self.context, resetId) except ResetIdNotFoundError: auditor.info(RESET_ID_404, instanceDatum=resetId) u = '/password-reset-not-found.html?resetId={0}' uri = u.format(resetId) else: if passwordResetUser.resetId_current(resetId): auditor.info(RESET_LOGIN, passwordResetUser) # Only log in when resetting the password login(self.context, passwordResetUser.user) uri = passwordResetUser.passwordSetUrl else: auditor.info(RESET_ID_410, passwordResetUser, resetId) u = '/password-reset-used.html?resetId={0}' uri = u.format(resetId) else: auditor.info(RESET_ID_400) # the reset ID is not specified uri = '/password-reset-no-id.html' assert uri, 'URI not set' return self.request.RESPONSE.redirect(uri)
def test_marks_behavior(self): fti = queryUtility(IDexterityFTI, name='upfront.assessmentitem.content.assessmentitem') factory = fti.factory new_assessmentitem = createObject(factory) self.failUnless(IAssessmentItem.providedBy(new_assessmentitem)) fti = queryUtility(IDexterityFTI, name='upfront.assessmentitem.content.answer') factory = fti.factory new_answer = createObject(factory) self.failUnless(IAnswer.providedBy(new_answer)) marks_behavior = getUtility(IBehavior, name = 'upfront.assessmentitem.behaviors.IMarks') # We expect this behavior to be a form field provider. Let's verify that self.failUnless( IFormFieldProvider.providedBy(marks_behavior.interface) ) # assert that you cannot add this behavior to a non-dexterity # content type doc = Document('doc') marks_adapter = IMarks(doc, None) self.assertEquals(False, marks_adapter is not None) # assert that new_assessmentitem object implements the behavior marks_adapter2 = IMarks(new_assessmentitem, None) self.assertEquals(True, marks_adapter2 is not None) # assert that new_answer object does not implements the behavior marks_adapter3 = IMarks(new_answer, None) self.assertEquals(False, marks_adapter3 is not None)
def setUp(self): self.app = self.layer["app"] self.portal = self.layer["portal"] self.request = self.layer["request"] setRoles(self.portal, TEST_USER_ID, ["Manager"]) typetool = self.portal.portal_types typetool.constructContent("Document", self.portal, "doc1") self.wf = getToolByName(self.portal, "portal_workflow", None) self.context = self.portal self.portal.portal_workflow.setChainForPortalTypes(("Discussion Item",), "comment_review_workflow") self.wf_tool = self.portal.portal_workflow # Add a conversation with three comments conversation = IConversation(self.portal.doc1) comment1 = createObject("plone.Comment") comment1.title = "Comment 1" comment1.text = "Comment text" comment1.Creator = "Jim" new_id_1 = conversation.addComment(comment1) self.comment1 = self.portal.doc1.restrictedTraverse("++conversation++default/%s" % new_id_1) comment2 = createObject("plone.Comment") comment2.title = "Comment 2" comment2.text = "Comment text" comment2.Creator = "Joe" new_id_2 = conversation.addComment(comment2) self.comment2 = self.portal.doc1.restrictedTraverse("++conversation++default/%s" % new_id_2) comment3 = createObject("plone.Comment") comment3.title = "Comment 3" comment3.text = "Comment text" comment3.Creator = "Emma" new_id_3 = conversation.addComment(comment3) self.comment3 = self.portal.doc1.restrictedTraverse("++conversation++default/%s" % new_id_3) self.conversation = conversation
def setUp(self): # Setup sandbox self.portal = self.layer['portal'] self.request = self.layer['request'] setRoles(self.portal, TEST_USER_ID, ['Manager']) self.document = self.portal['doc1'] conversation = IConversation(self.document) replies = IReplies(conversation) comment = createObject('plone.Comment') comment.text = 'This is a comment' new_id = replies.addComment(comment) comment = self.document.restrictedTraverse( '++conversation++default/{0}'.format(new_id) ) re_comment = createObject('plone.Comment') re_comment.text = 'This is a reply' re_comment.author_username = '******' re_comment.author_name = 'Juliana' re_comment.author_email = '*****@*****.**' replies = IReplies(comment) replies.addComment(re_comment)
def test_notify_user(self): # Add a comment with user notification enabled. Add another comment # and make sure an email is send to the user of the first comment. comment = createObject("plone.Comment") comment.text = "Comment text" comment.user_notification = True comment.author_email = "*****@*****.**" self.conversation.addComment(comment) comment = createObject("plone.Comment") comment.text = "Comment text" comment_id = self.conversation.addComment(comment) self.assertEqual(len(self.mailhost.messages), 1) self.assertTrue(self.mailhost.messages[0]) msg = str(self.mailhost.messages[0]) self.assertTrue("To: [email protected]" in msg) self.assertTrue("From: [email protected]" in msg) # We expect the headers to be properly header encoded (7-bit): self.assertTrue("Subject: =?utf-8?q?A_comment_has_been_posted=2E?=\n" in msg) # The output should be encoded in a reasonable manner # (in this case quoted-printable): self.assertTrue("A comment on 'K=C3=B6lle Alaaf' has been posted here:" in msg) self.assertTrue("http://nohost/plone/d=\noc1/view#%s" % comment_id in msg) self.assertTrue("Comment text" in msg) self.assertFalse("Approve comment" in msg) self.assertFalse("Delete comment" in msg)
def add_new_user(self, toAddr, profileDict): # Email address does not exist, but it is a legitimate address user = create_user_from_email(self.context, toAddr) # force verify vid = '%s-%s-verified' % (toAddr, self.adminInfo.id) evu = createObject('groupserver.EmailVerificationUserFromEmail', self.context, toAddr) evu.add_verification_id(vid) evu.verify_email(vid) # get the user object in the context of the group and site userInfo = createObject('groupserver.UserFromId', self.context, user.id) self.add_profile_attributes(userInfo, profileDict) auditor = self.get_auditor(userInfo) status = ADD_NEW_USER auditor.info(status, toAddr) joininguser = IGSJoiningUser(userInfo) joininguser.silent_join(self.groupInfo) e = '<code class="email">{0}</code>'.format(toAddr) msg = _('new-profile-member', '<li>A profile for ${user} has been created, and given the ' 'email address ${email}.</li>\n' '<li>${user} has been joined to ${group}.</li>\n', mapping={'email': e, 'user': userInfo_to_anchor(userInfo), 'group': groupInfo_to_anchor(self.groupInfo)}) retval = (msg, userInfo, status) return retval
def process_form(self): '''Process the forms in the page. This method uses the "submitted" pattern that is used for the XForms impementation on GroupServer. * The method is called whenever the page is loaded by tal:define="result view/process_form". * The submitted form is checked for the hidden "submitted" field. This field is only returned if the user submitted the form, not when the page is loaded for the first time. - If the field is present, then the form is processed. - If the field is absent, then the method re turns. RETURNS A "result" dictionary, that at-least contains the form that was submitted ''' form = self.context.REQUEST.form result = {} result['form'] = form if 'submitted' in form: groupIds = [k.split('-respond')[0] for k in form.keys() if '-respond' in k] responses = [form['%s-respond' % k] for k in groupIds] result['error'] = False acceptedMessage = declinedMessage = u'' accepted = [k.split('-accept')[0] for k in responses if '-accept' in k] if accepted: acceptedGroups = [createObject('groupserver.GroupInfo', self.groupsInfo.groupsObj, g) for g in accepted] self.accept_invitations(acceptedGroups) acceptedMessage = self.accept_message(acceptedGroups) declined = [k.split('-decline')[0] for k in responses if '-decline' in k] for d in declined: assert d not in accepted if declined: declinedGroups = [createObject('groupserver.GroupInfo', self.groupsInfo.groupsObj, g) for g in declined] self.decline_invitations(declinedGroups) declinedMessage = self.decline_message(declinedGroups) result['message'] = u'%s\n%s' % \ (acceptedMessage, declinedMessage) self.__currentInvitations = None assert 'error' in result, 'No "errror" in the result' assert type(result['error']) == bool assert 'message' in result, 'No "message" in the result' assert type(result['message']) == unicode # Invalidate the current invitations property, so it is recomputed. del self._current_invitations assert 'form' in result assert type(result['form']) == dict return result
def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) workflow = self.portal.portal_workflow workflow.doActionFor(self.portal.doc1, 'publish') # Create a conversation. conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') comment1.text = 'Comment Text' comment1.creator = 'jim' comment1.author_username = '******' comment1.creation_date = datetime(2006, 9, 17, 14, 18, 12) comment1.modification_date = datetime(2006, 9, 17, 14, 18, 12) self.new_id1 = conversation.addComment(comment1) comment2 = createObject('plone.Comment') comment2.text = 'Comment Text' comment2.creator = 'emma' comment2.author_username = '******' comment2.creation_date = datetime(2007, 12, 13, 4, 18, 12) comment2.modification_date = datetime(2007, 12, 13, 4, 18, 12) self.new_id2 = conversation.addComment(comment2) comment3 = createObject('plone.Comment') comment3.text = 'Comment Text' comment3.creator = 'lukas' comment3.author_username = '******' comment3.creation_date = datetime(2009, 4, 12, 11, 12, 12) comment3.modification_date = datetime(2009, 4, 12, 11, 12, 12) self.new_id3 = conversation.addComment(comment3) self.conversation = conversation
def setUp(self): # Setup session manager ztc.utils.setupCoreSessions(self.layer['app']) # Setup sandbox self.portal = self.layer['portal'] self.request = self.layer['request'] setRoles(self.portal, TEST_USER_ID, ['Manager']) name = self.portal.invokeFactory( id='doc1', title='Document 1', type_name='Document') self.document = self.portal[name] conversation = IConversation(self.document) replies = IReplies(conversation) comment = createObject('plone.Comment') comment.text = 'This is a comment' new_id = replies.addComment(comment) comment = self.document.restrictedTraverse( '++conversation++default/%s' % new_id) re_comment = createObject('plone.Comment') re_comment.text = 'This is a reply' re_comment.author_username = "******" re_comment.author_name = "Juliana" re_comment.author_email = "*****@*****.**" replies = IReplies(comment) new_re_id = replies.addComment(re_comment)
def __call__(self): siteInfo = createObject('groupserver.SiteInfo', self.context) auditor = Auditor(self.context, siteInfo) if len(self.traverse_subpath) == 1: # A verification ID is present verificationId = self.traverse_subpath[0] try: emailVerificationUser = \ createObject('groupserver.EmailVerificationUser', self.context, verificationId) except VerificationIdNotFoundError: auditor.info(VERIFY_ID_404, instanceDatum=verificationId) uri = '/email-verify-not-found.html?verificationId=%s' % \ verificationId else: if emailVerificationUser.verificationId_current(verificationId): auditor.info(VERIFY_LOGIN, emailVerificationUser) # Only log in when able to verify the email address login(self.context, emailVerificationUser.user) uri = '%s?verificationId=%s' % \ (emailVerificationUser.emailVerifyUrl, verificationId) else: auditor.info(VERIFY_ID_410, emailVerificationUser, verificationId) uri = '/email-verify-used.html?verificationId=%s' %\ verificationId else: auditor.info(VERIFY_ID_400) # No verification ID is present uri = '/email-verify-no-id.html' assert uri, 'URI not set' return self.request.RESPONSE.redirect(uri)
def test_add_comment(self): # Add comments to a CommentReplies adapter # Create a conversation. In this case we doesn't assign it to an # object, as we just want to check the Conversation object API. conversation = IConversation(self.portal.doc1) # Add a comment to the conversation replies = IReplies(conversation) comment = createObject('plone.Comment') comment.text = 'Comment text' new_id = replies.addComment(comment) comment = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_id) # Add a reply to the CommentReplies adapter of the first comment re_comment = createObject('plone.Comment') re_comment.text = 'Comment text' replies = IReplies(comment) new_re_id = replies.addComment(re_comment) # check that replies provides the IReplies interface self.assertTrue(IReplies.providedBy(replies)) # Make sure our comment was added self.assertTrue(new_re_id in replies) # Make sure it is also reflected in the conversation self.assertTrue(new_re_id in conversation) # Make sure the conversation has the correct comment id self.assertEqual(conversation[new_re_id].comment_id, new_re_id)
def __init__(self, site): self.site = site self.userInfo = createObject('groupserver.LoggedInUser', site) self.siteInfo = createObject('groupserver.SiteInfo', site) self.queries = AuditQuery() self.factory = ChangeAuditEventFactory()
def test_traversal(self): # Create a nested structure of comment replies and check the traversal # make sure comments are traversable, have an id, absolute_url and # physical path conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') comment1.text = 'Comment text' conversation.addComment(comment1) comment = createObject('plone.Comment') comment.text = 'Comment text' new_id = conversation.addComment(comment) comment = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_id) # Add a reply to the CommentReplies adapter of the first comment re_comment = createObject('plone.Comment') re_comment.text = 'Comment text' replies = IReplies(comment) new_re_id = replies.addComment(re_comment) re_comment = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_re_id) # Add a reply to the reply re_re_comment = createObject('plone.Comment') re_re_comment.text = 'Comment text' replies = IReplies(re_comment) new_re_re_id = replies.addComment(re_re_comment) re_re_comment = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_re_re_id) # Add a reply to the replies reply re_re_re_comment = createObject('plone.Comment') re_re_re_comment.text = 'Comment text' replies = IReplies(re_re_comment) new_re_re_re_id = replies.addComment(re_re_re_comment) re_re_re_comment = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_re_re_re_id) self.assertEqual(('', 'plone', 'doc1', '++conversation++default', str(new_id)), comment.getPhysicalPath()) self.assertEqual('http://nohost/plone/doc1/++conversation++default/' + str(new_id), comment.absolute_url()) self.assertEqual(('', 'plone', 'doc1', '++conversation++default', str(new_re_id)), re_comment.getPhysicalPath()) self.assertEqual('http://nohost/plone/doc1/++conversation++default/' + str(new_re_id), re_comment.absolute_url()) self.assertEqual(('', 'plone', 'doc1', '++conversation++default', str(new_re_re_id)), re_re_comment.getPhysicalPath()) self.assertEqual('http://nohost/plone/doc1/++conversation++default/' + str(new_re_re_id), re_re_comment.absolute_url()) self.assertEqual(('', 'plone', 'doc1', '++conversation++default', str(new_re_re_re_id)), re_re_re_comment.getPhysicalPath()) self.assertEqual('http://nohost/plone/doc1/++conversation++default/' + str(new_re_re_re_id), re_re_re_comment.absolute_url())
def __init__(self, user): self.user = user self.userInfo = createObject('groupserver.LoggedInUser', user) self.instanceUserInfo = IGSUserInfo(user) self.siteInfo = createObject('groupserver.SiteInfo', user) self.queries = AuditQuery() self.factory = CustomUserAuditEventFactory()
def __init__(self, groupInfo, eDict): self.groupInfo = groupInfo self.userInfo = createObject('groupserver.UserFromId', self.groupInfo.groupObj, eDict['user_id']) self.date = eDict['date'] self.removingUserInfo = createObject('groupserver.UserFromId', self.groupInfo.groupObj, eDict['admin_id']) self.css = 'leave-event'
def test_commentators(self): # add and remove a few comments to make sure the commentators # property returns a true set # Create a conversation. In this case we doesn't assign it to an # object, as we just want to check the Conversation object API. conversation = IConversation(self.portal.doc1) self.assertEqual(conversation.total_comments, 0) # Add a four comments from three different users # Note: in real life, we always create # comments via the factory to allow different factories to be # swapped in comment1 = createObject('plone.Comment') comment1.text = 'Comment text' comment1.author_username = "******" conversation.addComment(comment1) comment2 = createObject('plone.Comment') comment2.text = 'Comment text' comment2.author_username = "******" conversation.addComment(comment2) comment3 = createObject('plone.Comment') comment3.text = 'Comment text' comment3.author_username = "******" new_comment3_id = conversation.addComment(comment3) comment4 = createObject('plone.Comment') comment4.text = 'Comment text' comment4.author_username = "******" new_comment4_id = conversation.addComment(comment4) # check if all commentators are in the commentators list self.assertEqual(conversation.total_comments, 4) self.assertTrue('Jim' in conversation.commentators) self.assertTrue('Joe' in conversation.commentators) self.assertTrue('Jack' in conversation.commentators) # remove the comment from Jack del conversation[new_comment3_id] # check if Jack is still in the commentators list (since # he had added two comments) self.assertTrue('Jim' in conversation.commentators) self.assertTrue('Joe' in conversation.commentators) self.assertTrue('Jack' in conversation.commentators) self.assertEqual(conversation.total_comments, 3) # remove the second comment from Jack del conversation[new_comment4_id] # check if Jack has been removed from the commentators list self.assertTrue('Jim' in conversation.commentators) self.assertTrue('Joe' in conversation.commentators) self.assertFalse('Jack' in conversation.commentators) self.assertEqual(conversation.total_comments, 2)
def test_uid_is_unique(self): conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') conversation.addComment(comment1) comment2 = createObject('plone.Comment') conversation.addComment(comment2) brains = self.catalog.searchResults( portal_type = 'Discussion Item') self.assertNotEqual(brains[0].UID, brains[1].UID)
def update(self): self.__updated = True self.siteInfo = createObject('groupserver.SiteInfo', self.context) self.groupInfo = createObject('groupserver.GroupInfo', self.context) self.userInfo = createObject('groupserver.LoggedInUser', self.context)
def suggested_groups(self): siteInfo = createObject('groupserver.SiteInfo', self.context) groupNames = siteInfo.get_property('suggestedGroups', []) suggestedGroups = [] if self.maxGroupsToDisplay: groupNames = groupNames[:self.maxGroupsToDisplay] for groupName in groupNames: suggestedGroups.append( createObject('groupserver.GroupInfo', self.context, groupName)) return suggestedGroups
def update(self): self.__updated = True self.siteInfo = createObject('groupserver.SiteInfo', self.context) self.groupsInfo = createObject('groupserver.GroupsInfo', self.context) rws = [w for w in self.widgets if w.required] rwIds = ['\'#%s\'' % w.name.replace('.', '\\\\.') for w in rws] self.requiredWidgetsArray = '%s' % ', '.join(rwIds);
def test_connection_failure(self): sci = self.layer.sci sci['password'] = '******' from splunklib.binding import AuthenticationError with self.assertRaises(AuthenticationError): component.createObject(u'sparc.db.splunk.saved_searches_factory', sci)
def test_clear_and_rebuild_catalog_for_nested_comments(self): # Create a nested comment structure: # # Conversation # +- Comment 1 # +- Comment 1_1 # | +- Comment 1_1_1 # +- Comment 1_2 # +- Comment 2 # +- Comment 2_1 comment1_1 = createObject("plone.Comment") comment1_1.title = "Re: Comment 1" comment1_1.text = "Comment text" comment1_1_1 = createObject("plone.Comment") comment1_1_1.title = "Re: Re: Comment 1" comment1_1_1.text = "Comment text" comment1_2 = createObject("plone.Comment") comment1_2.title = "Re: Comment 1 (2)" comment1_2.text = "Comment text" comment2 = createObject("plone.Comment") comment2.title = "Comment 2" comment2.text = "Comment text" comment2_1 = createObject("plone.Comment") comment2_1.title = "Re: Comment 2" comment2_1.text = "Comment text" # Create the nested comment structure new_id_1 = self.conversation.addComment(self.comment) new_id_2 = self.conversation.addComment(comment2) comment1_1.in_reply_to = self.comment_id new_id_1_1 = self.conversation.addComment(comment1_1) comment1_1_1.in_reply_to = new_id_1_1 self.conversation.addComment(comment1_1_1) comment1_2.in_reply_to = new_id_1 self.conversation.addComment(comment1_2) comment2_1.in_reply_to = new_id_2 self.conversation.addComment(comment2_1) # Clear and rebuild catalog self.catalog.clearFindAndRebuild() # Check if comments are still there brains = self.catalog.searchResults({"portal_type": "Discussion Item"}) self.assertTrue(brains) self.assertEqual(len(brains), 6)
def test_do_not_notify_user_when_email_address_is_given(self): comment = createObject("plone.Comment") comment.text = "Comment text" comment.user_notification = True self.conversation.addComment(comment) comment = createObject("plone.Comment") comment.text = "Comment text" self.conversation.addComment(comment) self.assertEqual(len(self.mailhost.messages), 0)
def test_dict_operations(self): # test dict operations and acquisition wrapping # Create a conversation. In this case we doesn't assign it to an # object, as we just want to check the Conversation object API. conversation = IConversation(self.portal.doc1) # Add a comment. Note: in real life, we always create comments via the # factory to allow different factories to be swapped in comment1 = createObject('plone.Comment') comment1.text = 'Comment text' new_id1 = conversation.addComment(comment1) comment2 = createObject('plone.Comment') comment2.text = 'Comment text' new_id2 = conversation.addComment(comment2) # check if get returns a comment object, and None if the key # can not be found self.assertTrue(IComment.providedBy(conversation.get(new_id1))) self.assertTrue(IComment.providedBy(conversation.get(new_id2))) self.assertEqual(conversation.get(123), None) # check if keys return the ids of all comments self.assertEqual(len(conversation.keys()), 2) self.assertTrue(new_id1 in conversation.keys()) self.assertTrue(new_id2 in conversation.keys()) self.assertFalse(123 in conversation.keys()) # check if items returns (key, comment object) pairs self.assertEqual(len(conversation.items()), 2) self.assertTrue((new_id1, comment1) in conversation.items()) self.assertTrue((new_id2, comment2) in conversation.items()) # check if values returns the two comment objects self.assertEqual(len(conversation.values()), 2) self.assertTrue(comment1 in conversation.values()) self.assertTrue(comment2 in conversation.values()) # check if comment ids are in iterkeys self.assertTrue(new_id1 in conversation.iterkeys()) self.assertTrue(new_id2 in conversation.iterkeys()) self.assertFalse(123 in conversation.iterkeys()) # check if comment objects are in itervalues self.assertTrue(comment1 in conversation.itervalues()) self.assertTrue(comment2 in conversation.itervalues()) # check if iteritems returns (key, comment object) pairs self.assertTrue((new_id1, comment1) in conversation.iteritems()) self.assertTrue((new_id2, comment2) in conversation.iteritems())
def test_get_threads(self): # Create a conversation. In this case we doesn't assign it to an # object, as we just want to check the Conversation object API. conversation = IConversation(self.portal.doc1) IReplies(conversation) # Create a nested comment structure: # # Conversation # +- Comment 1 # +- Comment 1_1 # | +- Comment 1_1_1 # +- Comment 1_2 # +- Comment 2 # +- Comment 2_1 # Create all comments comment1 = createObject('plone.Comment') comment1.text = 'Comment text' comment1_1 = createObject('plone.Comment') comment1_1.text = 'Comment text' comment1_1_1 = createObject('plone.Comment') comment1_1_1.text = 'Comment text' comment1_2 = createObject('plone.Comment') comment1_2.text = 'Comment text' comment2 = createObject('plone.Comment') comment2.text = 'Comment text' comment2_1 = createObject('plone.Comment') comment2_1.text = 'Comment text' # Create the nested comment structure new_id_1 = conversation.addComment(comment1) new_id_2 = conversation.addComment(comment2) comment1_1.in_reply_to = new_id_1 new_id_1_1 = conversation.addComment(comment1_1) comment1_1_1.in_reply_to = new_id_1_1 new_id_1_1_1 = conversation.addComment(comment1_1_1) comment1_2.in_reply_to = new_id_1 new_id_1_2 = conversation.addComment(comment1_2) comment2_1.in_reply_to = new_id_2 new_id_2_1 = conversation.addComment(comment2_1) # Get threads self.assertEqual([ { 'comment': comment1, 'depth': 0, 'id': new_id_1 }, { 'comment': comment1_1, 'depth': 1, 'id': new_id_1_1 }, { 'comment': comment1_1_1, 'depth': 2, 'id': new_id_1_1_1 }, { 'comment': comment1_2, 'depth': 1, 'id': new_id_1_2 }, { 'comment': comment2, 'depth': 0, 'id': new_id_2 }, { 'comment': comment2_1, 'depth': 1, 'id': new_id_2_1 }, ], list(conversation.getThreads()))
def loggedInUserInfo(self): retval = createObject('groupserver.LoggedInUser', self.context) assert retval, 'Could not create the user-info for the logged '\ 'in user from %s' % self.context return retval
def __iter__(self): """Iterator of unicode capable ordered values""" return iter([ createObject(u'sparc.db.result_value', value) for value in self.context ])
def test_owner(self): comment1 = createObject('plone.Comment') self.assertEqual((['plone', 'acl_users'], TEST_USER_ID), comment1.getOwnerTuple())
def loggedInUser(self): '''Information about the currently logged-in user.''' retval = createObject('groupserver.LoggedInUser', self.context) return retval
def adminInfo(self): retval = createObject('groupserver.LoggedInUser', self.context) assert not(retval.anonymous) return retval
def test_factory(self): fti = queryUtility(IDexterityFTI, name='collective.composition.composition') factory = fti.factory new_object = createObject(factory) self.failUnless(IComposition.providedBy(new_object))
def test_no_name_title(self): conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') conversation.addComment(comment1) self.assertEqual('Anonymous on Document 1', comment1.Title())
def test_title(self): conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') comment1.author_name = 'Jim Fulton' conversation.addComment(comment1) self.assertEqual('Jim Fulton on Document 1', comment1.Title())
def test_id(self): comment1 = createObject('plone.Comment') comment1.comment_id = 123 self.assertEqual('123', comment1.id) self.assertEqual('123', comment1.getId()) self.assertEqual(u'123', comment1.__name__)
def test_traversal(self): # Create a nested structure of comment replies and check the traversal # make sure comments are traversable, have an id, absolute_url and # physical path conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') comment1.text = 'Comment text' conversation.addComment(comment1) comment = createObject('plone.Comment') comment.text = 'Comment text' new_id = conversation.addComment(comment) comment = self.portal.doc1.restrictedTraverse( '++conversation++default/{0}'.format(new_id), ) # Add a reply to the CommentReplies adapter of the first comment re_comment = createObject('plone.Comment') re_comment.text = 'Comment text' replies = IReplies(comment) new_re_id = replies.addComment(re_comment) re_comment = self.portal.doc1.restrictedTraverse( '++conversation++default/{0}'.format(new_re_id), ) # Add a reply to the reply re_re_comment = createObject('plone.Comment') re_re_comment.text = 'Comment text' replies = IReplies(re_comment) new_re_re_id = replies.addComment(re_re_comment) re_re_comment = self.portal.doc1.restrictedTraverse( '++conversation++default/{0}'.format(new_re_re_id), ) # Add a reply to the replies reply re_re_re_comment = createObject('plone.Comment') re_re_re_comment.text = 'Comment text' replies = IReplies(re_re_comment) new_re_re_re_id = replies.addComment(re_re_re_comment) re_re_re_comment = self.portal.doc1.restrictedTraverse( '++conversation++default/{0}'.format(new_re_re_re_id), ) self.assertEqual( ('', 'plone', 'doc1', '++conversation++default', str(new_id)), comment.getPhysicalPath(), ) self.assertEqual( 'http://nohost/plone/doc1/++conversation++default/' + str(new_id), comment.absolute_url(), ) self.assertEqual( ('', 'plone', 'doc1', '++conversation++default', str(new_re_id)), re_comment.getPhysicalPath(), ) self.assertEqual( 'http://nohost/plone/doc1/++conversation++default/' + str(new_re_id), re_comment.absolute_url(), ) self.assertEqual( ( '', 'plone', 'doc1', '++conversation++default', str(new_re_re_id), ), re_re_comment.getPhysicalPath(), ) self.assertEqual( 'http://nohost/plone/doc1/++conversation++default/' + str(new_re_re_id), re_re_comment.absolute_url(), ) self.assertEqual( ( '', 'plone', 'doc1', '++conversation++default', str(new_re_re_re_id), ), re_re_re_comment.getPhysicalPath(), ) self.assertEqual( 'http://nohost/plone/doc1/++conversation++default/' + str(new_re_re_re_id), re_re_re_comment.absolute_url(), )
def test_factory(self): fti = queryUtility(IDexterityFTI, name='News Item') factory = fti.factory new_object = createObject(factory) self.assertTrue(INewsItem.providedBy(new_object))
def test_creator_author_name(self): comment1 = createObject('plone.Comment') comment1.author_name = 'joey' self.assertEqual('joey', comment1.Creator())
def test_dict_api(self): # This test is for the ConversationReplies as well as the # CommentReplies adapter. # # Ensure all operations use only top-level comments. Add some # deeper children and ensure that these are not exposed through the # IReplies dict. # Create a conversation. In this case we doesn't assign it to an # object, as we just want to check the Conversation object API. conversation = IConversation(self.portal.doc1) replies = IReplies(conversation) # Create a nested comment structure: # # Conversation # +- Comment 1 # +- Comment 1_1 # | +- Comment 1_1_1 # +- Comment 1_2 # +- Comment 2 # +- Comment 2_1 # Create all comments comment1 = createObject('plone.Comment') comment1.text = 'Comment text' comment1_1 = createObject('plone.Comment') comment1_1.text = 'Comment text' comment1_1_1 = createObject('plone.Comment') comment1_1_1.text = 'Comment text' comment1_2 = createObject('plone.Comment') comment1_2.text = 'Comment text' comment2 = createObject('plone.Comment') comment2.text = 'Comment text' comment2_1 = createObject('plone.Comment') comment2_1.text = 'Comment text' # Create the nested comment structure new_id_1 = replies.addComment(comment1) comment1 = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_id_1) replies_to_comment1 = IReplies(comment1) new_id_2 = replies.addComment(comment2) comment2 = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_id_2) replies_to_comment2 = IReplies(comment2) new_id_1_1 = replies_to_comment1.addComment(comment1_1) comment1_1 = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_id_1_1) replies_to_comment1_1 = IReplies(comment1_1) replies_to_comment1_1.addComment(comment1_1_1) replies_to_comment1.addComment(comment1_2) replies_to_comment2.addComment(comment2_1) # check that replies only contain the direct comments # and no comments deeper than 1 self.assertEqual(conversation.total_comments(), 6) self.assertEqual(len(replies), 2) self.assertEqual(len(replies_to_comment1), 2) self.assertEqual(len(replies_to_comment1_1), 1) self.assertEqual(len(replies_to_comment2), 1)
def test_factory(self): fti = queryUtility(IDexterityFTI, name='collective.conference.speaker') factory = fti.factory new_object = createObject(factory) self.failUnless(ISpeaker.providedBy(new_object))
def test_factory(self): fti = queryUtility(IDexterityFTI, name='Task') factory = fti.factory obj = createObject(factory) self.assertTrue(ITask.providedBy(obj))
def process_form(self): '''Process the forms in the page. This method uses the "submitted" pattern that is used for the XForms impementation on GroupServer. * The method is called whenever the page is loaded by tal:define="result view/process_form". * The submitted form is checked for the hidden "submitted" field. This field is only returned if the user submitted the form, not when the page is loaded for the first time. - If the field is present, then the form is processed. - If the field is absent, then the method re turns. RETURNS A "result" dictionary, that at-least contains the form that was submitted''' # TOOD: I could probabily implement this page as a list of # choice fields, and a custom widget to display the data # about the membership request. However, it is easier to # reuse an old pattern than figure out how to get formlib # to behave. form = self.context.REQUEST.form result = {} result['form'] = form m = '' if 'submitted' in form: userIds = [k.split('-respond')[0] for k in list(form.keys()) if '-respond' in k] responses = [form['%s-respond' % k] for k in userIds] result['error'] = False acceptor = Acceptor(self.adminInfo, self.groupInfo) auditor = ResponseAuditor(self.context, self.adminInfo, self.groupInfo, self.siteInfo) accepted = [k.split('-accept')[0] for k in responses if '-accept' in k] if accepted: notifier = NotifyAccepted(self.context, self.request) for uid in accepted: userInfo = createObject('groupserver.UserFromId', self.context, uid) m = m + ('<li>%s</li>\n' % acceptor.accept(userInfo)) notifier.notify(userInfo, self.adminInfo) auditor.info(ACCEPT, userInfo) declined = [k.split('-decline')[0] for k in responses if '-decline' in k] for d in declined: assert d not in accepted if declined: notifier = NotifyDeclined(self.context, self.request) for uid in declined: userInfo = createObject('groupserver.UserFromId', self.context, uid) m = m + ('<li>%s</li>\n' % acceptor.decline(userInfo)) auditor.info(DECLINE, userInfo) notifier.notify(userInfo, self.adminInfo) result['message'] = '<ul>\n{0}</ul>'.format(m) assert 'error' in result assert 'message' in result assert 'form' in result return result
def siteInfo(self): '''Information about the current site.''' retval = createObject('groupserver.SiteInfo', self.context) return retval
def userInfo(self): retval = createObject('groupserver.UserFromId', self.context, self.userId) assert not(retval.anonymous) return retval
def test_creator(self): comment1 = createObject('plone.Comment') comment1.creator = 'jim' self.assertEqual('jim', comment1.Creator())
def test_factory(self): fti = queryUtility(IDexterityFTI, name='ExternalContent') factory = fti.factory new_object = createObject(factory) self.assertTrue(IExternalContent.providedBy(new_object))
def test_type(self): comment1 = createObject('plone.Comment') self.assertEqual(comment1.Type(), 'Comment')
def handleComment(self, action): context = aq_inner(self.context) # Check if conversation is enabled on this content object if not self.__parent__.restrictedTraverse( '@@conversation_view').enabled(): raise Unauthorized("Discussion is not enabled for this content " "object.") # Validation form data, errors = self.extractData() if errors: return # Validate Captcha registry = queryUtility(IRegistry) settings = registry.forInterface(IDiscussionSettings, check=False) portal_membership = getToolByName(self.context, 'portal_membership') if settings.captcha != 'disabled' and \ settings.anonymous_comments and \ portal_membership.isAnonymousUser(): if not 'captcha' in data: data['captcha'] = u"" captcha = CaptchaValidator(self.context, self.request, None, ICaptcha['captcha'], None) captcha.validate(data['captcha']) # some attributes are not always set author_name = u"" # Create comment comment = createObject('plone.Comment') # Set comment mime type to current setting in the discussion registry comment.mime_type = settings.text_transform # Set comment attributes (including extended comment form attributes) for attribute in self.fields.keys(): setattr(comment, attribute, data[attribute]) # Make sure author_name is properly encoded if 'author_name' in data: author_name = data['author_name'] if isinstance(author_name, str): author_name = unicode(author_name, 'utf-8') # Set comment author properties for anonymous users or members can_reply = getSecurityManager().checkPermission( 'Reply to item', context) portal_membership = getToolByName(self.context, 'portal_membership') if portal_membership.isAnonymousUser() and \ settings.anonymous_comments: # Anonymous Users comment.author_name = author_name comment.author_email = u"" comment.user_notification = None comment.creation_date = datetime.utcnow() comment.modification_date = datetime.utcnow() elif not portal_membership.isAnonymousUser() and can_reply: # Member member = portal_membership.getAuthenticatedMember() username = member.getUserName() email = member.getProperty('email') fullname = member.getProperty('fullname') if not fullname or fullname == '': fullname = member.getUserName() # memberdata is stored as utf-8 encoded strings elif isinstance(fullname, str): fullname = unicode(fullname, 'utf-8') if email and isinstance(email, str): email = unicode(email, 'utf-8') comment.creator = username comment.author_username = username comment.author_name = fullname comment.author_email = email comment.creation_date = datetime.utcnow() comment.modification_date = datetime.utcnow() else: # pragma: no cover raise Unauthorized( "Anonymous user tries to post a comment, but " "anonymous commenting is disabled. Or user does not have the " "'reply to item' permission.") # Add comment to conversation conversation = IConversation(self.__parent__) if data['in_reply_to']: # Add a reply to an existing comment conversation_to_reply_to = conversation.get(data['in_reply_to']) replies = IReplies(conversation_to_reply_to) comment_id = replies.addComment(comment) else: # Add a comment to the conversation comment_id = conversation.addComment(comment) # Redirect after form submit: # If a user posts a comment and moderation is enabled, a message is # shown to the user that his/her comment awaits moderation. If the user # has 'review comments' permission, he/she is redirected directly # to the comment. can_review = getSecurityManager().checkPermission( 'Review comments', context) workflowTool = getToolByName(context, 'portal_workflow') comment_review_state = workflowTool.getInfoFor(comment, 'review_state') if comment_review_state == 'pending' and not can_review: # Show info message when comment moderation is enabled IStatusMessage(self.context.REQUEST).addStatusMessage( _("Your comment awaits moderator approval."), type="info") self.request.response.redirect(self.action) else: # Redirect to comment (inside a content object page) self.request.response.redirect(self.action + '#' + str(comment_id))
def siteInfo(self): retval = createObject('groupserver.SiteInfo', self.context) return retval
def get_results(self): if not self.__updated: raise UpdateNotCalled() groupCache = getattr(self.view, '__group_object_cache', {}) authorCache = getattr(self.view, '__author_object_cache', {}) for result in self.results: r = GSFileSearchResult(self.view, self.context, result) postId = self.filePostMap.get(r.get_id(), '') authorInfo = authorCache.get(r.get_owner_id(), None) if not authorInfo: authorInfo = createObject('groupserver.UserFromId', self.context, r.get_owner_id()) authorCache[r.get_owner_id()] = authorInfo authorId = authorInfo.id only = False if self.view.author_count() == 1: only = True authorD = { 'id': authorInfo.id, 'exists': not authorInfo.anonymous, 'url': authorInfo.url, 'name': authorInfo.name, 'only': only, 'onlyURL': self.view.only_author_link(authorId) } groupInfo = groupCache.get(r.get_group_info().get_id(), None) if not groupInfo: groupInfo = createObject('groupserver.GroupInfo', self.context, r.get_group_info().get_id()) groupCache[r.get_group_info().get_id()] = groupInfo group_count = self.view.group_count() only_group = False if group_count == 1: only_group = True groupD = { 'id': groupInfo.get_id(), 'name': groupInfo.get_name(), 'url': groupInfo.get_url(), 'only': only_group, 'onlyURL': self.view.only_group_link(groupInfo.get_id()) } tags = ' '.join(r.get_tags()) tagSearch = self.view.get_search_url(searchText=tags) fileURL = '/r/file/%s' % r.get_id() fileD = { 'id': r.get_id(), 'file': fileURL, 'type': r.get_type(), 'size': r.get_size(), 'title': r.get_title(), 'tags': r.get_tags(), 'tag_search': tagSearch, 'date': r.get_date(), 'rfc3339_date': r.rfc3339_date, 'url': r.get_url(), 'thumbnail_url': r.thumbnail_url, } topicURL = '/groups/{0}/messages/topic/{1}'.format( groupInfo.id, postId) topicD = { 'name': r.get_topic_name(), 'url': topicURL, } postURL = '/r/post/%s' % postId postD = { 'id': postId, 'url': postURL, } retval = { 'file': fileD, 'group': groupD, 'author': authorD, 'post': postD, 'topic': topicD, 'context': self.context } assert retval if postId: # --=mpj17=-- Skips hidden posts yield retval
def groupInfo(self): retval = createObject('groupserver.GroupInfo', self.context) assert retval, \ 'Could not create the GroupInfo from %s' % self.context return retval
def test_getText_w_custom_targetMimetype(self): comment1 = createObject('plone.Comment') comment1.text = 'para' self.assertEqual(comment1.getText(targetMimetype='text/plain'), 'para')
def test_factory(self): fti = self.getFti() factory = fti.factory new_object = createObject(factory) self.assertTrue(IVideoEnabled.providedBy(new_object))
def test_mime_type(self): comment1 = createObject('plone.Comment') self.assertEqual(comment1.mime_type, 'text/plain')
def test_factory(self): comment1 = createObject('plone.Comment') self.assertTrue(IComment.providedBy(comment1))