class ConflictTests(TestCase): layer = LEGACY_COLLECTIVE_SOLR_FUNCTIONAL_TESTING def setUp(self): activateAndReindex(self.layer["portal"]) commit() self.browser = Browser(self.layer["app"]) self.browser.addHeader( "Authorization", "Basic %s:%s" % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)) def test_retry_on_conflict(self): """This tests transaction handling when indexing in Solr, or more specifically properly aborting a transaction. To do this we'll try to create some content and fake a `ConflictError` shortly before the transaction completes. The publisher will catch it and retry, but while doing so the object will get a different UID than the first time. Without being able to abort the transaction Solr would receive two sets of data and consequently return two results when searching for this particular piece of content later on. """ self.browser.open(self.layer["portal"].absolute_url()) self.browser.getLink("Page").click() self.browser.getControl("Title", index=0).value = "Foo" component.provideHandler(raise_on_first_add, (Interface, IObjectCreatedEvent)) self.browser.getControl("Save").click() self.assertEqual(len(UIDS), 2) self.assertEqual(len(solrSearchResults(SearchableText="Foo")), 1) sm = component.getSiteManager() sm.unregisterHandler(raise_on_first_add, (Interface, IObjectCreatedEvent))
def test_okay_browser(self): browser = Browser(self.app) app_url = self.app.absolute_url() portal_url = self.portal.absolute_url() # Try a couple of urls that should return the same. urls = ( app_url + '/@@ok', app_url + '/ok?hello=1', portal_url + '/@@ok', portal_url + '/ok?hello=1', ) for url in urls: browser.open(url) self.assertEqual(browser.contents, 'OK') get_header = browser.headers.get self.assertEqual(get_header('Expires'), 'Sat, 1 Jan 2000 00:00:00 GMT') self.assertEqual(get_header('Cache-Control'), 'max-age=0, must-revalidate, private') # Getting it with a browser gives some more headings than accessing # the view directly. self.assertEqual(get_header('content-length'), '2') # content-type has a charset, but we don't really care about that. self.assertTrue( get_header('content-type').startswith('text/plain'))
class LinkFunctionalTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format(SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_add_link(self): self.browser.open(self.portal_url) self.browser.getLink('Link').click() self.browser.getControl(name='form.widgets.IDublinCore.title')\ .value = 'My link' self.browser.getControl(name='form.widgets.IDublinCore.description')\ .value = 'This is my link.' self.browser.getControl(name='form.widgets.IShortName.id')\ .value = 'my-special-link' self.browser.getControl(name='form.widgets.remoteUrl.external')\ .value = 'https://plone.org' self.browser.getControl('Save').click() self.assertTrue(self.browser.url.endswith('my-special-link/view')) self.assertTrue('My link' in self.browser.contents) self.assertTrue('This is my link' in self.browser.contents)
class DocumentFunctionalTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_add_document(self): self.browser.open(self.portal_url) self.browser.getLink(url='http://nohost/plone/++add++Document').click() widget = 'form.widgets.IDublinCore.title' self.browser.getControl(name=widget).value = 'My document' widget = 'form.widgets.IDublinCore.description' self.browser.getControl(name=widget).value = 'This is my document.' widget = 'form.widgets.IRichTextBehavior.text' self.browser.getControl(name=widget).value = 'Lorem Ipsum' widget = 'form.widgets.IShortName.id' self.browser.getControl(name=widget).value = 'my-special-document' self.browser.getControl('Save').click() self.assertTrue(self.browser.url.endswith('my-special-document/view')) self.assertTrue('My document' in self.browser.contents) self.assertTrue('This is my document' in self.browser.contents) self.assertTrue('Lorem Ipsum' in self.browser.contents)
class AutoRotateTests(unittest.TestCase): layer = PROTECT_FUNCTIONAL_TESTING def setUp(self): self.portal = self.layer['portal'] self.browser = Browser(self.layer['app']) self.request = self.layer['request'] def test_keyrings_get_rotated_on_login(self): manager = getUtility(IKeyManager) ring = manager['_forms'] keys = ring.data ring.last_rotation = 0 transaction.commit() # should be rotated on login login(self.portal, TEST_USER_NAME) self.browser.open(self.portal.absolute_url() + '/login_form') self.browser.getControl(name='__ac_name').value = TEST_USER_NAME self.browser.getControl( name='__ac_password').value = TEST_USER_PASSWORD self.browser.getControl('Log in').click() self.assertNotEqual(keys, ring.data) self.assertNotEqual(ring.last_rotation, 0)
class TestPloneRootLoginURL(unittest.TestCase): layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.portal = self.layer['portal'] self.app = self.layer['app'] self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) ) def test_normal_redirect(self): url = '/@@plone-root-login?came_from=%s' % self.portal.absolute_url() self.browser.open(self.app.absolute_url() + url) self.assertNotEqual(self.browser.url, None) self.assertEqual(self.browser.url, self.portal.absolute_url()) def test_attacker_redirect(self): attackers = ( 'http://attacker.com', '\\attacker.com', ) for attacker in attackers: url = '@@plone-root-login?came_from=%s' % attacker with self.assertRaises(HostNotAllowed): self.browser.open(self.app.absolute_url() + url)
class TestCSRF(unittest.TestCase): layer = PROTECT_FUNCTIONAL_TESTING def setUp(self): self.portal = self.layer['portal'] self.browser = Browser(self.layer['app']) self.request = self.layer['request'] self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_change_password_on_root_does_not_throw_other_csrf_protection( self ): self.browser.open( '%s/acl_users/users/manage_users?user_id=%s&passwd=1' % ( self.layer['app'].absolute_url(), SITE_OWNER_NAME ) ) self.browser.getControl(name='password').value = SITE_OWNER_PASSWORD self.browser.getControl(name='confirm').value = SITE_OWNER_PASSWORD self.browser.getForm(action='manage_updateUserPassword').submit() self.assertEquals( self.browser.url, '%s/acl_users/users/manage_users?' 'manage_tabs_message=password+updated' % ( self.layer['app'].absolute_url() ) )
class SearchControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the search control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % ( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_search_control_panel_link(self): self.browser.open("%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Search').click() def test_search_control_panel_backlink(self): self.browser.open("%s/@@search-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_search_control_panel_sidebar(self): self.browser.open("%s/@@search-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel')) def test_search_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="search-controlpanel") self.assertTrue(view()) def test_enable_livesearch(self): self.browser.open("%s/@@search-controlpanel" % self.portal_url) self.browser.getControl('Enable LiveSearch').selected = True self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISearchSchema, prefix="plone") self.assertEqual(settings.enable_livesearch, True) def test_types_not_searched(self): self.browser.open("%s/@@search-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.types_not_searched:list').value = [ 'Discussion Item', 'News Item' ] self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISearchSchema, prefix="plone") self.assertFalse('Discussion Item' in settings.types_not_searched) self.assertFalse('News Item Item' in settings.types_not_searched)
class MarkupControlPanelFunctionalTest(unittest.TestCase): """Make sure changes in the markup control panel are properly stored in plone.app.registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % ( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_markup_control_panel_link(self): self.browser.open("%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Markup').click() def test_markup_control_panel_backlink(self): self.browser.open("%s/@@markup-controlpanel" % self.portal_url) self.assertTrue("Content" in self.browser.contents) def test_markup_control_panel_sidebar(self): self.browser.open("%s/@@markup-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel')) def test_markup_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="markup-controlpanel") self.assertTrue(view()) def test_default_type(self): self.browser.open("%s/@@markup-controlpanel" % self.portal_url) self.browser.getControl('Default format').value = ['text/plain'] self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMarkupSchema, prefix='plone') self.assertEqual(settings.default_type, 'text/plain') def test_allowed_types(self): self.browser.open("%s/@@markup-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.allowed_types:list').value = [ 'text/html', 'text/x-web-textile' ] self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMarkupSchema, prefix='plone') self.assertEqual(settings.allowed_types, ('text/html', 'text/x-web-textile'))
class TestRoot(unittest.TestCase, _BaseAutoTest): def setUp(self): self.portal = self.layer['portal'] self.browser = Browser(self.layer['app']) self.request = self.layer['request'] self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def open(self, path): self.browser.open(self.portal.aq_parent.absolute_url() + '/' + path)
class TableOfContentsBehaviorFunctionalTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() setRoles(self.portal, TEST_USER_ID, ['Contributor']) fti = DexterityFTI('tocdocument') self.portal.portal_types._setObject('tocdocument', fti) fti.klass = 'plone.dexterity.content.Item' fti.behaviors = ('plone.app.contenttypes.behaviors.tableofcontents.' 'ITableOfContents', ) self.fti = fti alsoProvides(self.portal.REQUEST, IPloneAppContenttypesLayer) alsoProvides(self.request, IPloneAppContenttypesLayer) from plone.app.contenttypes.behaviors.tableofcontents \ import ITableOfContents alsoProvides(self.request, ITableOfContents) self.portal.invokeFactory('tocdocument', id='tocdoc', title=u'Document with a table of contents') import transaction transaction.commit() # Set up browser self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_toc_in_edit_form(self): self.browser.open(self.portal_url + '/tocdoc/edit') self.assertTrue('Table of contents' in self.browser.contents) def test_toc_viewlet_shows_up(self): self.browser.open(self.portal_url + '/tocdoc/edit') toc_ctl = self.browser.getControl( name='form.widgets.ITableOfContents.table_of_contents:list') toc_ctl.value = [ u'selected', ] # Submit form self.browser.getControl('Save').click() self.assertTrue('<section id="document-toc"' in self.browser.contents)
def get_browser(self, logged_in=False, credentials={}): """Return a browser, potentially a logged in one. The default credentials are the admin ones """ commit() browser = Browser(self.app) if logged_in or credentials: username = credentials.get("username", self._default_credentials["username"]) password = credentials.get("password", self._default_credentials["password"]) browser.open("%s/@@login" % self.portal.absolute_url()) browser.getControl(name="__ac_name").value = username browser.getControl(name="__ac_password").value = password browser.getForm(id="loginForm").submit() return browser
class ProductsCMFPloneSetupTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) setRoles(self.portal, TEST_USER_ID, ['Manager']) def test_sitemap(self): self.portal.invokeFactory('Document', 'doc1', title="Document 1") self.portal.invokeFactory('Document', 'doc2', title="Document 2") self.portal.invokeFactory('Document', 'doc3', title="Document 3") transaction.commit() self.browser.open(self.portal_url + '/sitemap') output = lxml.html.fromstring(self.browser.contents) sitemap = output.xpath("//ul[@id='portal-sitemap']")[0].text_content() self.assertTrue('Document 1' in sitemap) self.assertTrue('Document 2' in sitemap) self.assertTrue('Document 3' in sitemap) def test_sitemap_nested(self): self.portal.invokeFactory('Folder', 'folder1', title='Folder 1') self.portal.invokeFactory('Document', 'doc1', title='Document 1') self.portal.invokeFactory('Folder', 'folder2', title='Folder 2') self.portal.folder1.invokeFactory( 'Document', 'doc12', title='Document 12') transaction.commit() self.browser.open(self.portal_url + '/sitemap') output = lxml.html.fromstring(self.browser.contents) sitemap = output.xpath("//ul[@id='portal-sitemap']")[0].text_content() self.assertTrue('Folder 1' in sitemap) self.assertTrue('Document 1' in sitemap) self.assertTrue('Folder 2' in sitemap) self.assertTrue('Document 12' in sitemap)
class NewsItemFunctionalTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_add_news_item(self): self.browser.open(self.portal_url) self.browser.getLink('News Item').click() self.browser.getControl(name='form.widgets.IDublinCore.title')\ .value = 'My news item' self.browser.getControl(name='form.widgets.IDublinCore.description')\ .value = 'This is my news item.' self.browser.getControl(name='form.widgets.IShortName.id')\ .value = '' self.browser.getControl(name='form.widgets.IRichTextBehavior.text')\ .value = 'Lorem Ipsum' self.browser.getControl('Save').click() self.assertTrue(self.browser.url.endswith('my-news-item/view')) self.assertTrue('My news item' in self.browser.contents) self.assertTrue('This is my news item' in self.browser.contents) self.assertTrue('Lorem Ipsum' in self.browser.contents) def test_add_news_item_with_shortname(self): self.browser.open(self.portal_url) self.browser.getLink('News Item').click() self.browser.getControl(name='form.widgets.IDublinCore.title')\ .value = 'My news item' self.browser.getControl(name='form.widgets.IShortName.id')\ .value = 'my-special-news' self.browser.getControl('Save').click() self.assertTrue(self.browser.url.endswith('my-special-news/view'))
def test_local_manager_in_sharing(self): transaction.commit() browser = Browser(self.layer["app"]) browser.addHeader( "Authorization", "Basic %s:%s" % ( TEST_USER_NAME, TEST_USER_PASSWORD, ), ) browser.open("{}/@@sharing".format(self.entity.absolute_url())) content = browser.contents self.assertIn("Can manage locally", content) browser.open("{}/@@sharing".format(self.contact.absolute_url())) content = browser.contents self.assertNotIn("Can manage locally", content)
class ControlpanelFunctionalTest(unittest.TestCase): layer = PAS_PLUGINS_Authomatic_PLONE_FUNCTIONAL_TESTING def setUp(self): app = self.layer["app"] self.portal = self.layer["portal"] self.request = self.layer["request"] self.portal_url = self.portal.absolute_url() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}", ) def test_empty_form(self): self.browser.open("%s/authomatic-controlpanel" % self.portal_url) self.assertTrue(" Settings" in self.browser.contents)
def test_custom_css_is_served_correctly_to_the_browser(self): """ Test all of custom colors css """ app = self.layer["app"] browser = Browser(app) browser.open(self._get_css_absolute_url()) old_custom_colors_css = browser.contents self.institution.header_color = "#ABABAB" self._fire_event(self.institution, "modified") import transaction transaction.commit( ) # Commit so that the test browser sees these changes browser.open(self._get_css_absolute_url()) new_custom_colors_css = browser.contents self.assertNotEqual(old_custom_colors_css, new_custom_colors_css) self.assertIn("--header-color: #ABABAB", new_custom_colors_css)
def test_sharing(self): contact = api.content.create( container=self.entity, type="imio.directory.Contact", title="contact", ) transaction.commit() browser = Browser(self.layer["app"]) browser.handleErrors = False browser.addHeader( "Authorization", "Basic %s:%s" % ( TEST_USER_NAME, TEST_USER_PASSWORD, ), ) browser.open("{}/@@sharing".format(contact.absolute_url())) checkbox = browser.getControl(name="entries.role_Reader:records") checkbox.value = True # be sure there is no traceback when sharing (subscriber related) browser.getControl(name="form.button.Save").click()
class EventFunctionalTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_add_event(self): self.browser.open(self.portal_url) self.browser.getLink('Event').click() self.browser.getControl( name='form.widgets.IDublinCore.title').value = 'My event' self.browser.getControl(name='form.widgets.IDublinCore.description' ).value = 'This is my event.' self.browser.getControl( name='form.widgets.IRichTextBehavior.text').value = 'Lorem Ipsum' self.browser.getControl( name='form.widgets.IEventBasic.start').value = '2013-01-01' self.browser.getControl( name='form.widgets.IEventBasic.end').value = '2013-01-12' self.browser.getControl( name='form.widgets.IShortName.id').value = 'my-special-event' self.browser.getControl('Save').click() self.assertTrue(self.browser.url.endswith('my-special-event/view')) self.assertIn('My event', self.browser.contents) self.assertIn('This is my event', self.browser.contents) self.assertIn('Lorem Ipsum', self.browser.contents) self.assertIn('2013-01-01', self.browser.contents) self.assertIn('2013-01-12', self.browser.contents)
class EasyFormRegistrationBehaviorFunctionalTest( RegistrationFormBase, unittest.TestCase ): """ basic use cases and tests for richtext behavior""" layer = COLLECTIVE_EASYFORMPLUGIN_REGISTRATION_FUNCTIONAL_TESTING _behaviors = ("easyformplugin.registration",) _portal_type = "TestEasyForm" def setUp(self): app = self.layer["app"] self.portal = self.layer["portal"] self.portal_url = self.portal.absolute_url() setRoles(self.portal, TEST_USER_ID, ["Manager"]) self._setupFTI() self.portal.invokeFactory(self._portal_type, "easyform1") setRoles(self.portal, TEST_USER_ID, ["Member"]) import transaction transaction.commit() # Set up browser self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( "Authorization", "Basic {0}:{1}".format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, ), ) def test_easyform_registration_in_edit_form(self): self.browser.open(self.portal_url + "/easyform1/edit") self.assertTrue("fieldset-registration" in self.browser.contents) def test_easyform_registration_behavior(self): IRegistrationForm.providedBy(self.portal.easyform1)
class FolderFunctionalTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_add_folder(self): self.browser.open(self.portal_url) self.browser.getLink(url='http://nohost/plone/++add++Folder').click() widget = 'form.widgets.IDublinCore.title' self.browser.getControl(name=widget).value = 'My folder' widget = 'form.widgets.IShortName.id' self.browser.getControl(name=widget).value = '' widget = 'form.widgets.IDublinCore.description' self.browser.getControl(name=widget).value = 'This is my folder.' self.browser.getControl('Save').click() self.assertTrue(self.browser.url.endswith('my-folder/view')) self.assertTrue('My folder' in self.browser.contents) self.assertTrue('This is my folder' in self.browser.contents) def test_add_folder_with_shortname(self): self.browser.open(self.portal_url) self.browser.getLink(url='http://nohost/plone/++add++Folder').click() widget = 'form.widgets.IDublinCore.title' self.browser.getControl(name=widget).value = 'My folder' widget = 'form.widgets.IShortName.id' self.browser.getControl(name=widget).value = 'my-special-folder' self.browser.getControl('Save').click() self.assertTrue(self.browser.url.endswith('my-special-folder/view'))
class TestCookieAuth(unittest.TestCase): layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.portal = self.layer['portal'] self.folder = self.portal['test-folder'] self.browser = Browser(self.layer['app']) self.auth_info = '%s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD) self.cookie = base64.encodestring(self.auth_info.encode('utf8'))[:-1] self.folder.manage_permission('View', ['Manager'], acquire=0) logout() def testAutoLoginPage(self): # Should send us to login_form self.browser.open(self.folder.absolute_url()) self.assertIn('200', self.browser.headers['status']) self.assertEqual( self.browser.url, 'http://nohost/plone/login?came_from=http%3A//nohost/plone/test-folder' # noqa: E501 ) def testInsufficientPrivileges(self): # Should send us to login_form self.browser.open(self.portal.absolute_url()) self.browser.cookies['__ac'] = self.cookie self.browser.open(self.folder.absolute_url()) self.assertIn('200', self.browser.headers['status']) self.assertEqual( self.browser.url, 'http://nohost/plone/login?came_from=http%3A//nohost/plone/test-folder' # noqa: E501 ) def testSetSessionCookie(self): # The __ac cookie should be set for the session only self.browser.open('http://nohost/plone/login') self.browser.getControl(name='__ac_name').value = TEST_USER_NAME self.browser.getControl( name='__ac_password').value = TEST_USER_PASSWORD self.browser.getControl('Log in').click() self.assertIn('200', self.browser.headers['status']) self.assertIn('__ac', self.browser.cookies) self.assertEqual( self.browser.cookies.getinfo('__ac')['path'], '/', ) self.assertIsNone(self.browser.cookies.getinfo('__ac')['expires'])
class RichTextBehaviorFunctionalTest(RichTextBase, unittest.TestCase): """ basic use cases and tests for richtext behavior""" layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING _behaviors = ( 'plone.app.contenttypes.behaviors.richtext.IRichTextBehavior', ) _portal_type = 'SomeDocument' def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.wf = getToolByName(self.portal, 'portal_workflow') self.portal.acl_users._doAddUser('user_std', 'secret', ['Member'], []) self.portal_url = self.portal.absolute_url() setRoles(self.portal, TEST_USER_ID, ['Manager']) self._setupFTI() self.portal.invokeFactory(self._portal_type, 'doc1') setRoles(self.portal, TEST_USER_ID, ['Member']) import transaction transaction.commit() # Set up browser self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_richtext_in_edit_form(self): self.browser.open(self.portal_url + '/doc1/edit') self.assertTrue('tinymce' in self.browser.contents) def test_richtext_behavior(self): IRichText.providedBy(self.portal.doc1)
class AutoCSRFProtectTests(unittest.TestCase, _BaseAutoTest): def setUp(self): self.portal = self.layer['portal'] self.browser = Browser(self.layer['app']) self.request = self.layer['request'] login(self.portal, TEST_USER_NAME) self.browser.open(self.portal.absolute_url() + '/login_form') self.browser.getControl(name='__ac_name').value = TEST_USER_NAME self.browser.getControl( name='__ac_password' ).value = TEST_USER_PASSWORD self.browser.getControl('Log in').click() def open(self, path): self.browser.open(self.portal.absolute_url() + '/' + path) def test_CSRF_header(self): self.request.environ['HTTP_X_CSRF_TOKEN'] = createToken() view = AuthenticatorView(None, self.request) self.assertEqual(view.verify(), True) def test_incorrect_CSRF_header(self): self.request.environ['HTTP_X_CSRF_TOKEN'] = 'foobar' view = AuthenticatorView(None, self.request) self.assertEqual(view.verify(), False) def test_only_add_auth_when_user_logged_in(self): logout() self.open('logout') self.open('test-unprotected') try: self.browser.getForm('one').getControl(name="_authenticator") self.assertEqual('anonymous should not be protected', '') except LookupError: pass
class AllowedFieldsControlPanelFuncionalTest(base.EasyFormTestCase): """Test that changes in the easyform control panel are actually stored in the registry. """ def setUpPloneSite(self): pass def setUp(self): self.app = self.layer["app"] self.portal = self.layer["portal"] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( "Authorization", "Basic " + SITE_OWNER_NAME + ":" + SITE_OWNER_PASSWORD) def test_easyform_control_panel_link(self): self.browser.open(self.portal_url + "/@@overview-controlpanel") self.browser.getLink("easyform").click() self.assertTrue("easyform Settings" in self.browser.contents) def test_easyform_control_panel_backlink(self): self.browser.open(self.portal_url + "/@@easyform-controlpanel") self.assertTrue("General" in self.browser.contents) def test_easyform_control_panel_sidebar(self): self.browser.open(self.portal_url + "/@@navigation-controlpanel") self.browser.getLink("Site Setup").click() self.assertEqual(self.browser.url, "http://nohost/plone/@@overview-controlpanel") def test_easyform_control_panel_checkbox(self): self.browser.open(self.portal_url + "/@@easyform-controlpanel") self.browser.getControl("Rich Text").selected = False self.browser.getControl("Save").click() registry = getUtility(IRegistry) self.assertNotIn( "plone.app.textfield.RichText", registry.records["easyform.allowedFields"].value, )
class ActionsDXTestCase(unittest.TestCase): layer = PLONE_APP_CONTENT_DX_FUNCTIONAL_TESTING def setUp(self): self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal.acl_users.userFolderAddUser('editor', 'secret', ['Editor'], []) # For z3c.forms request must provide IFormLayer alsoProvides(self.request, IFormLayer) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal.invokeFactory(type_name='Folder', id='f1', title='A Tést Folder') transaction.commit() self.browser = Browser(self.layer['app']) self.browser.handleErrors = False self.browser.addHeader('Authorization', 'Basic {}:{}'.format(TEST_USER_NAME, 'secret')) def tearDown(self): if 'f1' in self.portal.objectIds(): self.portal.manage_delObjects(ids='f1') transaction.commit() def test_delete_confirmation(self): folder = self.portal['f1'] form = getMultiAdapter((folder, self.request), name='delete_confirmation') form.update() cancel = form.buttons['Cancel'] form.handlers.getHandler(cancel)(form, form) self.assertFalse(form.is_locked) def test_delete_confirmation_if_locked(self): folder = self.portal['f1'] lockable = ILockable.providedBy(folder) form = getMultiAdapter((folder, self.request), name='delete_confirmation') form.update() self.assertFalse(form.is_locked) if lockable: lockable.lock() form = getMultiAdapter((folder, self.request), name='delete_confirmation') form.update() self.assertFalse(form.is_locked) # After switching the user it should not be possible to delete the # object. Of course this is only possible if our context provides # ILockable interface. if lockable: logout() login(self.portal, 'editor') form = getMultiAdapter((folder, self.request), name='delete_confirmation') form.update() self.assertTrue(form.is_locked) logout() login(self.portal, TEST_USER_NAME) ILockable(folder).unlock() def test_delete_confirmation_cancel(self): folder = self.portal['f1'] self.browser.open(folder.absolute_url() + '/delete_confirmation') self.browser.getControl(name='form.buttons.Cancel').click() context_state = getMultiAdapter((folder, self.request), name='plone_context_state') self.assertEqual(self.browser.url, context_state.view_url()) def prepare_for_acquisition_tests(self): """create content and an alternate authenticated browser session creates the following content structure: |-- f1 | |-- test |-- test """ # create a page at the root and one nested with the same id. p1 = self.portal.invokeFactory(type_name='Document', id='test', title='Test Page at Root') folder_1 = self.portal['f1'] p2 = folder_1.invokeFactory(type_name='Document', id='test', title='Test Page in Folder') contained_test_page = folder_1[p2] transaction.commit() # create an alternate browser also logged in with manager browser_2 = Browser(self.layer['app']) browser_2.handleErrors = False browser_2.addHeader('Authorization', 'Basic {}:{}'.format(TEST_USER_NAME, 'secret')) # return the id of the root page, the nested page itself, and the # alternate browser return p1, contained_test_page, browser_2 def test_delete_wrong_object_by_acquisition_with_action(self): """exposes delete-by-acquisition bug using the delete action see https://github.com/plone/Products.CMFPlone/issues/383 """ p1_id, page_2, browser_2 = self.prepare_for_acquisition_tests() # open two different browsers to the 'delete confirmation' view delete_url = page_2.absolute_url() + '/delete_confirmation' self.browser.open(delete_url) browser_2.open(delete_url) self.assertTrue(p1_id in self.portal) for browser in [self.browser, browser_2]: browser.getControl(name='form.buttons.Delete').click() # the nested folder should be gone, but the one at the root should # remain. self.assertFalse(page_2.id in self.portal['f1']) self.assertTrue(p1_id in self.portal) def test_rename_form(self): logout() folder = self.portal['f1'] # We need zope2.CopyOrMove permission to rename content self.browser.open(folder.absolute_url() + '/folder_rename') self.browser.getControl(name='form.widgets.new_id').value = 'f2' self.browser.getControl(name='form.widgets.new_title').value = 'F2' self.browser.getControl(name='form.buttons.Rename').click() self.assertEqual(folder.getId(), 'f2') self.assertEqual(folder.Title(), 'F2') self.assertEqual(self.browser.url, folder.absolute_url()) login(self.portal, TEST_USER_NAME) self.portal.manage_delObjects(ids='f2') transaction.commit() def test_rename_form_with_view_action(self): # can't be bothered to register blobs, instead we add documents to # typesUseViewActionInListings registry = self.portal.portal_registry registry['plone.types_use_view_action_in_listings'] = [ 'Image', 'File', 'Document' ] folder = self.portal['f1'] folder.invokeFactory('Document', 'document1') document1 = folder['document1'] transaction.commit() logout() # We need zope2.CopyOrMove permission to rename content self.browser.open(document1.absolute_url() + '/object_rename') self.browser.getControl(name='form.widgets.new_id').value = 'f2' self.browser.getControl(name='form.widgets.new_title').value = 'F2' self.browser.getControl(name='form.buttons.Rename').click() self.assertEqual(document1.getId(), 'f2') self.assertEqual(document1.Title(), 'F2') self.assertEqual(self.browser.url, document1.absolute_url() + '/view') login(self.portal, TEST_USER_NAME) self.portal.manage_delObjects(ids='f1') transaction.commit() def test_create_safe_id_on_renaming(self): logout() folder = self.portal['f1'] # We need zope2.CopyOrMove permission to rename content self.browser.open(folder.absolute_url() + '/folder_rename') self.browser.getControl(name='form.widgets.new_id').value = ' ? f4 4 ' self.browser.getControl(name='form.widgets.new_title').value = ' F2 ' self.browser.getControl(name='form.buttons.Rename').click() self.assertEqual(folder.getId(), 'f4-4') self.assertEqual(folder.Title(), 'F2') self.assertEqual(self.browser.url, folder.absolute_url()) login(self.portal, TEST_USER_NAME) self.portal.manage_delObjects(ids='f4-4') transaction.commit() def test_default_page_updated_on_rename(self): login(self.portal, TEST_USER_NAME) folder = self.portal['f1'] folder.invokeFactory(type_name='Document', id='d1', title='A Doc') doc = folder['d1'] folder.setDefaultPage('d1') transaction.commit() self.assertEqual(folder.getDefaultPage(), 'd1') # We need zope2.CopyOrMove permission to rename content self.browser.open(doc.absolute_url() + '/object_rename') self.browser.getControl(name='form.widgets.new_id').value = ' ?renamed' self.browser.getControl(name='form.widgets.new_title').value = 'Doc' self.browser.getControl(name='form.buttons.Rename').click() self.assertEqual(folder.getFolderContents()[0].id, 'renamed') self.assertEqual(folder.getDefaultPage(), 'renamed') def test_rename_form_cancel(self): folder = self.portal['f1'] _id = folder.getId() _title = folder.Title() self.browser.open(folder.absolute_url() + '/folder_rename') self.browser.getControl(name='form.buttons.Cancel').click() transaction.commit() self.assertEqual(self.browser.url, folder.absolute_url()) self.assertEqual(folder.getId(), _id) self.assertEqual(folder.Title(), _title) def test_rename_form_cancel_with_view_action(self): # can't be bothered to register blobs, instead we add documents to # typesUseViewActionInListings registry = self.portal.portal_registry registry['plone.types_use_view_action_in_listings'] = [ 'Image', 'File', 'Document' ] folder = self.portal['f1'] folder.invokeFactory('Document', 'document1') document1 = folder['document1'] transaction.commit() _id = document1.getId() _title = document1.Title() self.browser.open(document1.absolute_url() + '/object_rename') self.browser.getControl(name='form.buttons.Cancel').click() transaction.commit() self.assertEqual(self.browser.url, document1.absolute_url() + '/view') self.assertEqual(document1.getId(), _id) self.assertEqual(document1.Title(), _title) def _get_token(self, context): authenticator = getMultiAdapter((context, self.request), name='authenticator') return authenticator.token() def test_object_cut_view(self): folder = self.portal['f1'] # We need pass an authenticator token to prevent Unauthorized self.assertRaises(Unauthorized, self.browser.open, f'{folder.absolute_url():s}/object_cut') # We need to have Copy or Move permission to cut an object self.browser.open('{:s}/object_cut?_authenticator={:s}'.format( folder.absolute_url(), self._get_token(folder))) self.assertIn('__cp', self.browser.cookies) self.assertIn(f'{folder.Title():s} cut.', self.browser.contents) def test_object_cut_view_with_view_action(self): # can't be bothered to register blobs, instead we add documents to # typesUseViewActionInListings registry = self.portal.portal_registry registry['plone.types_use_view_action_in_listings'] = [ 'Image', 'File', 'Document' ] folder = self.portal['f1'] folder.invokeFactory('Document', 'document1') document1 = folder['document1'] transaction.commit() # We need pass an authenticator token to prevent Unauthorized self.assertRaises(Unauthorized, self.browser.open, f'{document1.absolute_url():s}/object_cut') # We need to have Copy or Move permission to cut an object self.browser.open('{:s}/object_cut?_authenticator={:s}'.format( document1.absolute_url(), self._get_token(document1))) self.assertIn('__cp', self.browser.cookies) self.assertIn(f'{document1.Title():s} cut.', self.browser.contents) self.assertEqual(document1.absolute_url() + '/view', self.browser.url) def test_object_copy_view(self): folder = self.portal['f1'] # We need pass an authenticator token to prevent Unauthorized self.assertRaises(Unauthorized, self.browser.open, f'{folder.absolute_url():s}/object_copy') self.browser.open('{:s}/object_copy?_authenticator={:s}'.format( folder.absolute_url(), self._get_token(folder))) self.assertIn('__cp', self.browser.cookies) self.assertIn(f'{folder.Title():s} copied.', self.browser.contents) def test_object_copy_with_view_action(self): # can't be bothered to register blobs, instead we add documents to # typesUseViewActionInListings registry = self.portal.portal_registry registry['plone.types_use_view_action_in_listings'] = [ 'Image', 'File', 'Document' ] folder = self.portal['f1'] folder.invokeFactory('Document', 'document1') document1 = folder['document1'] transaction.commit() # We need pass an authenticator token to prevent Unauthorized self.assertRaises(Unauthorized, self.browser.open, f'{document1.absolute_url():s}/object_copy') self.browser.open('{:s}/object_copy?_authenticator={:s}'.format( document1.absolute_url(), self._get_token(document1))) self.assertIn('__cp', self.browser.cookies) self.assertIn(f'{document1.Title():s} copied.', self.browser.contents) self.assertEqual(document1.absolute_url() + '/view', self.browser.url) def test_object_cut_and_paste(self): folder = self.portal['f1'] self.portal.invokeFactory(type_name='Document', id='d1', title='A Doc') doc = self.portal['d1'] transaction.commit() self.browser.open('{:s}/object_cut?_authenticator={:s}'.format( doc.absolute_url(), self._get_token(doc))) self.assertIn('__cp', self.browser.cookies) self.assertIn('d1', self.portal.objectIds()) self.assertIn('f1', self.portal.objectIds()) # We need pass an authenticator token to prevent Unauthorized self.assertRaises(Unauthorized, self.browser.open, f'{folder.absolute_url():s}/object_paste') self.browser.open('{:s}/object_paste?_authenticator={:s}'.format( folder.absolute_url(), self._get_token(doc))) self.assertIn('__cp', self.browser.cookies) transaction.commit() self.assertNotIn('d1', self.portal.objectIds()) self.assertIn('d1', folder.objectIds()) self.assertIn('Item(s) pasted.', self.browser.contents) def test_object_copy_and_paste(self): folder = self.portal['f1'] folder.invokeFactory(type_name='Document', id='d1', title='A Doc') doc = folder['d1'] transaction.commit() self.browser.open('{:s}/object_copy?_authenticator={:s}'.format( doc.absolute_url(), self._get_token(doc))) self.assertIn('__cp', self.browser.cookies) # We need pass an authenticator token to prevent Unauthorized self.assertRaises(Unauthorized, self.browser.open, f'{folder.absolute_url():s}/object_paste') self.browser.open('{:s}/object_paste?_authenticator={:s}'.format( folder.absolute_url(), self._get_token(folder))) transaction.commit() self.assertIn('f1', self.portal.objectIds()) self.assertIn('d1', folder.objectIds()) self.assertIn('copy_of_d1', folder.objectIds()) self.assertIn('Item(s) pasted.', self.browser.contents) def test_object_copy_and_paste_multiple_times(self): folder = self.portal['f1'] folder.invokeFactory(type_name='Document', id='d1', title='A Doc') doc = folder['d1'] transaction.commit() self.browser.open('{:s}/object_copy?_authenticator={:s}'.format( doc.absolute_url(), self._get_token(doc))) self.assertIn('__cp', self.browser.cookies) self.browser.open('{:s}/object_paste?_authenticator={:s}'.format( folder.absolute_url(), self._get_token(folder))) self.browser.open('{:s}/object_paste?_authenticator={:s}'.format( folder.absolute_url(), self._get_token(folder))) # Cookie should persist, because you can paste the item multiple times self.assertIn('__cp', self.browser.cookies) self.assertIn('f1', self.portal.objectIds()) self.assertIn('d1', folder.objectIds()) self.assertIn('copy_of_d1', folder.objectIds()) self.assertIn('copy2_of_d1', folder.objectIds()) self.assertIn('Item(s) pasted.', self.browser.contents)
class FolderViewFunctionalTest(unittest.TestCase): layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal_url = self.portal.absolute_url() self.portal.invokeFactory('Folder', id='folder', title='My Folder') self.folder = self.portal.folder self.folder_url = self.folder.absolute_url() self.folder.invokeFactory('Document', id='doc1', title='Document 1') import transaction transaction.commit() self.browser = Browser(app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_folder_view(self): self.browser.open(self.folder_url + '/view') self.assertIn('My Folder', self.browser.contents) self.assertIn('Document 1', self.browser.contents) def test_folder_summary_view(self): self.browser.open(self.folder_url + '/summary_view') self.assertIn('My Folder', self.browser.contents) self.assertIn('Document 1', self.browser.contents) def test_folder_full_view(self): self.browser.open(self.folder_url + '/full_view') self.assertIn('My Folder', self.browser.contents) self.assertIn('Document 1', self.browser.contents) def test_folder_tabular_view(self): self.browser.open(self.folder_url + '/tabular_view') self.assertIn('My Folder', self.browser.contents) self.assertIn('Document 1', self.browser.contents) def test_folder_album_view(self): self.folder.invokeFactory('Image', id='image1', title='Image 1') img1 = self.folder['image1'] img1.image = dummy_image() import transaction transaction.commit() self.browser.open(self.folder_url + '/album_view') self.assertIn('My Folder', self.browser.contents) self.assertIn('<img src="http://nohost/plone/folder/image1/@@images', self.browser.contents) def test_list_item_wout_title(self): """In content listings, if a content object has no title use it's id. """ self.folder.invokeFactory('Document', id='doc_wout_title') import transaction transaction.commit() # Document should be shown in listing view (and it's siblings) self.browser.open(self.folder_url + "/listing_view") self.assertIn('doc_wout_title', self.browser.contents) # And also in tabular view self.browser.open(self.folder_url + "/tabular_view") self.assertIn('doc_wout_title', self.browser.contents)
class LanguageControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the language control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % ( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def _inject_available_languages_field(self, value): """The in-and-out widget does not work without javascript, therefore we have to inject some values in order to make saving the form work. """ form = self.browser.getForm(id='LanguageControlPanel') name = 'form.widgets.available_languages:list' field = webtest.forms.Hidden(form._form, 'input', name, 0, value=value) form._form.field_order.append((name, field)) self.browser.getControl('Save').click() def test_language_control_panel_link(self): self.browser.open("%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Language').click() self.assertTrue("Language Settings" in self.browser.contents) def test_language_control_panel_backlink(self): self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_language_control_panel_sidebar(self): self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel')) def test_language_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="language-controlpanel") self.assertTrue(view()) def test_default_language(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.default_language, 'en') self.assertEqual( self.browser.getControl('Site language').value, ['en']) self.browser.getControl('Site language').value = ['de'] self._inject_available_languages_field('en') self._inject_available_languages_field('de') self.browser.getControl(name='form.buttons.save').click() self.assertEqual(settings.default_language, 'de') # def test_available_languages(self): # registry = getUtility(IRegistry) # settings = registry.forInterface(ILanguageSchema, prefix='plone') # self.browser.open( # "%s/@@language-controlpanel" % self.portal_url) # self.assertEqual(settings.available_languages, ['en']) # self.assertEqual( # self.browser.getControl( # name='form.widgets.available_languages.to' # ).options, # ['en'] # ) # control = self.browser.getForm(index=1) # self.in_out_select( # control, 'form.widgets.available_languages:list', 'Deutsch') # self.browser.getControl('Save').click() # self.assertEqual(settings.available_languages, ['en', 'de']) def test_use_combined_language_codes(self): """This checks swithing combined languages codes support off/on.""" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_combined_language_codes, True) self.assertEqual( self.browser.getControl( 'Show country-specific language variants').selected, True) self.browser.getControl( 'Show country-specific language variants').selected = False self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_combined_language_codes, False) def test_display_flags(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.display_flags, False) self.assertEqual( self.browser.getControl('Show language flags').selected, False) self.browser.getControl('Show language flags').selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.display_flags, True) def test_use_content_negotiation(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_content_negotiation, False) self.assertEqual( self.browser.getControl( 'Use the language of the content item').selected, False) self.browser.getControl( 'Use the language of the content item').selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_content_negotiation, True) def test_use_path_negotiation(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_path_negotiation, False) self.assertEqual( self.browser.getControl( 'Use language codes in URL path for manual override').selected, False) self.browser.getControl( 'Use language codes in URL path for manual override' ).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_path_negotiation, True) def test_use_cookie_negotiation(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_cookie_negotiation, False) self.assertEqual( self.browser.getControl('Use cookie for manual override').selected, False) self.browser.getControl( 'Use cookie for manual override').selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_cookie_negotiation, True) def test_authenticated_users_only(self): control_label = "Authenticated users only" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.authenticated_users_only, False) self.assertEqual( self.browser.getControl(control_label).selected, False) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.authenticated_users_only, True) def test_set_cookie_always(self): control_label = "Set the language cookie always" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.set_cookie_always, False) self.assertEqual( self.browser.getControl(control_label).selected, False) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.set_cookie_always, True) def test_use_subdomain_negotiation(self): control_label = "Use subdomain" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_subdomain_negotiation, False) self.assertEqual( self.browser.getControl(control_label).selected, False) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_subdomain_negotiation, True) def test_use_cctld_negotiation(self): control_label = "Use top-level domain" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_cctld_negotiation, False) self.assertEqual( self.browser.getControl(control_label).selected, False) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_cctld_negotiation, True) def test_use_request_negotiation(self): control_label = "Use browser language request negotiation" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open("%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_request_negotiation, False) self.assertEqual( self.browser.getControl(control_label).selected, False) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_request_negotiation, True)
class TypesControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the types control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.types_url = "%s/@@content-controlpanel" % self.portal_url self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_types_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Editing').click() def test_standard_type_select(self): self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Link'] self.browser.getForm(action=self.types_url).submit() self.assertIn('content-controlpanel', self.browser.url) def test_standard_type_cancel(self): self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Link'] self.browser.getControl('Cancel').click() self.assertIn('@@overview-controlpanel', self.browser.url) def test_standard_type_allow_commenting(self): self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Link'] self.browser.getForm(action=self.types_url).submit() self.browser.getControl('Allow comments').selected = True self.browser.getControl('Save').click() # Check if settings got saved correctly self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Link'] self.browser.getForm(action=self.types_url).submit() self.assertIn('Globally addable', self.browser.contents) self.assertIn('Allow comments', self.browser.contents) self.assertEqual( self.browser.getControl('Allow comments').selected, True ) self.assertIn('Visible in searches', self.browser.contents) self.assertIn( '<input id="redirect_links" type="checkbox" class="noborder"' ' name="redirect_links:boolean" checked="checked" />', self.browser.contents) self.assertIn( '<label for="redirect_links">Redirect immediately to link target', self.browser.contents ) def test_standard_types_redirect_links(self): self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Link'] self.browser.getForm(action=self.types_url).submit() self.browser.getControl( 'Redirect immediately to link target' ).selected = True self.browser.getControl('Save').click() # Check if settings got saved correctly self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Link'] self.browser.getForm(action=self.types_url).submit() self.assertTrue( 'Redirect immediately to link target' in self.browser.contents ) self.assertEqual( self.browser.getControl( 'Redirect immediately to link target').selected, True ) def test_set_no_default_workflow(self): # references http://dev.plone.org/plone/ticket/11901 self.browser.open(self.types_url) self.browser.getControl(name="new_workflow").value = ['[none]'] self.browser.getControl(name="form.button.Save").click() # Check that setting No workflow as default workflow doesn't break # break editing types self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Link'] self.browser.getForm(action=self.types_url).submit() self.assertIn('Globally addable', self.browser.contents) self.assertIn('Allow comments', self.browser.contents) self.assertIn('Visible in searches', self.browser.contents) def test_disable_versioning_removes_behavior(self): self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Document'] self.browser.getForm(action=self.types_url).submit() self.browser.getControl(name='versionpolicy').value = ['off'] self.browser.getForm(action=self.types_url).submit() portal_types = self.portal.portal_types doc_type = portal_types.Document self.assertTrue( 'plone.app.versioningbehavior.behaviors.IVersionable' not in doc_type.behaviors) # noqa def test_enable_versioning_behavior_on_document(self): self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['Document'] self.browser.getForm(action=self.types_url).submit() self.browser.getControl(name='versionpolicy').value = ['off'] self.browser.getForm(action=self.types_url).submit() portal_types = self.portal.portal_types doc_type = portal_types.Document self.assertTrue( 'plone.app.versioningbehavior.behaviors.IVersionable' not in doc_type.behaviors) # noqa self.browser.getControl(name='versionpolicy').value = ['manual'] self.browser.getForm(action=self.types_url).submit() self.assertTrue( 'plone.app.versioningbehavior.behaviors.IVersionable' in doc_type.behaviors) def test_enable_versioning_behavior_on_file(self): self.browser.open(self.types_url) self.browser.getControl(name='type_id').value = ['File'] self.browser.getForm(action=self.types_url).submit() self.browser.getControl(name='versionpolicy').value = ['off'] self.browser.getForm(action=self.types_url).submit() portal_types = self.portal.portal_types file_type = portal_types.File # File has no Versioning and no Locking on default, but needs it self.assertTrue( 'plone.app.versioningbehavior.behaviors.IVersionable' not in file_type.behaviors) # noqa self.assertTrue( 'plone.app.lockingbehavior.behaviors.ILocking' not in file_type.behaviors) # noqa self.browser.getControl(name='versionpolicy').value = ['manual'] self.browser.getForm(action=self.types_url).submit() self.assertTrue( 'plone.app.versioningbehavior.behaviors.IVersionable' in file_type.behaviors) self.assertTrue( 'plone.app.lockingbehavior.behaviors.ILocking' in file_type.behaviors)
class FilterControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the site control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() registry = getUtility(IRegistry) self.settings = registry.forInterface( IFilterSchema, prefix="plone") self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) self.safe_html = getattr( getToolByName(self.portal, 'portal_transforms'), 'safe_html', None) def test_filter_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Site').click() def test_filter_control_panel_backlink(self): self.browser.open( "%s/@@filter-controlpanel" % self.portal_url) self.assertTrue("Security" in self.browser.contents) def test_filter_control_panel_sidebar(self): self.browser.open( "%s/@@filter-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_filter_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="filter-controlpanel") self.assertTrue(view()) def test_disable_filtering(self): self.browser.open( "%s/@@filter-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.disable_filtering:list').value = "selected" self.browser.getControl('Save').click() # test that the transform is disabled self.assertEqual( self.settings.disable_filtering, 1) # anything passes nasty_html = '<script></script>' ds = datastream('dummy_name') self.assertEqual( nasty_html, str(self.safe_html.convert(nasty_html, ds)) ) def test_nasty_tags(self): self.browser.open( "%s/@@filter-controlpanel" % self.portal_url) self.assertEqual( self.browser.getControl(name='form.widgets.nasty_tags').value, 'style\nobject\nembed\napplet\nscript\nmeta') self.browser.getControl( name='form.widgets.nasty_tags').value = 'div\na' valid_tags = self.browser.getControl( name='form.widgets.valid_tags').value self.assertTrue(valid_tags.startswith('a\nabbr\nacronym\naddress')) valid_tags = valid_tags.replace('a\n', '') valid_tags = self.browser.getControl( name='form.widgets.valid_tags').value = valid_tags self.browser.getControl('Save').click() self.assertEqual(self.settings.nasty_tags, [u'div', u'a']) self.assertNotIn(u'a', self.settings.valid_tags) # test that <a> is filtered self.assertFalse(self.settings.disable_filtering) good_html = '<p><a href="http://example.com">harmless link</a></p>' ds = datastream('dummy_name') self.assertEqual( self.safe_html.convert(good_html, ds).getData(), '<p/>' )
class RedirectionControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the redirection control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', f'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}', ) def test_redirection_controlpanel_link(self): self.browser.open("%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('URL Management').click() def test_redirection_controlpanel_backlink(self): self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_redirection_controlpanel_sidebar(self): self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_redirection_controlpanel_view(self): view = getMultiAdapter( (self.portal, self.portal.REQUEST), name="redirection-controlpanel" ) self.assertTrue(view()) def test_redirection_controlpanel_add_redirect(self): storage = getUtility(IRedirectionStorage) redirection_path = '/alias-folder' target_path = '/test-folder' storage_path = '/plone/alias-folder' self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='redirection').value = redirection_path self.browser.getControl(name='target_path').value = target_path self.browser.getControl(name='form.button.Add').click() self.assertTrue( storage.has_path(storage_path), f'Redirection storage should have path "{storage_path}"', ) def test_redirection_controlpanel_remove_redirects(self): storage = getUtility(IRedirectionStorage) for i in range(31): storage[f'/plone/alias{i}'] = '/plone/test-folder' transaction.commit() self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) # A batch of 15 is shown, so some are missing. self.assertTrue('/plone/alias1' in self.browser.contents) self.assertTrue('/plone/alias10' in self.browser.contents) self.assertTrue('/plone/alias19' in self.browser.contents) self.assertTrue('/plone/alias2' in self.browser.contents) self.assertFalse('/plone/alias29' in self.browser.contents) # query aliases starting with /alias2 self.browser.getControl(name='q').value = '/alias2' self.browser.getControl(name='form.button.filter').click() self.assertFalse('/plone/alias1' in self.browser.contents) self.assertTrue('/plone/alias2' in self.browser.contents) self.assertTrue('/plone/alias29' in self.browser.contents) # The filter could return one value too much. # This tests that we have excludemax=True in the RedirectionSet. self.assertFalse('/plone/alias3' in self.browser.contents) self.assertFalse('/plone/alias30' in self.browser.contents) # Remove two. self.browser.getControl(name='redirects:tuple').value = [ '/plone/alias2', '/plone/alias20', ] self.browser.getControl(name='form.button.Remove').click() self.assertFalse('/plone/alias2' in storage) self.assertFalse('/plone/alias20' in storage) self.assertTrue('/plone/alias1' in storage) self.assertTrue('/plone/alias29' in storage) self.assertEqual(storage.get('/plone/alias29'), '/plone/test-folder') def test_redirection_controlpanel_remove_matching_redirects(self): storage = getUtility(IRedirectionStorage) for i in range(30): storage[f'/plone/alias{i}'] = '/plone/test-folder' transaction.commit() # Removing matching redirects can only happen when a filter is selected. self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='form.button.MatchRemove').click() self.assertTrue( 'No alternative urls selected for removal.' in self.browser.contents ) self.assertEqual(len(storage), 30) # query aliases starting with /alias2 self.browser.getControl(name='q').value = '/alias2' # The filter is immediately taken into account, # without first explicitly clicking filter. # self.browser.getControl(name='form.button.filter').click() self.browser.getControl(name='form.button.MatchRemove').click() self.assertEqual(len(storage), 19) self.assertFalse('/plone/alias2' in storage) self.assertFalse('/plone/alias20' in storage) self.assertFalse('/plone/alias29' in storage) self.assertTrue('/plone/alias1' in storage) self.assertTrue('/plone/alias12' in storage) def test_redirection_controlpanel_set(self): storage = getUtility(IRedirectionStorage) portal_path = self.layer['portal'].absolute_url_path() now = DateTime('2022-02-03') for i in range(1000): storage.add( '{:s}/foo/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), now=now, ) redirects = RedirectionSet() self.assertEqual(len(redirects), 1000) self.assertDictEqual( redirects[0], { 'datetime': DateTime('2022-02-03'), 'manual': False, 'path': '/foo/0', 'redirect': f'{portal_path:s}/foo/0', 'redirect-to': '/bar/0', }, ) self.assertDictEqual( redirects[999], { 'datetime': DateTime('2022-02-03'), 'manual': False, 'path': '/foo/999', 'redirect': f'{portal_path:s}/foo/999', 'redirect-to': '/bar/999', }, ) self.assertEqual(len(list(iter(redirects))), 1000) self.assertDictEqual( list(iter(redirects))[0], { 'datetime': DateTime('2022-02-03'), 'manual': False, 'path': '/foo/0', 'redirect': f'{portal_path:s}/foo/0', 'redirect-to': '/bar/0', }, ) def test_redirection_controlpanel_batching(self): storage = getUtility(IRedirectionStorage) portal_path = self.layer['portal'].absolute_url_path() for i in range(1000): storage.add( '{:s}/foo/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), ) view = getMultiAdapter( (self.layer['portal'], self.layer['request']), name='redirection-controlpanel', ) # Test that view/redirects returns batch self.assertIsInstance(view.redirects(), Batch) # Test that view/batching returns batching with anchor in urls batching = view.batching() self.assertIn('?b_start:int=990#manage-existing-aliases', batching) def test_redirection_controlpanel_redirect_alias_exists(self): path_alias = '/alias' path_target = '/test-folder' storage_alias = f'/plone{path_alias}' storage_target = f'/plone{path_target}' storage = getUtility(IRedirectionStorage) storage.add(storage_alias, storage_target) transaction.commit() self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='redirection').value = path_alias self.browser.getControl(name='target_path').value = path_target self.browser.getControl(name='form.button.Add').click() self.assertTrue( storage.get(storage_alias) == storage_target, f'{storage_target} not target of alternative url!', ) self.assertTrue( 'The provided alternative url already exists!' in self.browser.contents, 'Message "alternative url already exists" not in page!', ) def test_redirection_controlpanel_filtering(self): storage = getUtility(IRedirectionStorage) portal_path = self.layer['portal'].absolute_url_path() for i in range(1000): storage.add( '{:s}/foo1/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), ) for i in range(1000): storage.add( '{:s}/foo2/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), ) redirects = RedirectionSet() self.assertEqual(len(redirects), 2000) redirects = RedirectionSet(query='/foo') self.assertEqual(len(redirects), 2000) redirects = RedirectionSet(query='/foo1') self.assertEqual(len(redirects), 1000) redirects = RedirectionSet(query='/foo2') self.assertEqual(len(redirects), 1000) # this should return one and not two (we need excludemax=True) redirects = RedirectionSet(query='/foo1/777') self.assertEqual(len(redirects), 1) request = self.layer['request'].clone() request.form['q'] = '/foo' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.0)) request = self.layer['request'].clone() request.form['q'] = '/foo1' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(1000 / 15.0)) request = self.layer['request'].clone() request.form['q'] = '/foo2' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(1000 / 15.0)) request = self.layer['request'].clone() view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.0)) # Filtering without new request does not have effect because memoize request.form['q'] = '/foo2' self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.0)) def test_redirection_controlpanel_filter_manual(self): storage = getUtility(IRedirectionStorage) portal_path = self.layer['portal'].absolute_url_path() for i in range(100): storage.add( '{:s}/foo/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), manual=False, ) for i in range(100, 300): storage.add( '{:s}/foo/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), manual=True, ) redirects = RedirectionSet() self.assertEqual(len(redirects), 300) # Form has yes, no, or empty string, anything else is ignored # (so treated as empty string). redirects = RedirectionSet(manual='yes') self.assertEqual(len(redirects), 200) redirects = RedirectionSet(manual='no') self.assertEqual(len(redirects), 100) redirects = RedirectionSet(manual='') self.assertEqual(len(redirects), 300) redirects = RedirectionSet(manual='badvalue') self.assertEqual(len(redirects), 300) request = self.layer['request'].clone() request.form['manual'] = '' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(300 / 15.0)) request = self.layer['request'].clone() request.form['manual'] = 'yes' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(200 / 15.0)) request = self.layer['request'].clone() request.form['manual'] = 'no' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(100 / 15.0)) def test_redirection_controlpanel_filter_date(self): storage = getUtility(IRedirectionStorage) portal_path = self.layer['portal'].absolute_url_path() time0 = DateTime('2001-01-01') for i in range(400): storage.add( '{:s}/foo/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), now=time0 + i, ) redirects = RedirectionSet() self.assertEqual(len(redirects), 400) # created can be anything that can be parsed by DateTime. # Otherwise it is ignored. self.assertEqual(len(RedirectionSet(created='2019-01-01')), 400) self.assertEqual(len(RedirectionSet(created='1999-01-01')), 0) self.assertEqual(len(RedirectionSet(created='2001-01-01')), 0) self.assertEqual(len(RedirectionSet(created='2001-01-02')), 1) self.assertEqual(len(RedirectionSet(created='2001-02-01')), 31) self.assertEqual(len(RedirectionSet(created='2001-02-01 00:00:00')), 31) self.assertEqual(len(RedirectionSet(created='2001-02-01 00:00:01')), 32) self.assertEqual(len(RedirectionSet(created='badvalue')), 400) # DateTime('2002-01-01') results in a timezone GMT+0 self.assertEqual(len(RedirectionSet(created='2002-01-01')), 365) # DateTime('2002/01/01') results in a timezone GMT+1 for me, # or a different zone depending on where in the world you are. # So we need to be lenient in the tests. self.assertGreaterEqual(len(RedirectionSet(created='2002/01/01')), 364) self.assertLessEqual(len(RedirectionSet(created='2002/01/01')), 366) request = self.layer['request'].clone() request.form['datetime'] = '' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(400 / 15.0)) request = self.layer['request'].clone() request.form['datetime'] = '2001-01-27' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(27 / 15.0)) request = self.layer['request'].clone() request.form['datetime'] = '2002-01-01' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(365 / 15.0)) request = self.layer['request'].clone() request.form['datetime'] = '2019-01-01' view = getMultiAdapter( (self.layer['portal'], request), name='redirection-controlpanel' ) self.assertEqual(view.redirects().numpages, math.ceil(400 / 15.0)) def test_redirection_controlpanel_redirect_no_target(self): path_alias = '/alias' path_target = '/not-existing' self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='redirection').value = path_alias self.browser.getControl(name='target_path').value = path_target self.browser.getControl(name='form.button.Add').click() self.assertTrue( 'The provided target object does not exist.' in self.browser.contents, 'Message "target does not exist" not in page!', ) def test_redirection_controlpanel_missing_slash_target(self): path_alias = '/alias' path_target = 'Members' self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='redirection').value = path_alias self.browser.getControl(name='target_path').value = path_target self.browser.getControl(name='form.button.Add').click() self.assertTrue( 'Target path must start with a slash.' in self.browser.contents, 'Errormessage for missing slash on target path missing', ) def test_redirection_controlpanel_missing_slash_alias(self): path_alias = 'alias' path_target = '/Members' self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='redirection').value = path_alias self.browser.getControl(name='target_path').value = path_target self.browser.getControl(name='form.button.Add').click() self.assertTrue( 'Alternative url path must start with a slash.' in self.browser.contents, 'Errormessage for missing slash on alternative url missing', ) def test_manage_aliases_standard(self): storage = getUtility(IRedirectionStorage) folder = self.portal['test-folder'] self.browser.open("%s/@@manage-aliases" % folder.absolute_url()) self.browser.getControl(name='redirection').value = '/alias' self.browser.getControl(name='form.button.Add').click() self.assertTrue( 'Alternative url added.' in self.browser.contents, 'Message for added alternative url missing', ) self.assertTrue(storage.has_path('/plone/alias')) self.assertEqual(storage.get('/plone/alias'), '/plone/test-folder') def test_manage_aliases_remove(self): storage = getUtility(IRedirectionStorage) folder = self.portal['test-folder'] storage['/plone/alias1'] = '/plone/test-folder' storage['/plone/alias2'] = '/plone/test-folder' storage['/plone/alias3'] = '/plone/test-folder' transaction.commit() self.browser.open("%s/@@manage-aliases" % folder.absolute_url()) self.browser.getControl(name='redirects:tuple').value = [ '/plone/alias1', '/plone/alias2', ] self.browser.getControl(name='form.button.Remove').click() self.assertTrue( 'Alternative urls removed.' in self.browser.contents, 'Message for removed alternative url missing', ) self.assertFalse('/plone/alias1' in storage) self.assertFalse('/plone/alias2' in storage) self.assertTrue('/plone/alias3' in storage) self.assertEqual(storage.get('/plone/alias3'), '/plone/test-folder') def test_manage_aliases_navigation_root(self): from zope.interface import alsoProvides from plone.app.layout.navigation.interfaces import INavigationRoot storage = getUtility(IRedirectionStorage) folder = self.portal['test-folder'] alsoProvides(folder, INavigationRoot) transaction.commit() self.browser.open("%s/@@manage-aliases" % folder.absolute_url()) self.browser.getControl(name='redirection').value = '/alias' self.browser.getControl(name='form.button.Add').click() self.assertTrue( 'Alternative url added.' in self.browser.contents, 'Message for added alternative url missing', ) self.assertTrue(storage.has_path('/plone/test-folder/alias')) self.assertEqual( storage.get('/plone/test-folder/alias'), '/plone/test-folder' ) # Add the navigation root path explicitly. self.browser.getControl( name='redirection' ).value = '/test-folder/alias2' self.browser.getControl(name='form.button.Add').click() self.assertTrue( 'Alternative url added.' in self.browser.contents, 'Message for added alternative url missing', ) self.assertTrue(storage.has_path('/plone/test-folder/alias2')) self.assertEqual( storage.get('/plone/test-folder/alias2'), '/plone/test-folder' ) def test_absolutize_path(self): # absolutize_path is a helper function that returns a tuple # of absolute path and error message. from Products.CMFPlone.controlpanel.browser.redirects import ( absolutize_path as ap, ) # A path is required. self.assertEqual(ap(''), ('', 'You have to enter an alternative url.')) self.assertEqual( ap('', is_source=False), ('', 'You have to enter a target.') ) # relative paths are not accepted self.assertEqual( ap('foo'), ('foo', 'Alternative url path must start with a slash.') ) self.assertEqual( ap('foo', is_source=True), ('foo', 'Alternative url path must start with a slash.'), ) self.assertEqual( ap('foo', is_source=False), ('foo', 'Target path must start with a slash.'), ) # absolute paths are good self.assertEqual(ap('/foo'), ('/plone/foo', None)) self.assertEqual(ap('/foo', is_source=True), ('/plone/foo', None)) # for targets, an object must exist on the path self.assertEqual( ap('/foo', is_source=False), ('/plone/foo', 'The provided target object does not exist.'), ) self.assertEqual( ap('/test-folder', is_source=False), ('/plone/test-folder', None) ) self.assertEqual( ap('/test-folder/@@sharing', is_source=False), ('/test-folder/@@sharing', 'Target path must not be a view.'), ) # A source must not exist. self.assertEqual( ap('/test-folder'), ( '/plone/test-folder', 'Cannot use a working path as alternative url.', ), ) # More general: a source must not be traversable already. self.assertEqual( ap('/view'), ('/plone/view', 'Cannot use a working path as alternative url.'), ) self.assertEqual( ap('/@@overview-controlpanel'), ( '/@@overview-controlpanel', 'Alternative url path must not be a view.', ), ) # And a source must not exist via (implicit) acquisition. # We might *want* to allow this, but such a redirect would not have effect, # because acquisition happens earlier. # See https://github.com/collective/Products.RedirectionTool/issues/12 self.portal.invokeFactory('Document', 'doc') self.assertEqual( ap('/test-folder/doc'), ( '/plone/test-folder/doc', 'Cannot use a working path as alternative url.', ), ) # A source must not already exist in the redirect list. storage = getUtility(IRedirectionStorage) portal_path = self.portal.absolute_url_path() storage.add( f'{portal_path:s}/foo', f'{portal_path:s}/test-folder', ) self.assertEqual( ap('/foo', is_source=True), ('/plone/foo', 'The provided alternative url already exists!'), ) # For targets, we now accept external urls. # Note that this can only be done on the control panel, # so by default only by Site Administrators or Managers. self.assertEqual( ap('https://example.org', is_source=False), ('https://example.org', None), ) self.assertEqual( ap('http://example.org', is_source=False), ('http://example.org', None), ) self.assertEqual( ap( 'https://example.org/some/path?foo=bar&bar=foo', is_source=False, ), ('https://example.org/some/path?foo=bar&bar=foo', None), ) self.assertEqual( ap('http://', is_source=False), ('http://', 'Target path must start with a slash.'), ) # Using '//' to ignore http/https differences seems useless, # as we don't include content but only link to it. self.assertEqual( ap('//example.org', is_source=False), ( '/plone//example.org', 'The provided target object does not exist.', ), ) def test_upload_two_columns(self): self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) # Note: the targets must exist as actual content. data = [ (b'/old-home-page.asp', b'/test-folder'), (b'/people/JoeT', b'/Members'), ] csv = b'\n'.join([b','.join(d) for d in data]) self.browser.getControl(name='file').add_file( io.BytesIO(csv), 'text/plain', 'redirects.csv' ) self.browser.getControl(name='form.button.Upload').click() self.assertNotIn( 'Please pick a file to upload.', self.browser.contents ) self.assertNotIn( 'No alternative urls were added.', self.browser.contents ) self.assertNotIn('Please correct these errors', self.browser.contents) storage = getUtility(IRedirectionStorage) self.assertEqual(len(storage), 2) self.assertEqual( storage.get('/plone/old-home-page.asp'), '/plone/test-folder' ) self.assertEqual(storage.get('/plone/people/JoeT'), '/plone/Members') # Test the internals. redirect = storage._paths['/plone/old-home-page.asp'] self.assertEqual(redirect[0], '/plone/test-folder') self.assertIsInstance(redirect[1], DateTime) self.assertEqual(redirect[2], True) # manual def test_upload_four_columns(self): # Two columns are the minimum, # but we can handle a third column with a datetime, # a fourth column with manual True/False, # and more columns that we ignore. now = DateTime() self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) # Note: the targets must exist as actual content. data = [ # We can first have a header, which should be ignored. # Second one should have the same number of columns, # otherwise the delimiter detection can get it wrong. (b'old path', b'new path', b'datetime', b'manual'), # bad dates are silently ignored (b'/baddate', b'/test-folder', b'2006-13-62', b'yes'), # two columns: (b'/two', b'/test-folder'), # third column with date: (b'/three', b'/test-folder', b'2003-01-31'), # fourth column with manual: ( b'/four', b'/test-folder', b'2004/01/27 10:00:00 GMT-3', b'False', ), # fifth column is ignored: (b'/five', b'/test-folder', b'2005-01-31', b'True', b'ignored'), # manual can be '0' (or anything starting with f/F/n/N/0) (b'/zero', b'/test-folder', b'2000-01-31', b'0'), ] csv = b'\n'.join([b','.join(d) for d in data]) self.browser.getControl(name='file').add_file( io.BytesIO(csv), 'text/plain', 'redirects.csv' ) self.browser.getControl(name='form.button.Upload').click() self.assertNotIn( 'Please pick a file to upload.', self.browser.contents ) self.assertNotIn( 'No alternative urls were added.', self.browser.contents ) self.assertNotIn('Please correct these errors', self.browser.contents) # All five lines have been added. storage = getUtility(IRedirectionStorage) self.assertEqual(len(storage), 6) self.assertEqual(storage.get('/plone/two'), '/plone/test-folder') old_paths = [ '/plone/baddate', '/plone/five', '/plone/four', '/plone/three', '/plone/two', '/plone/zero', ] self.assertListEqual(sorted(list(storage)), old_paths) self.assertListEqual( sorted(list(storage.redirects('/plone/test-folder'))), old_paths ) # Test the internals. # two columns: # (b'/two', b'/test-folder'), redirect = storage._paths['/plone/two'] self.assertEqual(redirect[0], '/plone/test-folder') self.assertIsInstance(redirect[1], DateTime) self.assertGreater(redirect[1], now) self.assertEqual(redirect[2], True) # manual # third column with date: # (b'/three', b'/test-folder', b'2003-01-31'), redirect = storage._paths['/plone/three'] self.assertEqual(redirect[0], '/plone/test-folder') self.assertEqual(redirect[1], DateTime('2003-01-31')) self.assertEqual(redirect[2], True) # fourth column with manual: # (b'/four', b'/test-folder', b'2004/01/27 10:00:00 GMT-3', b'False'), redirect = storage._paths['/plone/four'] self.assertEqual(redirect[0], '/plone/test-folder') self.assertEqual(redirect[1], DateTime('2004/01/27 10:00:00 GMT-3')) self.assertEqual(redirect[2], False) # fifth column is ignored: # (b'/five', b'/test-folder', b'2005-01-31', b'True', b'ignored'), redirect = storage._paths['/plone/five'] self.assertEqual(redirect[0], '/plone/test-folder') self.assertEqual(redirect[1], DateTime('2005-01-31')) self.assertEqual(redirect[2], True) # manual can be '0' (or anything starting with f/F/n/N/0) # (b'/zero', b'/test-folder', b'2000-01-31', b'0'), redirect = storage._paths['/plone/zero'] self.assertEqual(redirect[0], '/plone/test-folder') self.assertEqual(redirect[1], DateTime('2000-01-31')) self.assertEqual(redirect[2], False) # bad dates are silently ignored # (b'/baddate', b'/test-folder', b'2006-13-62', b'yes'), redirect = storage._paths['/plone/baddate'] self.assertEqual(redirect[0], '/plone/test-folder') self.assertGreater(redirect[1], now) self.assertEqual(redirect[2], True) def test_upload_bad(self): self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) # The targets must exist as actual content. # We try a good one and one that does not exist. data = [ (b'/old-home-page.asp', b'/test-folder'), (b'/people/JoeT', b'/no-such-content'), ] csv = b'\n'.join([b','.join(d) for d in data]) self.browser.getControl(name='file').add_file( io.BytesIO(csv), 'text/plain', 'redirects.csv' ) self.browser.getControl(name='form.button.Upload').click() self.assertNotIn( 'Please pick a file to upload.', self.browser.contents ) self.assertIn('No alternative urls were added.', self.browser.contents) self.assertIn('Please correct these errors', self.browser.contents) storage = getUtility(IRedirectionStorage) self.assertEqual(len(storage), 0) def test_download_empty(self): self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='form.button.Download').click() self.assertEqual( self.browser.headers['Content-Disposition'], 'attachment; filename=redirects.csv', ) contents = self.browser.contents.splitlines() self.assertEqual(len(contents), 1) self.assertEqual(contents[0], 'old path,new path,datetime,manual') def test_download_bigger(self): storage = getUtility(IRedirectionStorage) portal_path = self.layer['portal'].absolute_url_path() now = DateTime('2019/01/27 10:00:00 GMT-3') for i in range(2000): storage.add( '{:s}/foo/{:s}'.format(portal_path, str(i)), '{:s}/bar/{:s}'.format(portal_path, str(i)), now=now, manual=True, ) transaction.commit() self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='form.button.Download').click() self.assertEqual( self.browser.headers['Content-Disposition'], 'attachment; filename=redirects.csv', ) contents = self.browser.contents.splitlines() # pop the header self.assertEqual(contents.pop(0), 'old path,new path,datetime,manual') self.assertEqual(len(contents), 2000) # The order is probably the alphabetical order of the old path, # but that is not important and may change, # so let's sort it in the tests for good measure. # Note that '999' sorts alphabetically after '1999'. contents.sort() self.assertEqual( contents[0], '/foo/0,/bar/0,2019/01/27 10:00:00 GMT-3,True' ) self.assertEqual( contents[1999], '/foo/999,/bar/999,2019/01/27 10:00:00 GMT-3,True' ) def test_download_upload(self): # Test uploading a download and downloading an upload. # 1. Manually add some redirects. storage = getUtility(IRedirectionStorage) portal_path = self.layer['portal'].absolute_url_path() now = DateTime('2019/01/27 10:00:00 GMT-3') for i in range(10): storage.add( '{:s}/foo/{:s}'.format(portal_path, str(i)), f'{portal_path:s}/test-folder', now=now, manual=True, ) transaction.commit() # 2. Download the redirects. self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='form.button.Download').click() self.assertEqual( self.browser.headers['Content-Disposition'], 'attachment; filename=redirects.csv', ) downloaded_contents = self.browser.contents contents = downloaded_contents.splitlines() self.assertEqual(contents.pop(0), 'old path,new path,datetime,manual') self.assertEqual(len(contents), 10) contents.sort() self.assertEqual( contents[0], '/foo/0,/test-folder,2019/01/27 10:00:00 GMT-3,True' ) # 3. clear the redirect storage storage.clear() transaction.commit() self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='form.button.Download').click() contents = self.browser.contents.splitlines() self.assertEqual(len(contents), 1) self.assertEqual(contents[0], 'old path,new path,datetime,manual') # 4. upload the original download self.browser.open("%s/@@redirection-controlpanel" % self.portal_url) self.browser.getControl(name='file').add_file( io.BytesIO(safe_bytes(downloaded_contents)), 'text/plain', 'redirects.csv', ) self.browser.getControl(name='form.button.Upload').click() self.assertNotIn( 'Please pick a file to upload.', self.browser.contents ) self.assertNotIn( 'The provided target object does not exist.', self.browser.contents ) self.assertNotIn( 'No alternative urls were added.', self.browser.contents ) self.assertNotIn('Please correct these errors', self.browser.contents) self.assertEqual(len(storage), 10) # 5. download the upload self.browser.getControl(name='form.button.Download').click() new_downloaded_contents = self.browser.contents contents = downloaded_contents.splitlines() self.assertEqual(contents.pop(0), 'old path,new path,datetime,manual') self.assertEqual(len(contents), 10) contents.sort() self.assertEqual( contents[0], '/foo/0,/test-folder,2019/01/27 10:00:00 GMT-3,True' ) # and it is actually the same as the original download self.assertEqual(new_downloaded_contents, downloaded_contents)
class SiteControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the site control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % ( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_site_control_panel_link(self): self.browser.open("%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Site').click() def test_site_control_panel_backlink(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_site_control_panel_sidebar(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel')) def test_site_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="site-controlpanel") self.assertTrue(view()) def test_site_title_is_stored_in_registry(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"My Site" self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISiteSchema, prefix="plone") self.assertEqual(settings.site_title, u"My Site") def test_site_title_can_be_looked_up_by_plone_portal_state(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"My Site" self.browser.getControl('Save').click() portal_state = getMultiAdapter((self.portal, self.request), name=u'plone_portal_state') self.assertEqual(portal_state.portal_title(), u'My Site') @unittest.skip("XXX: TODO! We have to patch CMFDefault for this.") def test_site_title_can_be_looked_up_by_portal_title(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"My Site" self.browser.getControl('Save').click() self.assertEqual(self.portal.title, u'My Site') self.assertEqual(self.portal.Title(), u'My Site') def test_site_logo_is_stored_in_registry(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) ctrl = self.browser.getControl(name="form.widgets.site_logo") ctrl.add_file(BytesIO(SITE_LOGO_HEX), 'image/png', 'pixel.png') self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISiteSchema, prefix='plone') self.assertEqual(settings.site_logo, SITE_LOGO_BASE64) def test_exposeDCMetaTags(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"Plone Site" self.browser.getControl('Expose Dublin Core metadata').selected = True self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISiteSchema, prefix="plone") self.assertEqual(settings.exposeDCMetaTags, True) def test_exposeDCMetaTags_exposes_meta_tags(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"Plone Site" self.browser.getControl('Expose Dublin Core metadata').selected = True self.browser.getControl('Save').click() self.browser.open(self.portal_url) self.assertTrue('DC.type' in self.browser.contents) def test_enable_sitemap(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"Plone Site" self.browser.getControl('Expose sitemap.xml.gz').selected = True self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISiteSchema, prefix="plone") self.assertEqual(settings.enable_sitemap, True) def test_enable_sitemap_enables_the_sitemap(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"Plone Site" self.browser.getControl('Expose sitemap.xml.gz').selected = True self.browser.getControl('Save').click() self.browser.open("%s/sitemap.xml.gz" % self.portal_url) self.assertEqual(self.browser.headers['status'].lower(), '200 ok') self.assertEqual(self.browser.headers['content-type'], 'application/octet-stream') def test_webstats_js(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"Plone Site" self.browser.getControl(name='form.widgets.webstats_js').value = \ u"<script>a=1</script>" self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISiteSchema, prefix="plone") self.assertEqual(settings.webstats_js, u"<script>a=1</script>") def test_webstat_js_shows_up_on_site(self): self.browser.open("%s/@@site-controlpanel" % self.portal_url) self.browser.getControl('Site title').value = u"Plone Site" self.browser.getControl(name='form.widgets.webstats_js').value = \ u"<script>a=1</script>" self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISiteSchema, prefix="plone") self.assertEqual(settings.webstats_js, u"<script>a=1</script>") self.browser.open(self.portal_url) self.assertTrue("<script>a=1</script>" in self.browser.contents)
class ImagePublisherTests(unittest.TestCase): layer = PLONE_NAMEDFILE_FUNCTIONAL_TESTING def setUp(self): if six.PY2: raise unittest.SkipTest('Disabled in py2 for now.') data = getFile('image.png') item = DummyContent() item.image = NamedImage(data, 'image/png', u'image.png') self.layer['app']._setOb('item', item) self.item = self.layer['app'].item self.view = self.item.unrestrictedTraverse('@@images') self._orig_sizes = ImageScaling._sizes self.browser = Browser(self.layer['app']) self.browser.handleErrors = False self.browser.addHeader('Referer', self.layer['app'].absolute_url()) def tearDown(self): ImageScaling._sizes = self._orig_sizes def testPublishScaleViaUID(self): scale = self.view.scale('image', width=64, height=64) transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url) self.assertEqual('image/png', self.browser.headers['content-type']) assertImage(self, self.browser.contents, 'PNG', (64, 64)) def testPublishWebDavScaleViaUID(self): scale = self.view.scale('image', width=64, height=64) transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url + '/manage_DAVget') self.assertEqual('image/png', self.browser.headers['content-type']) assertImage(self, self.browser.contents, 'PNG', (64, 64)) def testPublishFTPScaleViaUID(self): scale = self.view.scale('image', width=64, height=64) transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url + '/manage_FTPget') self.assertIn('200', self.browser.headers['status']) # Same remark as in testPublishWebDavScaleViaUID is valid here. self.assertEqual('image/png', self.browser.headers['content-type']) assertImage(self, self.browser.contents, 'PNG', (64, 64)) def testHeadRequestMethod(self): scale = self.view.scale('image', width=64, height=64) transaction.commit() # make sure the referenced image scale is available url = str(scale.url) self.browser.open(url) GET_length = len(self.browser.contents) self.browser = Browser(self.layer['app']) self.browser.handleErrors = False self.browser.addHeader('Referer', self.layer['app'].absolute_url()) def make_head_request(args): return self.browser.testapp.head(url, **args) self.browser._processRequest(url, make_head_request) self.assertEqual('image/png', self.browser.headers['content-type']) self.assertEqual( self.browser.headers['Content-Length'], str(GET_length) ) self.assertEqual(self.browser.contents, b'') def testPublishThumbViaUID(self): ImageScaling._sizes = {'thumb': (128, 128)} scale = self.view.scale('image', 'thumb') transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url) self.assertEqual('image/png', self.browser.headers['content-type']) assertImage(self, self.browser.contents, 'PNG', (128, 128)) def testPublishCustomSizeViaUID(self): # set custom image sizes ImageScaling._sizes = {'foo': (23, 23)} scale = self.view.scale('image', 'foo') transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url) self.assertEqual('image/png', self.browser.headers['content-type']) assertImage(self, self.browser.contents, 'PNG', (23, 23)) def testPublishThumbViaName(self): ImageScaling._sizes = {'thumb': (128, 128)} transaction.commit() # make sure traversing works as is and with scaling # first the field without a scale name self.browser.open( self.layer['app'].absolute_url() + '/item/@@images/image' ) self.assertEqual('image/png', self.browser.headers['content-type']) self.assertEqual(self.browser.contents, getFile('image.png')) # and last a scaled version self.browser.open( self.layer['app'].absolute_url() + '/item/@@images/image/thumb' ) self.assertEqual('image/png', self.browser.headers['content-type']) assertImage(self, self.browser.contents, 'PNG', (128, 128)) def testPublishCustomSizeViaName(self): # set custom image sizes ImageScaling._sizes = {'foo': (23, 23)} transaction.commit() # make sure traversing works as expected self.browser.open( self.layer['app'].absolute_url() + '/item/@@images/image/foo' ) assertImage(self, self.browser.contents, 'PNG', (23, 23)) def testPublishScaleWithInvalidUID(self): scale = self.view.scale('image', width=64, height=64) transaction.commit() # change the url so it's invalid... from zExceptions import NotFound with self.assertRaises(NotFound): self.browser.open(scale.url.replace('.png', 'x.png')) def testPublishScaleWithInvalidScale(self): scale = self.view.scale('image', 'no-such-scale') transaction.commit() self.assertEqual(scale, None) def test_getAvailableSizesWithInvalidScaleMethod(self): self.assertEqual(self.view.getAvailableSizes('no-such-scale'), {}) def test_getAvailableSizesWithInvalidScaleProperty(self): self.assertEqual(self.view.available_sizes, {}) def test_getImageSizeWithInvalidScale(self): self.assertEqual(self.view.getImageSize('no-such-scale'), (0, 0)) def testGuardedAccess(self): # make sure it's not possible to access scales of forbidden images self.item.__allow_access_to_unprotected_subobjects__ = 0 ImageScaling._sizes = {'foo': (23, 23)} transaction.commit() self.browser.addHeader( 'Authorization', 'Basic {0:s}:{1:s}'.format(TEST_USER_NAME, TEST_USER_PASSWORD) ) from zExceptions import Unauthorized with self.assertRaises(Unauthorized): self.browser.open( self.layer['app'].absolute_url() + '/item/@@images/image/foo' ) self.item.__allow_access_to_unprotected_subobjects__ = 1
class AddonsControlPanelFunctionalTest(unittest.TestCase): """Test that the add-ons control panel works nicely.""" layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_addons_controlpanel_link(self): self.browser.open( '%s/@@overview-controlpanel' % self.portal_url) self.browser.getLink('Add-ons').click() def test_addons_controlpanel_backlink(self): self.browser.open( '%s/prefs_install_products_form' % self.portal_url) self.assertTrue('General' in self.browser.contents) def test_addons_controlpanel_sidebar(self): self.browser.open( '%s/prefs_install_products_form' % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_addons_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name='prefs_install_products_form') self.assertTrue(view()) def test_addons_controlpanel_no_upgrades(self): self.browser.open( '%s/prefs_install_products_form' % self.portal_url) self.assertIn('No upgrades in this corner', self.browser.contents) def test_addons_controlpanel_installable(self): self.browser.open( '%s/prefs_install_products_form' % self.portal_url) # We expect a few standard add-ons. self.assertIn('Workflow Policy Support', self.browser.contents) self.assertIn('Multilingual Support', self.browser.contents) self.assertIn('plone.session', self.browser.contents) def test_addons_controlpanel_not_installable(self): self.browser.open( '%s/prefs_install_products_form' % self.portal_url) # We do not expect some other add-ons. self.assertNotIn('plone.app.upgrade', self.browser.contents) self.assertNotIn('Products.CMFPlone', self.browser.contents) def test_addons_controlpanel_install_and_uninstall_all(self): self.browser.open( '%s/prefs_install_products_form' % self.portal_url) self.assertNotIn('Installed', self.browser.contents) self.assertNotIn('Uninstalled', self.browser.contents) # It is hard to determine which exact product will be installed # by clicking on a button, because they are all called 'Install'. # We install all available products. for buttons in range(12): try: self.browser.getControl('Install', index=buttons) except LookupError: break else: # Either our test logic is off, or the code that determines # which products are installable is actually wrong. raise AssertionError('Too many Install buttons.') # Click all install buttons. for button in range(buttons): # Always install the first. self.browser.getControl('Install', index=0).click() self.assertIn('Installed', self.browser.contents) # There are no more install buttons. with self.assertRaises(LookupError): self.browser.getControl('Install', index=0) # There should now be just as many Uninstall buttons. self.browser.getControl('Uninstall', index=buttons - 1) for button in range(buttons): # Always uninstall the first. self.browser.getControl('Uninstall', index=0).click() self.assertIn('Uninstalled', self.browser.contents) # There are no more uninstall buttons. with self.assertRaises(LookupError): self.browser.getControl('Uninstall', index=0) # Instead, we could install all again if we want. self.browser.getControl('Install', index=buttons - 1)
class SearchControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the search control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_search_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Search').click() def test_search_control_panel_backlink(self): self.browser.open( "%s/@@search-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_search_control_panel_sidebar(self): self.browser.open( "%s/@@search-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_search_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="search-controlpanel") self.assertTrue(view()) def test_enable_livesearch(self): self.browser.open( "%s/@@search-controlpanel" % self.portal_url) self.browser.getControl('Enable LiveSearch').selected = True self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISearchSchema, prefix="plone") self.assertEqual(settings.enable_livesearch, True) def test_types_not_searched(self): self.browser.open( "%s/@@search-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.types_not_searched:list' ).value = ['Discussion Item', 'News Item'] self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(ISearchSchema, prefix="plone") self.assertFalse('Discussion Item' in settings.types_not_searched) self.assertFalse('News Item Item' in settings.types_not_searched)
class SecurityControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the security control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() registry = getUtility(IRegistry) self.settings = registry.forInterface( ISecuritySchema, prefix="plone") self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_security_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Security').click() def test_security_control_panel_backlink(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.assertTrue("Security" in self.browser.contents) def test_security_control_panel_sidebar(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_enable_self_reg(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.browser.getControl('Enable self-registration').selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.enable_self_reg, True) def test_enable_user_pwd_choice(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.browser.getControl( 'Let users select their own passwords').selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.enable_user_pwd_choice, True) def test_enable_user_folders(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.browser.getControl( 'Enable User Folders').selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.enable_user_folders, True) def test_allow_anon_views_about(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.browser.getControl( "Allow anyone to view 'about' information").selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.allow_anon_views_about, True) def test_use_email_as_login(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.browser.getControl( "Use email address as login name").selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.use_email_as_login, True) def test_use_uuid_as_userid(self): self.browser.open( "%s/@@security-controlpanel" % self.portal_url) self.browser.getControl( "Use UUID user ids").selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.use_uuid_as_userid, True)
class LanguageControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the language control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def _inject_available_languages_field(self, value): """The in-and-out widget does not work without javascript, therefore we have to inject some values in order to make saving the form work. """ form = self.browser.getForm(id='LanguageControlPanel') name = 'form.widgets.available_languages:list' field = webtest.forms.Hidden(form._form, 'input', name, 0, value=value) form._form.field_order.append((name, field)) self.browser.getControl('Save').click() def test_language_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Language').click() self.assertTrue("Language Settings" in self.browser.contents) def test_language_control_panel_backlink(self): self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_language_control_panel_sidebar(self): self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_language_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="language-controlpanel") self.assertTrue(view()) def test_default_language(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.default_language, 'en') self.assertEqual( self.browser.getControl( 'Site language' ).value, ['en'] ) self.browser.getControl( 'Site language' ).value = ['de'] self._inject_available_languages_field('en') self._inject_available_languages_field('de') self.browser.getControl(name='form.buttons.save').click() self.assertEqual(settings.default_language, 'de') # def test_available_languages(self): # registry = getUtility(IRegistry) # settings = registry.forInterface(ILanguageSchema, prefix='plone') # self.browser.open( # "%s/@@language-controlpanel" % self.portal_url) # self.assertEqual(settings.available_languages, ['en']) # self.assertEqual( # self.browser.getControl( # name='form.widgets.available_languages.to' # ).options, # ['en'] # ) # control = self.browser.getForm(index=1) # self.in_out_select( # control, 'form.widgets.available_languages:list', 'Deutsch') # self.browser.getControl('Save').click() # self.assertEqual(settings.available_languages, ['en', 'de']) def test_use_combined_language_codes(self): """This checks swithing combined languages codes support off/on.""" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_combined_language_codes, True) self.assertEqual( self.browser.getControl( 'Show country-specific language variants' ).selected, True ) self.browser.getControl( 'Show country-specific language variants' ).selected = False self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_combined_language_codes, False) def test_display_flags(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.display_flags, False) self.assertEqual( self.browser.getControl( 'Show language flags' ).selected, False ) self.browser.getControl( 'Show language flags' ).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.display_flags, True) def test_use_content_negotiation(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_content_negotiation, False) self.assertEqual( self.browser.getControl( 'Use the language of the content item' ).selected, False ) self.browser.getControl( 'Use the language of the content item' ).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_content_negotiation, True) def test_use_path_negotiation(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_path_negotiation, False) self.assertEqual( self.browser.getControl( 'Use language codes in URL path for manual override' ).selected, False ) self.browser.getControl( 'Use language codes in URL path for manual override' ).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_path_negotiation, True) def test_use_cookie_negotiation(self): registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_cookie_negotiation, False) self.assertEqual( self.browser.getControl( 'Use cookie for manual override' ).selected, False ) self.browser.getControl( 'Use cookie for manual override' ).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_cookie_negotiation, True) def test_authenticated_users_only(self): control_label = "Authenticated users only" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.authenticated_users_only, False) self.assertEqual( self.browser.getControl(control_label).selected, False ) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.authenticated_users_only, True) def test_set_cookie_always(self): control_label = "Set the language cookie always" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.set_cookie_always, False) self.assertEqual( self.browser.getControl(control_label).selected, False ) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.set_cookie_always, True) def test_use_subdomain_negotiation(self): control_label = "Use subdomain" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_subdomain_negotiation, False) self.assertEqual( self.browser.getControl(control_label).selected, False ) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_subdomain_negotiation, True) def test_use_cctld_negotiation(self): control_label = "Use top-level domain" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_cctld_negotiation, False) self.assertEqual( self.browser.getControl(control_label).selected, False ) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_cctld_negotiation, True) def test_use_request_negotiation(self): control_label = "Use browser language request negotiation" registry = getUtility(IRegistry) settings = registry.forInterface(ILanguageSchema, prefix='plone') self.browser.open( "%s/@@language-controlpanel" % self.portal_url) self.assertEqual(settings.use_request_negotiation, False) self.assertEqual( self.browser.getControl(control_label).selected, False ) self.browser.getControl(control_label).selected = True self._inject_available_languages_field('en') self.browser.getControl('Save').click() self.assertEqual(settings.use_request_negotiation, True)
class MailControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the mail control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_mail_controlpanel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Mail').click() def test_mail_controlpanel_backlink(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_mail_controlpanel_sidebar(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_mail_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="mail-controlpanel") self.assertTrue(view()) def test_mail_controlpanel_smtp_host(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.smtp_host').value = 'example.com' self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") self.assertEqual(settings.smtp_host, 'example.com') def test_mail_controlpanel_smtp_port(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.smtp_port').value = '88' self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") self.assertEqual(str(settings.smtp_port), '88') def test_mail_controlpanel_smtp_userid(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.smtp_userid').value = '*****@*****.**' self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") self.assertEqual(settings.smtp_userid, '*****@*****.**') def test_mail_controlpanel_smtp_pass(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.smtp_pass').value = 'secret' self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") self.assertEqual(settings.smtp_pass, 'secret') def test_mail_controlpanel_smtp_pass_keep_on_saving(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.smtp_userid').value = '*****@*****.**' self.browser.getControl( name='form.widgets.smtp_pass').value = 'secret' self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() self.browser.getControl(name='form.buttons.save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") self.assertEqual(settings.smtp_pass, 'secret') def test_mail_controlpanel_email_from_name(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") self.assertEqual(settings.email_from_name, 'John') def test_mail_controlpanel_email_from_address(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") self.assertEqual(settings.email_from_address, '*****@*****.**') def test_mail_controlpanel_contactinfo_page(self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() self.browser.open( "%s/contact-info" % self.portal_url) self.assertTrue( 'Message' in self.browser.contents, u'Message exists not in the contact-info form!' ) def test_controlpanel_overview_shows_no_unconfigured_mailhost_warning( self): self.browser.open( "%s/@@mail-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.email_from_name').value = 'John' self.browser.getControl( name='form.widgets.email_from_address').value = \ '*****@*****.**' self.browser.getControl(name='form.buttons.save').click() self.browser.open( "%s/overview-controlpanel" % self.portal_url) self.assertFalse( 'not configured a mail host' in self.browser.contents, u'There should not be a warning for unconfigured mailhost!' ) def test_controlpanel_overview_shows_unconfigured_mailhost_warning( self): registry = getUtility(IRegistry) settings = registry.forInterface(IMailSchema, prefix="plone") settings.email_from_name = None settings.email_from_address = None self.browser.open( "%s/overview-controlpanel" % self.portal_url) self.assertTrue( 'not configured a mail host' in self.browser.contents, u'There should be a warning for unconfigured mailhost!' )
class NavigationControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the navigation control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_navigation_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Navigation').click() self.assertTrue("Navigation Settings" in self.browser.contents) def test_navigation_control_panel_backlink(self): self.browser.open( "%s/@@navigation-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_navigation_control_panel_sidebar(self): self.browser.open( "%s/@@navigation-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_navigation_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="navigation-controlpanel") self.assertTrue(view()) def test_generate_tabs(self): registry = getUtility(IRegistry) settings = registry.forInterface(INavigationSchema, prefix='plone') self.browser.open( "%s/@@navigation-controlpanel" % self.portal_url) self.assertEqual(settings.generate_tabs, True) self.assertEqual( self.browser.getControl('Automatically generate tabs').selected, True ) self.browser.getControl('Automatically generate tabs').selected = False self.browser.getControl('Save').click() self.assertEqual(settings.generate_tabs, False) def test_nonfolderish_tabs(self): registry = getUtility(IRegistry) settings = registry.forInterface(INavigationSchema, prefix='plone') self.browser.open( "%s/@@navigation-controlpanel" % self.portal_url) self.assertEqual(settings.generate_tabs, True) self.assertEqual( self.browser.getControl('Automatically generate tabs').selected, True ) self.browser.getControl( 'Generate tabs for items other than folders').selected = False self.browser.getControl('Save').click() self.assertEqual(settings.nonfolderish_tabs, False) def test_displayed_types(self): registry = getUtility(IRegistry) settings = registry.forInterface(INavigationSchema, prefix='plone') self.browser.open( "%s/@@navigation-controlpanel" % self.portal_url) self.browser.getControl('Collection', index=0).selected = True self.browser.getControl('Comment').selected = True self.browser.getControl('Event').selected = True self.browser.getControl('File').selected = True self.browser.getControl('Folder').selected = True self.browser.getControl('Image').selected = True self.browser.getControl('Link').selected = True self.browser.getControl('News Item').selected = True self.browser.getControl('Page').selected = True self.browser.getControl('Save').click() self.assertTrue('Collection' in settings.displayed_types) self.assertTrue('Discussion Item' in settings.displayed_types) self.assertTrue('Event' in settings.displayed_types) self.assertTrue('File' in settings.displayed_types) self.assertTrue('Folder' in settings.displayed_types) self.assertTrue('Image' in settings.displayed_types) self.assertTrue('Link' in settings.displayed_types) self.assertTrue('News Item' in settings.displayed_types) self.assertTrue('Document' in settings.displayed_types) def test_workflow_settings(self): registry = getUtility(IRegistry) settings = registry.forInterface(INavigationSchema, prefix='plone') self.browser.open( "%s/@@navigation-controlpanel" % self.portal_url) self.browser.getControl('Filter on workflow state').selected = True self.browser.getControl('Externally visible [external]').selected = True # noqa self.browser.getControl('Internal draft [internal]').selected = True self.browser.getControl('Internally published [internally_published]').selected = True # noqa self.browser.getControl('Pending [pending]').selected = True self.browser.getControl('Private [private]').selected = True self.browser.getControl('Public draft [visible]').selected = True self.browser.getControl('Published [published]').selected = True self.browser.getControl("Save").click() self.assertTrue(self.browser.url.endswith('navigation-controlpanel')) self.assertTrue('Changes saved.' in self.browser.contents) self.assertTrue(settings.filter_on_workflow) self.assertTrue('external' in settings.workflow_states_to_show) self.assertTrue('internal' in settings.workflow_states_to_show) self.assertTrue('internally_published' in settings.workflow_states_to_show) # noqa self.assertTrue('pending' in settings.workflow_states_to_show) self.assertTrue('private' in settings.workflow_states_to_show) self.assertTrue('visible' in settings.workflow_states_to_show) self.assertTrue('published' in settings.workflow_states_to_show) def test_show_excluded_items(self): registry = getUtility(IRegistry) settings = registry.forInterface(INavigationSchema, prefix='plone') self.browser.open( "%s/@@navigation-controlpanel" % self.portal_url) self.browser.getControl( 'Show items normally excluded from navigation if viewing their children.').selected = False # noqa self.browser.getControl("Save").click() self.assertFalse(settings.show_excluded_items)
class UserGroupsControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the user groups control panel are actually creating and changing users and groups. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def _generateGroups(self): groupsTool = getToolByName(self.portal, 'portal_groups') self.groups = [{ 'id': 'group1', 'title': "Group 1" }, { 'id': 'group2', 'title': "Group 2" }, { 'id': 'group3', 'title': "Group 3 accentué" }] for group in self.groups: groupsTool.addGroup(group['id'], [], [], title=group['title']) def _generateUsers(self): self.members = [ { 'username': '******', 'fullname': 'Kevin Hughes', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Richard Ramirez', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Kyle Brown', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Julian Green', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Makayla Coleman', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Sean Foster', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Molly Martin', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Jordan Thompson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Tyler Rivera', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Megan Murphy', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Gracie Diaz', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Rachel Morgan', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Maya Price', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Blake Jenkins', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Owen Ramirez', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Owen Cook', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Jayden Hill', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Joseph Ramirez', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Nathan Young', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Kaitlyn Hernandez', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Faith Price', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Sofia Williams', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'David Sanders', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Jack Simmons', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Cole Howard', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Rachel Miller', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Henry Patterson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Avery Cooper', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Sydney Bennett', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Daniel Johnson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Autumn Brooks', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Alexandra Nelson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Brian Simmons', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Kevin Hughes', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Sydney Evans', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Emma Brown', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Lauren Martin', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Isabelle Russell', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Anna Baker', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Brady Watson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Kaitlyn Robinson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Riley Richardson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Kayla Sanders', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Sara Richardson', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Trinity Gonzales', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Madeline Garcia', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Brian Gray', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Victoria Perez', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Charles Rodriguez', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Abigail Simmons', 'email': '*****@*****.**' }, { 'username': '******', 'fullname': 'Émilie Richard', 'email': '*****@*****.**' }, ] rtool = getToolByName(self.portal, 'portal_registration') for member in self.members: rtool.addMember(member['username'], 'somepassword', properties=member) def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.usergroups_url = "%s/@@usergroup-userprefs" % self.portal_url self.groups_url = "%s/@@usergroup-groupprefs" % self.portal_url self._generateGroups() self._generateUsers() transaction.commit() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % ( SITE_OWNER_NAME, SITE_OWNER_PASSWORD, )) def test_usergroups_control_panel_link(self): self.browser.open("%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Users and Groups').click() self.assertEqual(self.browser.url, self.usergroups_url) def test_usergroups_groups_link(self): self.browser.open(self.usergroups_url) self.browser.getLink('Groups', index=0).click() self.assertEqual(self.browser.url, "%s/@@usergroup-groupprefs" % self.portal_url) def test_usergroups_settings_link(self): self.browser.open(self.usergroups_url) self.browser.getLink('Settings').click() self.assertEqual(self.browser.url, "%s/@@usergroup-controlpanel" % self.portal_url) def test_usergroups_memberfields_link(self): self.browser.open(self.usergroups_url) self.browser.getLink('Member fields').click() self.assertEqual(self.browser.url, "%s/@@member-fields" % self.portal_url) def test_user_search_by_name(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'Richard' self.browser.getControl(name='form.button.Search').click() self.assertIn('Richard Ramirez', self.browser.contents) self.assertIn('Sara Richardson', self.browser.contents) self.assertIn('Émilie Richard', self.browser.contents) def test_user_search_by_name_accent(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'Émilie' self.browser.getControl(name='form.button.Search').click() self.assertIn('Émilie Richard', self.browser.contents) def test_user_search_by_id(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertIn('Autumn Brooks', self.browser.contents) def test_user_search_by_mail(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'DohPmgIa@' self.browser.getControl(name='form.button.Search').click() self.assertIn('Gracie Diaz', self.browser.contents) def test_user_show_all(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='form.button.FindAll').click() # Check that first 10 members (sorted by fullname) are shown. for member in sorted( self.members, key=lambda k: normalizeString(k['fullname']))[:10]: self.assertIn(member['fullname'], self.browser.contents) def test_user_show_all_with_search_term(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'no-user' self.browser.getControl(name='form.button.FindAll').click() # Check that all members is shown and search term is ignored self.assertIn('Avery Cooper', self.browser.contents) def test_user_add_new_link(self): self.browser.open(self.usergroups_url) self.browser.getLink(id='add-user').click() self.assertEqual(self.browser.url, "%s/@@new-user" % self.portal_url) def test_user_modify_roles(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() # Check that contributor role is not enabled and enable it self.assertFalse( self.browser.getControl( name='users.roles:list:records').getControl( value='Contributor').selected) self.browser.getControl(name='users.roles:list:records').getControl( value='Contributor').selected = True self.browser.getControl(name='form.button.Modify').click() # Check that contributor role is now enabled for this user self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertTrue( self.browser.getControl( name='users.roles:list:records').getControl( value='Contributor').selected) def test_user_delete(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertIn('Autumn Brooks', self.browser.contents) # Delete user self.browser.getControl(name='delete:list').getControl( value='TWrMCLIo').selected = True self.browser.getControl(name='form.button.Modify').click() # Check that user does not exist anymore self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertNotIn('Autumn Brooks', self.browser.contents) def test_groups_search_by_id(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'group1' self.browser.getControl(name='form.button.Search').click() self.assertIn('Group 1', self.browser.contents) def test_groups_search_by_name(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'Group 3 accentué' self.browser.getControl(name='form.button.Search').click() self.assertIn('Group 3 accentué', self.browser.contents) def test_groups_modify_roles(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'group1' # Check that role is not selected yet and then select it and apply it. form = self.browser.getForm(id='groups_search') ctrls = form._form.fields.get('group_group1:list') roles = [ctrl._value for ctrl in ctrls] expected = 'Site Administrator' self.assertIn(expected, roles) idx = roles.index(expected) self.assertFalse(ctrls[idx].checked) ctrls[idx].checked = True self.browser.getControl('Save').click() # Check that role is now selected form = self.browser.getForm(id='groups_search') ctrl = form._form.get('group_group1:list', index=idx) self.assertEqual(ctrl._value, expected) self.assertTrue(ctrl.checked) def test_groups_delete_group(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'group1' # Delete a group self.browser.getControl(name='delete:list').getControl( value='group1').selected = True self.browser.getControl(name='form.button.Modify').click() # Check that group doesn't exist anymore self.browser.getControl(name='searchstring').value = 'group1' self.assertNotIn('Group 1', self.browser.contents) def test_groups_show_all(self): self.browser.open(self.groups_url) self.browser.getControl(name='form.button.FindAll').click() for group in self.groups: self.assertIn(group['title'], self.browser.contents) def test_group_add_users(self): self.browser.open(self.groups_url) self.browser.getLink('Group 1 (group1)').click() self.assertIn('There is no group or user attached to this group.', self.browser.contents) # Add user (Autumn Brooks) to selected group (Group 1) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.browser.getControl(name='add:list').getControl( value='TWrMCLIo').selected = True # Check that user is now part of the group self.browser.getControl( 'Add selected groups and users to this group').click() self.assertIn('Autumn Brooks', self.browser.contents) def test_group_add_group(self): self.browser.open(self.groups_url) self.browser.getLink('Group 1 (group1)').click() self.assertIn('There is no group or user attached to this group.', self.browser.contents) # Add group2 to selected group 1 self.browser.getControl(name='searchstring').value = 'group2' self.browser.getControl(name='form.button.Search').click() self.browser.getControl(name='add:list').getControl( value='group2').selected = True # Check that group is now part of the group self.browser.getControl( 'Add selected groups and users to this group').click() self.assertIn('Group 2', self.browser.contents) # Check that you can still add a user too. This failed at some point: # https://github.com/plone/Products.CMFPlone/issues/3048 # Add user (Autumn Brooks) to selected group (Group 1) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.browser.getControl(name='add:list').getControl( value='TWrMCLIo').selected = True self.browser.getControl( 'Add selected groups and users to this group').click() # Check that both group and user are now part of the group self.browser.open(self.groups_url) self.browser.getLink('Group 1 (group1)').click() self.assertIn('Autumn Brooks', self.browser.contents) self.assertIn('Group 2', self.browser.contents) def test_usergroups_settings_many_users(self): self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.many_users:list').controls[0].selected = True self.browser.getControl('Save').click() # Check that show all button for users is no longer available self.browser.open(self.usergroups_url) self.assertNotIn('Show all', self.browser.contents) # Check that empty search does not trigger show all self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = '' def test_usergroups_settings_many_groups(self): self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.many_groups:list').controls[0].selected = True self.browser.getControl('Save').click() # Check that show all button for groups is no longer available self.browser.open(self.groups_url) self.assertNotIn('Show all', self.browser.contents) self.assertNotIn('DIispfuF', self.browser.contents)
class FilterControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the site control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() registry = getUtility(IRegistry) self.settings = registry.forInterface(IFilterSchema, prefix="plone") self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', f'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}') self.safe_html = getattr( getToolByName(self.portal, 'portal_transforms'), 'safe_html', None) def test_filter_control_panel_link(self): self.browser.open("%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Site').click() def test_filter_control_panel_backlink(self): self.browser.open("%s/@@filter-controlpanel" % self.portal_url) self.assertTrue("Security" in self.browser.contents) def test_filter_control_panel_sidebar(self): self.browser.open("%s/@@filter-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel')) def test_filter_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="filter-controlpanel") self.assertTrue(view()) def test_disable_filtering(self): self.browser.open("%s/@@filter-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.disable_filtering:list').value = "selected" self.browser.getControl('Save').click() # test that the transform is disabled self.assertEqual(self.settings.disable_filtering, 1) # anything passes nasty_html = '<script></script>' ds = datastream('dummy_name') self.assertEqual(nasty_html, str(self.safe_html.convert(nasty_html, ds))) def test_nasty_tags(self): self.browser.open("%s/@@filter-controlpanel" % self.portal_url) self.assertEqual( self.browser.getControl(name='form.widgets.nasty_tags').value, 'style\nobject\nembed\napplet\nscript\nmeta') self.browser.getControl( name='form.widgets.nasty_tags').value = 'div\na' valid_tags = self.browser.getControl( name='form.widgets.valid_tags').value self.assertTrue(valid_tags.startswith('a\nabbr\nacronym\naddress')) valid_tags = valid_tags.replace('a\n', '') valid_tags = self.browser.getControl( name='form.widgets.valid_tags').value = valid_tags self.browser.getControl('Save').click() self.assertEqual(self.settings.nasty_tags, ['div', 'a']) self.assertNotIn('a', self.settings.valid_tags) # test that <a> is filtered self.assertFalse(self.settings.disable_filtering) good_html = '<p><a href="http://example.com">harmless link</a></p>' ds = datastream('dummy_name') self.assertEqual( self.safe_html.convert(good_html, ds).getData(), '<p/>')
class MarkupControlPanelFunctionalTest(unittest.TestCase): """Make sure changes in the markup control panel are properly stored in plone.app.registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_markup_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Markup').click() def test_markup_control_panel_backlink(self): self.browser.open( "%s/@@markup-controlpanel" % self.portal_url) self.assertTrue("Content" in self.browser.contents) def test_markup_control_panel_sidebar(self): self.browser.open( "%s/@@markup-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_markup_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="markup-controlpanel") self.assertTrue(view()) def test_default_type(self): self.browser.open( "%s/@@markup-controlpanel" % self.portal_url) self.browser.getControl('Default format').value = ['text/plain'] self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMarkupSchema, prefix='plone') self.assertEqual(settings.default_type, 'text/plain') def test_allowed_types(self): self.browser.open( "%s/@@markup-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.allowed_types:list' ).value = ['text/html', 'text/x-web-textile'] self.browser.getControl('Save').click() registry = getUtility(IRegistry) settings = registry.forInterface(IMarkupSchema, prefix='plone') self.assertEqual(settings.allowed_types, ('text/html', 'text/x-web-textile'))
class ImagePublisherTests(unittest.TestCase): layer = PLONE_NAMEDFILE_FUNCTIONAL_TESTING def setUp(self): if six.PY2: raise unittest.SkipTest("Disabled in py2 for now.") data = getFile("image.png") item = DummyContent() item.image = NamedImage(data, "image/png", u"image.png") self.layer["app"]._setOb("item", item) self.item = self.layer["app"].item self.view = self.item.unrestrictedTraverse("@@images") self._orig_sizes = ImageScaling._sizes self.browser = Browser(self.layer["app"]) self.browser.handleErrors = False self.browser.addHeader("Referer", self.layer["app"].absolute_url()) def tearDown(self): ImageScaling._sizes = self._orig_sizes def testPublishScaleViaUID(self): scale = self.view.scale("image", width=64, height=64) transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url) self.assertEqual("image/png", self.browser.headers["content-type"]) assertImage(self, self.browser.contents, "PNG", (64, 64)) def testPublishWebDavScaleViaUID(self): scale = self.view.scale("image", width=64, height=64) transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url + "/manage_DAVget") self.assertEqual("image/png", self.browser.headers["content-type"]) assertImage(self, self.browser.contents, "PNG", (64, 64)) def testPublishFTPScaleViaUID(self): scale = self.view.scale("image", width=64, height=64) transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url + "/manage_FTPget") self.assertIn("200", self.browser.headers["status"]) # Same remark as in testPublishWebDavScaleViaUID is valid here. self.assertEqual("image/png", self.browser.headers["content-type"]) assertImage(self, self.browser.contents, "PNG", (64, 64)) def testHeadRequestMethod(self): scale = self.view.scale("image", width=64, height=64) transaction.commit() # make sure the referenced image scale is available url = str(scale.url) self.browser.open(url) GET_length = len(self.browser.contents) self.browser = Browser(self.layer["app"]) self.browser.handleErrors = False self.browser.addHeader("Referer", self.layer["app"].absolute_url()) def make_head_request(args): return self.browser.testapp.head(url, **args) self.browser._processRequest(url, make_head_request) self.assertEqual("image/png", self.browser.headers["content-type"]) self.assertEqual(self.browser.headers["Content-Length"], str(GET_length)) self.assertEqual(self.browser.contents, b"") def testPublishThumbViaUID(self): ImageScaling._sizes = {"thumb": (128, 128)} scale = self.view.scale("image", "thumb") transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url) self.assertEqual("image/png", self.browser.headers["content-type"]) assertImage(self, self.browser.contents, "PNG", (128, 128)) def testPublishCustomSizeViaUID(self): # set custom image sizes ImageScaling._sizes = {"foo": (23, 23)} scale = self.view.scale("image", "foo") transaction.commit() # make sure the referenced image scale is available self.browser.open(scale.url) self.assertEqual("image/png", self.browser.headers["content-type"]) assertImage(self, self.browser.contents, "PNG", (23, 23)) def testPublishThumbViaName(self): ImageScaling._sizes = {"thumb": (128, 128)} transaction.commit() # make sure traversing works as is and with scaling # first the field without a scale name self.browser.open(self.layer["app"].absolute_url() + "/item/@@images/image") self.assertEqual("image/png", self.browser.headers["content-type"]) self.assertEqual(self.browser.contents, getFile("image.png")) # and last a scaled version self.browser.open( self.layer["app"].absolute_url() + "/item/@@images/image/thumb" ) self.assertEqual("image/png", self.browser.headers["content-type"]) assertImage(self, self.browser.contents, "PNG", (128, 128)) def testPublishCustomSizeViaName(self): # set custom image sizes ImageScaling._sizes = {"foo": (23, 23)} transaction.commit() # make sure traversing works as expected self.browser.open(self.layer["app"].absolute_url() + "/item/@@images/image/foo") assertImage(self, self.browser.contents, "PNG", (23, 23)) def testPublishScaleWithInvalidUID(self): scale = self.view.scale("image", width=64, height=64) transaction.commit() # change the url so it's invalid... from zExceptions import NotFound with self.assertRaises(NotFound): self.browser.open(scale.url.replace(".png", "x.png")) def testPublishScaleWithInvalidScale(self): scale = self.view.scale("image", "no-such-scale") transaction.commit() self.assertEqual(scale, None) def test_getAvailableSizesWithInvalidScaleMethod(self): self.assertEqual(self.view.getAvailableSizes("no-such-scale"), {}) def test_getAvailableSizesWithInvalidScaleProperty(self): self.assertEqual(self.view.available_sizes, {}) def test_getImageSizeWithInvalidScale(self): self.assertEqual(self.view.getImageSize("no-such-scale"), (0, 0)) def testGuardedAccess(self): # make sure it's not possible to access scales of forbidden images self.item.__allow_access_to_unprotected_subobjects__ = 0 ImageScaling._sizes = {"foo": (23, 23)} transaction.commit() self.browser.addHeader( "Authorization", "Basic {0:s}:{1:s}".format(TEST_USER_NAME, TEST_USER_PASSWORD), ) from zExceptions import Unauthorized with self.assertRaises(Unauthorized): self.browser.open( self.layer["app"].absolute_url() + "/item/@@images/image/foo" ) self.item.__allow_access_to_unprotected_subobjects__ = 1 def testSVGPublishThumbViaName(self): ImageScaling._sizes = {"thumb": (128, 128)} data = getFile("image.svg") svg = DummyContent() svg.image = NamedImage(data, "image/svg+xml", u"image.svg") self.layer["app"]._setOb("svg", svg) svg = self.layer["app"].svg transaction.commit() # make sure traversing works as is and with scaling # first the field without a scale name self.browser.open(self.layer["app"].absolute_url() + "/svg/@@images/image") self.assertEqual("image/svg+xml", self.browser.headers["content-type"]) self.assertEqual(self.browser.contents, getFile("image.svg")) # and last a scaled version self.browser.open( self.layer["app"].absolute_url() + "/svg/@@images/image/thumb" ) self.assertEqual("image/svg+xml", self.browser.headers["content-type"]) self.assertEqual(self.browser.contents, data)
class EditingControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the editing control panel are actually stored in the registry. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.request = self.layer['request'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() registry = getUtility(IRegistry) self.settings = registry.forInterface(IEditingSchema, prefix='plone') self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_editing_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Editing').click() def test_editing_control_panel_backlink(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.assertTrue("Content" in self.browser.contents) def test_editing_control_panel_sidebar(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) @unittest.skip("TODO: Not implemented yet.") def test_visible_ids_active(self): pass def test_default_editor(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.browser.getControl("Default editor").value = ["None"] self.browser.getControl('Save').click() self.assertEqual(self.settings.default_editor, "None") @unittest.skip("TODO: Not implemented yet.") def test_default_editor_active(self): pass def test_available_editors_hidden(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.assertTrue('Available editors' not in self.browser.contents) def test_ext_editor(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.browser.getControl("Enable External Editor feature")\ .selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.ext_editor, True) @unittest.skip("TODO: Not implemented yet.") def test_ext_editor_active(self): pass def test_enable_link_integrity_checks(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.browser.getControl("Enable link integrity checks")\ .selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.enable_link_integrity_checks, True) def test_enable_link_integrity_checks_active(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.browser.getControl("Enable link integrity checks")\ .selected = True self.browser.getControl('Save').click() self.assertTrue(linkintegrity_enabled()) def test_lock_on_ttw_edit(self): self.browser.open( "%s/@@editing-controlpanel" % self.portal_url) self.browser.getControl("Enable locking for through-the-web edits")\ .selected = True self.browser.getControl('Save').click() self.assertEqual(self.settings.lock_on_ttw_edit, True) @unittest.skip("TODO: Not implemented yet.") def test_lock_on_ttw_edit_active(self): pass
class SyndicationControlPanelFunctionalTest(unittest.TestCase): layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_syndication_controlpanel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Syndication').click() def test_syndication_controlpanel_backlink(self): self.browser.open( "%s/@@syndication-controlpanel" % self.portal_url) self.assertTrue("General" in self.browser.contents) def test_syndication_controlpanel_sidebar(self): self.browser.open( "%s/@@syndication-controlpanel" % self.portal_url) self.browser.getLink('Site Setup').click() self.assertTrue( self.browser.url.endswith('/plone/@@overview-controlpanel') ) def test_syndication_controlpanel_view(self): view = getMultiAdapter((self.portal, self.portal.REQUEST), name="syndication-controlpanel") self.assertTrue(view()) def test_syndication_controlpanel_enabled(self): self.browser.open( "%s/@@syndication-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.default_enabled:list').value = True self.browser.getControl( name='form.widgets.show_author_info:list').value = False self.browser.getControl( name='form.widgets.show_syndication_link:list').value = True self.browser.getControl('Save').click() self.assertTrue('Changes saved' in self.browser.contents) self.browser.open( "%s/@@syndication-controlpanel" % self.portal_url) self.assertEqual( self.browser.getControl( name='form.widgets.default_enabled:list' ).value, ['selected'] ) self.assertEqual( self.browser.getControl( name='form.widgets.show_author_info:list').value, [] ) self.assertEqual( self.browser.getControl( name='form.widgets.show_syndication_link:list' ).value, ['selected'] ) def test_create_collection(self): """Create collection and check if synPropertiesForm link is present. """ # create collection self.portal.invokeFactory('Collection', 'collection') self.portal.collection.query = [ { "i": "portal_type", "o": "plone.app.querystring.operation.selection.any", "v": ["News Item"] }, { "i": "review_state", "o": "plone.app.querystring.operation.selection.any", "v": ["published"] } ] transaction.commit() # Enable syndication self.browser.open( "%s/@@syndication-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.default_enabled:list').value = ['selected'] self.browser.getControl( name='form.widgets.show_syndication_link:list' ).value = ['selected'] self.browser.getControl('Save').click() self.assertTrue('Changes saved' in self.browser.contents) self.browser.open(self.portal_url + '/collection') self.assertTrue('/RSS' in self.browser.contents)
class TestSiteAdministratorRoleFunctional(unittest.TestCase): layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def _generateUsers(self): rtool = getToolByName(self.portal, 'portal_registration') rtool.addMember('DIispfuF', 'secret', ['Member'], []) rtool.addMember('siteadmin', 'secret', ['Site Administrator'], []) rtool.addMember('root', 'secret', ['Manager'], []) def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.request = self.layer['request'] self.portal_url = self.portal.absolute_url() self.usergroups_url = "%s/@@usergroup-userprefs" % self.portal_url self.groups_url = "%s/@@usergroup-groupprefs" % self.portal_url self._generateUsers() setRoles(self.portal, TEST_USER_ID, ['Manager']) transaction.commit() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (TEST_USER_ID, TEST_USER_PASSWORD,) ) self.normal_user = '******' def _get_authenticator(self, browser=None): if not browser: browser = self.browser return browser.getControl(name='_authenticator').value def _simplify_white_space(self, text): """For easier testing we replace all white space with one space. And we remove white space around '<' and '>'. So this: <p id="foo"> Bar </p> becomes this: <p id="foo">Bar</p> """ text = re.sub(r'\s*<\s*', '<', text) text = re.sub(r'\s*>\s*', '>', text) text = re.sub(r'\s+', ' ', text) return text def testControlPanelOverview(self): # make sure we can view the Site Setup page, # at both old and new URLs view = self.portal.restrictedTraverse('plone_control_panel') self.assertTrue(view()) view = self.portal.restrictedTraverse('overview-controlpanel') self.assertTrue(view()) def testUserManagerRoleCheckboxIsDisabledForNonManagers(self): login(self.portal, 'siteadmin') view = self.portal.restrictedTraverse('@@usergroup-userprefs') contents = view() self.assertTrue('<input type="checkbox" class="noborder" ' 'name="users.roles:list:records" value="Manager" ' 'disabled="disabled" />' in contents) def testManagerCanDelegateManagerRoleForUsers(self): # a user with the Manager role can grant the Manager role self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) self.browser.open(self.usergroups_url) form = { '_authenticator': self._get_authenticator(), 'users.id:records': self.normal_user, 'users.roles:list:records': 'Manager', 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form) self.browser.post(self.usergroups_url, post_data) self.assertIn('Status: 200', str(self.browser.headers)) roles = self.portal.acl_users.getUserById(self.normal_user).getRoles() self.assertEqual(['Manager', 'Authenticated'], roles) def testNonManagersCannotDelegateManagerRoleForUsers(self): # a user without the Manager role cannot delegate the Manager role self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open(self.usergroups_url) form = { '_authenticator': self._get_authenticator(), 'users.id:records': self.normal_user, 'users.roles:list:records': 'Manager', 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form) with self.assertRaises(zExceptions.Forbidden): self.browser.post(self.usergroups_url, post_data) roles = self.portal.acl_users.getUserById(self.normal_user).getRoles() self.assertEqual(['Member', 'Authenticated'], roles) def testNonManagersCanEditOtherRolesOfUsersWithManagerRole(self): roles = self.portal.acl_users.getUserById('root').getRoles() self.assertEqual(['Manager', 'Authenticated'], roles) self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open(self.usergroups_url) form = { '_authenticator': self._get_authenticator(), 'users.id:records': 'root', 'users.roles:list:records': ('Member', 'Manager'), 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form, doseq=True) self.browser.post(self.usergroups_url, post_data) roles = self.portal.acl_users.getUserById('root').getRoles() self.assertEqual(['Authenticated', 'Manager', 'Member'], sorted(roles)) def testGroupManagerRoleCheckboxIsDisabledForNonManagers(self): self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open(self.groups_url) contents = self._simplify_white_space(self.browser.contents) self.assertTrue('<input type="checkbox" class="noborder" ' 'name="group_Reviewers:list" value="Manager" ' 'disabled="disabled" />' in contents) def testManagerCanDelegateManagerRoleForGroups(self): # a user with the Manager role can grant the Manager role roles = self.portal.acl_users.getGroupById('Reviewers').getRoles() self.assertEqual(['Reviewer', 'Authenticated'], roles) self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) self.browser.open(self.groups_url) form = { '_authenticator': self._get_authenticator(), 'group_Reviewers:list': ('', 'Manager'), 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form, doseq=True) self.browser.post(self.groups_url, post_data) roles = self.portal.acl_users.getGroupById('Reviewers').getRoles() self.assertEqual(['Manager', 'Authenticated'], roles) def testNonManagersCannotDelegateManagerRoleForGroups(self): # a user without the Manager role cannot delegate the Manager role self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open(self.groups_url) form = { '_authenticator': self._get_authenticator(), 'group_Reviewers:list': ('', 'Manager'), 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form, doseq=True) with self.assertRaises(zExceptions.Forbidden): self.browser.post(self.groups_url, post_data) # self.assertEqual(403, res.status) roles = self.portal.acl_users.getGroupById('Reviewers').getRoles() self.assertEqual(['Reviewer', 'Authenticated'], roles) def testNonManagersCanEditOtherRolesOfGroupsWithManagerRole(self): self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') roles = self.portal.acl_users.getUserById('root').getRoles() self.assertEqual(['Manager', 'Authenticated'], roles) self.browser.open(self.groups_url) form = { '_authenticator': self._get_authenticator(), 'group_Administrators:list': ('', 'Member', 'Manager'), 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form, doseq=True) self.browser.post(self.groups_url, post_data) # self.assertEqual(200, res.status) roles = self.portal.acl_users.getGroupById('Administrators').getRoles() self.assertEqual(['Authenticated', 'Manager', 'Member'], sorted(roles)) def test_usergroup_usermembership_blocks_escalation(self): self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') # groups granting the Manager role shouldn't show as a valid option to # add self.browser.open( self.portal_url + '/@@usergroup-usermembership?userid=%s' % self.normal_user) contents = self._simplify_white_space(self.browser.contents) self.assertTrue( '<input type="checkbox" class="noborder" name="add:list" ' 'value="Administrators" disabled="disabled" />' in contents ) # and should not be addable form = { '_authenticator': self._get_authenticator(), 'add:list': 'Administrators', 'form.submitted': 1, } post_data = urlencode(form) with self.assertRaises(zExceptions.Forbidden): self.browser.open( self.portal_url + '/@@usergroup-usermembership?userid=%s' % self.normal_user, post_data ) # self.assertEqual(403, res.status) roles = self.portal.acl_users.getUserById(self.normal_user).getRoles() self.assertEqual(['Member', 'Authenticated'], roles) def test_usergroup_groupmembership_blocks_escalation(self): # should not show section to add users for groups granting the Manager # role self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open( self.portal_url + '/@@usergroup-groupmembership?groupname=Administrators' ) contents = self._simplify_white_space(self.browser.contents) self.assertFalse('Search for new group members' in contents) # and should not be addable if we try to force it form = { '_authenticator': self._get_authenticator(), 'add:list': self.normal_user, 'form.submitted': 1, } post_data = urlencode(form) with self.assertRaises(zExceptions.Forbidden): self.browser.post( self.portal_url + '/@@usergroup-groupmembership?groupname=Administrators', post_data ) # self.assertEqual(403, res.status) roles = self.portal.acl_users.getUserById(self.normal_user).getRoles() self.assertEqual(['Member', 'Authenticated'], roles) def test_user_registration_form_blocks_escalation(self): # groups granting the Manager role should not be available for # selection self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open(self.portal_url + '/@@new-user') contents = self._simplify_white_space(self.browser.contents) self.assertFalse( '<input class="label checkboxType" id="form.groups.0" ' 'name="form.groups" type="checkbox" value="Administrators ' '(Administrators)" />' in contents ) # and should not be getting that roles if we try to force it form = { '_authenticator': self._get_authenticator(), 'form.widgets.username': '******', 'form.widgets.email': '*****@*****.**', 'form.widgets.password': '******', 'form.widgets.password_ctl': 'secret', 'form.widgets.groups:list': 'Administrators', 'form.widgets.groups-empty-marker': '1', 'form.buttons.register': 'Register', } post_data = urlencode(form) self.browser.post(self.portal_url + '/@@new-user', post_data) self.assertEqual( ['Member', 'Authenticated'], self.portal.acl_users.getUserById('newuser').getRoles()) def test_users_overview_blocks_deleting_managers(self): # a user without the Manager role cannot delete a user with the # Manager role self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open(self.usergroups_url) contents = self._simplify_white_space(self.browser.contents) self.assertTrue( '<input type="checkbox" class="noborder notify" ' 'name="delete:list" value="root" disabled="disabled" />' in contents) form = { '_authenticator': self._get_authenticator(), 'users.id:records': 'root', 'delete:list': 'root', 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form) with self.assertRaises(zExceptions.Forbidden): self.browser.post(self.usergroups_url, post_data) # self.assertEqual(403, res.status) user = self.portal.acl_users.getUserById('root') self.assertTrue(user is not None) def test_groups_overview_blocks_deleting_managers(self): # a user without the Manager role cannot delete a group with the # Manager role self.browser.addHeader( 'Authorization', 'Basic siteadmin:secret') self.browser.open(self.groups_url) contents = self._simplify_white_space(self.browser.contents) self.assertTrue( '<input type="checkbox" class="noborder notify" ' 'name="delete:list" value="Administrators" disabled="disabled" />' in contents ) form = { '_authenticator': self._get_authenticator(), 'delete:list': 'Administrators', 'form.button.Modify': 'Save', 'form.submitted': 1, } post_data = urlencode(form) with self.assertRaises(zExceptions.Forbidden): self.browser.post(self.groups_url, post_data) # self.assertEqual(403, res.status) group = self.portal.acl_users.getGroupById('Administrators') self.assertTrue(group is not None)
class UserGroupsControlPanelFunctionalTest(unittest.TestCase): """Test that changes in the user groups control panel are actually creating and changing users and groups. """ layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING def _generateGroups(self): groupsTool = getToolByName(self.portal, 'portal_groups') self.groups = [ {'id': 'group1', 'title': "Group 1"}, {'id': 'group2', 'title': "Group 2"}, {'id': 'group3', 'title': "Group 3 accentué"} ] for group in self.groups: groupsTool.addGroup(group['id'], [], [], title=group['title']) def _generateUsers(self): self.members = [ {'username': '******', 'fullname': 'Kevin Hughes', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Richard Ramirez', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Kyle Brown', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Julian Green', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Makayla Coleman', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Sean Foster', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Molly Martin', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Jordan Thompson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Tyler Rivera', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Megan Murphy', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Gracie Diaz', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Rachel Morgan', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Maya Price', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Blake Jenkins', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Owen Ramirez', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Owen Cook', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Jayden Hill', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Joseph Ramirez', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Nathan Young', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Kaitlyn Hernandez', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Faith Price', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Sofia Williams', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'David Sanders', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Jack Simmons', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Cole Howard', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Rachel Miller', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Henry Patterson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Avery Cooper', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Sydney Bennett', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Daniel Johnson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Autumn Brooks', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Alexandra Nelson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Brian Simmons', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Kevin Hughes', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Sydney Evans', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Emma Brown', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Lauren Martin', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Isabelle Russell', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Anna Baker', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Brady Watson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Kaitlyn Robinson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Riley Richardson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Kayla Sanders', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Sara Richardson', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Trinity Gonzales', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Madeline Garcia', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Brian Gray', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Victoria Perez', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Charles Rodriguez', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Abigail Simmons', 'email': '*****@*****.**'}, {'username': '******', 'fullname': 'Émilie Richard', 'email': '*****@*****.**'}, ] rtool = getToolByName(self.portal, 'portal_registration') for member in self.members: rtool.addMember(member['username'], 'somepassword', properties=member) def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] self.portal_url = self.portal.absolute_url() self.usergroups_url = "%s/@@usergroup-userprefs" % self.portal_url self.groups_url = "%s/@@usergroup-groupprefs" % self.portal_url self._generateGroups() self._generateUsers() transaction.commit() self.browser = Browser(self.app) self.browser.handleErrors = False self.browser.addHeader( 'Authorization', 'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,) ) def test_usergroups_control_panel_link(self): self.browser.open( "%s/@@overview-controlpanel" % self.portal_url) self.browser.getLink('Users and Groups').click() self.assertEqual( self.browser.url, self.usergroups_url ) def test_usergroups_groups_link(self): self.browser.open(self.usergroups_url) self.browser.getLink('Groups', index=0).click() self.assertEqual( self.browser.url, "%s/@@usergroup-groupprefs" % self.portal_url ) def test_usergroups_settings_link(self): self.browser.open(self.usergroups_url) self.browser.getLink('Settings').click() self.assertEqual( self.browser.url, "%s/@@usergroup-controlpanel" % self.portal_url ) def test_usergroups_memberfields_link(self): self.browser.open(self.usergroups_url) self.browser.getLink('Member fields').click() self.assertEqual( self.browser.url, "%s/@@member-fields" % self.portal_url ) def test_user_search_by_name(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'Richard' self.browser.getControl(name='form.button.Search').click() self.assertIn('Richard Ramirez', self.browser.contents) self.assertIn('Sara Richardson', self.browser.contents) self.assertIn('Émilie Richard', self.browser.contents) def test_user_search_by_name_accent(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'Émilie' self.browser.getControl(name='form.button.Search').click() self.assertIn('Émilie Richard', self.browser.contents) def test_user_search_by_id(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertIn('Autumn Brooks', self.browser.contents) def test_user_search_by_mail(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'DohPmgIa@' self.browser.getControl(name='form.button.Search').click() self.assertIn('Gracie Diaz', self.browser.contents) def test_user_show_all(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='form.button.FindAll').click() # Check that first 10 members (sorted by fullname) are shown. for member in sorted( self.members, key=lambda k: normalizeString(k['fullname']) )[:10]: self.assertIn(member['fullname'], self.browser.contents) def test_user_show_all_with_search_term(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'no-user' self.browser.getControl(name='form.button.FindAll').click() # Check that all members is shown and search term is ignored self.assertIn('Avery Cooper', self.browser.contents) def test_user_add_new_link(self): self.browser.open(self.usergroups_url) self.browser.getLink(id='add-user').click() self.assertEqual( self.browser.url, "%s/@@new-user" % self.portal_url ) def test_user_modify_roles(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() # Check that contributor role is not enabled and enable it self.assertFalse(self.browser.getControl( name='users.roles:list:records' ).getControl(value='Contributor').selected) self.browser.getControl( name='users.roles:list:records' ).getControl(value='Contributor').selected = True self.browser.getControl(name='form.button.Modify').click() # Check that contributor role is now enabled for this user self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertTrue(self.browser.getControl( name='users.roles:list:records' ).getControl(value='Contributor').selected) def test_user_delete(self): self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertIn('Autumn Brooks', self.browser.contents) # Delete user self.browser.getControl(name='delete:list').getControl( value='TWrMCLIo').selected = True self.browser.getControl(name='form.button.Modify').click() # Check that user does not exist anymore self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.assertNotIn('Autumn Brooks', self.browser.contents) def test_groups_search_by_id(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'group1' self.browser.getControl(name='form.button.Search').click() self.assertIn('Group 1', self.browser.contents) def test_groups_search_by_name(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'Group 3 accentué' self.browser.getControl(name='form.button.Search').click() self.assertIn('Group 3 accentué', self.browser.contents) def test_groups_modify_roles(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'group1' # Check that role is not selected yet and then select it and apply it. form = self.browser.getForm(id='groups_search') ctrls = form._form.fields.get('group_group1:list') roles = [ctrl._value for ctrl in ctrls] expected = 'Site Administrator' self.assertIn(expected, roles) idx = roles.index(expected) self.assertFalse(ctrls[idx].checked) ctrls[idx].checked = True self.browser.getControl('Save').click() # Check that role is now selected form = self.browser.getForm(id='groups_search') ctrl = form._form.get('group_group1:list', index=idx) self.assertEqual(ctrl._value, expected) self.assertTrue(ctrl.checked) def test_groups_delete_group(self): self.browser.open(self.groups_url) self.browser.getControl(name='searchstring').value = 'group1' # Delete a group self.browser.getControl( name='delete:list' ).getControl(value='group1').selected = True self.browser.getControl(name='form.button.Modify').click() # Check that group doesn't exist anymore self.browser.getControl(name='searchstring').value = 'group1' self.assertNotIn('Group 1', self.browser.contents) def test_groups_show_all(self): self.browser.open(self.groups_url) self.browser.getControl(name='form.button.FindAll').click() for group in self.groups: self.assertIn(group['title'], self.browser.contents) def test_group_add_users(self): self.browser.open(self.groups_url) self.browser.getLink('Group 1 (group1)').click() self.assertIn( 'There is no group or user attached to this group.', self.browser.contents ) # Add user (Autumn Brooks) to selected group (Group 1) self.browser.getControl(name='searchstring').value = 'TWrMCLIo' self.browser.getControl(name='form.button.Search').click() self.browser.getControl(name='add:list').getControl( value='TWrMCLIo').selected = True # Check that user is now part of the group self.browser.getControl( 'Add selected groups and users to this group').click() self.assertIn('Autumn Brooks', self.browser.contents) def test_group_add_group(self): self.browser.open(self.groups_url) self.browser.getLink('Group 1 (group1)').click() self.assertIn( 'There is no group or user attached to this group.', self.browser.contents ) # Add group2 to selected group 1 self.browser.getControl(name='searchstring').value = 'group2' self.browser.getControl(name='form.button.Search').click() self.browser.getControl(name='add:list').getControl( value='group2').selected = True # Check that group is now part of the group self.browser.getControl( 'Add selected groups and users to this group').click() self.assertIn('Group 2', self.browser.contents) def test_usergroups_settings_many_users(self): self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.many_users:list' ).controls[0].selected = True self.browser.getControl('Save').click() # Check that show all button for users is no longer available self.browser.open(self.usergroups_url) self.assertNotIn('Show all', self.browser.contents) # Check that empty search does not trigger show all self.browser.open(self.usergroups_url) self.browser.getControl(name='searchstring').value = '' def test_usergroups_settings_many_groups(self): self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url) self.browser.getControl( name='form.widgets.many_groups:list' ).controls[0].selected = True self.browser.getControl('Save').click() # Check that show all button for groups is no longer available self.browser.open(self.groups_url) self.assertNotIn('Show all', self.browser.contents) self.assertNotIn('DIispfuF', self.browser.contents)