def test_ws_createItemOptionalAdvisers(self): """ Test when passing associatedGroups while creating the item. """ cfg = self.meetingConfig cfg.setUsedItemAttributes(['description', 'detailedDescription']) # by default no item exists self.changeUser('pmCreator1') req = self._prepareCreationData() # while passing no correct data req._creationData._optionalAdvisers = [self.vendors_uid, 'unknown_uid'] responseHolder = createItemResponse() with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) # advices not enabled self.assertEqual( cm.exception.string, "The advices functionnality is not enabled for this configuration!") # enable advices, will fail because unknown_uid cfg.setUseAdvices(True) cfg.setSelectableAdvisers([self.developers_uid, self.vendors_uid]) with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, 'The \"optionalAdvisers\" data contains wrong values: "unknown_uid"!') # now with correct data req._creationData._optionalAdvisers = [self.developers_uid, self.vendors_uid] newItem, response = self._createItem(req) self.assertEqual(newItem.getOptionalAdvisers(), (self.developers_uid, self.vendors_uid)) self.assertTrue(self.developers_uid in newItem.adviceIndex) self.assertTrue(self.vendors_uid in newItem.adviceIndex)
def test_ws_createItemWithExtraAttrs(self): """ It is possible to specify arbitraty extraAttrs so we may create items even when using a specific profile adding is own fields. For now it only works with XHTML TextFields. """ self.changeUser('pmManager') req = self._prepareCreationData() ExtraAttr = GTD('http://ws4pm.imio.be', 'ExtraAttr')('').pyclass() ExtraAttr._key = 'unexisting_key' ExtraAttr._value = '<p>XHTML content</p>' req._creationData._extraAttrs = [ExtraAttr] responseHolder = createItemResponse() # key must be found in the MeetingItem's schema with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "The extraAttr 'unexisting_key' was not found the the MeetingItem schema!") # only works with RichText fields req._creationData._extraAttrs[0]._key = 'privacy' with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, "The extraAttr 'privacy' must correspond to a field using a 'RichWidget' in the MeetingItem schema!") # working example, use RichText field 'notes' req._creationData._extraAttrs[0]._key = 'notes' response = SOAPView(self.portal, req).createItemRequest(req, responseHolder) item = self.portal.portal_catalog(UID=response._UID)[0].getObject() self.assertEqual(item.getNotes(), '<p>XHTML content</p>')
def test_ws_createItemAssociatedGroups(self): """ Test when passing associatedGroups while creating the item. """ cfg = self.meetingConfig cfg.setUsedItemAttributes(['description', 'detailedDescription']) # by default no item exists self.changeUser('pmCreator1') req = self._prepareCreationData() # while passing no correct data req._creationData._associatedGroups = [self.vendors_uid, 'unknown_uid'] responseHolder = createItemResponse() with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) # optional field not enabled self.assertEqual( cm.exception.string, "The optional field \"associatedGroups\" is not activated in this configuration!") # enable optional field, will fail because unknown_uid cfg.setUsedItemAttributes(cfg.getUsedItemAttributes() + ('associatedGroups', )) with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, 'The \"associatedGroups\" data contains wrong values: "unknown_uid"!') # now with correct data req._creationData._associatedGroups = [self.vendors_uid, self.developers_uid] newItem, response = self._createItem(req) self.assertEqual(newItem.getAssociatedGroups(), (self.vendors_uid, self.developers_uid))
def test_ws_createItemWithPreferredMeeting(self): """ It is possible to specify a preferred meeting, but the given preferred meeting UID must be a meeting accepting items. """ self.changeUser('pmManager') # create a fresh meeting that will accept items meeting = self.create('Meeting') req = self._prepareCreationData() req._creationData._preferredMeeting = 'unexisting_meeting_UID' responseHolder = createItemResponse() with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "The given preferred meeting UID (unexisting_meeting_UID) is not a meeting accepting items!") req._creationData._preferredMeeting = meeting.UID() response = SOAPView(self.portal, req).createItemRequest(req, responseHolder) # an item has been created with correct preferredMeeting item = self.portal.portal_catalog(UID=response._UID)[0].getObject() self.assertTrue(item.getPreferredMeeting() == meeting.UID()) # if no preferredMeeting is provided, the default value 'whatever' is used req._creationData._preferredMeeting = None response = SOAPView(self.portal, req).createItemRequest(req, responseHolder) item = self.portal.portal_catalog(UID=response._UID)[0].getObject() self.assertTrue(item.getPreferredMeeting() == ITEM_NO_PREFERRED_MEETING_VALUE)
def _createItem(self, req): """ Create the item with data given in req parameter """ responseHolder = createItemResponse() response = SOAPView(self.portal, req).createItemRequest(req, responseHolder) newItem = self.portal.uid_catalog(UID=response._UID)[0].getObject() return newItem, response
def test_ws_createItemRaisedZSIFaults(self): """ Test SOAP service behaviour when creating an item with some wrong arguments """ # by default no item exists self.changeUser('pmCreator1') req = self._prepareCreationData() responseHolder = createItemResponse() # the title is mandatory req._creationData._title = None with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "A 'title' is mandatory!") req._creationData._title = 'A valid title' # the meetingConfigId must exists req._meetingConfigId = 'wrongMeetingConfigId' with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "Unknown meetingConfigId : 'wrongMeetingConfigId'!") req._meetingConfigId = self.usedMeetingConfigId # the connected user must be able to create an item for the given proposingGroupId req._proposingGroupId = 'vendors' with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "'pmCreator1' can not create items for the 'vendors' group!") # the connected user must be able to create an item with the given category # set back correct proposingGroup req._proposingGroupId = 'developers' # if category is mandatory and empty, it raises ZSI.Fault self.meetingConfig.setUseGroupsAsCategories(False) req._creationData._category = None with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "In this config, category is mandatory!") # wrong category and useGroupsAsCategories, ZSI.Fault self.meetingConfig.setUseGroupsAsCategories(True) req._creationData._category = 'wrong-category-id' with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "This config does not use categories, the given 'wrong-category-id' " "category can not be used!") # wrong category and actually accepting categories, aka useGroupsAsCategories to False self.meetingConfig.setUseGroupsAsCategories(False) with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "'wrong-category-id' is not available for the 'developers' group!") # if the user trying to create an item has no member area, a ZSI.Fault is raised # remove the 'pmCreator2' personal area self.changeUser('admin') self.portal.Members.manage_delObjects(ids=['pmCreator2']) req._proposingGroupId = 'vendors' self.changeUser('pmCreator2') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "No member area for 'pmCreator2'. Never connected to PloneMeeting?")
def test_ws_createItemToDiscuss(self): """ Test SOAP service behaviour when creating an item using toDiscuss : - optional field so only useable when relevant; - if not set, then default value is used. """ cfg = self.meetingConfig # by default no item exists self.changeUser('pmCreator1') req = self._prepareCreationData() responseHolder = createItemResponse() # we can not use an optional field that is not activated in the current MeetingConfig cfg.setUsedItemAttributes(( 'description', 'detailedDescription', )) self.assertFalse('toDiscuss' in cfg.getUsedItemAttributes()) # set toDiscuss to True req._creationData._toDiscuss = True with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, "The optional field \"toDiscuss\" is not activated in this configuration!" ) # if we activate it, then the resulting item is correct cfg.setUsedItemAttributes(cfg.getUsedItemAttributes() + ('toDiscuss', )) # create item first time when default is True, then False # as given in soap request, it is True each time cfg.setToDiscussDefault(False) newItem, response = self._createItem(req) self.assertTrue(newItem.getToDiscuss()) cfg.setToDiscussDefault(True) newItem, response = self._createItem(req) self.assertTrue(newItem.getToDiscuss()) # if not set in soap request, parameter is ignored, again with default True and False # as not given in soap request, it is the default defined value req._creationData._toDiscuss = None cfg.setToDiscussDefault(False) newItem, response = self._createItem(req) self.assertFalse(newItem.getToDiscuss()) cfg.setToDiscussDefault(True) newItem, response = self._createItem(req) self.assertTrue(newItem.getToDiscuss())
def test_ws_createItemWithOptionalFields(self): """ Test SOAP service behaviour when creating an item with some optional fields """ # by default no item exists self.changeUser('pmCreator1') req = self._prepareCreationData() responseHolder = createItemResponse() # we can not use an optional field that is not activated in the current MeetingConfig self.assertTrue('motivation' not in self.meetingConfig.getUsedItemAttributes()) req._creationData._motivation = '<p>Motivation sample text</p>' with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "The optional field \"motivation\" is not activated in this configuration!") # if we activate it, then the resulting item is correct self.meetingConfig.setUsedItemAttributes(self.meetingConfig.getUsedItemAttributes() + ('motivation', )) newItem, response = self._createItem(req) self.assertTrue(newItem.getMotivation() == '<p>Motivation sample text</p>')
def test_ws_createItemInTheNameOf(self): """ It is possible for Managers and MeetingManagers to create an item inTheNameOf another user Every other checks are made except that for using the inTheNameOf functionnality : - the calling user must be 'Manager' or 'MeetingManager' - the created item is finally like if created by the inTheNameOf user """ self.meetingConfig.setUseGroupsAsCategories(False) # check first a working example the degrades it... # and every related informations (creator, ownership, ...) are corretly linked to inTheNameOf user self.changeUser('pmManager') req = self._prepareCreationData() req._inTheNameOf = 'pmCreator2' req._proposingGroupId = 'vendors' req._creationData._category = 'development' data = {'title': 'My annex 1', 'filename': 'smallTestFile.pdf', 'file': 'smallTestFile.pdf'} req._creationData._annexes = [self._prepareAnnexInfo(**data)] responseHolder = createItemResponse() response = SOAPView(self.portal, req).createItemRequest(req, responseHolder) # as we switch user while using inTheNameOf, make sure we have # falled back to original user self.assertTrue(self.portal.portal_membership.getAuthenticatedMember().getId() == 'pmManager') # make also sure that cached methods using user_id are correct as well newItem = self.portal.uid_catalog(UID=response._UID)[0].getObject() # as the item is really created by the inTheNameOf user, everything is correct self.assertEqual(newItem.Creator(), 'pmCreator2') self.assertEqual(newItem.owner_info()['id'], 'pmCreator2') # with those data but with a non 'Manager'/'MeetingManager', it fails self.changeUser('pmCreator1') cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "You need to be 'Manager' or 'MeetingManager' to create an item 'inTheNameOf'!") # now use the MeetingManager but specify a proposingGroup the inTheNameOf user can not create for self.changeUser('pmManager') req._proposingGroupId = 'developers' cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "'pmCreator2' can not create items for the 'developers' group!") # now for an unexisting inTheNameOf userid req._inTheNameOf = 'unexistingUserId' # set back correct proposingGroupId req._proposingGroupId = 'vendors' cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "Trying to create an item 'inTheNameOf' an unexisting user 'unexistingUserId'!") # create an itemInTheNameOf a user having no personal area... # if the user trying to create an item has no member area, a ZSI.Fault is raised # remove the 'pmCreator2' personal area self.changeUser('admin') # remove the created item because we can not remove a folder containing items # it would raise a BeforeDeleteException in PloneMeeting newItem.aq_inner.aq_parent.manage_delObjects(ids=[newItem.getId(), ]) self.portal.Members.manage_delObjects(ids=['pmCreator2']) self.changeUser('pmManager') req._inTheNameOf = 'pmCreator2' cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual(cm.exception.string, "No member area for 'pmCreator2'. Never connected to PloneMeeting?") # test that _listAllowedRolesAndUsers is not messed up # this happened before because ToolPloneMeeting.get_plone_groups_for_user # had a different value between request.AUTHENTICATED_USER and api.user.get_current self._check_after_inTheNameOf()
def test_ws_createItemRequest(self): """ In the default test configuration, the user 'pmCreator1' can create an item for proposingGroup 'developers' in the MeetingConfig 'plonegov-assembly' """ # by default no item exists self.changeUser('pmCreator1') self.failUnless(len(self.portal.portal_catalog(portal_type='MeetingItemPga')) == 0) req = self._prepareCreationData() # This is what the sent enveloppe should looks like, note that the decision is "Décision<strong>wrongTagd</p>" # instead of '<p>Décision</p>' so we check accents and missing <p></p> req._creationData._decision = 'Décision<strong>wrongTagd</p>' # Serialize the request so it can be easily tested request = serializeRequest(req) expected = """POST /plone/createItemRequest HTTP/1.0 Authorization: Basic %s:%s Content-Length: 102 Content-Type: text/xml SOAPAction: / <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" """ \ """xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" """ \ """xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">""" \ """<SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body xmlns:ns1="http://ws4pm.imio.be"><ns1:createItemRequest>""" \ """<meetingConfigId>plonegov-assembly</meetingConfigId><proposingGroupId>developers</proposingGroupId>""" \ """<creationData xsi:type="ns1:CreationData"><title>My new item title</title><category>development</category>""" \ """<description><p>Description</p></description>""" \ """<detailedDescription><p>Detailed description</p></detailedDescription>""" \ """<decision>D\xc3\xa9cision<strong>wrongTagd</p></decision></creationData><cleanHtml>true</cleanHtml>""" \ """</ns1:createItemRequest>""" \ """</SOAP-ENV:Body></SOAP-ENV:Envelope>""" % ('pmCreator1', 'meeting') result = """POST /plone/createItemRequest HTTP/1.0 Authorization: Basic %s:%s Content-Length: 102 Content-Type: text/xml SOAPAction: / %s""" % ('pmCreator1', 'meeting', request) self.assertEqual(expected, result) # now really use the SOAP method to create an item newItem, response = self._createItem(req) newItemUID = newItem.UID() resp = deserialize(response) expected = """<ns1:createItemResponse xmlns:ns1="http://ws4pm.imio.be" """ \ """xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" """\ """xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" """ \ """xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" """ \ """xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <UID>%s</UID> <warnings>%s</warnings> </ns1:createItemResponse> """ % (newItemUID, translate(WRONG_HTML_WARNING, domain='imio.pm.ws', mapping={'item_path': newItem.absolute_url_path(), 'creator': 'pmCreator1'}, context=self.request) ) self.assertEqual(expected, resp) # the item is actually created self.failUnless(len(self.portal.portal_catalog(portal_type='MeetingItemPga', UID=newItemUID)) == 1) # responseHolder for tests here above responseHolder = createItemResponse() # check that we can create an item with a NoneType HTML field req._creationData._decision = None newItemWithEmptyDecisionUID = SOAPView(self.portal, req).createItemRequest(req, responseHolder)._UID self.failUnless(len(self.portal.portal_catalog(portal_type='MeetingItemPga', UID=newItemWithEmptyDecisionUID)) == 1) # No matter how the item is created, with or without a decision, every HTML fields are surrounded by <p></p> obj = self.portal.portal_catalog(portal_type='MeetingItemPga', UID=newItemWithEmptyDecisionUID)[0].getObject() self.failIf(obj.getDecision(keepWithNext=False) != '<p></p>')
def test_ws_createItemInTheNameOf(self): """ It is possible for Managers and MeetingManagers to create an item inTheNameOf another user Every other checks are made except that for using the inTheNameOf functionnality : - the calling user must be 'Manager' or 'MeetingManager' - the created item is finally like if created by the inTheNameOf user """ # check first a working example the degrades it... # and every related informations (creator, ownership, ...) are corretly linked to inTheNameOf user self.changeUser('pmManager') req = self._prepareCreationData() req._inTheNameOf = 'pmCreator2' req._proposingGroupId = 'vendors' responseHolder = createItemResponse() response = SOAPView(self.portal, req).createItemRequest(req, responseHolder) # as we switch user while using inTheNameOf, make sure we have # falled back to original user self.assertTrue(self.portal.portal_membership.getAuthenticatedMember(). getId() == 'pmManager') newItem = self.portal.uid_catalog(UID=response._UID)[0].getObject() # as the item is really created by the inTheNameOf user, everything is correct self.assertEqual(newItem.Creator(), 'pmCreator2') self.assertEqual(newItem.owner_info()['id'], 'pmCreator2') # with those data but with a non 'Manager'/'MeetingManager', it fails self.changeUser('pmCreator1') cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, "You need to be 'Manager' or 'MeetingManager' to create an item 'inTheNameOf'!" ) # now use the MeetingManager but specify a proposingGroup the inTheNameOf user can not create for self.changeUser('pmManager') req._proposingGroupId = 'developers' cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, "'pmCreator2' can not create items for the 'developers' group!") # now for an unexisting inTheNameOf userid req._inTheNameOf = 'unexistingUserId' # set back correct proposingGroupId req._proposingGroupId = 'vendors' cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, "Trying to create an item 'inTheNameOf' an unexisting user 'unexistingUserId'!" ) # create an itemInTheNameOf a user having no personal area... # if the user trying to create an item has no member area, a ZSI.Fault is raised # remove the 'pmCreator2' personal area self.changeUser('admin') # remove the created item because we can not remove a folder containing items # it would raise a BeforeDeleteException in PloneMeeting newItem.aq_inner.aq_parent.manage_delObjects(ids=[ newItem.getId(), ]) self.portal.Members.manage_delObjects(ids=['pmCreator2']) self.changeUser('pmManager') req._inTheNameOf = 'pmCreator2' cleanRamCacheFor('Products.PloneMeeting.ToolPloneMeeting.userIsAmong') with self.assertRaises(ZSI.Fault) as cm: SOAPView(self.portal, req).createItemRequest(req, responseHolder) self.assertEqual( cm.exception.string, "No member area for 'pmCreator2'. Never connected to PloneMeeting?" )