Beispiel #1
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)
Beispiel #2
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()])
Beispiel #3
0
 def test_publishinfo_is_reset_for_copied_objects(self):
     content = self.repository['testcontent']
     IPublishInfo(content).published = True
     copier = zope.copypastemove.interfaces.IObjectCopier(content)
     new_name = copier.copyTo(self.repository)
     copied = self.repository[new_name]
     self.assertEqual(False, IPublishInfo(copied).published)
Beispiel #4
0
    def test_updates_configured_content_and_publishes(self):
        self.repository['topics'] = zeit.content.rawxml.rawxml.RawXML()
        text = zeit.content.text.text.Text()
        text.text = ''
        self.repository['redirects'] = text

        config = zope.app.appsetup.product.getProductConfiguration(
            'zeit.retresco')
        config['topiclist'] = 'http://xml.zeit.de/topics'
        config['topic-redirect-id'] = 'http://xml.zeit.de/redirects'

        with mock.patch(
                'zeit.retresco.connection.TMS.get_all_topicpages',
                new=lambda x: iter([{
                    'id': 'berlin',
                    'title': 'Berlin',
                    'topic_type': 'location',
                    'redirect': '/thema/hamburg'}])):
            zeit.retresco.connection._update_topiclist()

        topics = self.repository['topics']
        self.assertEqual(True, IPublishInfo(topics).published)
        redirects = self.repository['redirects']
        self.assertEqual(True, IPublishInfo(redirects).published)
        self.assertIn('hamburg', redirects.text)
Beispiel #5
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)
Beispiel #6
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)
 def test_start_job_retracts_urls(self):
     self.repository['foo'] = ExampleContentType()
     self.repository['bar'] = ExampleContentType()
     IPublishInfo(self.repository['bar']).published = True
     IPublishInfo(self.repository['foo']).published = True
     job = zeit.cms.retractlog.retractlog.Job()
     job.urls = ['http://xml.zeit.de/foo', 'http://xml.zeit.de/bar']
     job.start()
     self.assertFalse(IPublishInfo(self.repository['foo']).published)
     self.assertFalse(IPublishInfo(self.repository['bar']).published)
Beispiel #8
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)
Beispiel #9
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')
Beispiel #10
0
 def test_delete_button_is_not_displayed_for_folder_with_subfolder(self):
     folder = self.repository['online']
     subfolder = folder['2005']
     self.assertFalse(IPublishInfo(folder).published)
     self.assertFalse(IPublishInfo(subfolder).published)
     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
Beispiel #11
0
 def test_publish_button_publishes_volume_content(self):
     self.elastic.search.return_value = zeit.cms.interfaces.Result([{
         'url':
         '/testcontent'
     }])
     with mock.patch('zeit.workflow.publish.PublishTask'
                     '.call_publish_script') as script:
         self.publish_content()
         script.assert_called_with(
             ['work/testcontent', 'work/2015/01/ausgabe'])
     self.assertTrue(IPublishInfo(self.repository['testcontent']).published)
     self.assertTrue(
         IPublishInfo(self.repository['2015']['01']['ausgabe']).published)
Beispiel #12
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])
Beispiel #13
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
Beispiel #14
0
 def create_article_with_references(self):
     from zeit.content.article.edit.body import EditableBody
     from zeit.content.article.article import Article
     from zeit.content.article.interfaces import IArticle
     from zeit.content.portraitbox.portraitbox import Portraitbox
     from zeit.content.infobox.infobox import Infobox
     import zeit.cms.browser.form
     article = Article()
     zeit.cms.content.field.apply_default_values(article, IArticle)
     article.year = 2017
     article.title = u'title'
     article.ressort = u'Deutschland'
     portraitbox = Portraitbox()
     self.repository['portraitbox'] = portraitbox
     body = EditableBody(article, article.xml.body)
     portraitbox_reference = body.create_item('portraitbox', 1)
     portraitbox_reference._validate = mock.Mock()
     portraitbox_reference.references = portraitbox
     infobox = Infobox()
     self.repository['infobox'] = infobox
     infobox_reference = body.create_item('infobox', 2)
     infobox_reference._validate = mock.Mock()
     infobox_reference.references = infobox
     self.repository['image'] = zeit.cms.interfaces.ICMSContent(
         'http://xml.zeit.de/2006/DSC00109_2.JPG')
     image_reference = body.create_item('image', 3)
     image_reference.references = image_reference.references.create(
         self.repository['image'])
     image_reference._validate = mock.Mock()
     self.repository['article_with_ref'] = article
     IPublishInfo(article).urgent = True
     return self.repository['article_with_ref']
Beispiel #15
0
    def setup_dates_so_content_is_publishable(self):
        DAY1 = datetime(2010, 1, 1, tzinfo=pytz.UTC)
        DAY2 = datetime(2010, 2, 1, tzinfo=pytz.UTC)
        DAY3 = datetime(2010, 3, 1, tzinfo=pytz.UTC)

        # XXX it would be nicer to patch this just for the items in question,
        # but we lack the mechanics to easily substitute adapter instances
        sem = self.patches.add('zeit.cms.content.interfaces.ISemanticChange')
        sem().last_semantic_change = DAY1
        sem().has_semantic_change = False
        for item in self.related:
            info = IPublishInfo(item)
            info.published = True
            info.date_last_published = DAY2
        dc = self.patches.add('zope.dublincore.interfaces.IDCTimes')
        dc().modified = DAY3
Beispiel #16
0
    def test_publish_sends_push_messages(self):
        # This tests the integration with zeit.push, but not the actual push
        # methods themselves.
        self.create_breakingnews()
        self.fill_in_required_values()
        self.browser.getControl('Publish and push').click()
        self.browser.open('@@publish')
        article = ICMSContent('http://xml.zeit.de/online/2007/01/foo')
        self.assertEqual(True, IPublishInfo(article).published)
        for service in ['homepage', 'urbanairship', 'twitter', 'facebook']:
            notifier = zope.component.getUtility(
                zeit.push.interfaces.IPushNotifier, name=service)
            self.assertEqual(1, len(notifier.calls))
            self.assertEqual(article.title, notifier.calls[0][0])

        urbanairship = zope.component.getUtility(
            zeit.push.interfaces.IPushNotifier, name='urbanairship')
        self.assertEqual(
            'eilmeldung.json',
            urbanairship.calls[0][2]['message'].config['payload_template'])
        facebook = zope.component.getUtility(
            zeit.push.interfaces.IPushNotifier, name='facebook')
        self.assertEqual(
            zeit.push.facebook.facebookAccountSource(None).MAIN_ACCOUNT,
            facebook.calls[0][2]['account'])
Beispiel #17
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')
Beispiel #18
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)
Beispiel #19
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)
        ])
Beispiel #20
0
 def test_sets_first_paragraph_and_publishes(self):
     self.publisher.send('mytext', 'http://zeit.de/foo')
     zeit.workflow.testing.run_publish(
         zeit.cms.workflow.interfaces.PRIORITY_HIGH)
     article = self.repository['foo']
     self.assertEqual(True, IPublishInfo(article).published)
     self.assertEllipsis(
         '<p...><a href="http://zeit.de/foo">mytext</a></p>',
         lxml.etree.tostring(IEditableBody(article).values()[0].xml))
Beispiel #21
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))
Beispiel #22
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)
Beispiel #23
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
Beispiel #24
0
 def test_delete_button_is_displayed_for_folder_without_published_objects(
         self):
     folder = self.repository['testing']
     folder['foo'] = ExampleContentType()
     self.assertFalse(IPublishInfo(folder).published)
     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)
     browser.getControl('Delete')  # 'Delete' button exists
Beispiel #25
0
    def add(self, object, container=None):
        super(Add, self).add(object, container)
        zeit.content.article.interfaces.IBreakingNews(
            self._created_object).is_breaking = True
        # We need to check out the new article so that AfterCheckout events are
        # run (which e.g. set default values of ICommonMetadata fields), but
        # the user won't want to edit anything right now, so we check in
        # immediately (and redirect to a view that triggers publishing).
        self._created_object = ICheckinManager(self._created_object).checkin()
        self._checked_out = False

        IPublishInfo(self._created_object).urgent = True
Beispiel #26
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')
Beispiel #27
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)])
Beispiel #28
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))
Beispiel #29
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)
Beispiel #30
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)