def test_soap_searchItems(self): """Check the fact of searching items informations about existing items.""" SAME_TITLE = 'sameTitleForBothItems' ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal, minimal=True) # Create 2 items, one for 'pmCreator1' and one for 'pmCreator2' # items are only viewable by their creator as 'pmCreatorx' not in the same proposingGroup self.changeUser('pmCreator1') item1 = self.create('MeetingItem') item1.setTitle(SAME_TITLE) item1.reindexObject(idxs=['Title', ]) self.changeUser('pmCreator2') item2 = self.create('MeetingItem') item2.setTitle(SAME_TITLE) item2.reindexObject(idxs=['Title', ]) # we have to commit() here or portal used behing the SOAP call # does not have the freshly created item... transaction.commit() # searchItems will automatically restrict searches to the connected user self.changeUser('pmCreator1') result = ws4pmSettings._soap_searchItems({'Title': SAME_TITLE}) self.assertTrue(len(result), 1) self.assertTrue(result[0].UID == item1.UID()) self.changeUser('pmCreator2') result = ws4pmSettings._soap_searchItems({'Title': SAME_TITLE}) self.assertTrue(len(result), 1) self.assertTrue(result[0].UID == item2.UID())
def test_canNotSendIfInNoPMCreatorGroup(self): """ If the user that wants to send the item in PloneMeeting is not a creator in PM, aka is not in a _creators suffixed group, a message is displayed to him. """ # remove pmCreator2 from the vendors_creators group # first check that the user is actually in a _creators group pmCreator2 = self.portal.portal_membership.getMemberById('pmCreator2') self.assertTrue([ group for group in self.portal.acl_users.source_groups. getGroupsForPrincipal(pmCreator2) if group.endswith('_creators') ]) self.portal.portal_groups.removePrincipalFromGroup( 'pmCreator2', self.vendors_creators) # pmCreator2 is no more in a _creators group self.assertFalse([ group for group in self.portal.acl_users.source_groups. getGroupsForPrincipal(pmCreator2) if group.endswith('_creators') ]) # try to send the item setCorrectSettingsConfig(self.portal) self.changeUser('pmCreator2') self.tool.getPloneMeetingFolder('plonemeeting-assembly', 'pmCreator2') transaction.commit() # create an element to send... document = createDocument(self.portal.Members.pmCreator2) messages = IStatusMessage(self.request) # if no item is created, _sendToPloneMeeting returns None self.assertFalse( self._sendToPloneMeeting(document, user='******', proposingGroup=self.vendors_uid)) msg = _(NO_PROPOSING_GROUP_ERROR, mapping={'userId': 'pmCreator2'}) self.assertEqual(messages.show()[-3].message, translate(msg))
def test_canNotConnectTemporarily(self): """ Test a connection problem in PloneMeeting after an item has already been sent - connect to PM successfully - send the item successfully - break settings - check what is going on while not being able to show PM related informations """ self.changeUser('admin') document = createDocument(self.portal) viewlet = PloneMeetingInfosViewlet(document, self.request, None, None) viewlet.update() # send an element to PloneMeeting item = self._sendToPloneMeeting(document) # correctly sent self.assertTrue(viewlet.available() is True) self.assertTrue( viewlet.getPloneMeetingLinkedInfos()[0]['UID'] == item.UID()) setCorrectSettingsConfig(self.portal, **{'pm_url': u'http://wrong/url'}) cleanMemoize(self.request, viewlet) # no available # a message is returned in the viewlet by the viewlet.available method self.assertTrue(viewlet.available() == (UNABLE_TO_CONNECT_ERROR, 'error')) # the annotations on the document are still correct self.assertTrue( IAnnotations(document)[WS4PMCLIENT_ANNOTATION_KEY] == ['plonemeeting-assembly'])
def test_soap_getItemTemplate(self): """Check while getting rendered template for an item. getItemTemplate will automatically use currently connected user to render item template regarding the _getUserIdToUseInTheNameOfWith.""" ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal, minimal=True) # by default no item exist in the portal... So create one! self.changeUser('pmManager') item = self.create('MeetingItem') # we have to commit() here or portal used behing the SOAP call # does not have the freshly created item... transaction.commit() self.assertTrue(ws4pmSettings._soap_getItemTemplate( {'itemUID': item.UID(), 'templateId': POD_TEMPLATE_ID_PATTERN.format('itemTemplate', 'odt')})) # getItemTemplate is called inTheNameOf the currently connected user # if the user (like 'pmCreator1') can see the item, he gets the rendered template # either (like for 'pmCreator2') nothing is returned self.changeUser('pmCreator1') self.assertTrue(ws4pmSettings._soap_getItemTemplate( {'itemUID': item.UID(), 'templateId': POD_TEMPLATE_ID_PATTERN.format('itemTemplate', 'odt')})) self.changeUser('pmCreator2') self.assertFalse(ws4pmSettings._soap_getItemTemplate( {'itemUID': item.UID(), 'templateId': POD_TEMPLATE_ID_PATTERN.format('itemTemplate', 'odt')}))
def test_soap_createItem(self): """Check item creation. Item creation will automatically use currently connected user to create the item regarding the _getUserIdToUseInTheNameOfWith.""" cfg2 = self.meetingConfig2 cfg2Id = cfg2.getId() ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal, minimal=True) self.changeUser('pmManager') self.setMeetingConfig(cfg2Id) test_meeting = self.create('Meeting') self.freezeMeeting(test_meeting) self.changeUser('pmCreator1') # create the 'pmCreator1' member area to be able to create an item pmFolder = self.tool.getPloneMeetingFolder(cfg2Id) # we have to commit() here or portal used behing the SOAP call # does not have the freshly created item... transaction.commit() # create an item for 'pmCreator1' data = {'title': u'My sample item', 'category': u'deployment', 'description': u'<p>My description</p>', # also use accents, this was failing with suds-jurko 0.5 'decision': u'<p>My d\xe9cision</p>', 'preferredMeeting': test_meeting.UID(), 'externalIdentifier': u'my-external-identifier', 'extraAttrs': [{'key': 'internalNotes', 'value': '<p>Internal notes</p>'}]} result = ws4pmSettings._soap_createItem(cfg2Id, 'developers', data) # commit again so the item is really created transaction.commit() # the item is created and his UID is returned # check that the item is actually created inTheNameOf 'pmCreator1' itemUID = result[0] item = self.portal.uid_catalog(UID=itemUID)[0].getObject() # created in the 'pmCreator1' member area self.assertTrue(item.aq_inner.aq_parent.UID(), pmFolder.UID()) self.assertTrue(item.owner_info()['id'] == 'pmCreator1') self.assertEqual(item.Title(), data['title']) self.assertEqual(item.getCategory(), data['category']) self.assertEqual(item.Description(), data['description']) self.assertEqual(item.getDecision(), data['decision'].encode('utf-8')) self.assertEqual(item.getPreferredMeeting(), test_meeting.UID(), data['preferredMeeting']) self.assertEqual(item.externalIdentifier, data['externalIdentifier']) # extraAttrs self.assertEqual(item.getInternalNotes(), data['extraAttrs'][0]['value']) # if we try to create with wrong data, the SOAP ws returns a response # that is displayed to the user creating the item data['category'] = 'unexisting-category-id' result = ws4pmSettings._soap_createItem('plonegov-assembly', 'developers', data) self.assertIsNone(result) messages = IStatusMessage(self.request) # a message is displayed self.assertEqual(messages.show()[-1].message, u"An error occured during the item creation in PloneMeeting! " "The error message was : Server raised fault: ''unexisting-category-id' " "is not available for the 'developers' group!'")
def test_soap_getMeetingAcceptingItems(self): """Check getting accepting items meeting. Should only return meetings in the state 'creation' and 'frozen'""" ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal, minimal=True) cfg = self.meetingConfig cfgId = cfg.getId() meetings = ws4pmSettings._soap_getMeetingsAcceptingItems( {'meetingConfigId': cfgId, 'inTheNameOf': 'pmCreator1'} ) self.assertEqual(meetings, []) self.changeUser('pmManager') meeting_1 = self.create('Meeting', date=datetime(2013, 3, 3)) meeting_2 = self.create('Meeting', date=datetime(2013, 3, 3)) transaction.commit() self.changeUser('pmCreator1') meetings = ws4pmSettings._soap_getMeetingsAcceptingItems( {'meetingConfigId': cfgId, 'inTheNameOf': 'pmCreator1'} ) # so far find the two meetings self.assertEqual(len(meetings), 2) # freeze meeting_2 => it still should be in the accepting items meetings self.changeUser('pmManager') api.content.transition(meeting_2, 'freeze') transaction.commit() self.changeUser('pmCreator1') meetings = ws4pmSettings._soap_getMeetingsAcceptingItems( {'meetingConfigId': cfgId, 'inTheNameOf': 'pmCreator1'} ) self.assertEqual(len(meetings), 2) self.changeUser('pmManager') api.content.transition(meeting_2, 'publish') api.content.transition(meeting_2, 'decide') transaction.commit() # after publishing meeting_2, it should not be in the results anymore. self.changeUser('pmCreator1') meetings = ws4pmSettings._soap_getMeetingsAcceptingItems( {'meetingConfigId': cfgId, 'inTheNameOf': 'pmCreator1'} ) self.assertEqual(len(meetings), 1) self.assertEqual(meetings[0].UID, meeting_1.UID()) # if no inTheNameOf param is explicitly passed, _soap_getMeetingsAcceptingItems() # should set a default one. meetings = ws4pmSettings._soap_getMeetingsAcceptingItems( {'meetingConfigId': cfgId} ) self.assertEqual(len(meetings), 1) self.assertEqual(meetings[0].UID, meeting_1.UID()) # As pmManager, we should get all the meetings meetings = ws4pmSettings._soap_getMeetingsAcceptingItems( {'meetingConfigId': cfgId, 'inTheNameOf': 'pmManager'} ) self.assertEqual(len(meetings), 2)
def test_soap_getConfigInfos(self): """Check that we receive valid infos about the PloneMeeting's configuration.""" ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal, minimal=True) configInfos = ws4pmSettings._soap_getConfigInfos() # check thatt we received elements like MeetingConfig and MeetingGroups self.assertTrue(configInfos.configInfo) self.assertTrue(configInfos.groupInfo) # by default, no categories self.assertFalse(hasattr(configInfos.configInfo[0], 'categories')) # we can ask categories by passing a showCategories=True to _soap_getConfigInfos configInfos = ws4pmSettings._soap_getConfigInfos(showCategories=True) self.assertTrue(hasattr(configInfos.configInfo[1], 'categories'))
def test_sendItemToPloneMeeting(self): """Test that the item is actually sent to PloneMeeting.""" setCorrectSettingsConfig(self.portal) self.changeUser('pmCreator1') # create an element to send... document = createDocument(self.portal.Members.pmCreator1) self._configureRequestForView(document) view = document.restrictedTraverse(SEND_TO_PM_VIEW_NAME).form_instance # create an annex to send... annex = createAnnex(self.portal.Members.pmCreator1) # before sending, no item is linked to the document ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') self.assertTrue( len( ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()})) == 0) # create the 'pmCreator1' member area to be able to create an item self.tool.getPloneMeetingFolder('plonemeeting-assembly', 'pmCreator1') # we have to commit() here or portal used behing the SOAP call # does not have the freshly created member area... transaction.commit() # send to PloneMeeting # as form.button.Send is not in the form, nothing is done but returning the views's index # the form for sending an element is displayed form_action = '<form class="rowlike enableUnloadProtection kssattr-formname-send_to_plonemeeting_form"' \ ' action="{0}/Members/pmCreator1/document" method="post"' \ ' id="form" enctype="multipart/form-data">'.format(self.portal.absolute_url()) self.assertTrue(form_action in view()) self.assertTrue( len( ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()})) == 0) # now send the element to PM view.proposingGroupId = 'developers' view.request.form['form.widgets.annexes'] = [annex.UID()] # view._doSendToPloneMeeting returns True if the element was actually sent self.assertTrue(view._doSendToPloneMeeting()) # while the element is sent, the view will return nothing... self.assertFalse(view()) # now that the element has been sent, an item is linked to the document items = ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()}) self.assertTrue(len(items) == 1) # moreover, as defined in the configuration, 1 annex were added to the item itemInfos = ws4pmSettings._soap_getItemInfos({ 'UID': items[0]['UID'], 'showAnnexes': True })[0] self.assertTrue(len(itemInfos['annexes']) == 1)
def test_canNotExecuteWrongAction(self): """While calling the view to execute an action, we check if the user can actually execute the action regarding the parameters defined in settings.generated_actions.""" setCorrectSettingsConfig(self.portal) self.changeUser('pmCreator1') # create an element to send... document = createDocument(self.portal.Members.pmCreator1) # build an url that should not be accessible by the user # if the url does not correspond to an available wsclient linked action, # an Unauthorized is raised. This make sure the triggered action is # available to the user self.request.set('URL', document.absolute_url()) self.request.set( 'ACTUAL_URL', document.absolute_url() + '/%s' % SEND_TO_PM_VIEW_NAME) self.request.set('meetingConfigId', 'wrong-meeting-config-id') view = document.restrictedTraverse(SEND_TO_PM_VIEW_NAME).form_instance self.assertRaises(Unauthorized, view)
def test_soap_getItemInfos(self): """Check the fact of getting informations about an existing item.""" ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal, minimal=True) # by default no item exist in the portal... So create one! self.changeUser('pmManager') item = self.create('MeetingItem') # we have to commit() here or portal used behing the SOAP call # does not have the freshly created item... transaction.commit() self.assertTrue(len(ws4pmSettings._soap_getItemInfos({'UID': item.UID()})) == 1) # getItemInfos is called inTheNameOf the currently connected user # if the user (like 'pmCreator1') can see the item, he gets it in the request # either (like for 'pmCreator2') the item is not found self.changeUser('pmCreator1') self.assertTrue(len(ws4pmSettings._soap_getItemInfos({'UID': item.UID()})) == 1) self.changeUser('pmCreator2') self.assertTrue(len(ws4pmSettings._soap_getItemInfos({'UID': item.UID()})) == 0)
def test_soap_connectToPloneMeeting(self): """Check that we can actually connect to PloneMeeting with given parameters.""" ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') settings = ws4pmSettings.settings() setCorrectSettingsConfig(self.portal, minimal=True) # with valid informations, we can connect to PloneMeeting SOAP webservices self.failUnless(ws4pmSettings._soap_connectToPloneMeeting()) # if either url or username/password is not valid, we can not connect... valid_url = settings.pm_url settings.pm_url = settings.pm_url + 'invalidEndOfURL' cleanMemoize(self.request) # with invalid url, it fails... self.failIf(ws4pmSettings._soap_connectToPloneMeeting()) settings.pm_url = valid_url # with valid url but wrong password, it fails... settings.pm_password = u'wrongPassword' cleanMemoize(self.request) self.failIf(ws4pmSettings._soap_connectToPloneMeeting())
def test_canNotConnectToPloneMeeting(self): """If no valid parameters are defined in the settings, the view is not accessible and a relevant message if displayed to the member in portal_messages.""" # set base params to avoid extra status messages like 'no field_mappings defined' setCorrectSettingsConfig(self.portal, setConnectionParams=False, withValidation=False) # only available to connected users self.changeUser('pmCreator1') self._configureRequestForView(self.portal) view = self.portal.restrictedTraverse( SEND_TO_PM_VIEW_NAME).form_instance # when we can not connect, a message is displayed to the user messages = IStatusMessage(self.request) self.assertTrue(len(messages.show()) == 0) # call the view view() self.assertTrue(len(messages.show()) == 1) self.assertEquals(messages.show()[0].message, UNABLE_TO_CONNECT_ERROR)
def test_soap_getItemCreationAvailableData(self): """Check that we receive the list of available data for creating an item.""" ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal, minimal=True) availableData = ws4pmSettings._soap_getItemCreationAvailableData() availableData.sort() self.assertEqual(availableData, ['annexes', 'associatedGroups', 'category', 'decision', 'description', 'detailedDescription', 'externalIdentifier', 'extraAttrs', 'groupsInCharge', 'motivation', 'optionalAdvisers', 'preferredMeeting', 'proposingGroup', 'title', 'toDiscuss'])
def test_checkAlreadySentToPloneMeeting(self): """Test in case we sent the element again to PloneMeeting, that should not happen... It check also that relevant annotation wipe out works correctly.""" ws4pmSettings = getMultiAdapter((self.portal, self.request), name='ws4pmclient-settings') setCorrectSettingsConfig(self.portal) settings = ws4pmSettings.settings() self.changeUser('pmCreator1') # create an element to send... document = createDocument(self.portal.Members.pmCreator1) self._configureRequestForView(document) view = document.restrictedTraverse(SEND_TO_PM_VIEW_NAME).form_instance view.proposingGroupId = 'developers' # create the 'pmCreator1' member area to be able to create an item self.tool.getPloneMeetingFolder('plonemeeting-assembly', 'pmCreator1') self.tool.getPloneMeetingFolder('plonegov-assembly', 'pmCreator1') # we have to commit() here or portal used behing the SOAP call # does not have the freshly created member area... transaction.commit() # before sending, the element is not linked annotations = IAnnotations(document) self.assertFalse(WS4PMCLIENT_ANNOTATION_KEY in annotations) self.assertFalse( view.ws4pmSettings.checkAlreadySentToPloneMeeting( document, self.request.get('meetingConfigId'))) # send the document self.assertTrue(view._doSendToPloneMeeting()) # is linked to one item self.assertTrue(annotations[WS4PMCLIENT_ANNOTATION_KEY] == [ self.request.get('meetingConfigId'), ]) self.assertTrue( view.ws4pmSettings.checkAlreadySentToPloneMeeting( document, (self.request.get('meetingConfigId'), ))) self.assertTrue( len( ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()})) == 1) messages = IStatusMessage(self.request) # there is one message saying that the item was correctly sent shownMessages = messages.show() self.assertEquals(shownMessages[-1].message, CORRECTLY_SENT_TO_PM_INFO) # call form again, it will display relevant status messages # the rendered form is u'' self.assertTrue(settings.only_one_sending) self.assertTrue(view() == u'') # the item is not created again # is still linked to one item self.assertTrue(annotations[WS4PMCLIENT_ANNOTATION_KEY] == [ self.request.get('meetingConfigId'), ]) self.assertTrue( len( ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()})) == 1) # a warning is displayed to the user self.request.response.status = 200 # if status in 300, messages are not deleted with show self.assertEquals(messages.show()[-1].message, ALREADY_SENT_TO_PM_ERROR) settings.only_one_sending = False self.assertFalse(settings.only_one_sending) view._finishedSent = False self.request.response.status = 200 # if status in 300, render is not called by z3cform self.assertIn('Send to PloneMeeting Assembly', view()) self.assertEqual(len(messages.show()), 0) # if we remove the item in PloneMeeting, the view is aware of it itemUID = str( ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()})[0]['UID']) # avoid weird ConflictError while committing because of # self.portal._volatile_cache_keys PersistentMapping self.portal._volatile_cache_keys._p_changed = False transaction.commit() item = self.portal.uid_catalog(UID=itemUID)[0].getObject() # remove the item item.aq_inner.aq_parent.manage_delObjects(ids=[ item.getId(), ]) transaction.commit() # checkAlreadySentToPloneMeeting will wipe out inconsistent annotations # for now, annotations are inconsistent self.assertTrue(annotations[WS4PMCLIENT_ANNOTATION_KEY] == [ self.request.get('meetingConfigId'), ]) self.assertFalse( view.ws4pmSettings.checkAlreadySentToPloneMeeting( document, (self.request.get('meetingConfigId'), ))) # now it is consistent self.assertFalse(WS4PMCLIENT_ANNOTATION_KEY in annotations) self.assertTrue( len( ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()})) == 0) # the item can be sent again and will be linked to a new created item self.assertTrue(view._doSendToPloneMeeting()) self.assertTrue( view.ws4pmSettings.checkAlreadySentToPloneMeeting( document, (self.request.get('meetingConfigId'), ))) self.assertTrue( len( ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()})) == 1) # the item can also been send to another meetingConfig self.request.set('meetingConfigId', 'plonegov-assembly') view = document.restrictedTraverse(SEND_TO_PM_VIEW_NAME).form_instance view.proposingGroupId = 'developers' self.assertFalse( view.ws4pmSettings.checkAlreadySentToPloneMeeting( document, (self.request.get('meetingConfigId'), ))) self.request.form['form.widgets.category'] = [ u'deployment', ] self.assertTrue(view._doSendToPloneMeeting()) self.assertTrue( view.ws4pmSettings.checkAlreadySentToPloneMeeting( document, (self.request.get('meetingConfigId'), ))) self.assertTrue(annotations[WS4PMCLIENT_ANNOTATION_KEY] == [ 'plonemeeting-assembly', self.request.get('meetingConfigId'), ]) # if we remove the 2 items, a call to checkAlreadySentToPloneMeeting # without meetingConfigs will wipeout the annotations transaction.commit() itemUIDs = [ str(elt['UID']) for elt in ws4pmSettings._soap_searchItems( {'externalIdentifier': document.UID()}) ] item1 = self.portal.uid_catalog(UID=itemUIDs[0])[0].getObject() item2 = self.portal.uid_catalog(UID=itemUIDs[1])[0].getObject() item1.aq_inner.aq_parent.manage_delObjects(ids=[ item1.getId(), ]) item2.aq_inner.aq_parent.manage_delObjects(ids=[ item2.getId(), ]) transaction.commit() # annotations are still messed up self.assertTrue(annotations[WS4PMCLIENT_ANNOTATION_KEY] == [ 'plonemeeting-assembly', self.request.get('meetingConfigId'), ]) # wipe out annotations view.ws4pmSettings.checkAlreadySentToPloneMeeting(document) self.assertFalse(WS4PMCLIENT_ANNOTATION_KEY in annotations)
def test_saveSettings(self): """While settings are saved, some actions are added to portal_actions/object_buttons.""" setRoles(self.portal, TEST_USER_ID, ('Manager', )) login(self.portal, TEST_USER_NAME) # for now, there are no relative plonemeeting actions in portal_actions/object_buttons object_buttons_ids = self.portal.portal_actions.object_buttons.objectIds( ) self.failIf([ actId for actId in object_buttons_ids if actId.startswith(ACTION_SUFFIX) ]) setCorrectSettingsConfig(self.portal, withValidation=False) # now relevant actions exist object_buttons_ids = self.portal.portal_actions.object_buttons.objectIds( ) self.assertEquals( len([ actId for actId in object_buttons_ids if actId.startswith(ACTION_SUFFIX) ]), 5) # and it is correctly configured setRoles(self.portal, TEST_USER_ID, ('Member', )) # plone.app.testing does not manage request/URL and request/ACTUAL_URL # and request/ACTUAL_URL is necessary for listFilteredActionsFor self.request.set('URL', self.portal.absolute_url()) self.request.set('ACTUAL_URL', self.portal.absolute_url()) object_buttons = self.portal.portal_actions.listFilteredActionsFor( self.portal)['object_buttons'] # 2 of the generated actions are not available to non 'Managers' self.assertEquals( len([ act for act in object_buttons if act['id'].startswith(ACTION_SUFFIX) ]), 5 - 2) # now save again with just 2 actions to generate generated_actions = [ { 'pm_meeting_config_id': 'plonegov-assembly', 'condition': u'python:True', 'permissions': u'View' }, { 'pm_meeting_config_id': 'plonemeeting-assembly', 'condition': u'python:True', 'permissions': u'View' }, ] setCorrectSettingsConfig(self.portal, withValidation=False, **{'generated_actions': generated_actions}) object_buttons = self.portal.portal_actions.listFilteredActionsFor( self.portal)['object_buttons'] pm_object_buttons = [ act for act in object_buttons if act['id'].startswith(ACTION_SUFFIX) ] # only 2 actions exist now self.assertEquals(len(pm_object_buttons), 2) # and it is valid ones self.assertTrue( 'meetingConfigId=plonegov-assembly' in pm_object_buttons[0]['url']) self.assertTrue('meetingConfigId=plonemeeting-assembly' in pm_object_buttons[1]['url'])