def test_subtask_response(self): """When a subtask is added it should automaticly add a response on maintask""" intids = getUtility(IIntIds) maintask = create_task(self.portal, title='maintask') subtask = create_task(maintask, title='subtask') responses = IResponseContainer(maintask) self.assertEquals( responses[-1].added_object.to_id, intids.getId(subtask)) self.assertEquals(len(responses), 2) # all different remote requests should not # generate an response maintask.REQUEST.environ['X_OGDS_AC'] = 'hugo.boss' create_task(maintask, title='subtask') self.assertEquals(len(IResponseContainer(maintask)), 2) maintask.REQUEST.environ['X_OGDS_AC'] = None maintask.REQUEST.environ['X_OGDS_CID'] = 'client_a' create_task(maintask, title='subtask') self.assertEquals(len(IResponseContainer(maintask)), 2) maintask.REQUEST.environ['X_OGDS_CID'] = None maintask.REQUEST.set('X-CREATING-SUCCESSOR', True) create_task(maintask, title='subtask') self.assertEquals(len(IResponseContainer(maintask)), 2)
def test_reassign_remote_view(self): task = self.providing_stub([ITask, IAttributeAnnotatable]) self.expect(task.Type()).result('opengever.task.task') self.expect(task.responsible).result('old_responsible') task.responsible = 'hugo.boss' # worfklow_tool wft = self.stub() self.mock_tool(wft, 'portal_workflow') with self.mocker.order(): wft.getInfoFor(task, 'review_state').result( 'task-state-resolved') wft.getInfoFor(task, 'review_state').result( 'task-state-in-progress') wft.doActionFor(task, u'task-transition-reassign') wft.getTitleForStateOnType( ANY, 'opengever.task.task').result('Resolved') user = SimpleUser('hanspeter', '', ('manage', ), []) newSecurityManager(self.create_dummy(), user) # reassign request reassign_request = self.stub_request( interfaces=[IInternalOpengeverRequestLayer, ], stub_response=False) getter = self.stub() self.expect(reassign_request.get).result(getter) self.expect(getter('text')).result(u'Simpletext') self.expect(getter('responsible')).result('hugo.boss') self.expect(getter('responsible_client')).result('client1') self.expect(getter('transition')).result( u'task-transition-reassign') # reassign respone response = self.stub_response(request=reassign_request) self.expect(response.setHeader("Content-type", "text/plain")) # an ObjectModifiedEvent should be notified to update the local roles handler = self.stub() self.mock_handler(handler, [IObjectModifiedEvent]) self.expect(handler(ANY)).result(True) self.replay() # REASSIGN TRANSITION # first request view = SyncTaskWorkflowStateReceiveView(task, reassign_request) view() self.assertEquals(IResponseContainer(task)[0].text, u'Simpletext') self.assertEquals(len(IResponseContainer(task)), 1)
def test_creating_and_extraction(self): class DummyResponse(object): def getStatus(self): return 200 class DummyRequest(dict): def __init__(self): self.response = DummyResponse() remote_task = self.providing_stub([ITask, IAttributeAnnotatable]) request = DummyRequest() context = self.providing_stub([ITask, IAttributeAnnotatable]) self.replay() response = Response(u'Sample text') response.creator = u'hugo.boss' response.date = DateTime("02.07.2010") response.add_change('review_state', 'State', 'before-state', 'after-state') response.add_change('responsible', 'Responsible', 'hugo.boss', 'james.bond') container = IResponseContainer(remote_task) container.add(response) # extract request.intids_mapping = {} data = ExtractResponses(remote_task, request)() # receive request['responses'] = data ReceiveResponses(context, request)() # check if the response is correctly synced self.assertTrue(len(IResponseContainer(context)) == 1) synced_response = IResponseContainer(context)[0] self.assertEquals(synced_response.text, response.text) self.assertEquals(synced_response.creator, response.creator) self.assertEquals(synced_response.date, response.date) # changes self.assertEquals(synced_response.changes, [{ u'after': u'after-state', u'id': u'review_state', u'name': u'State', u'before': u'before-state' }, { u'after': u'james.bond', u'id': u'responsible', u'name': u'Responsible', u'before': u'hugo.boss' }])
def test_remote_view(self): task = self.providing_stub([ITask, IAttributeAnnotatable]) self.expect(task.Type()).result('opengever.task.task') # worfklow_tool wft = self.stub() self.mock_tool(wft, 'portal_workflow') with self.mocker.order(): wft.getInfoFor(task, 'review_state').result( 'task-state-resolved') wft.getInfoFor(task, 'review_state').result( 'task-state-in-progress') wft.doActionFor(task, u'task-transition-resolved-in-progress') wft.getTitleForStateOnType( ANY, 'opengever.task.task').result('Resolved') user = SimpleUser('hanspeter', '', ('manage', ), []) newSecurityManager(self.create_dummy(), user) # request request = self.stub_request( interfaces=[IInternalOpengeverRequestLayer, ], stub_response=False) getter = self.stub() self.expect(request.get).result(getter) self.expect(getter('text')).result(u'Simpletext') self.expect(getter('responsible')).result(None) self.expect(getter('responsible_client')).result(None) self.expect(getter('transition')).result( u'task-transition-resolved-in-progress') #response response = self.stub_response(request=request) self.expect(response.setHeader("Content-type", "text/plain")) self.replay() # NORMAL TRANSITION # first request view = SyncTaskWorkflowStateReceiveView(task, request) view() # second request should do nothing view = SyncTaskWorkflowStateReceiveView(task, request) view() self.assertEquals(len(IResponseContainer(task)), 1) self.assertEquals(IResponseContainer(task)[0].text, u'Simpletext') self.assertEquals(len(IResponseContainer(task)[0].changes), 1) self.assertEquals(IResponseContainer(task)[0].creator, 'hanspeter')
def test_adds_corresponding_answer(self): self.login(self.dossier_responsible) change_task_workflow_state( self.subtask, 'task-transition-resolved-tested-and-closed') self.assertEqual('task-transition-resolved-tested-and-closed', IResponseContainer(self.subtask)[-1].transition)
def extract_responses(self, intids_mapping=None): if intids_mapping is None: intids_mapping = {} self.intids_mapping = intids_mapping data = [] for resp in IResponseContainer(self.context): resp_data = {} for key in IPersistentResponse.names(): attr = IPersistentResponse[key] if type(attr) == Attribute: val = getattr(resp, key, None) try: val = self._encode(val) except ValueError: # the intid in the relation value is not listed # in the mapping - so we skip it. pass else: resp_data[key] = val data.append(resp_data) return json.dumps(data)
def test_response_view(self): # test added objects info add_simple_response(self.task, text=u'field', added_object=[self.doc1, self.doc2]) # test field changes info add_simple_response(self.task, text=u'field', field_changes=( (ITask['responsible'], TEST_USER_ID), (ITask['responsible_client'], 'plone'), ), transition=u'task-transition-open-in-progress') # test successsor info successor_oguid = ISuccessorTaskController(self.successor).get_oguid() add_simple_response(self.task, successor_oguid=successor_oguid) transaction.commit() self.assertEquals(len(IResponseContainer(self.task)), 3) # test different responeses and their infos self.browser.open('%s/tabbedview_view-overview' % self.task.absolute_url()) # TODO: replace with OGBrowse API. What is it looking for? self.assertEquals( 'Added successor task', self.browser.css('div.response-info div span.label') [0].plain_text()) successor_info = """<span class="issueChange"><span class="wf-task-state-open"><a href="http://nohost/plone/dossier-1/task-2" title="[Plone] > dossier-1 > Test task 1"><span class="rollover-breadcrumb icon-task-remote-task">Test task 1</span></a> <span class="discreet">(Client2 / <a href="http://nohost/plone/@@user-details/testuser2">User 2 Test (testuser2)</a>)</span></span></span>""" self.assertTrue(successor_info in self.browser.contents) responsible_container = self.browser.xpath( "//div[@class='response-info']/div[descendant-or-self::*[contains(text(), 'label_responsible')]]" )[0] links = responsible_container.xpath("./*/a") self.assertEquals( ['User 2 Test (testuser2)', 'User Test (test_user_1_)'], [l.text for l in links]) self.assertEquals([ 'http://nohost/plone/@@user-details/testuser2', 'http://nohost/plone/@@user-details/test_user_1_' ], [l.attrib["href"] for l in links]) documents = self.browser.css( ".contenttype-opengever-document-document") self.assertEquals(['Doc 1', 'Doc 2'], [d.plain_text() for d in documents]) self.assertEquals([ 'http://nohost/plone/dossier-1/document-1', 'http://nohost/plone/dossier-1/document-2' ], [d.attrib["href"] for d in documents]) # edit and delete should not be possible self.assertEquals([], self.browser.css("input[type='submit']"))
def test_responsible_change_is_visible_in_the_response(self, browser): self.login(self.regular_user, browser) ITask(self.task).responsible = u'team:1' self.task.get_sql_object().responsible = u'team:1' self.set_workflow_state('task-state-open', self.task) browser.open(self.task, view='tabbedview_view-overview') browser.click_on('task-transition-open-in-progress') browser.fill({'Response': u'Das \xfcbernehme ich!'}) browser.click_on('Save') response = IResponseContainer(self.task)[-1] expected = [{'before': u'team:1', 'after': 'kathi.barfuss', 'id': 'responsible', 'name': u'label_responsible'}, {'before': 'task-state-open', 'after': 'task-state-in-progress', 'id': 'review_state', 'name': u'Issue state'}] self.assertEquals( expected, [dict(change) for change in response.changes]) browser.open(self.task, view='tabbedview_view-overview') self.assertEquals( u'Accepted by B\xe4rfuss K\xe4thi (kathi.barfuss), responsible ' u'changed from Projekt \xdcberbaung Dorfmatte (Finanzamt) to ' u'B\xe4rfuss K\xe4thi (kathi.barfuss).', browser.css('.answer h3').text[0])
def test_syncing_response_changes(self): add_simple_response( self.task, text=u'Neu zugewiesen', field_changes=[(ITask['responsible'], 'peter.mueller'), (ITask['responsible_client'], 'client2')], transition='task-transition-reassign', ) copy = create(Builder('task').in_state('task-state-in-progress')) IResponseTransporter(self.task).send_responses( 'client1', copy.get_physical_path()) self.assertEquals([{ u'after': u'peter.mueller', u'id': u'responsible', u'name': u'label_responsible', u'before': u'hugo.boss' }, { u'after': u'client2', u'id': u'responsible_client', u'name': u'label_resonsible_client', u'before': u'client1' }], IResponseContainer(copy)[1].changes)
def make_responses_persistent(self, task): responses = IResponseContainer(task) for response in responses: if response.changes: changes = [ PersistentMapping(change) for change in response.changes ] response.changes = PersistentList(changes)
def test_adding_a_subtask_add_response_on_main_task(self): intids = getUtility(IIntIds) maintask = create(Builder('task').titled('maintask')) subtask = create(Builder('task').within(maintask).titled('maintask')) response = IResponseContainer(maintask)[-1] self.assertEquals(intids.getId(subtask), response.added_object.to_id) self.assertEquals('transition-add-subtask', response.transition)
def test_adding_a_subtask_via_remote_request_does_not_add_response_to_main_task(self): maintask = create(Builder('task').titled('maintask')) # all different remote requests should not # generate an response maintask.REQUEST.environ['X_OGDS_AC'] = 'hugo.boss' create(Builder('task').within(maintask).titled('subtask')) self.assertEquals(0, len(IResponseContainer(maintask))) maintask.REQUEST.environ['X_OGDS_AC'] = None maintask.REQUEST.environ['X_OGDS_AUID'] = 'client1' create(Builder('task').within(maintask).titled('subtask')) self.assertEquals(0, len(IResponseContainer(maintask))) maintask.REQUEST.environ['X_OGDS_AUID'] = None maintask.REQUEST.set('X-CREATING-SUCCESSOR', True) create(Builder('task').within(maintask).titled('subtask')) self.assertEquals(0, len(IResponseContainer(maintask)))
def test_adding_a_document_add_response_on_main_task(self): intids = getUtility(IIntIds) maintask = create(Builder('task').titled('maintask')) document = create( Builder('document').within(maintask).titled('Letter to Peter')) response = IResponseContainer(maintask)[-1] self.assertEquals(intids.getId(document), response.added_object.to_id) self.assertEquals('transition-add-document', response.transition)
def test_test_and_closed_sync(self): """The responsible value None is given in string (remote_request) the responsible should not be set.""" task = self.providing_stub([ITask, IAttributeAnnotatable]) self.expect(task.Type()).result('opengever.task.task') # request request = self.stub_request( interfaces=[IInternalOpengeverRequestLayer, ], stub_response=False) getter = self.stub() self.expect(request.get).result(getter) self.expect(getter('text')).result(u'Closing text') self.expect(getter('responsible')).result('None') self.expect(getter('responsible_client')).result('None') self.expect(getter('transition')).result( u'task-transition-tested-and-closed') #response response = self.stub_response(request=request) self.expect(response.setHeader("Content-type", "text/plain")) # worfklow_tool wft = self.stub() self.mock_tool(wft, 'portal_workflow') with self.mocker.order(): wft.getInfoFor(task, 'review_state').result( 'task-state-in-progress') wft.getInfoFor(task, 'review_state').result( 'task-state-tested-and-closed') wft.doActionFor(task, u'task-transition-tested-and-closed') wft.getTitleForStateOnType( ANY, 'opengever.task.task').result('Closed') self.replay() view = SyncTaskWorkflowStateReceiveView(task, request) view() self.assertEquals(IResponseContainer(task)[0].text, u'Closing text') self.assertEquals(len(IResponseContainer(task)), 1)
def test_add_response_appends_a_new_response_obj_to_the_context_response_container( self): dossier = create(Builder('dossier')) task = create(Builder('task').within(dossier)) response_container = IResponseContainer(task) self.assertEqual(0, len(response_container)) ICommentResponseHandler(task).add_response("My response") self.assertEqual(1, len(response_container))
def test_adds_an_corresponding_response(self, browser): self.assign_task('James', 'james.bond', 'Please make that for me.') response = IResponseContainer(self.task)[-1] self.assertEquals( [{'after': u'james.bond', 'id': 'responsible', 'name': u'label_responsible', 'before': 'test_user_1_'}], response.changes) self.assertEquals('Please make that for me.', response.text)
def test_send_responses(self): copy = create(Builder('task').in_state('task-state-in-progress')) IResponseTransporter(self.task).send_responses( 'client1', copy.get_physical_path()) responses = IResponseContainer(copy) self.assertEquals(1, len(responses)) self.assertEquals('task-transition-open-in-progress', responses[0].transition) self.assertEquals(u'Ich \xfcbernehme diese Aufgabe', responses[0].text) self.assertEquals(TEST_USER_ID, responses[0].creator)
def reassign_team_tasks(task, event): if event.action != 'task-transition-open-in-progress': return if task.is_team_task: old_responsible = ITask(task).responsible ITask(task).responsible = api.user.get_current().getId() IResponseContainer(task)[-1].add_change( 'responsible', _(u"label_responsible", default=u"Responsible"), old_responsible, ITask(task).responsible)
def test_add_form(self): data = {'form.widgets.transition': 'task-transition-open-in-progress'} self.browser.open('%s/addresponse' % self.task.absolute_url(), data=urllib.urlencode(data)) self.assertEquals('Test task 1: task-transition-open-in-progress', self.browser.locate(".documentFirstHeading").text) self.browser.fill_in("form.widgets.text", value="peter") self.browser.click("form.buttons.save") self.assertEquals(len(IResponseContainer(self.task)), 1)
def test_add_form_with_related_items(self): self.browser.open('%s/addresponse' % self.task.absolute_url()) self.browser.fill_in("form.widgets.relatedItems.widgets.query", value=u"Doc 1") self.browser.click("form.widgets.relatedItems.buttons.search") self.browser.check("Doc 1") self.browser.click("form.buttons.save") self.assertEquals(len(IResponseContainer(self.task)), 1) self.assertEquals(self.task.relatedItems[0].to_object, self.doc1)
def test_migrates_plone_task_response_creator(self): task = create(Builder('task')) response = Response('') response.creator = 'HANS.MUSTER' IResponseContainer(task).add(response) PloneTasksMigrator(self.portal, { 'HANS.MUSTER': 'hans.muster' }, 'move').migrate() self.assertEquals('hans.muster', response.creator)
def test_comment_is_synced_to_successor(self): predecessor = create(Builder('task')) successor = create(Builder('task').successor_from(predecessor)) activate_request_layer(self.portal.REQUEST, IInternalOpengeverRequestLayer) response_container = IResponseContainer(successor) self.assertEqual(0, len(response_container)) ICommentResponseHandler(predecessor).add_response("My response") self.assertEqual(1, len(response_container))
def test_migrates_plone_task_responsible_after(self): task = create(Builder('task')) response = Response('') response.add_change('responsible', 'foo', 'peter', 'HANS.MUSTER') IResponseContainer(task).add(response) PloneTasksMigrator(self.portal, { 'HANS.MUSTER': 'hans.muster' }, 'move').migrate() self.assertEquals('hans.muster', response.changes[-1]['after'])
def test_null_fallback(self, browser): # add null response null_response = Response(None) IResponseContainer(self.task).add(null_response) transaction.commit() browser.login() self.visit_overview(browser) self.assertEqual('answer null-transition', browser.css('div.answer')[0].get('class')) self.assertEqual('', self.get_latest_answer(browser))
def create_responses(self, data): container = IResponseContainer(self.context) for resp_data in data: response = Response('') for key, value in resp_data.items(): if value: value = self._decode(value) setattr(response, key, value) container.add(response) modified(self.context)
def test_adds_an_corresponding_response(self, browser): self.login(self.regular_user, browser=browser) responsible = 'fa:{}'.format(self.secretariat_user.getId()) self.assign_task(responsible, u'Please make that for me.') response = IResponseContainer(self.task)[-1] self.assertEquals([{ 'after': self.secretariat_user.getId(), 'id': 'responsible', 'name': u'label_responsible', 'before': self.regular_user.getId() }], response.changes) self.assertEquals('Please make that for me.', response.text)
def test_do_not_add_the_same_response_twice_but_return_ok_anyway(self): task = create(Builder('task').in_state('task-state-in-progress')) self.prepare_request(task, text=u'Response text!', transition='base-response') receiver = BaseResponseSyncerReceiver(task, self.request) self.assertEquals('OK', receiver()) self.assertEquals('OK', receiver()) response_container = IResponseContainer(task) self.assertEqual(1, len(response_container), "Should not add the same response twice")
def test_deadline_change_synchronisation(self): IDeadlineModifier(self.task).modify_deadline( date(2016, 03, 29), u'Frist wurde verschoben.', u'task-transition-modify-deadline') copy = create(Builder('task').in_state('task-state-in-progress')) IResponseTransporter(self.task).send_responses( 'client1', copy.get_physical_path()) self.assertEquals([{ u'after': date(2016, 03, 29), u'id': u'deadline', u'name': u'label_deadline', u'before': date(2016, 03, 27) }], IResponseContainer(copy)[1].changes)
def test_adds_a_response_to_the_given_context(self): task = create(Builder('task')) self.prepare_request(task, text=u'Response text', transition='base-response') BaseResponseSyncerReceiver(task, self.request)() response_container = IResponseContainer(task) self.assertEqual(1, len(response_container)) response = response_container[0] self.assertEqual('Response text', response.text) self.assertEqual('base-response', response.transition)
def test_response_and_response_changes_are_persistent(self, browser): self.login(self.dossier_responsible, browser=browser) browser.open(self.task) browser.click_on('task-transition-modify-deadline') browser.fill({ 'Response': u'Nicht mehr so dringend ...', 'New Deadline': '1.1.2017' }) browser.click_on('Save') response = IResponseContainer(self.task)[-1] self.assertIsInstance(response, Persistent) self.assertIsInstance(response.changes, PersistentList) self.assertIsInstance(response.changes[0], PersistentMapping)