def _update_topiclist(): config = zope.app.appsetup.product.getProductConfiguration('zeit.retresco') keywords = zeit.cms.interfaces.ICMSContent(config['topiclist'], None) if not zeit.content.rawxml.interfaces.IRawXML.providedBy(keywords): raise ValueError('%s is not a raw xml document' % config['topiclist']) redirects = zeit.cms.interfaces.ICMSContent(config['topic-redirect-id'], None) if not zeit.content.text.interfaces.IText.providedBy(redirects): raise ValueError('%s is not a text document' % config['topic-redirect-id']) log.info('Retrieving all topic pages from TMS') tms = zope.component.getUtility(zeit.retresco.interfaces.ITMS) topicpages = tms.get_all_topicpages() with checked_out(keywords) as co: co.xml = _build_topic_xml(topicpages) zeit.cms.workflow.interfaces.IPublish(keywords).publish(background=False) try: transaction.commit() except Exception: # We don't really care about the DAV cache, to be honest. Worst case we # won't see the matching zeit.objectlog entry for this publish. transaction.abort() log.warning('Error during commit', exc_info=True) # Refresh iterator topicpages = tms.get_all_topicpages() with checked_out(redirects) as co: co.text = _build_topic_redirects(topicpages) zeit.cms.workflow.interfaces.IPublish(redirects).publish(background=False)
def _update_topiclist(): config = zope.app.appsetup.product.getProductConfiguration('zeit.retresco') keywords = zeit.cms.interfaces.ICMSContent(config['topiclist'], None) if not zeit.content.rawxml.interfaces.IRawXML.providedBy(keywords): raise ValueError( '%s is not a raw xml document' % config['topiclist']) redirects = zeit.cms.interfaces.ICMSContent( config['topic-redirect-id'], None) if not zeit.content.text.interfaces.IText.providedBy(redirects): raise ValueError( '%s is not a text document' % config['topic-redirect-id']) log.info('Retrieving all topic pages from TMS') tms = zope.component.getUtility(zeit.retresco.interfaces.ITMS) topicpages = tms.get_all_topicpages() with checked_out(keywords) as co: co.xml = _build_topic_xml(topicpages) zeit.cms.workflow.interfaces.IPublish(keywords).publish(async=False) # Refresh iterator topicpages = tms.get_all_topicpages() with checked_out(redirects) as co: co.text = _build_topic_redirects(topicpages) zeit.cms.workflow.interfaces.IPublish(redirects).publish(async=False)
def test_articles_are_not_added_to_feed_when_teaser_was_added(self): cp = self.repository['cp'] cp = self.publish(cp) self.assertEqual( ['http://xml.zeit.de/test2', 'http://xml.zeit.de/testcontent'], [x.get('href') for x in cp.xml.feed.getchildren()]) # Create a teaser and insert it. self.repository['content'] = ( zeit.cms.testcontenttype.testcontenttype.TestContentType()) with checked_out(cp) as working: teaser = self.create_teaser(working) teaser.insert(0, self.repository['content']) xml_teaser = zope.component.getMultiAdapter( (teaser, 0), zeit.content.cp.interfaces.IXMLTeaser) xml_teaser.free_teaser = True cp = self.publish(cp) self.assertEqual( [xml_teaser.original_uniqueId, 'http://xml.zeit.de/test2', 'http://xml.zeit.de/testcontent'], [x.get('href') for x in cp.xml.feed.getchildren()]) # When the article is added to the CP the article will not be added to # the RSS feed because a teaser referencing the article is already in # the feed with checked_out(cp) as working: teaser = self.create_teaser(working) teaser.insert(0, self.repository['content']) cp = self.repository['cp'] cp = self.publish(cp) self.assertEqual( [xml_teaser.original_uniqueId, 'http://xml.zeit.de/test2', 'http://xml.zeit.de/testcontent'], [x.get('href') for x in cp.xml.feed.getchildren()])
def test_should_populate_video_group_from_playlist(self): created = datetime.datetime(2014, 9, 22, 8, 0, tzinfo=pytz.UTC) video1 = zeit.content.video.video.Video() video2 = zeit.content.video.video.Video() video1.title = 'Video 1' self.repository['video1'] = video1 video1 = self.repository['video1'] with checked_out(video1) as co: zope.dublincore.interfaces.IDCTimes(co).created = created video2.title = 'Video 2' self.repository['video2'] = video2 video2 = self.repository['video2'] with checked_out(video2) as co: zope.dublincore.interfaces.IDCTimes(co).created = created playlist = zeit.content.video.playlist.Playlist() playlist.videos = (video1, video2) self.repository['playlist'] = playlist with checked_out(self.category) as co: co.video_playlist = playlist.uniqueId self.category.last_created = created - datetime.timedelta(1) self.builder(()) body = self.newsletter['newsletter_body'] video_group = body.values()[self.VIDEO_GROUP_POSITION] self.assertEqual(2, len(video_group)) self.assertEqual('Video 1', video_group.values()[0].reference.title) self.assertEqual('Video 2', video_group.values()[1].reference.title)
def test_not_overridable_values_are_always_proxied_to_target(self): image = ICMSContent('http://xml.zeit.de/2006/DSC00109_2.JPG') with checked_out(image) as co: IImageMetadata(co).origin = 'originalorigin' content = self.repository['testcontent'] ref = content.images.create(image) content.images = (ref, ) self.assertEqual('originalorigin', ref.origin) ref.update_metadata() self.assertEqual('originalorigin', ref.origin) with checked_out(ref.target) as co: IImageMetadata(co).origin = 'updatedorigin' ref.update_metadata() self.assertEqual('updatedorigin', ref.origin)
def setUp(self): super(LSCDefaultTest, self).setUp() self.repository[ 'article'] = zeit.content.article.testing.create_article() with checked_out(self.repository['article']) as co: co.body.create_item('liveblog') self.assertFalse(ISemanticChange(co).has_semantic_change)
def test_match_product(self): hook = zeit.cms.checkout.webhook.Hook(None) hook.add_exclude('product', 'ZEI') self.assertFalse(hook.should_exclude(self.repository['testcontent'])) with checked_out(self.repository['testcontent']) as co: co.product = Product('ZEI') self.assertTrue(hook.should_exclude(self.repository['testcontent']))
def test_url_not_equal_uniqueId_does_not_match(self): with checked_out(self.repository['banner']) as co: co.xml = etree.fromstring('<xml><article_id>' 'http://xml.zeit.de/foo' '</article_id></xml>') self.assertFalse( IBreakingNews(self.repository['article']).banner_matches())
def test_converts_imagegroup(self): group = zeit.content.image.testing.create_image_group() with checked_out(group) as co: meta = zeit.content.image.interfaces.IImageMetadata(co) meta.title = u'mytitle' meta.caption = u'mycaption' data = zeit.retresco.interfaces.ITMSRepresentation(group)() self.assert_editing_fields(data) self.assertEqual({ 'body': '<body/>', 'date': '1970-01-01T00:00:00Z', 'doc_type': 'image-group', 'payload': { 'document': { 'last_modified_by': 'zope.user', 'title': 'mytitle', }, 'image': {'caption': 'mycaption'}, 'meta': {'type': 'image-group'}, 'body': { 'title': 'mytitle', 'text': 'mycaption', }, 'vivi': { 'cms_icon': ('/@@/zeit-content-image-interfaces' '-IImageGroup-zmi_icon.png'), 'cms_preview_url': '/repository/image-group/thumbnail', 'publish_status': 'not-published' } }, 'url': '/image-group/', 'title': 'mytitle', 'teaser': 'mycaption', }, data)
def test_commonmetadata_fields_xmlteaser_doesnt_have_should_delegate(self): from zeit.cms.checkout.helper import checked_out with checked_out(self.repository["testcontent"]) as co: co.title = "original" self.teaser.free_teaser = True self.assertEqual("original", self.teaser.title)
def test_converts_recipe_attributes(self): recipe = zeit.cms.interfaces.ICMSContent( 'http://xml.zeit.de/zeit-magazin/wochenmarkt/rezept') with checked_out(recipe): pass data = zeit.retresco.interfaces.ITMSRepresentation(recipe)() payload = { 'search': [ 'Die leckere Fleisch-Kombi:subheading', 'Grillwurst:ingredient', 'Hahn:ingredient', 'Hähnchen:ingredient', 'Hühnchen:ingredient', 'Pastagerichte:category', 'Tomate:ingredient', 'Tomaten-Grieß:recipe_title', 'Tomaten:ingredient', 'Vier Rezepte für eine Herdplatte:title', 'Wurst-Hähnchen:recipe_title', 'Wurst:ingredient', 'Wurstiges:category' ], 'subheadings': ['Die leckere Fleisch-Kombi'], 'titles': ['Tomaten-Grieß', 'Wurst-Hähnchen'], 'categories': ['pastagerichte', 'wurstiges'], 'complexities': ['ambitioniert', 'einfach'], 'servings': ['2', '6'], 'times': ['unter 30 Minuten', 'über 60 Minuten'], 'ingredients': [ 'brathaehnchen', 'bratwurst', 'chicken-nuggets', 'gries', 'gurke', 'tomate' ] } self.assertEqual(payload, data['payload']['recipe'])
def test_copies_tags_to_head(self): self.setup_tags('foo') with checked_out(self.repository['testcontent']): pass self.assertEllipsis( '...<tag...>foo</tag>...', lxml.etree.tostring(self.repository['testcontent'].xml.head))
def test_header_has_security_declaration(self): article = zeit.cms.interfaces.ICMSContent( 'http://xml.zeit.de/online/2007/01/Somalia') with checked_out(article, temporary=False) as co: co = zope.security.proxy.ProxyFactory(co) with self.assertNothingRaised(): co.header.clear()
def test_converts_image(self): image = zeit.cms.interfaces.ICMSContent( 'http://xml.zeit.de/2006/DSC00109_2.JPG') with checked_out(image): pass # trigger uuid creation data = zeit.retresco.interfaces.ITMSRepresentation(image)() self.assert_editing_fields(data) self.assertEqual({ 'body': '<body/>', 'date': '1970-01-01T00:00:00Z', 'doc_type': 'image', 'payload': { 'document': { 'author': [u'Jochen Stahnke'], 'banner': True, 'last_modified_by': 'zope.user', }, 'meta': {'type': 'image'}, 'body': { 'title': 'DSC00109_2.JPG', 'text': 'DSC00109_2.JPG', }, 'vivi': { 'cms_icon': ('/@@/zeit-content-image-interfaces' '-IImage-zmi_icon.png'), 'cms_preview_url': ('/repository/2006/' 'DSC00109_2.JPG/thumbnail'), 'publish_status': 'not-published' } }, 'url': '/2006/DSC00109_2.JPG', 'title': 'DSC00109_2.JPG', 'teaser': 'DSC00109_2.JPG', }, data)
def get_content(self): from zeit.cms.checkout.helper import checked_out import zeit.cms.interfaces content = zeit.cms.interfaces.ICMSContent( 'http://xml.zeit.de/testcontent') with checked_out(content) as co: yield co
def test_handles_non_ascii(self): with checked_out(self.repository['testcontent']) as co: co.ressort = u'Zeit für die Schule' b = self.browser b.open('http://localhost/++skin++vivi/repository/testcontent') b.getLink('DAV Properties').click() self.assertEllipsis('...Zeit für die Schule...', b.contents)
def assert_updated(self, referenced, factory_name): self.repository['refed'] = referenced # article = self.get_article() reference = self.get_factory(article, factory_name)() reference.references = self.repository['refed'] self.repository['article'] = article # import zeit.workflow.interfaces import datetime import pytz workflow = zeit.workflow.interfaces.ITimeBasedPublishing( self.repository['refed']) workflow.release_period = (None, datetime.datetime(2005, 1, 2, tzinfo=pytz.UTC)) # from zeit.cms.checkout.helper import checked_out with checked_out(self.repository['article']): pass self.assertEqual( u'2005-01-02T00:00:00+00:00', self.repository['article'].xml.body.division.getchildren()[0].get( 'expires'))
def test_metadata_of_reference_is_updated_on_checkin(self): self.repository['target'].teaserTitle = u'foo' content = self.repository['content'] with checked_out(content) as co: co.references = (co.references.create(self.repository['target']), ) self.assertEqual( u'foo', self.repository['content'].xml.body.references.reference.title) with checked_out(self.repository['target']) as co: co.teaserTitle = u'bar' with checked_out(self.repository['content']): pass self.assertEqual( u'bar', self.repository['content'].xml.body.references.reference.title)
def test_authorships_should_not_be_copied_on_copy(self): with checked_out(self.repository['testcontent']) as co: co.authorships = [co.authorships.create(self.repository['author'])] zope.copypastemove.interfaces.IObjectCopier( self.repository['testcontent']).copyTo(self.repository['online']) self.assertEqual( ('',), self.repository['online']['testcontent'].authors)
def test_number_of_feed_items_is_limited(self): cp = self.repository['cp'] self.publish(cp) cp = self.repository['cp'] def insert_teaser(working, i): teaser = self.create_teaser(working) name = 'test%s' % i self.repository[name] = ( zeit.cms.testcontenttype.testcontenttype.TestContentType()) content = self.repository[name] teaser.insert(0, content) with checked_out(cp) as working: for i in range(3, 6): insert_teaser(working, i) cp = self.repository['cp'] self.publish(cp) cp = self.repository['cp'] items = cp.xml.feed.getchildren() self.assertEqual(5, len(items)) # the oldest item ('testcontent') has been purged from the list expected = ['http://xml.zeit.de/test%s' % i for i in [5, 4, 3, 2]] + [ 'http://xml.zeit.de/testcontent'] self.assertEqual(expected, [x.get('href') for x in items])
def test_article_should_not_mangle_divisions_on_checkin(self): from zeit.cms.checkout.helper import checked_out article = self.get_article_with_paras() self.repository['article'] = article with checked_out(self.repository['article']): pass self.assertEqual( 1, len(self.repository['article'].xml.body.findall('division')))
def test_checkin_should_not_fail_with_no_tags_and_no_rankedTags_element( self): repository = zope.component.getUtility( zeit.cms.repository.interfaces.IRepository) repository['content'] = create_testcontent() with checked_out(repository['content']): # cycle pass
def test_skips_newsimport_images(self): group = zeit.content.image.testing.create_image_group() with checked_out(group): pass # trigger uuid creation self.repository['news'] = zeit.cms.repository.folder.Folder() self.repository['news']['group'] = group data = zeit.retresco.interfaces.ITMSRepresentation(group)() self.assertEqual(None, data)
def test_ssoid_is_updated_on_changing_email(self): with self.acs(self.author.email, id=12345): self.repository['author'] = self.author self.assertEqual(12345, self.author.ssoid) with self.acs(u'hans.mü[email protected]', id=67890): with checked_out(self.repository['author']) as co: co.email = u'hans.mü[email protected]' self.assertEqual(67890, self.repository['author'].ssoid)
def test_uses_target_id_for_renameable_content(self): with checked_out(self.repository['testcontent']) as co: rn = zeit.cms.repository.interfaces.IAutomaticallyRenameable(co) rn.renameable = True rn.rename_to = 'changed' ref = zope.app.keyreference.interfaces.IKeyReference(co) self.assertEqual( 'http://xml.zeit.de/changed', ref.referenced_object)
def test_does_not_break_if_lsp_is_none(self): content = self.repository['testcontent'] with checked_out(content, semantic_change=True, temporary=False): transaction.commit() zope.event.notify( zeit.cms.workflow.interfaces.BeforePublishEvent(content, None)) published = zeit.cms.workflow.interfaces.IPublishInfo(content) self.assertNotEqual(None, published.date_last_published_semantic)
def test_tms_returns_enriched_article_body(self): with checked_out(self.repository['testcontent']): pass # Trigger mock connector uuid creation self.layer['request_handler'].response_body = json.dumps({ 'body': '<body>lorem ipsum</body>'}) tms = zope.component.getUtility(zeit.retresco.interfaces.ITMS) result = tms.get_article_body(self.repository['testcontent']) self.assertEqual('<body>lorem ipsum</body>', result)
def test_bottom_advertisement_should_be_appended(self): with checked_out(self.repository['mynl']) as co: co.ad_bottom_title = u'Some ad' self.builder(()) body = self.newsletter['newsletter_body'] advertisement = body[self.BOTTOM_AD_POSITION] self.assertEqual('advertisement-bottom', advertisement.type) self.assertEqual(u'Some ad', advertisement.title)
def test_should_be_updated_on_checkin(self): self.repository['target'].teaserTitle = u'foo' content = self.repository['content'] with checked_out(content) as co: co.related = self.repository['target'] with checked_out(self.repository['target']) as co: co.teaserTitle = u'bar' with checked_out(self.repository['content']): pass body = self.repository['content'].xml['body'] # Since ExampleContentType (our reference target) implements # ICommonMetadata, its XMLReferenceUpdater will write 'title' (among # others) into the XML. self.assertEqual(u'bar', body['references']['reference']['title'])
def test_resolves_reference_from_source_config(self): self.repository['storystream'] = ExampleContentType() with checked_out(self.repository['testcontent']) as co: co.storystreams = (zeit.cms.content.sources.StorystreamSource()( None).find('test'),) self.assertEqual( self.repository['storystream'], self.repository['testcontent'].storystreams[0].references)
def test_not_renameable_and_no_new_name_should_not_rename(self): from zeit.cms.repository.interfaces import IAutomaticallyRenameable content = self.get_content() from zeit.cms.checkout.helper import checked_out with checked_out(content) as co: renameable = IAutomaticallyRenameable(co) renameable.renameable = False self.assertNotIn('new-name', content.__parent__.keys()) self.assertIn('testcontent', content.__parent__.keys())
def test_no_channels_copies_ressort_to_channel_on_change(self): with checked_out(self.repository['testcontent']) as co: co.ressort = u'Deutschland' zope.lifecycleevent.modified( co, zope.lifecycleevent.Attributes( zeit.cms.testcontenttype.interfaces.IExampleContentType, 'ressort')) self.assertEqual((('Deutschland', None), ), co.channels)
def test_should_not_break_if_playlist_id_resolves_to_something_else(self): with checked_out(self.category) as co: co.video_playlist = self.category.uniqueId self.builder(()) body = self.newsletter['newsletter_body'] self.assertNotEqual(0, len(body)) video_group = body.values()[self.VIDEO_GROUP_POSITION] self.assertEqual('Video', video_group.title) self.assertEqual(0, len(video_group))
def test_converts_rawxml(self): self.repository['embed'] = zeit.content.rawxml.rawxml.RawXML() with checked_out(self.repository['embed']) as co: co.title = 'mytitle' data = zeit.retresco.interfaces.ITMSRepresentation( self.repository['embed'])() self.assertEqual('rawxml', data['doc_type']) self.assertEqual('mytitle', data['title']) self.assertEqual({'title': 'embed'}, data['payload']['body'])
def test_thisweeks_advert_should_be_omitted_on_unchecked_weekday(self): weekday = datetime.date.today().weekday() with checked_out(self.repository['mynl']) as co: co.ad_thisweeks_title = u'Some ad' setattr(co, 'ad_thisweeks_on_%d' % weekday, False) self.builder(()) body = self.newsletter['newsletter_body'] self.assertFalse( any(ad.type == 'advertisement-thisweeks' for ad in body.values()))
def test_iimages_should_contain_referenced_objects_image(self): from zeit.content.image.interfaces import IImages from zeit.cms.checkout.helper import checked_out import zeit.content.image.testing self.teaser.free_teaser = True group = zeit.content.image.testing.create_image_group() with checked_out(self.repository["testcontent"]) as co: IImages(co).image = group self.assertEqual(group, IImages(self.teaser).image)
def test_no_tags_cause_rankedTags_element_to_be_removed_from_xml(self): content = create_testcontent() content.xml.head.rankedTags = 'bla bla bla' repository = zope.component.getUtility( zeit.cms.repository.interfaces.IRepository) repository['content'] = content with checked_out(repository['content']): # cycle pass self.assertNotIn('rankedTags', repository['content'].xml.head.keys())
def test_get_article_keywords_uses_published_content_endpoint_as_default( self): with checked_out(self.repository['testcontent']): pass # Trigger mock connector uuid creation tms = zope.component.getUtility(zeit.retresco.interfaces.ITMS) tms.get_article_keywords(self.repository['testcontent']) # First requests will be enrich and index self.assertTrue( '/in-text-linked-documents/' in self.layer['request_handler'].requests[2].get('path'))
def setUp(self): super(IntegrationTest, self).setUp() self.tms = zeit.retresco.connection.TMS( os.environ['ZEIT_RETRESCO_URL']) self.article = zeit.cms.interfaces.ICMSContent( 'http://xml.zeit.de/online/2007/01/Somalia') with checked_out(self.article): # Trigger mock connector uuid creation. # This also serves as test isolation, since we get a random uuid # on each run, with which we also clean up in TMS on tearDown. pass
def test_sets_end_on_article_when_no_longer_in_lead(self): self.publish(self.repository['cp']) with checked_out(self.repository['cp']) as cp: for entry in cp['lead'].values()[0]: cp['lead'].values()[0].remove(entry) self.publish(self.repository['cp']) leadtime = zeit.content.cp.interfaces.ILeadTime(self.repository['foo']) self.assertNotEqual(None, leadtime.end) self.assertEllipsis( '...<attribute...name="leadtime_end">...', lxml.etree.tostring(self.repository['foo'].xml, pretty_print=True))
def test_existing_tags_should_cause_rankedTags_to_be_added_to_xml(self): repository = zope.component.getUtility( zeit.cms.repository.interfaces.IRepository) repository['content'] = create_testcontent() with checked_out(repository['content']) as content: self.set_tags(content, """ <tag uuid="uid-karenduve">Karen Duve</tag> <tag uuid="uid-berlin">Berlin</tag> """) self.assertEqual( ['Karen Duve', 'Berlin'], repository['content'].xml.head.rankedTags.getchildren())
def test_rankedTags_in_xml_should_be_updated_on_modified_event(self): repository = zope.component.getUtility( zeit.cms.repository.interfaces.IRepository) repository['content'] = create_testcontent() with checked_out(repository['content']) as content: self.set_tags(content, """ <tag uuid="uid-karenduve">Karen Duve</tag> <tag uuid="uid-berlin">Berlin</tag> """) zope.lifecycleevent.modified(content) self.assertEqual( ['Karen Duve', 'Berlin'], content.xml.head.rankedTags.getchildren())
def test_empty_local_values_leave_original_ones_alone(self): image = ICMSContent('http://xml.zeit.de/2006/DSC00109_2.JPG') with checked_out(image) as co: IImageMetadata(co).title = 'originaltitle' IImageMetadata(co).caption = 'originalcaption' content = self.repository['testcontent'] ref = content.images.create(image) content.images = (ref,) self.assertEqual('originaltitle', ref.xml.get('title')) self.assertEqual('originalcaption', ref.xml.bu) ref.update_metadata() self.assertEqual('originaltitle', ref.xml.get('title')) self.assertEqual('originalcaption', ref.xml.bu)
def test_checkout_preserves_dav_properties_from_xml(self): # We need a DAV property that is handled by a separate adapter to see # the effect, since direct DAV properties are directly copied to XML, # so for those it makes no difference if e.g. VirtualProperties were # still used for checked-out IVirtualContent, which they should not be. self.assertEqual('seo-title', zeit.seo.interfaces.ISEO( self.folder['xanten']).html_title) with checked_out(self.folder['xanten']) as co: self.assertEqual( 'seo-title', zeit.seo.interfaces.ISEO(co).html_title) zeit.seo.interfaces.ISEO(co).html_title = 'changed' self.assertEqual('changed', zeit.seo.interfaces.ISEO( self.folder['xanten']).html_title)
def test_converts_infobox(self): self.repository['infobox'] = zeit.content.infobox.infobox.Infobox() with checked_out(self.repository['infobox']) as co: co.supertitle = 'mytitle' co.contents = (('foo!', '<p>bar!</p>'),) data = zeit.retresco.interfaces.ITMSRepresentation( self.repository['infobox'])() self.assertEqual('infobox', data['doc_type']) self.assertEqual('mytitle', data['title']) self.assertEqual({ 'supertitle': 'mytitle', 'title': 'foo!', 'text': '<p>bar!</p>\n', }, data['payload']['body'])
def test_converts_portraitbox(self): self.repository[ 'portraitbox'] = zeit.content.portraitbox.portraitbox.Portraitbox() with checked_out(self.repository['portraitbox']) as co: co.name = 'mytitle' co.text = '<p>my text</p>' data = zeit.retresco.interfaces.ITMSRepresentation( self.repository['portraitbox'])() self.assertEqual('portraitbox', data['doc_type']) self.assertEqual('mytitle', data['title']) self.assertEqual({ 'title': 'mytitle', 'text': '<p>my text</p>', }, data['payload']['body'])
def test_teasers_are_added_only_once(self): cp = self.repository['cp'] self.publish(cp) cp = self.repository['cp'] with checked_out(cp) as working: t3 = self.create_teaser(working) t3.insert(0, self.repository['testcontent']) cp = self.repository['cp'] self.publish(cp) cp = self.repository['cp'] items = cp.xml.feed.getchildren() self.assertEqual(2, len(items))
def test_disabled_tags_should_be_removed_from_xml(self): repository = zope.component.getUtility( zeit.cms.repository.interfaces.IRepository) repository['content'] = create_testcontent() with checked_out(repository['content']) as \ content: self.set_tags(content, """ <tag uuid="uid-karenduve">Karen Duve</tag> <tag uuid="uid-berlin">Berlin</tag> """) tagger = Tagger(content) del tagger[u'☃Berlin'] self.assertEqual( ['Karen Duve'], repository['content'].xml.head.rankedTags.getchildren())
def test_moving_referenced_article_updates_uniqueId_on_cp_checkin(self): cp = zeit.content.cp.centerpage.CenterPage() t1 = self.create_teaser(cp) self.create_teaser(cp) t1.insert(0, self.repository['testcontent']) zope.copypastemove.interfaces.IObjectMover( self.repository['testcontent']).moveTo( self.repository, 'changed') self.repository['cp'] = cp with checked_out(cp): pass cp = self.repository['cp'] self.assertIn( 'http://xml.zeit.de/changed', lxml.etree.tostring(cp.xml, pretty_print=True))
def test_converts_author(self): self.repository['willy'] = zeit.content.author.author.Author() with checked_out(self.repository['willy']) as co: co.firstname = u'William' co.lastname = u'Shakespeare' co.summary = u'To be...' co.biography = '...or not to be!' data = zeit.retresco.interfaces.ITMSRepresentation( self.repository['willy'])() self.assertEqual('author', data['doc_type']) self.assertEqual('William Shakespeare', data['title']) self.assertEqual({ 'supertitle': 'To be...', 'title': 'William Shakespeare', 'text': '...or not to be!', }, data['payload']['body'])
def test_get_article_keywords_order_is_given_by_cms_payload(self): with checked_out(self.repository['testcontent']): pass # Trigger mock connector uuid creation tagger = zeit.retresco.tagger.Tagger(self.repository['testcontent']) self.add_tag(tagger, 'New York', 'location', True) self.add_tag(tagger, 'Obama', 'person', True) self.add_tag(tagger, 'Merkel', 'person', True) self.add_tag(tagger, 'Clinton', 'person', False) dav_tagger = zeit.connector.interfaces.IWebDAVProperties(tagger) self.layer['request_handler'].response_body = json.dumps({ 'entity_links': [ # already linked: still shown {'key': 'Merkel', 'key_type': 'person', 'score': "10.0", 'status': 'linked', 'link': '/thema/merkel'}, # pinned: comes first {'key': 'Obama', 'key_type': 'person', 'score': "8.0", 'status': 'not_linked', 'link': '/thema/obama'}, # not pinned: after pinned ones, by score {'key': 'Clinton', 'key_type': 'person', 'score': "6.0", 'status': 'not_linked', 'link': '/thema/clinton'}, # not in CMS list: after pinned ones, by score {'key': 'Berlin', 'key_type': 'location', 'score': "5.0", 'status': 'not_linked', 'link': '/thema/berlin'}, # no link: ignored {'key': 'Washington', 'key_type': 'location', 'score': "3.0", 'status': 'not_linked', 'link': None}, # pinned: comes first {'key': 'New York', 'key_type': 'location', 'score': "1.0", 'status': 'not_linked', 'link': '/thema/newyork'}, ], 'doc_type': 'article', 'payload': { 'tagging': { name: value for (name, ns), value in dav_tagger.items() if ns == 'http://namespaces.zeit.de/CMS/tagging' } }, }) tms = zope.component.getUtility(zeit.retresco.interfaces.ITMS) result = tms.get_article_keywords(self.repository['testcontent']) self.assertEqual( ['New York', 'Obama', 'Merkel', 'Clinton', 'Berlin'], [x.label for x in result]) self.assertEqual('thema/newyork', result[0].link)
def test_publish_does_not_cycle_mismatched_cp(self): # Clear rules cache so we get the empty ruleset, so we can publish. gocept.cache.method.clear() zope.app.appsetup.product.getProductConfiguration( 'zeit.edit')['rules-url'] = 'file://%s' % ( pkg_resources.resource_filename( 'zeit.content.cp.tests.fixtures', 'empty_rules.py')) self.repository['cp'] = CenterPage() with checked_out(self.repository['cp']) as cp: zope.interface.noLongerProvides(cp, ICP2015) zope.interface.alsoProvides(cp, ICP2009) before_publish = zeit.cms.workflow.interfaces.IModified( self.repository['cp']).date_last_checkout IPublish(self.repository['cp']).publish() zeit.workflow.testing.run_publish() after_publish = zeit.cms.workflow.interfaces.IModified( self.repository['cp']).date_last_checkout self.assertEqual(before_publish, after_publish)
def test_moving_image_updates_uniqueId_in_referencing_obj(self): # This is basically the same test as zeit.cms.redirect.tests.test_move, # but for image references instead of related references. image = ICMSContent('http://xml.zeit.de/2006/DSC00109_2.JPG') with checked_out(self.repository['testcontent']) as co: zeit.content.image.interfaces.IImages(co).image = image zope.copypastemove.interfaces.IObjectMover(image).moveTo( self.repository, 'changed') gocept.async.tests.process() content = self.repository['testcontent'] with mock.patch('zeit.cms.redirect.interfaces.ILookup') as lookup: self.assertEqual( 'http://xml.zeit.de/changed', zeit.content.image.interfaces.IImages(content).image.uniqueId) self.assertFalse(lookup().find.called) self.assertIn( 'http://xml.zeit.de/changed', lxml.etree.tostring(content.xml, pretty_print=True))
def test_teasers_are_not_added_to_feed_when_article_was_added(self): cp = self.repository['cp'] cp = self.publish(cp) self.assertEqual( ['http://xml.zeit.de/test2', 'http://xml.zeit.de/testcontent'], [x.get('href') for x in cp.xml.feed.getchildren()]) # Create a teaser and insert it. with checked_out(cp) as working: teaser = self.create_teaser(working) teaser.insert(0, self.repository['test2']) xml_teaser = zope.component.getMultiAdapter( (teaser, 0), zeit.content.cp.interfaces.IXMLTeaser) xml_teaser.free_teaser = True cp = self.repository['cp'] cp = self.publish(cp) # The teaser was not added to the feed because the object it references # is already in the feed # self.assertEquals(2, len(cp.xml.feed.getchildren())) self.assertEqual( ['http://xml.zeit.de/test2', 'http://xml.zeit.de/testcontent'], [x.get('href') for x in cp.xml.feed.getchildren()])
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