Пример #1
0
    def test_publishes_and_retracts_multiple_objects_in_single_script_call(
            self):
        c1 = zeit.cms.interfaces.ICMSContent(
            'http://xml.zeit.de/online/2007/01/Somalia')
        c2 = zeit.cms.interfaces.ICMSContent(
            'http://xml.zeit.de/online/2007/01/eta-zapatero')
        IPublishInfo(c1).urgent = True
        IPublishInfo(c2).urgent = True
        with mock.patch('zeit.workflow.publish.PublishTask'
                        '.call_publish_script') as script:
            IPublish(self.repository).publish_multiple([c1, c2], async=False)
            script.assert_called_with([
                'work/online/2007/01/Somalia',
                'work/online/2007/01/eta-zapatero'
            ])
        self.assertTrue(IPublishInfo(c1).published)
        self.assertTrue(IPublishInfo(c2).published)

        with mock.patch('zeit.workflow.publish.RetractTask'
                        '.call_retract_script') as script:
            IPublish(self.repository).retract_multiple([c1, c2], async=False)
            script.assert_called_with([
                'work/online/2007/01/Somalia',
                'work/online/2007/01/eta-zapatero'
            ])
        self.assertFalse(IPublishInfo(c1).published)
        self.assertFalse(IPublishInfo(c2).published)
Пример #2
0
 def test_opening_dialog_from_folder_view_points_to_content(self):
     # Regression VIV-452
     from zeit.cms.testcontenttype.testcontenttype import ExampleContentType
     from zeit.cms.workflow.interfaces import IPublish, IPublishInfo
     zope.component.hooks.setSite(self.getRootFolder())
     self.repository['other'] = ExampleContentType()
     self.prepare_content('http://xml.zeit.de/other')
     self.prepare_content('http://xml.zeit.de/testcontent')
     transaction.commit()
     IPublish(self.repository['other']).publish(background=False)
     IPublish(self.repository['testcontent']).publish(background=False)
     transaction.commit()
     self.open('/repository')
     s = self.selenium
     s.click('xpath=//*[contains(text(), "testcontent")]')
     s.waitForElementPresent('css=#bottomcontent a[title=Retract]')
     s.click('css=#bottomcontent a[title="Additional actions"]')
     s.click('css=#bottomcontent a[title=Retract]')
     s.waitForElementPresent('css=ol#worklist')
     s.waitForElementPresent('css=li.busy[action=start_job]')
     s.waitForElementNotPresent('css=li.busy[action=start_job]')
     s.waitForPageToLoad()
     self.assertFalse(
         IPublishInfo(self.repository['testcontent']).published)
     self.assertTrue(IPublishInfo(self.repository['other']).published)
Пример #3
0
 def update(self):
     if self.bcobj.skip_import:
         return True
     self._update()
     self._handle_images()
     if self.bcobj.state == 'ACTIVE':
         IPublish(self.cmsobj).publish(background=False)
     else:
         log.info('Deactivating %s', self.bcobj)
         if IPublishInfo(self.cmsobj).published:
             IPublish(self.cmsobj).retract(background=False)
Пример #4
0
    def test_error_in_one_item_continues_with_other_items(self):
        c1 = zeit.cms.interfaces.ICMSContent(
            'http://xml.zeit.de/online/2007/01/Somalia')
        c2 = zeit.cms.interfaces.ICMSContent(
            'http://xml.zeit.de/online/2007/01/eta-zapatero')
        IPublishInfo(c1).urgent = True
        IPublishInfo(c2).urgent = True

        calls = []

        def after_publish(context, event):
            calls.append(context.uniqueId)
            if context.uniqueId == c1.uniqueId:
                raise RuntimeError('provoked')

        self.zca.patch_handler(after_publish,
                               (zeit.cms.interfaces.ICMSContent,
                                zeit.cms.workflow.interfaces.IPublishedEvent))

        with self.assertRaises(RuntimeError):
            IPublish(self.repository).publish_multiple([c1, c2], async=False)

        # PublishedEvent still happens for c2, even though c1 raised
        self.assertIn(c2.uniqueId, calls)
        # Error is logged
        log = zeit.objectlog.interfaces.ILog(c1)
        self.assertEqual([
            u'${name}: ${new_value}', u'Collective Publication',
            u'Error during publish/retract: ${exc}: ${message}'
        ], [x.message for x in log.get_log()])
Пример #5
0
 def test_synchronous_multi_publishing_works_with_unique_ids(self):
     article = ICMSContent('http://xml.zeit.de/online/2007/01/Somalia')
     info = IPublishInfo(article)
     info.urgent = True
     IPublish(article).publish_multiple([article.uniqueId],
                                        background=False)
     self.assertTrue(info.published)
Пример #6
0
    def test_error_during_publish_multiple_is_written_to_objectlog(self):
        c1 = ICMSContent('http://xml.zeit.de/online/2007/01/Flugsicherheit')
        c2 = ICMSContent('http://xml.zeit.de/online/2007/01/Saarland')
        i1 = IPublishInfo(c1)
        i2 = IPublishInfo(c2)
        self.assertFalse(i1.published)
        self.assertFalse(i2.published)
        i1.urgent = True
        i2.urgent = True

        publish = IPublish(c1).publish_multiple([c1, c2])
        transaction.commit()

        with self.assertRaises(Exception) as err:
            publish.get()
        transaction.begin()

        self.assertEqual("Error during publish/retract: ScriptError: ('', 1)",
                         str(err.exception))
        self.assertIn(
            "Error during publish/retract: ScriptError: ('', 1)",
            [zope.i18n.interpolate(m, m.mapping) for m in get_object_log(c1)])
        self.assertIn(
            "Error during publish/retract: ScriptError: ('', 1)",
            [zope.i18n.interpolate(m, m.mapping) for m in get_object_log(c2)])
Пример #7
0
    def test_publish_multiple_via_celery_end_to_end(self):
        c1 = ICMSContent('http://xml.zeit.de/online/2007/01/Flugsicherheit')
        c2 = ICMSContent('http://xml.zeit.de/online/2007/01/Saarland')
        i1 = IPublishInfo(c1)
        i2 = IPublishInfo(c2)
        self.assertFalse(i1.published)
        self.assertFalse(i2.published)
        i1.urgent = True
        i2.urgent = True

        publish = IPublish(c1).publish_multiple([c1, c2])
        transaction.commit()
        self.assertEqual('Published.', publish.get())
        transaction.begin()

        self.assertEllipsis(
            """\
Running job ...
    for http://xml.zeit.de/online/2007/01/Flugsicherheit,
        http://xml.zeit.de/online/2007/01/Saarland
Publishing http://xml.zeit.de/online/2007/01/Flugsicherheit,
       http://xml.zeit.de/online/2007/01/Saarland
...
Done http://xml.zeit.de/online/2007/01/Flugsicherheit,
 http://xml.zeit.de/online/2007/01/Saarland (...s)""", self.log.getvalue())

        self.assertIn('Published', get_object_log(c1))
        self.assertIn('Published', get_object_log(c2))
Пример #8
0
 def test_last_published_by_takes_last_entry_from_objectlog(self):
     content = self.repository['testcontent']
     info = IPublishInfo(content)
     self.assertEqual(None, info.last_published_by)
     info.urgent = True
     IPublish(content).publish(background=False)
     self.assertEqual('zope.user', info.last_published_by)
Пример #9
0
 def update(self):
     lsc = zeit.cms.content.interfaces.ISemanticChange(
         self.cmsobj).last_semantic_change
     if self.bcobj.updated_at <= lsc:
         return False
     self._update()
     IPublish(self.cmsobj).publish(background=False)
Пример #10
0
 def test_delete_menu_item_is_not_displayed_for_published_objects(self):
     content = self.repository['testcontent']
     IPublishInfo(content).set_can_publish(CAN_PUBLISH_SUCCESS)
     IPublish(content).publish()
     self.browser.open(
         'http://*****:*****@@delete.html')
Пример #11
0
 def _store(self, content):
     obj = zeit.content.text.text.Text()
     filename = self.FILENAME.format(
         now=datetime.datetime.now().strftime('%Y%m%d%H%M'))
     log.info('Storing new contents as %s/%s', self.folder_id, filename)
     obj.text = content
     self.folder[filename] = obj
     IPublish(self.folder[filename]).publish(background=False)
Пример #12
0
 def __call__(self):
     all_content_to_publish = \
         self.context.content_with_references_for_publishing()
     job = IPublish(self.context).publish_multiple(
         all_content_to_publish,
         priority=zeit.cms.workflow.interfaces.IPublishPriority(
             self.context))
     return json.dumps(job.id)
Пример #13
0
 def sweep(self, keep):
     names = sorted(self.folder.keys())
     if len(names) <= keep:
         return
     delete = names[:-keep]
     for name in delete:
         IPublish(self.folder[name]).retract(background=False)
         del self.folder[name]
Пример #14
0
 def publish(obj):
     if obj is None:
         log.info('Got None to publish')
         return
     if not IPublishInfo(obj).published:
         log.info('Publishing %s' % obj)
         IPublish(obj).publish(background=False)
     else:
         log.info('%s already published' % obj)
Пример #15
0
 def test_object_already_checked_out_should_raise(self):
     article = ICMSContent('http://xml.zeit.de/online/2007/01/Somalia')
     IPublishInfo(article).urgent = True
     zeit.cms.checkout.interfaces.ICheckoutManager(article).checkout()
     zope.security.management.endInteraction()
     with zeit.cms.testing.interaction('zope.producer'):
         with self.assertRaises(Exception) as info:
             IPublish(article).publish(async=False)
         self.assertIn('LockingError', str(info.exception))
     self.assertEqual(False, IPublishInfo(article).published)
Пример #16
0
 def delete(self):
     if not isinstance(self.bcobj, DeletedVideo):
         return False
     elif self.cmsobj is None:
         # Deleted in BC and no CMS object: we're done.
         return True
     log.info('Deleting %s', self.bcobj)
     if IPublishInfo(self.cmsobj).published:
         IPublish(self.cmsobj).retract(background=False)
     del self.bcobj.__parent__[self.bcobj.id]
     return True
Пример #17
0
 def test_accepts_uniqueId_as_well_as_ICMSContent(self):
     with mock.patch('zeit.workflow.publish.MultiPublishTask.run') as run:
         IPublish(self.repository).publish_multiple([
             self.repository['testcontent'],
             'http://xml.zeit.de/online/2007/01/Somalia'
         ],
                                                    async=False)
         ids = run.call_args[0][0]
         self.assertEqual([
             'http://xml.zeit.de/testcontent',
             'http://xml.zeit.de/online/2007/01/Somalia'
         ], ids)
Пример #18
0
 def test_determines_priority_via_adapter(self):
     content = self.repository['testcontent']
     info = IPublishInfo(content)
     info.urgent = True
     self.assertFalse(info.published)
     with mock.patch(
             'zeit.cms.workflow.interfaces.IPublishPriority') as priority,\
             mock.patch.object(zeit.workflow.publish.PUBLISH_TASK,
                               'apply_async') as apply_async:
         priority.return_value = zeit.cms.workflow.interfaces.PRIORITY_LOW
         IPublish(content).publish()
     apply_async.assert_called_with(([u'http://xml.zeit.de/testcontent'], ),
                                    queuename='publish_lowprio')
Пример #19
0
    def test_rename_menu_item_is_not_displayed_for_published_objects(self):
        content = self.repository['testcontent']
        IPublishInfo(content).set_can_publish(CAN_PUBLISH_SUCCESS)
        IPublish(content).publish()
        b = self.browser
        b.open('http://*****:*****@@rename-box')

        # Cannot rename even if one enters the URL manually
        b.open('http://*****:*****@@rename-box')
        with self.assertRaises(LookupError):
            b.getControl('Rename')  # 'Rename' button is missing
Пример #20
0
 def test_displays_last_published_information(self):
     article = zeit.cms.interfaces.ICMSContent(
         'http://xml.zeit.de/online/2007/01/Somalia')
     IContentWorkflow(article).urgent = True
     IPublish(article).publish()
     IPublishInfo(article).date_last_published = datetime.datetime(
         2013, 7, 2, 9, 31, 24, tzinfo=pytz.utc)
     b = self.browser
     b.open('http://localhost/++skin++vivi/repository'
            '/online/2007/01/Somalia/@@checkout')
     b.open('@@contents')
     self.assertEllipsis(
         '...last published at...02.07.2013...on...11:31...by'
         '...zope.user...', b.contents)
Пример #21
0
    def test_publish_and_retract_in_same_process(self):
        article = ICMSContent('http://xml.zeit.de/online/2007/01/Somalia')
        info = IPublishInfo(article)
        info.urgent = True
        publish = IPublish(article)
        self.assertFalse(info.published)
        publish.publish(async=False)
        self.assertTrue(info.published)
        publish.retract(async=False)
        self.assertFalse(info.published)

        logs = reversed(zeit.objectlog.interfaces.ILog(article).logs)
        self.assertEqual(['${name}: ${new_value}', 'Published', 'Retracted'],
                         [x.message for x in logs])
Пример #22
0
 def delete_except(cls, known):
     """There is no way in the BC API to get data about deleted playlists,
     so we fall back on deleting any playlist that BC does not know about.
     """
     if not known:  # safetybelt
         return
     folder = zeit.brightcove.convert.playlist_location(None)
     cms_names = set(folder.keys())
     bc_names = set(x.id for x in known)
     for name in cms_names - bc_names:
         log.info('Deleting <Playlist id=%s>', name)
         cmsobj = folder[name]
         if IPublishInfo(cmsobj).published:
             IPublish(cmsobj).retract(background=False)
         del folder[name]
Пример #23
0
 def test_delete_button_is_not_displayed_for_folder_with_published_objects(
         self):
     folder = self.repository['testing']
     folder['foo'] = content = ExampleContentType()
     self.assertFalse(IPublishInfo(folder).published)
     IPublishInfo(content).set_can_publish(CAN_PUBLISH_SUCCESS)
     IPublish(content).publish()
     browser = testing.Browser(self.layer['wsgi_app'])
     browser.login('producer', 'producerpw')
     browser.open('http://*****:*****@@delete.html')
     url = link.url.split("'")[1]  # embedded in lightbox javascript
     browser.open(url)
     with self.assertRaises(LookupError):
         browser.getControl('Delete')  # 'Delete' button is missing
Пример #24
0
    def test_error_during_publish_is_written_to_objectlog(self):
        content = ICMSContent('http://xml.zeit.de/online/2007/01/Somalia')
        info = IPublishInfo(content)
        self.assertFalse(info.published)
        info.urgent = True

        publish = IPublish(content).publish()
        transaction.commit()

        with self.assertRaises(Exception) as err:
            publish.get()
        transaction.begin()

        self.assertEqual(self.error, str(err.exception))
        self.assertIn(self.error, [
            zope.i18n.interpolate(m, m.mapping)
            for m in get_object_log(content)
        ])
Пример #25
0
 def test_breaking_flag_is_removed_from_service_after_send(self):
     content = ExampleContentType()
     self.repository['foo'] = content
     push = zeit.push.interfaces.IPushMessages(content)
     push.message_config = ({
         'type': 'facebook',
         'enabled': True,
         'breaking_news': True,
         'override_text': 'facebook'
     }, )
     IPublishInfo(content).urgent = True
     IPublish(content).publish()
     self.assertEqual(({
         'type': 'facebook',
         'enabled': False,
         'breaking_news': False,
         'override_text': 'facebook'
     }, ), push.message_config)
Пример #26
0
    def test_publish_via_celery_end_to_end(self):
        content = ICMSContent('http://xml.zeit.de/online/2007/01/Somalia')
        info = IPublishInfo(content)
        self.assertFalse(info.published)
        info.urgent = True

        publish = IPublish(content).publish()
        transaction.commit()
        self.assertEqual('Published.', publish.get())
        transaction.begin()

        self.assertEllipsis(
            """\
Running job ...
Publishing http://xml.zeit.de/online/2007/01/Somalia
...
Done http://xml.zeit.de/online/2007/01/Somalia (...s)...""",
            self.log.getvalue())
        self.assertIn('Published', get_object_log(content))
Пример #27
0
 def send(self, text, link, **kw):
     article = ICMSContent(self.uniqueId)
     log.debug('Setting %s, %s as body of %s', text, link, self.uniqueId)
     self._ensure_unlocked(article)
     with checked_out(article) as co:
         IBreakingNewsBody(co).text = u'<a href="{link}">{text}</a>'.format(
             link=link, text=text)
         # XXX The checked_out helper is rather technical (it does not
         # simulate a complete user interaction), thus specifying
         # checked_out(semantic_change=True) doesn't help: Since the checked
         # out object is newly created and we don't (can't?) call
         # transaction.commit() here (and a temporary workingcopy does not
         # really participate in the ZODB machinery anyway), the _p_mtime of
         # the checked out object is not set, which means its modified date
         # is not updated -- which means LSC would be set to the last
         # modified date taken from the repository, which is not what we
         # want.
         ISemanticChange(co).last_semantic_change = datetime.now(pytz.UTC)
     IPublishInfo(article).urgent = True
     IPublish(article).publish()
Пример #28
0
 def test_multiple_created_articles_push_with_auhtor_template(self):
     from zeit.content.article.article import Article
     from zeit.cms.workflow.interfaces import IPublish, IPublishInfo
     content = Article()
     content.title = 'bar'
     zope.event.notify(ObjectCreatedEvent(content))
     self.repository['bar'] = content
     IPublishInfo(self.repository['bar']).urgent = True
     IPublishInfo(self.repository['foo']).urgent = True
     IPublish(content).publish_multiple(
         [self.repository['foo'], self.repository['bar']])
     calls = zope.component.getUtility(zeit.push.interfaces.IPushNotifier,
                                       name='urbanairship').calls
     self.assertEqual(calls[0][1], 'http://www.zeit.de/foo')
     self.assertEqual(calls[0][2].get('enabled'), True)
     self.assertEqual(calls[0][2].get('type'), 'mobile')
     self.assertEqual(calls[0][2].get('payload_template'), 'authors.json')
     self.assertEqual(calls[1][1], 'http://www.zeit.de/bar')
     self.assertEqual(calls[1][2].get('enabled'), True)
     self.assertEqual(calls[1][2].get('type'), 'mobile')
     self.assertEqual(calls[1][2].get('payload_template'), 'authors.json')
Пример #29
0
def _update_article(article):
    # Ensure the article is unlocked, so cycling it will actually do something.
    lockable = zope.app.locking.interfaces.ILockable(article, None)
    if not lockable:
        return
    if lockable.isLockedOut():
        lockable.breaklock()
    if lockable.ownLock():
        # If we wanted to do an automatic update, we would have to delete the
        # user's workingcopy, losing data, which is unacceptable. Instead, we
        # do nothing, thus the ILeadTime will be written to XML later on, when
        # the user checks in.
        return

    if IPublishInfo(article).published:
        IPublish(article).publish()
    else:
        # This should never actually happen, since a centerpage cannot be
        # published when it contains unpublished content, so this is more for
        # completeness' sake.
        with checked_out(article):
            pass
Пример #30
0
    def setUp(self):
        # We cannot retrieve the state of eager results, so fake them here, as
        # publishing itself is tested elsewhere.
        mocker = mock.patch('celery.result.AsyncResult.state',
                            new_callable=mock.PropertyMock,
                            return_value='SUCCESS')
        mocker.start()
        self.addCleanup(mocker.stop)
        super(RetractBannerTest, self).setUp()
        banner_config = zeit.content.rawxml.rawxml.RawXML()
        banner_config.xml = lxml.etree.fromstring(
            '<xml><article_id>'
            'http://xml.zeit.de/online/2007/01/Somalia'
            '</article_id></xml>')
        self.repository['banner'] = banner_config
        IPublish(self.repository['banner']).publish(background=False)

        # Make Somalia breaking news, so the retract section is shown.
        article = ICMSContent('http://xml.zeit.de/online/2007/01/Somalia')
        with zeit.cms.checkout.helper.checked_out(article) as co:
            zeit.content.article.interfaces.IBreakingNews(
                co).is_breaking = True

        transaction.commit()