コード例 #1
0
    def test_untrashing_available_for_trashed_document(self, browser):
        self.login(self.regular_user, browser)

        trasher = ITrashable(self.document)
        trasher.trash()

        expected_file_actions = [
            {
                u'id': u'download_copy',
                u'title': u'Download copy',
                u'icon': u''
            },
            {
                u'id': u'attach_to_email',
                u'title': u'Attach to email',
                u'icon': u''
            },
            {
                u'id': u'open_as_pdf',
                u'title': u'Open as PDF',
                u'icon': u''
            },
            {
                u'id': u'untrash_document',
                u'title': u'Untrash document',
                u'icon': u''
            },
        ]
        self.assertEqual(expected_file_actions,
                         self.get_file_actions(browser, self.document))
コード例 #2
0
    def __call__(self):
        paths = self.request.get('paths')
        if paths:
            for item in paths:
                obj = self.context.restrictedTraverse(item)
                if not api.user.has_permission(
                        'opengever.trash: Untrash content', obj=obj):
                    msg = _(u'Untrashing ${title} is forbidden',
                            mapping={'title': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='error')
                    continue

                trasher = ITrashable(obj)
                trasher.untrash()

            return self.request.RESPONSE.redirect(
                '%s#documents' % (self.context.absolute_url()))

        else:
            msg = _(u'You have not selected any items.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')

            return self.request.RESPONSE.redirect('%s#trash' %
                                                  self.context.absolute_url())
コード例 #3
0
ファイル: dx.py プロジェクト: 4teamwork/opengever.core
    def after_create(self, obj):
        if self._trashed:
            trasher = ITrashable(obj)
            trasher.trash()

        obj.update_filename()
        super(MailBuilder, self).after_create(obj)
コード例 #4
0
ファイル: trash.py プロジェクト: 4teamwork/opengever.core
    def reply(self):

        # Disable CSRF protection
        alsoProvides(self.request,
                     plone.protect.interfaces.IDisableCSRFProtection)

        trasher = ITrashable(self.context)
        try:
            trasher.trash()
        except TrashError as exc:
            if exc.message == 'Already trashed':
                self.request.response.setStatus(400)
                return {'error': {
                    'type': 'Bad Request',
                    'message': 'Already trashed',
                }}
            elif exc.message == 'Document checked out':
                self.request.response.setStatus(400)
                return {'error': {
                    'type': 'Bad Request',
                    'message': 'Can not trash a checked-out document',
                }}

        self.request.response.setStatus(204)
        return super(Trash, self).reply()
コード例 #5
0
    def reply(self):

        # Disable CSRF protection
        alsoProvides(self.request,
                     plone.protect.interfaces.IDisableCSRFProtection)

        trasher = ITrashable(self.context)
        try:
            trasher.trash()
        except TrashError as exc:
            if exc.message == 'Already trashed':
                self.request.response.setStatus(400)
                return {
                    'error': {
                        'type': 'Bad Request',
                        'message': 'Already trashed',
                    }
                }
            elif exc.message == 'Document checked out':
                self.request.response.setStatus(400)
                return {
                    'error': {
                        'type': 'Bad Request',
                        'message': 'Can not trash a checked-out document',
                    }
                }

        self.request.response.setStatus(204)
        return super(Trash, self).reply()
コード例 #6
0
ファイル: dx.py プロジェクト: lukasgraf/opengever.core
    def after_create(self, obj):
        if self._trashed:
            trasher = ITrashable(obj)
            trasher.trash()

        obj.update_filename()
        super(MailBuilder, self).after_create(obj)
コード例 #7
0
 def test_untrash_document(self, browser):
     self.login(self.regular_user, browser)
     trasher = ITrashable(self.document)
     trasher.trash()
     browser.open(self.document.absolute_url() + '/@untrash',
                  method='POST', headers={'Accept': 'application/json'})
     self.assertEqual(204, browser.status_code)
     self.assertFalse(ITrashed.providedBy(self.document))
コード例 #8
0
ファイル: builders.py プロジェクト: vincero/opengever.core
    def after_create(self, obj):
        if self.checked_out:
            IAnnotations(obj)[CHECKIN_CHECKOUT_ANNOTATIONS_KEY] = self.checked_out

        if self._trashed:
            trasher = ITrashable(obj)
            trasher.trash()

        super(DocumentBuilder, self).after_create(obj)
コード例 #9
0
    def after_create(self, obj):
        if self.checked_out:
            IAnnotations(
                obj)[CHECKIN_CHECKOUT_ANNOTATIONS_KEY] = self.checked_out

        if self._trashed:
            trasher = ITrashable(obj)
            trasher.trash()

        super(DocumentBuilder, self).after_create(obj)
コード例 #10
0
    def reply(self):

        # Disable CSRF protection
        alsoProvides(self.request,
                     plone.protect.interfaces.IDisableCSRFProtection)

        trasher = ITrashable(self.context)
        trasher.untrash()

        self.request.response.setStatus(204)
        return super(Untrash, self).reply()
コード例 #11
0
ファイル: trash.py プロジェクト: 4teamwork/opengever.core
    def reply(self):

        # Disable CSRF protection
        alsoProvides(self.request,
                     plone.protect.interfaces.IDisableCSRFProtection)

        trasher = ITrashable(self.context)
        trasher.untrash()

        self.request.response.setStatus(204)
        return super(Untrash, self).reply()
コード例 #12
0
    def test_remove_action_not_available_in_private_folder(self, browser):
        self.login(self.manager, browser=browser)

        ITrashable(self.document).trash()
        browser.open(self.dossier, view="tabbed_view/listing?view_name=trash")
        self.assertItemsEqual([u'More actions \u25bc', 'untrashed', 'remove'],
                              browser.css('#tabbedview-menu a').text)

        ITrashable(self.private_document).trash()
        browser.open(self.private_dossier,
                     view="tabbed_view/listing?view_name=trash")
        self.assertItemsEqual([u'More actions \u25bc', 'untrashed'],
                              browser.css('#tabbedview-menu a').text)
コード例 #13
0
    def after_create(self, obj):
        if self._checked_out:
            IAnnotations(
                obj)[CHECKIN_CHECKOUT_ANNOTATIONS_KEY] = self._checked_out
            obj.reindexObject(idxs=['checked_out'])

        if self._trashed:
            trasher = ITrashable(obj)
            trasher.trash()

        if self._is_shadow:
            obj.as_shadow_document()

        super(DocumentBuilder, self).after_create(obj)
コード例 #14
0
    def remove(self):
        assert self.meeting.is_editable()

        # the agenda_item is ad hoc if it has a document but no proposal
        if self.has_document and not self.has_proposal:
            document = self.resolve_document()
            trasher = ITrashable(document)
            trasher.trash()

        session = create_session()
        if self.proposal:
            self.proposal.remove_scheduled(self.meeting)
        session.delete(self)
        self.meeting.reorder_agenda_items()
コード例 #15
0
ファイル: dx.py プロジェクト: 4teamwork/opengever.core
    def after_create(self, obj):
        if self._checked_out:
            IAnnotations(obj)[CHECKIN_CHECKOUT_ANNOTATIONS_KEY] = self._checked_out
            obj.reindexObject(idxs=['checked_out'])

        if self._trashed:
            trasher = ITrashable(obj)
            trasher.trash()

        if self._is_shadow:
            obj.as_shadow_document()
            obj.reindexObject(idxs=["review_state"])

        super(DocumentBuilder, self).after_create(obj)
コード例 #16
0
    def remove(self):
        assert self.meeting.is_editable()

        # the agenda_item is ad hoc if it has a document but no proposal
        if self.has_document and not self.has_proposal:
            document = self.resolve_document()
            trasher = ITrashable(document)
            trasher.trash()

        session = create_session()
        if self.proposal:
            self.proposal.remove_scheduled(self.meeting)
        session.delete(self)
        self.meeting.reorder_agenda_items()
コード例 #17
0
    def test_trash_excerpt_is_forbidden_when_it_has_been_returned_to_proposal(
            self, browser):
        self.login(self.committee_responsible, browser)
        agenda_item = self.schedule_proposal(self.meeting,
                                             self.submitted_proposal)
        agenda_item.decide()
        excerpt1 = agenda_item.generate_excerpt('excerpt 1')

        ITrashable(excerpt1).trash()

        ITrashable(excerpt1).untrash()
        agenda_item.return_excerpt(excerpt1)

        with self.assertRaises(TrashError):
            ITrashable(excerpt1).trash()
コード例 #18
0
    def test_get_size_on_mails(self):
        self.grant('Manager')
        mail = create(Builder('mail').with_message('Not really an email'))
        self.assertEquals(19, IObjectSize(mail).get_size())

        ITrashable(mail).trash()
        self.assertEquals(0, IObjectSize(mail).get_size())
コード例 #19
0
    def test_remove_excerpt_for_agendaitem_removes_relation_in_submitted_proposal(
            self, browser):
        self.login(self.committee_responsible, browser)
        agenda_item = self.schedule_proposal(self.meeting,
                                             self.submitted_proposal)
        agenda_item.decide()
        excerpt1 = agenda_item.generate_excerpt('excerpt 1')
        agenda_item.generate_excerpt('excerpt 2')

        self.assertEqual(2, len(self.submitted_proposal.excerpts))
        self.assertEqual(
            2, len(self.submitted_proposal.get_excerpts(include_trashed=True)))
        self.assertEqual(
            2, len(agenda_item.get_excerpt_documents(include_trashed=True)))
        self.assertEqual(2, len(list(_relations(self.submitted_proposal))))

        ITrashable(excerpt1).trash()
        with elevated_privileges():
            Remover([excerpt1]).remove()

        self.assertEqual(1, len(self.submitted_proposal.excerpts))
        self.assertEqual(
            1, len(self.submitted_proposal.get_excerpts(include_trashed=True)))
        self.assertEqual(
            1, len(agenda_item.get_excerpt_documents(include_trashed=True)))
        self.assertEqual(1, len(list(_relations(self.submitted_proposal))))
コード例 #20
0
    def __call__(self):
        paths = self.request.get('paths')
        catalog = getToolByName(self.context, 'portal_catalog')
        if paths:
            for item in paths:
                obj = self.context.restrictedTraverse(item)
                brains = catalog(path=item)

                # check that the object isn't already trashed
                if not brains:
                    msg = _(
                        u'could not trash the object ${obj}, '
                        'it is already trashed',
                        mapping={'obj': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='error')
                    continue
                # check that the document isn't checked_out
                if brains[0].checked_out:
                    msg = _(
                        u'could not trash the object ${obj}, it is checked out.',
                        mapping={'obj': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='error')
                    continue

                if not api.user.has_permission(
                        'opengever.trash: Trash content', obj=obj):
                    msg = _(u'Trashing ${title} is forbidden',
                            mapping={'title': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='error')
                    continue

                trasher = ITrashable(obj)
                trasher.trash()
                msg = _(u'the object ${obj} trashed',
                        mapping={'obj': obj.Title().decode('utf-8')})
                IStatusMessage(self.request).addStatusMessage(msg, type='info')

        else:
            msg = _(u'You have not selected any items.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')

        return self.request.RESPONSE.redirect('{}#documents'.format(
            self.context.absolute_url()))
コード例 #21
0
ファイル: trash.py プロジェクト: 4teamwork/opengever.core
    def __call__(self):
        paths = self.request.get('paths')
        if paths:
            for item in paths:
                obj = self.context.restrictedTraverse(item)

                trasher = ITrashable(obj)
                try:
                    trasher.trash()
                except TrashError as exc:
                    if exc.message == 'Already trashed':
                        msg = _(
                            u'could not trash the object ${obj}, '
                            'it is already trashed',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    elif exc.message == 'Document checked out':
                        msg = _(
                            u'could not trash the object ${obj}, it is checked'
                            ' out.',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    elif exc.message == 'The document has been returned as excerpt':
                        msg = _(
                            u'could not trash the object ${obj}, it is an excerpt'
                            ' that has been returned to the proposal.',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(
                        msg, type='error')
                except Unauthorized:
                    msg = _(u'Trashing ${title} is forbidden',
                            mapping={'title': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(
                        msg, type='error')

                else:
                    msg = _(u'the object ${obj} trashed',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(
                        msg, type='info')

        else:
            msg = _(u'You have not selected any items.')
            IStatusMessage(self.request).addStatusMessage(
                msg, type='error')

        return self.request.RESPONSE.redirect(
            '{}#documents'.format(self.context.absolute_url()))
コード例 #22
0
    def test_get_size_on_document(self):
        self.grant('Manager')
        document = create(
            Builder('document').attach_file_containing('Hello World'))
        self.assertEquals(11, IObjectSize(document).get_size())

        ITrashable(document).trash()
        self.assertEquals(0, IObjectSize(document).get_size())
コード例 #23
0
ファイル: trash.py プロジェクト: robertmuehsig/opengever.core
    def __call__(self):
        paths = self.request.get('paths')
        if paths:
            for item in paths:
                obj = self.context.restrictedTraverse(item)

                trasher = ITrashable(obj)
                try:
                    trasher.trash()
                except TrashError as exc:
                    if exc.message == 'Already trashed':
                        msg = _(
                            u'could not trash the object ${obj}, '
                            'it is already trashed',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    elif exc.message == 'Document checked out':
                        msg = _(
                            u'could not trash the object ${obj}, it is checked'
                            ' out.',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    elif exc.message == 'The document has been returned as excerpt':
                        msg = _(
                            u'could not trash the object ${obj}, it is an excerpt'
                            ' that has been returned to the proposal.',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='error')
                except Unauthorized:
                    msg = _(u'Trashing ${title} is forbidden',
                            mapping={'title': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='error')

                else:
                    msg = _(u'the object ${obj} trashed',
                            mapping={'obj': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='info')

        else:
            msg = _(u'You have not selected any items.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')

        return self.request.RESPONSE.redirect('{}#documents'.format(
            self.context.absolute_url()))
コード例 #24
0
    def delete(self):
        """Unschedule the current agenda_item. If the agenda_item has no
        proposal, the agenda_item gets deleted. If there is a proposal related,
        the proposal is unscheduled.
        """

        if not self.context.model.is_editable():
            raise Unauthorized("Editing is not allowed")

        # the agenda_item is ad hoc if it has a document but no proposal
        if self.agenda_item.has_document and not self.agenda_item.has_proposal:
            document = self.agenda_item.resolve_document()
            trasher = ITrashable(document)
            trasher.trash()

        self.agenda_item.remove()

        return JSONResponse(self.request).info(
            _(u'agenda_item_deleted',
              default=u'Agenda Item Successfully deleted')).dump()
コード例 #25
0
ファイル: trash.py プロジェクト: lukasgraf/opengever.core
    def __call__(self):
        paths = self.request.get('paths')
        if paths:
            for item in paths:
                obj = self.context.restrictedTraverse(item)
                trasher = ITrashable(obj)
                try:
                    trasher.untrash()
                except Unauthorized:
                    msg = _(u'Untrashing ${title} is forbidden',
                            mapping={'title': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(msg,
                                                                  type='error')

            return self.request.RESPONSE.redirect(
                '%s#documents' % (self.context.absolute_url()))

        else:
            msg = _(u'You have not selected any items.')
            IStatusMessage(self.request).addStatusMessage(msg, type='error')

            return self.request.RESPONSE.redirect('%s#trash' %
                                                  self.context.absolute_url())
コード例 #26
0
ファイル: trash.py プロジェクト: 4teamwork/opengever.core
    def __call__(self):
        paths = self.request.get('paths')
        if paths:
            for item in paths:
                obj = self.context.restrictedTraverse(item)
                trasher = ITrashable(obj)
                try:
                    trasher.untrash()
                except Unauthorized:
                    msg = _(u'Untrashing ${title} is forbidden',
                            mapping={'title': obj.Title().decode('utf-8')})
                    IStatusMessage(self.request).addStatusMessage(
                        msg, type='error')

            return self.request.RESPONSE.redirect('%s#documents' % (
                self.context.absolute_url()))

        else:
            msg = _(u'You have not selected any items.')
            IStatusMessage(self.request).addStatusMessage(
                msg, type='error')

            return self.request.RESPONSE.redirect(
                '%s#trash' % self.context.absolute_url())
コード例 #27
0
    def test_trashed_exceprts_are_not_listed_for_ad_hoc_agendaitem(
            self, browser):
        self.login(self.committee_responsible, browser)
        agenda_item = self.schedule_ad_hoc(self.meeting, 'Foo')
        agenda_item.decide()
        excerpt1 = agenda_item.generate_excerpt('excerpt 1')
        agenda_item.generate_excerpt('excerpt 2')

        excerpts = browser.open(self.agenda_item_url(
            agenda_item, 'list')).json.get('items')[0].get('excerpts')
        self.assertEqual(len(excerpts), 2)

        ITrashable(excerpt1).trash()
        excerpts = browser.open(self.agenda_item_url(
            agenda_item, 'list')).json.get('items')[0].get('excerpts')
        self.assertEqual(len(excerpts), 1)

        excerpt_links = ' '.join([excerpt.get('link') for excerpt in excerpts])
        excerpt_titles = browser.open_html(excerpt_links).css('a').text
        self.assertEqual(['excerpt 2'], excerpt_titles)
コード例 #28
0
    def test_remove_excerpt_for_adhoc_agendaitem_removes_entry_from_sql_database(
            self, browser):
        self.login(self.committee_responsible, browser)
        agenda_item = self.schedule_ad_hoc(self.meeting, 'Foo')
        agenda_item.decide()
        excerpt1 = agenda_item.generate_excerpt('excerpt 1')
        agenda_item.generate_excerpt('excerpt 2')

        self.assertEqual(
            2, len(agenda_item.get_excerpt_documents(include_trashed=True)))
        excerpts = Excerpt.query.filter(
            Excerpt.agenda_item_id == agenda_item.agenda_item_id).all()
        self.assertEqual(2, len(excerpts))

        ITrashable(excerpt1).trash()
        with elevated_privileges():
            Remover([excerpt1]).remove()

        self.assertEqual(
            1, len(agenda_item.get_excerpt_documents(include_trashed=True)))
        excerpts = Excerpt.query.filter(
            Excerpt.agenda_item_id == agenda_item.agenda_item_id).all()
        self.assertEqual(1, len(excerpts))
コード例 #29
0
    def test_content_modifications_update_usage(self):
        """Test that adding, updating, removing and moving update the usage.

        This test is implemented as story so that we do not create that many
        objects in order to speed up tests.
        As soon as we can use fixtures these tests can be refactored.
        """
        self.grant('Manager')

        user_root = create(Builder('private_root'))
        user_folder = create_members_folder(user_root)
        user_dossier = create(Builder('dossier').within(user_folder))
        shared_dossier = create(Builder('dossier'))
        self.assertEqual(0, ISizeQuota(user_folder).get_usage(),
                         'Expected usage to be 0 for an empty root.')

        with self.assert_usage_change(user_folder, +1,
                                      'add first document'):
            doc1 = create(Builder('document')
                          .attach_file_containing('X')
                          .within(user_dossier))

        with self.assert_usage_change(user_folder, -1 + 2,
                                      'update document'):
            doc1.file = NamedBlobFile('XX', filename=u'test.txt')
            notify(ObjectModifiedEvent(doc1))

        with self.assert_usage_change(user_folder, +3,
                                      'add second document'):
            doc2 = create(Builder('document')
                          .attach_file_containing('XXX')
                          .within(user_dossier))

        with self.assert_usage_change(user_folder, -3,
                                      'move away from quota container'):
            shared_dossier.manage_pasteObjects(
                user_dossier.manage_cutObjects([doc2.getId()]))

        with self.assert_usage_change(user_folder, +3,
                                      'move back into quota container'):
            user_dossier.manage_pasteObjects(
                shared_dossier.manage_cutObjects([doc2.getId()]))

        with self.assert_usage_change(user_folder, -3, 'trash document'):
            ITrashable(doc2).trash()

        with self.assert_usage_change(user_folder, +3, 'restore document'):
            ITrashable(doc2).untrash()

        with self.assert_usage_change(user_folder, -3,
                                      'delete'):
            user_dossier.manage_delObjects([doc2.getId()])

        # clear and recalculate
        self.assertEqual(2, ISizeQuota(user_folder).get_usage())
        ISizeQuota(user_folder).get_usage_map(for_writing=True).clear()
        self.assertEqual(0, ISizeQuota(user_folder).get_usage())
        ISizeQuota(user_folder).recalculate()
        self.assertEqual(2, ISizeQuota(user_folder).get_usage())

        # changes to foreign user folders should never affect our user folder
        with self.assert_usage_change(user_folder, 0,
                                      'create and fill foreign user folder'):
            john_doe = create(Builder('user').named('John', 'Deo')
                              .with_roles('Contributor', 'Editor', 'Reader'))
            login(self.portal, john_doe.getId())
            other_user_folder = create_members_folder(user_root)
            other_user_dossier = create(Builder('dossier').within(
                other_user_folder))
            create(Builder('document')
                   .attach_file_containing('XXX')
                   .within(other_user_dossier))
            login(self.portal, TEST_USER_NAME)

        with self.assert_usage_change(user_folder, 0,
                                      'recalculate without change'):
            ISizeQuota(user_folder).get_usage_map(
                for_writing=True)['purge-me'] = 999
            ISizeQuota(user_folder).recalculate()
コード例 #30
0
 def is_untrash_document_available(self):
     trasher = ITrashable(self.context)
     return trasher.verify_may_untrash(raise_on_violations=False)