class LeadImageBehaviorFunctionalTest(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('leadimagefolder')
        self.portal.portal_types._setObject('leadimagefolder', fti)
        fti.klass = 'plone.dexterity.content.Container'
        fti.behaviors = (
            'plone.app.contenttypes.behaviors.leadimage.ILeadImage', )
        self.fti = fti
        alsoProvides(self.portal.REQUEST, IPloneAppContenttypesLayer)
        alsoProvides(self.request, IPloneAppContenttypesLayer)
        from plone.app.contenttypes.behaviors.leadimage import ILeadImage
        alsoProvides(self.request, ILeadImage)
        self.portal.invokeFactory('leadimagefolder',
                                  id='leadimagefolder',
                                  title=u'Folder with a lead image')
        import transaction
        transaction.commit()
        # Set up browser
        self.browser = Browser(app)
        self.browser.handleErrors = False
        self.browser.addHeader(
            'Authorization', 'Basic %s:%s' % (
                SITE_OWNER_NAME,
                SITE_OWNER_PASSWORD,
            ))

    def test_lead_image_in_edit_form(self):
        self.browser.open(self.portal_url + '/leadimagefolder/edit')
        self.assertTrue('Lead Image' in self.browser.contents)
        self.assertTrue('Lead Image Caption' in self.browser.contents)

    def test_lead_image_viewlet_shows_up(self):
        self.browser.open(self.portal_url + '/leadimagefolder/edit')
        # Image upload
        file_path = os.path.join(os.path.dirname(__file__), "image.jpg")
        file_ctl = self.browser.getControl(
            name='form.widgets.ILeadImage.image')
        file_ctl.add_file(open(file_path), 'image/png', 'image.jpg')
        # Image caption
        self.browser.getControl(name='form.widgets.ILeadImage.image_caption'
                                ).value = 'My image caption'
        # Submit form
        self.browser.getControl('Save').click()

        self.assertTrue('My image caption' in self.browser.contents)
        self.assertTrue('image.jpg' in self.browser.contents)

        self.assertTrue('<div class="leadImage">' in self.browser.contents)

        # But doesn't show up on folder_contents, which is not a default view
        self.browser.open(self.portal_url + '/leadimagefolder/folder_contents')
        self.assertTrue('<div class="leadImage">' not in self.browser.contents)
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/plone_control_panel" % 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("Plone Configuration" 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.assertEqual(self.browser.url,
                         'http://nohost/plone/@@overview-controlpanel')

    def test_search_controlpanel_view(self):
        view = getMultiAdapter((self.portal, self.portal.REQUEST),
                               name="search-controlpanel")
        view = view.__of__(self.portal)
        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)
示例#3
0
 def getBrowser(self, loggedIn=True):
     """ instantiate and return a testbrowser for convenience """
     browser = Browser(self.layer['app'])
     if loggedIn:
         browser.addHeader('Authorization', 'Basic %s:%s' % (
             TEST_USER_NAME, TEST_USER_PASSWORD))
     return browser
示例#4
0
 def getBrowser(self, loggedIn=True):
     """ instantiate and return a testbrowser for convenience """
     browser = Browser(self.layer['app'])
     if loggedIn:
         auth = 'Basic {0}'.format(self.getCredentials())
         browser.addHeader('Authorization', auth)
     return browser
示例#5
0
class TestNewsletterView(unittest.TestCase):

    layer = COLLECTIVE_MAILCHIMP_INTEGRATION_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),
        )

    def test_empty_form(self):
        self.browser.open("%s/newsletter" % self.portal_url)
        self.browser.getControl(name="form.buttons.subscribe").click()
        self.assertTrue("Required input is missing." in self.browser.contents)

    def test_form_with_invalid_email_address(self):
        self.browser.open("%s/newsletter" % self.portal_url)
        self.browser.getControl(name="form.widgets.email").value = \
            "Not an email address"
        self.browser.getControl(name="form.buttons.subscribe").click()
        self.assertTrue("Invalid email address" in self.browser.contents)
示例#6
0
class FileFunctionalTest(unittest.TestCase):

    layer = 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,
            ))

    def test_alternative_mime_icon_doc_for_file(self):
        self.browser.open(self.portal_url)
        self.browser.getLink('File').click()

        self.browser.getControl(name='form.widgets.title')\
            .value = "My file"
        self.browser.getControl(name='form.widgets.description')\
            .value = "This is my doc file."
        file_path = os.path.join(os.path.dirname(__file__), "file.doc")
        file_ctl = self.browser.getControl(name='form.widgets.file')
        file_ctl.add_file(open(file_path), 'application/msword', 'file.doc')
        self.browser.getControl('Save').click()
        self.assertTrue(self.browser.url.endswith('file.doc/view'))
        self.assertTrue('http://www.testurl02.com/' in self.browser.contents)
示例#7
0
    def test_navroot_params_on_404_widget_in_path(self):
        app = self.layer['app']
        portal = self.layer['portal']
        setRoles(portal, TEST_USER_ID, ['Contributor'])
        portal.invokeFactory('Folder', 'subfolder')

        self.settings.enabled = True
        self.settings.parameterExpressions = {
            'navigation_root_id': 'python:portal_state.navigation_root().getId()'  # noqa
        }

        transaction.commit()

        browser = Browser(app)
        browser.addHeader('Accept', 'text/html')
        error = None
        try:
            browser.open(
                '{0:s}/widget/oauth_login/info.txt'.format(
                    portal['subfolder'].absolute_url()
                )
            )
        except HTTPError as e:
            error = e
        self.assertEqual(error.code, 404)

        self.assertTrue("This is the theme" in browser.contents)
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 %s:%s' % (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.assertTrue('Title' in self.browser.contents)
        self.assertTrue('Description' in self.browser.contents)
        self.assertTrue('Text' in self.browser.contents)
        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.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)
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.IRichText.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)
示例#10
0
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().submit()
        self.assertEquals(
            self.browser.url,
            '%s/acl_users/users/manage_users?manage_tabs_message=password+updated'
            % (self.layer['app'].absolute_url()))
示例#11
0
    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 {0}:{1}'.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
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)
示例#13
0
class TestBlogEntry(TestCase):

    layer = FTW_BLOG_FUNCTIONAL_TESTING

    def setUp(self):
        super(TestBlogEntry, self).setUp()

        self.browser = Browser(self.layer['app'])
        self.browser.handleErrors = False
        self.browser.addHeader(
            'Authorization', 'Basic %s:%s' % (
                TEST_USER_NAME,
                TEST_USER_PASSWORD,
            ))

        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        self.blog = self.portal.get(self.portal.invokeFactory('Blog', 'blog'))
        transaction.commit()

    def test_add_blog_entry(self):
        self.browser.open("%s/createObject?type_name=BlogEntry" %
                          self.blog.absolute_url())
        self.browser.getControl(name='title').value = 'Blog Entry'
        self.browser.getControl(name='form.button.save').click()

        self.assertEquals(len(self.blog.objectIds()), 1,
                          'Expect one blog entry')

        doc = PyQuery(self.browser.contents)
        self.assertEquals(
            doc('.documentFirstHeading').text(), 'Blog Entry',
            'Wrong title found')
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)
示例#15
0
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.assertEqual(self.browser.url,
                         'http://nohost/plone/@@overview-controlpanel')

    def test_markup_controlpanel_view(self):
        view = getMultiAdapter((self.portal, self.portal.REQUEST),
                               name="markup-controlpanel")
        view = view.__of__(self.portal)
        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'))
示例#16
0
 def getBrowser(self, loggedIn=True):
     """ instantiate and return a testbrowser for convenience """
     browser = Browser(self.layer['app'])
     if loggedIn:
         browser.addHeader('Authorization', 'Basic %s:%s' % (
             TEST_USER_NAME, TEST_USER_PASSWORD))
     return browser
示例#17
0
class PortletsFunctionalTestCase(unittest.TestCase, Functional):
    """Base class for functional integration tests for plone.app.portlets.
    This may provide specific set-up and tear-down operations, or provide
    convenience methods.
    """

    layer = PLONE_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()
        self.browser = Browser(self.app)
        self.browser.handleErrors = True
        self.app.acl_users.userFolderAddUser('app', 'secret', ['Manager'], [])
        from plone.testing import z2
        z2.login(self.app['acl_users'], 'app')

        import transaction
        transaction.commit()
        self.site_administrator_browser = Browser(self.app)
        self.site_administrator_browser.handleErrors = False
        self.site_administrator_browser.addHeader(
            'Authorization',
            'Basic %s:%s' % ('app', 'secret')
        )
    class TestEmptyLayoutBug(CMFDVFTITestCase.CMFDVFTITestCase):
        # Finally, here is why we did all this...

        def setUp(self):
            super(TestEmptyLayoutBug, self).setUp()
            # Make a DynFolder
            self.folder.invokeFactory('DynFolder', id='dynfolder')
            self.dynfolder = self.folder.dynfolder
            self.dynfolder.layout = ''  # Empty layout triggers bug
            self.dynfolder_path = self.dynfolder.absolute_url(1)

            # Make a DynDocument
            self.folder.invokeFactory('DynDocument', id='dyndocument')
            self.dyndocument = self.folder.dyndocument
            self.dyndocument.layout = ''  # Empty layout triggers bug
            self.dyndocument_path = self.dyndocument.absolute_url(1)
            import transaction
            transaction.commit()
            from plone.testing.z2 import Browser
            self.browser = Browser(self.layer['app'])
            self.browser.handleErrors = False
            self.browser.addHeader(
                'Authorization', 'Basic %s:%s' %
                (TEST_USER_NAME, TEST_USER_PASSWORD,)
            )

        def test_FolderEmptyLayoutBug(self):
            self.browser.open(self.dynfolder.absolute_url() + '/view')
            self.assertEqual(self.browser._response.status_code, 200)

        def test_DocumentEmptyLayoutBug(self):
            self.browser.open(self.dyndocument.absolute_url() + '/view')
            self.assertEqual(self.browser._response.status_code, 200)
class AuthenticatedTestCase(unittest.TestCase):
    """Teste funcionais com usuário autenticado"""

    layer = FUNCTIONAL_TESTING

    def setUp(self):
        Globals.DevelopmentMode = True
        self.portal = self.layer['portal']
        registry = getUtility(IRegistry)
        self.settings = registry.forInterface(IThemeSettings)  # noqa: P001
        self.browser = Browser(self.layer['app'])
        self.login_browser()
        import transaction
        transaction.commit()

    def login_browser(self):
        """Autentica usuário de teste no browser"""
        self.browser.handleErrors = False
        basic_auth = 'Basic {0}'.format(
            '{0}:{1}'.format(SITE_OWNER_NAME, SITE_OWNER_PASSWORD),
        )
        self.browser.addHeader('Authorization', basic_auth)

    def base_test(self, cor):
        """Teste base dos temas"""
        theme = getTheme(cor)
        applyTheme(theme)
        self.settings.enabled = True
        import transaction
        transaction.commit()

        # Testa se elementos do dashboard aparecem.
        self.browser.open('{0}/dashboard'.format(self.portal.absolute_url()))
        self.assertIn('id="kssPortalMessage"', self.browser.contents)
        self.assertIn('dashboard</h1>', self.browser.contents)

        # Testa se elementos da 'Informação Pessoal' aparecem.
        self.browser.open('{0}/@@user-information?userid=admin'.format(
            self.portal.absolute_url()))
        self.assertIn('id="kssPortalMessage"', self. browser.contents)
        self.assertIn('Change your personal information',
                      self.browser.contents)

        # Testa se elementos da 'Preferências Pessoais' aparecem.
        self.browser.open('{0}/@@user-preferences?userid=admin'.format(
            self.portal.absolute_url()))
        self.assertIn('id="kssPortalMessage"', self.browser.contents)
        self.assertIn('Your personal settings', self.browser.contents)

    def test_tema_verde_autenticado(self):
        self.base_test('verde')

    def test_tema_amarelo_autenticado(self):
        self.base_test('amarelo')

    def test_tema_branco_autenticado(self):
        self.base_test('branco')

    def test_tema_azul_autenticado(self):
        self.base_test('azul')
示例#20
0
class TestEditing(unittest.TestCase):
    """Test Taxonomy Editing"""

    layer = FUNCTIONAL_TESTING

    def setUp(self):
        self.portal = self.layer['portal']
        self.document = api.content.create(container=self.portal,
                                           type='Document',
                                           title='Doc')
        self.browser = Browser(self.layer['app'])
        self.browser.handleErrors = False
        self.browser.addHeader(
            'Authorization', 'Basic {0}:{1}'.format(SITE_OWNER_NAME,
                                                    SITE_OWNER_PASSWORD))
        commit()

    def test_edit_doc(self):
        self.browser.open(self.portal.absolute_url() + '/doc/edit')

        # check for editing buttons
        self.assertIn('name="form.widgets.test.taxonomy_test.from"',
                      self.browser.contents)
        self.assertIn('name="form.widgets.test.taxonomy_test.to"',
                      self.browser.contents)
        self.assertIn('name="from2toButton"', self.browser.contents)
        self.assertIn('name="to2fromButton"', self.browser.contents)
        self.assertIn('name="moveUpButton"', self.browser.contents)
        self.assertIn('name="moveDownButton"', self.browser.contents)

        tax_from = self.browser.getControl(
            name='form.widgets.test.taxonomy_test.from')
        self.assertEqual(tax_from.options, ['1', '2', '3', '5'])
    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 {0}:{1}'.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_last_modified_no_etags(self):
        """
        When a new content type is added, the resulting page should not be
        cached since it has messages. However, it should only trigger an etag
        if its been configured to use etags
        """
        # Add folder content
        setRoles(self.portal, TEST_USER_ID, ('Manager',))
        self.portal.invokeFactory('Folder', 'f1')
        self.portal['f1'].title = u"Folder one"
        self.portal['f1'].description = u"Folder one description"
        self.portal['f1'].reindexObject()

        self.cacheSettings.operationMapping = {'plone.content.itemView': 'plone.app.caching.weakCaching'}
        self.registry['plone.app.caching.weakCaching.lastModified'] = True
        self.registry['plone.app.caching.weakCaching.etags'] = None

        import transaction; transaction.commit()

        # log in and create a content type
        browser = Browser(self.app)
        browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
        browser.open("%s/++add++Document" % self.portal['f1'].absolute_url())
        browser.getControl(name='form.widgets.IDublinCore.title').value="dummy content"
        browser.getControl('Save').click()
        self.assertFalse('Etag' in browser.headers)

        # now set up etags and make sure that a header is added
        self.registry['plone.app.caching.weakCaching.etags'] = ('lastModified',)
        import transaction; transaction.commit()
        browser.open("%s/dummy-content/edit"%self.portal['f1'].absolute_url())
        browser.getControl(name='form.widgets.IDublinCore.title').value="dummy content"
        browser.getControl('Save').click()
        self.assertTrue('Etag' in browser.headers)
示例#23
0
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):
        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_barsview_mini(self):

        app = self.layer['app']
        portal = self.layer['portal']
       
        browser = Browser(app)
        browser.handleErrors = False
        browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
        
        import transaction
        transaction.commit()
        page = portal.absolute_url() + '/orgnizationfolder1/@@barsview_mini'        
        url1 = portal.absolute_url() + '/orgnizationfolder1/orgnization1'
        isrc1 = portal.absolute_url() + '/orgnizationfolder1/orgnization1' + "/@@images/image/mini"
        title1= "Gif image" 
        url2 = portal.absolute_url() + '/orgnizationfolder1/orgnization2'
        isrc2 = portal.absolute_url() + '/orgnizationfolder1/orgnization2' + "/@@images/image/mini"
        title2= "Jpeg image"  
        url3 = portal.absolute_url() + '/orgnizationfolder1/orgnization3'
        isrc3 = portal.absolute_url() + '/orgnizationfolder1/orgnization3' + "/@@images/image/mini"
        title3= "Png image"                
        browser.open(page)
        lookstr1 = '<div class="banner"><a href="%s"><img src="%s" alt="%s" /></a></div>' % (url1,isrc1,title1)
        lookstr2 = '<div class="banner"><a href="%s"><img src="%s" alt="%s" /></a></div>' % (url2,isrc2,title2) 
        lookstr3 = '<div class="banner"><a href="%s"><img src="%s" alt="%s" /></a></div>' % (url3,isrc3,title3)                
#        import pdb
#        pdb.set_trace()


        self.assertTrue(lookstr1 in browser.contents)  
        self.assertTrue(lookstr2 in browser.contents) 
        self.assertTrue(lookstr3 in browser.contents)                           
示例#25
0
    def test_redirect_to_uuid_invalid_uuid(self):
        from mechanize import HTTPError

        portal = self.layer['portal']
        app = self.layer['app']

        setRoles(portal, TEST_USER_ID, ['Manager'])

        portal.invokeFactory('Document', 'd1')
        portal.invokeFactory('Document', 'd2')

        import transaction
        transaction.commit()

        from plone.testing.z2 import Browser
        browser = Browser(app)
        browser.addHeader(
            'Authorization',
            'Basic {0}:{1}'.format(TEST_USER_ID, TEST_USER_PASSWORD, )
        )

        try:
            url = '{0}/@@redirect-to-uuid/gibberish'
            browser.open(url.format(portal.absolute_url()))
            self.fail('No error raised')
        except HTTPError, e:
            self.assertEqual(e.code, 404)
示例#26
0
    def test_uuid_view(self):

        from plone.uuid.interfaces import IUUID

        portal = self.layer['portal']
        app = self.layer['app']

        setRoles(portal, TEST_USER_ID, ['Manager'])

        portal.invokeFactory('Document', 'd1')

        d1 = portal['d1']
        uuid = IUUID(d1)

        import transaction
        transaction.commit()

        from plone.testing.z2 import Browser
        browser = Browser(app)
        browser.addHeader(
            'Authorization',
            'Basic {0}:{1}'.format(TEST_USER_ID, TEST_USER_PASSWORD, )
        )

        browser.open('{0}/@@uuid'.format(d1.absolute_url()))
        self.assertEqual(uuid, browser.contents)
示例#27
0
class ReviewListTestCase(PloneTestCase):
    """dsfsdaf"""

    def afterSetUp(self):
        self.uf = self.portal.acl_users
        self.uf.userFolderAddUser('reviewer', 'secret', ['Reviewer'], [])
        transaction.commit()
        self.browser = Browser(self.layer['app'])
        self.wftool = getToolByName(self.portal, 'portal_workflow')

    def createDocument(self, id, title, description):
        self.setRoles(['Manager', ])
        self.portal.invokeFactory(id=id, type_name='Document')
        doc = getattr(self.portal, id)
        doc.setTitle(title)
        doc.setDescription(description)
        # we don't want it in the navigation
        doc.setExcludeFromNav(True)
        doc.reindexObject()
        transaction.commit()
        return doc

    def submitToReview(self, obj):
        '''call the workflow action 'submit' for an object'''
        self.wftool.doActionFor(obj, 'submit')

    def test_unauthenticated(self):
        '''
        unauthenticated users do not have the necessary permissions to view
        the review list
        '''
        self.browser.open('http://nohost/plone/full_review_list')
        self.assertTrue('Login Name' in self.browser.contents)

    def test_authenticated(self):
        '''
        unauthenticated users do not have the necessary permissions to view
        the review list
        '''
        self.browser.addHeader('Authorization',
                               'Basic %s:%s' % ('reviewer', 'secret'))
        self.browser.open('http://nohost/plone/full_review_list')
        self.assertTrue('Full review list:' in self.browser.contents)

    def test_with_content(self):
        '''
        unauthenticated users do not have the necessary permissions to view
        the review list
        '''
        doc = self.createDocument(
            'testdoc', 'Test Document', 'Test Description')
        self.wftool.doActionFor(doc, 'submit')
        transaction.commit()

        self.browser.addHeader('Authorization',
                               'Basic %s:%s' % ('reviewer', 'secret'))
        self.browser.open('http://nohost/plone/full_review_list')
        self.assertTrue('Full review list:' in self.browser.contents)
        # test if the table with review items contains an entry for testdoc
        self.assertTrue('value="/plone/testdoc"' in self.browser.contents)
示例#28
0
    def testquestion(self):
        app = self.layer['app']        
        portal = self.layer['portal']
        
        browser = Browser(app)
        browser.handleErrors = False
        
        browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
        import transaction
        transaction.commit()
        
        ques = portal['questionfolder']['question'].absolute_url()
        browser.open(ques)
        
        browser.getControl(name='form.submit').click()
        
        open('/tmp/test.html','w').write(browser.contents)
        
        self.assertTrue("question" in browser.contents)
        self.assertTrue("question description" in browser.contents)
        
        self.assertTrue("4" in browser.contents)

        self.assertTrue("test_user_1_" in browser.contents)
        self.assertTrue("defaultUser.png" in browser.contents)
        
        self.assertTrue("answerone" in browser.contents)
        
        self.assertTrue("answertwo" in browser.contents)
        self.assertTrue("answerthree" in browser.contents)
        self.assertTrue("add an answer" in browser.contents)
示例#29
0
class FileFunctionalTest(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,)
        )

    def test_add_pyfile(self):
        self.browser.open(self.portal_url)

        self.browser.getLink('CodeFile').click()
        self.browser.getControl(name='form.widgets.title')\
            .value = "My file"
        self.browser.getControl(name='form.widgets.description')\
            .value = "This is my file."
        file_path = os.path.join(os.path.dirname(__file__), "temp.py")
        file_ctl = self.browser.getControl(name='form.widgets.file')
        file_ctl.add_file(open(file_path), 'image/png', 'temp.py')
        self.browser.getControl('Save').click()
        self.assertTrue(self.browser.url.endswith('temp.py/view'))
        self.assertTrue('My file' in self.browser.contents)
        self.assertTrue('This is my file' in self.browser.contents)
示例#30
0
    def _workplace_inline_link_test(self, id_, label):
        browser = Browser(self.layer['app'])
        browser.handleErrors = False
        browser.addHeader('Authorization', 'Basic %s:%s' % (
                SITE_OWNER_NAME, SITE_OWNER_PASSWORD))

        portal_url = self.layer['portal'].portal_url()
        browser.open('/'.join((portal_url, self.translated('workplace'))))
        doc = PyQuery(browser.contents)

        links = doc('#content .sl-text-wrapper a')
        filtered_links = filter(
            lambda node: node.text_content() == label,
            links)

        self.assertEquals(
            len(filtered_links),
            1,
            'Expected one link "%s", but found: %s' % (
                label,
                str(map(lambda node: node.text_content(), filtered_links))))

        self.assertEquals(
            '/'.join((browser.url, id_)),
            filtered_links[0].get('href'),
            'Link "%s" seems to point to a wrong place.' % filtered_links[0].text_content())
class PAMFuncTestHelperViews(unittest.TestCase):

    layer = PAM_FUNCTIONAL_TESTING

    def setUp(self):
        self.portal = self.layer['portal']
        self.request = self.layer['request']
        alsoProvides(self.layer['request'], IPloneAppMultilingualInstalled)
        self.browser = Browser(self.layer['app'])
        self.browser.handleErrors = False
        self.browser.addHeader('Authorization',
                               'Basic %s:%s' % (TEST_USER_NAME,
                                                TEST_USER_PASSWORD))
        self.settings = getUtility(IRegistry).forInterface(
            ILanguageSchema,
            prefix='plone')

    def test_universal_link_view(self):
        self.settings.use_request_negotiation = True
        self.browser.addHeader('Accept-Language', 'ca')

        a_ca = createContentInContainer(
            self.portal['ca'], 'Document', title=u"Test document")
        a_en = api.translate(a_ca, 'en')
        api.translate(a_ca, 'es')

        transaction.commit()

        self.browser.open(a_en.absolute_url())
        self.browser.getLink("Universal link").click()
        self.assertEqual(self.browser.url, a_ca.absolute_url())
class TestAngularJsPortletNavigationFunctional(unittest.TestCase):

    layer = PLONE_APP_ANGULARJS_FUNCTIONAL_TESTING

    def setUp(self):
        self.app = self.layer["app"]
        self.portal = self.layer["portal"]
        self.request = self.layer["request"]
        from plone.testing.z2 import Browser
        from plone.app.testing import SITE_OWNER_NAME
        from plone.app.testing import SITE_OWNER_PASSWORD

        self.portal_url = self.portal.absolute_url()
        setRoles(self.portal, TEST_USER_ID, ["Manager"])
        self.browser = Browser(self.app)
        self.browser.handleErrors = False
        self.browser.addHeader("Authorization", "Basic %s:%s" % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD))

    def test_api_navigation_nested(self):
        self.portal.invokeFactory("Folder", "news", title="News")
        self.portal.news.invokeFactory("Folder", "news1", title="News 1")
        import transaction

        transaction.commit()
        self.browser.open(self.portal_url + "/++api++v1/portlet_navigation?path=/news/news1")
        output = json.loads(self.browser.contents)
        self.assertEqual(output[0]["id"], u"news")
        self.assertEqual(output[0]["children"][0]["id"], u"news1")
示例#33
0
 def getBrowser(self, loggedIn=True):
     """ instantiate and return a testbrowser for convenience """
     browser = Browser(self.layer['app'])
     if loggedIn:
         auth = 'Basic %s' % self.getCredentials()
         browser.addHeader('Authorization', auth)
     return browser
示例#34
0
 def test_navigate_save(self):
     from zope.component import getUtility
     from plone.registry.interfaces import IRegistry
     from my315ok.products.interfaces import IMy315okProductsSettings
     
     app = self.layer['app']
     portal = self.layer['portal']
     
     browser = Browser(app)
     browser.handleErrors = False
     
     # Simulate HTTP Basic authentication
     browser.addHeader('Authorization',
             'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,)
         )
     
     # Open Plone's site setup
     browser.open("%s/plone_control_panel" % portal.absolute_url())
     
     # Go to the control panel
     browser.getLink('My315okProducts settings').click()
     
     # Edit the DAM codes field
     browser.getControl(name='form.widgets.wordsNum').value = "32"
     browser.getControl('Save').click()
     
     # Verify that this made it into the registry
     registry = getUtility(IRegistry)
     settings = registry.forInterface(IMy315okProductsSettings)
     self.assertEqual(settings.wordsNum,32)
示例#35
0
class PortletsFunctionalTestCase(unittest.TestCase, Functional):
    """Base class for functional integration tests for plone.app.portlets.
    This may provide specific set-up and tear-down operations, or provide
    convenience methods.
    """

    layer = PLONE_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()
        self.browser = Browser(self.app)
        self.browser.handleErrors = True
        self.app.acl_users.userFolderAddUser('app', 'secret', ['Manager'], [])
        from plone.testing import z2
        z2.login(self.app['acl_users'], 'app')

        import transaction
        transaction.commit()
        self.site_administrator_browser = Browser(self.app)
        self.site_administrator_browser.handleErrors = False
        self.site_administrator_browser.addHeader(
            'Authorization',
            'Basic %s:%s' % ('app', 'secret')
        )
class TestNewsletterView(unittest.TestCase):

    layer = COLLECTIVE_MAILCHIMP_INTEGRATION_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),
        )

    def test_empty_form(self):
        self.browser.open("%s/newsletter" % self.portal_url)
        self.browser.getControl(name="form.buttons.subscribe").click()
        self.assertTrue("Required input is missing." in self.browser.contents)

    def test_form_with_invalid_email_address(self):
        self.browser.open("%s/newsletter" % self.portal_url)
        self.browser.getControl(name="form.widgets.email").value = \
            "Not an email address"
        self.browser.getControl(name="form.buttons.subscribe").click()
        self.assertTrue("Invalid email address" in self.browser.contents)
class TestInvitation(TestCase):

    layer = FTW_PARTICIPATION_FUNCTIONAL_TESTING

    def setUp(self):
        super(TestInvitation, self).setUp()

        self.portal = self.layer['portal']
        self.portal_url = self.portal.portal_url()

        self.demo_folder = self.portal.get(self.portal.invokeFactory(
            'Folder', 'demo-folder'))
        transaction.commit()

        self.browser = Browser(self.layer['app'])
        self.browser.handleErrors = False

    def test_userid_differ_userlogin(self):
        member = self.portal.portal_membership.getMemberById(TEST_USER_ID_2)
        member.setMemberProperties({'email':'*****@*****.**'})
        inv1 = Invitation(target=self.demo_folder, email='*****@*****.**', inviter='admin',
                          roles=['Reader'])
        url = '%s/@@invitations?iid=%s' % (self.portal_url, inv1.iid)
        transaction.commit()
        self.browser.addHeader('Authorization', 'Basic %s:%s' % (
            TEST_USER_ID_2, TEST_USER_PW_2, ))

        self.browser.open(url)
        self.assertIn('Invitations', self.browser.contents)
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)
    def test_outbox(self):
        browser = Browser(self.app)
        browser.handleErrors = False
        browser.addHeader('Authorization', 'Basic %s:%s' % ('fromer', 'secret',))

        portalURL = self.portal.absolute_url()
        browser.open(portalURL)
        self.assertIn('fromer', browser.contents)
        
        browser.open(portalURL+'/@@my_mailbox')

        self.assertIn('*****@*****.**', browser.contents)
        self.assertIn('*****@*****.**', browser.contents)
        self.assertIn('Test subject 1', browser.contents)
        self.assertIn('This is a mail body.', browser.contents)
        self.assertIn('Test subject 2', browser.contents)        
        self.assertIn('The body\nof the mail.', browser.contents)
        
        self.assertNotIn('*****@*****.**', browser.contents)

        browser = Browser(self.app)
        browser.handleErrors = False
        browser.addHeader('Authorization', 'Basic %s:%s' % ('toer', 'secret',))
        browser.open(portalURL+'/@@my_mailbox')
        self.assertIn('*****@*****.**', browser.contents)
        
示例#40
0
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 %s:%s' % (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('Save').click()

        self.assertTrue(self.browser.url.endswith('my-link/view'))
        self.assertTrue('My link' in self.browser.contents)
        self.assertTrue('This is my link' in self.browser.contents)
示例#41
0
class BaseTestCase(unittest.TestCase):

    def setUp(self):
        self.portal = self.layer['portal']
        self.request = self.layer['request']
        alsoProvides(self.request, IFormLayer)

        transaction.commit()

        # Get a testbrowser
        self.browser = Browser(self.layer['app'])
        self.browser.handleErrors = False
        self.browser.addHeader('Referer', self.portal.absolute_url())
        self.browser.addHeader(
            'Authorization',
            'Basic {0:s}:{1:s}'.format(TEST_USER_NAME, TEST_USER_PASSWORD))

        # Do an initial page load to make sure the bundles get compiled
        # (which currently commits a transaction)
        # before we render exception views
        self.browser.open(self.portal.absolute_url())

        setRoles(self.portal, TEST_USER_ID, ['Manager', ])

    def _get_token(self, obj):
        return getMultiAdapter(
            (obj, self.request), name='authenticator').token()
    def test_view(self):

        app = self.layer["app"]
        portal = self.layer["portal"]

        browser = Browser(app)
        browser.handleErrors = False
        browser.addHeader("Authorization", "Basic %s:%s" % (TEST_USER_ID, TEST_USER_PASSWORD))

        import transaction

        transaction.commit()

        page = portal.absolute_url() + "/marketfolder1/marketpreview"
        browser.open(page)
        open("/tmp/test.html", "w").write(browser.contents)
        # 我申请的会议
        self.assertTrue("meetapply1" in browser.contents)

        # 我申请的礼品
        self.assertTrue("gift1" in browser.contents)
        # 我申请的彩页
        self.assertTrue("promotion1" in browser.contents)
        # 部门费用
        self.assertTrue("3" in browser.contents)
        self.assertTrue("15000" in browser.contents)
        # 地区拓展费用
        self.assertTrue("爱数" in browser.contents)
        self.assertTrue("1000.0" in browser.contents)
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 %s:%s' % (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()
        self.browser.getControl(name='form.widgets.IDublinCore.title')\
            .value = "My folder"
        self.browser.getControl(name='form.widgets.IDublinCore.description')\
            .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)
示例#44
0
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.IRichText',)
    _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 %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,)
        )

    def test_richtext_in_edit_form(self):
        self.browser.open(self.portal_url + '/doc1/edit')
        self.assertTrue('mce_editable' in self.browser.contents)

    def test_richtext_behavior(self):
        IRichText.providedBy(self.portal.doc1)
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()
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        fti = DexterityFTI('leadimagedocument')
        self.portal.portal_types._setObject('leadimagedocument', fti)
        fti.klass = 'plone.dexterity.content.Item'
        fti.behaviors = (
            'plone.app.contenttypes.behaviors.leadimage.ILeadImage',
        )
        self.fti = fti
        alsoProvides(self.portal.REQUEST, IPloneAppContenttypesLayer)
        alsoProvides(self.request, IPloneAppContenttypesLayer)
        from plone.app.contenttypes.behaviors.leadimage import ILeadImage
        alsoProvides(self.request, ILeadImage)
        self.portal.invokeFactory(
            'leadimagedocument',
            id='leadimagedoc',
            title=u'Document with a lead image'
        )
        import transaction
        transaction.commit()
        # Set up browser
        self.browser = Browser(app)
        self.browser.handleErrors = False
        self.browser.addHeader(
            'Authorization',
            'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,)
        )

    def test_lead_image_in_edit_form(self):
        self.browser.open(self.portal_url + '/leadimagedoc/edit')
        self.assertTrue('Lead Image' in self.browser.contents)
        self.assertTrue('Lead Image Caption' in self.browser.contents)

    def test_lead_image_viewlet_shows_up(self):
        self.browser.open(self.portal_url + '/leadimagedoc/edit')
        # Image upload
        file_path = os.path.join(os.path.dirname(__file__), "image.jpg")
        file_ctl = self.browser.getControl(
            name='form.widgets.ILeadImage.image'
        )
        file_ctl.add_file(open(file_path), 'image/png', 'image.jpg')
        # Image caption
        self.browser.getControl(
            name='form.widgets.ILeadImage.image_caption'
        ).value = 'My image caption'
        # Submit form
        self.browser.getControl('Save').click()

        self.assertTrue('My image caption' in self.browser.contents)
        self.assertTrue('image.jpg' in self.browser.contents)

        self.assertTrue('<div class="leadImage">' in self.browser.contents)
示例#46
0
    def test_navroot_params_on_404_widget_in_path(self):
        app = self.layer['app']
        portal = self.layer['portal']
        setRoles(portal, TEST_USER_ID, ['Contributor'])
        portal.invokeFactory('Folder', 'subfolder')

        self.settings.enabled = True
        self.settings.parameterExpressions = {
            'navigation_root_id':
            'python:portal_state.navigation_root().getId()'  # noqa
        }

        transaction.commit()

        browser = Browser(app)
        browser.addHeader('Accept', 'text/html')
        error = None
        try:
            browser.open('{0:s}/widget/oauth_login/info.txt'.format(
                portal['subfolder'].absolute_url()))
        except HTTPError as e:
            error = e
        self.assertEqual(error.code, 404)

        self.assertTrue("This is the theme" in browser.contents)
class RSSTileTest(TestCase):
    layer = COLLECTIVE_TILES_RSSMIXER_FUNCTIONAL_TESTING

    def setUp(self):
        self.portal = self.layer['portal']
        self.portalURL = self.portal.absolute_url()

        self.browser = Browser(self.layer['app'])
        self.browser.handleErrors = False
        self.browser.addHeader(
            'Authorization',
            'Basic {0}:{1}'.format(TEST_USER_NAME, TEST_USER_PASSWORD),
        )

        self.unprivileged_browser = Browser(self.layer['app'])
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        dirname = os.path.dirname(test_dir.__file__)
        self.foo = 'file://{0}'.format(os.path.join(dirname, 'RSS-foo.xml'))
        self.bar = 'file://{0}'.format(os.path.join(dirname, 'RSS-bar.xml'))

    def test_rss_tile(self):
        """This tile shows the first five items in a RSS feed.

        """
        # Use the RSS stored in the test directory, this way we don't have an
        # external dependency.

        query = {'urls': [self.foo, '']}
        url = '{0}/@@collective.tiles.rssmixer/unique?{1}'.format(
            self.portalURL, urlencode(query, doseq=True))
        self.unprivileged_browser.open(url)

        self.assertIn('rss-mixer-tile', self.unprivileged_browser.contents)

        self.assertIn(
            '<a href="http://*****:*****@@collective.tiles.rssmixer/unique?{1}'.format(
            self.portalURL, urlencode(query, doseq=True))
        self.unprivileged_browser.open(url)
        self.assertIn(
            '<span class="feed-source">bar</span>',
            self.unprivileged_browser.contents,
        )
        self.assertIn(
            '<span class="feed-source">foo</span>',
            self.unprivileged_browser.contents,
        )
class AuthenticatedTestCase(unittest.TestCase):
    """Teste funcionais com usuário autenticado"""

    layer = FUNCTIONAL_TESTING

    def setUp(self):
        Globals.DevelopmentMode = True
        self.portal = self.layer['portal']
        self.settings = getUtility(IRegistry).forInterface(IThemeSettings)
        self.browser = Browser(self.layer['app'])
        self.login_browser()
        import transaction
        transaction.commit()

    def login_browser(self):
        """Autentica usuário de teste no browser"""
        self.browser.handleErrors = False
        basic_auth = 'Basic {0}'.format(
            '{0}:{1}'.format(SITE_OWNER_NAME, SITE_OWNER_PASSWORD)
        )
        self.browser.addHeader('Authorization', basic_auth)

    def base_test(self, cor):
        """Teste base dos temas"""
        theme = getTheme(cor)
        applyTheme(theme)
        self.settings.enabled = True
        import transaction
        transaction.commit()

        # Testa se elementos do dashboard aparecem.
        self.browser.open('{0}/dashboard'.format(self.portal.absolute_url()))
        self.assertIn('id="kssPortalMessage"', self.browser.contents)
        self.assertIn('dashboard</h1>', self.browser.contents)

        # Testa se elementos da 'Informação Pessoal' aparecem.
        self.browser.open('{0}/@@user-information?userid=admin'.format(
            self.portal.absolute_url()))
        self.assertIn('id="kssPortalMessage"', self. browser.contents)
        self.assertIn('Change your personal information',
                      self.browser.contents)

        # Testa se elementos da 'Preferências Pessoais' aparecem.
        self.browser.open('{0}/@@user-preferences?userid=admin'.format(
            self.portal.absolute_url()))
        self.assertIn('id="kssPortalMessage"', self.browser.contents)
        self.assertIn('Your personal settings', self.browser.contents)

    def test_tema_verde_autenticado(self):
        self.base_test('verde')

    def test_tema_amarelo_autenticado(self):
        self.base_test('amarelo')

    def test_tema_branco_autenticado(self):
        self.base_test('branco')

    def test_tema_azul_autenticado(self):
        self.base_test('azul')
    def test_resources(self):

        import transaction
        transaction.commit()

        # Request a skin image
        now = stable_now()
        browser = Browser(self.app)
        browser.open(self.portal.absolute_url() + '/rss.png')
        self.assertEqual('plone.resource', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.strongCaching',
                         browser.headers['X-Cache-Operation'])
        # This should use cacheInBrowserAndProxy
        self.assertEqual('max-age=86400, proxy-revalidate, public',
                         browser.headers['Cache-Control'])
        # remove this when the next line works
        self.assertIsNotNone(browser.headers.get('Last-Modified'))
        timedelta = dateutil.parser.parse(browser.headers['Expires']) - now
        self.assertGreater(timedelta, datetime.timedelta(seconds=86390))

        # Request the skin image again -- with an IMS header to test 304
        lastmodified = browser.headers['Last-Modified']
        browser = Browser(self.app)
        browser.raiseHttpErrors = False
        browser.addHeader('If-Modified-Since', lastmodified)
        browser.open(self.portal.absolute_url() + '/rss.png')
        self.assertEqual('plone.resource', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.strongCaching',
                         browser.headers['X-Cache-Operation'])
        # This should be a 304 response
        self.assertEqual('304 Not Modified', browser.headers['Status'])
        self.assertEqual('', browser.contents)

        # Request a large datafile (over 64K) to test files that use
        # the "response.write()" function to initiate a streamed response.
        # This is of type OFS.Image.File but it should also apply to
        # large OFS.Image.Image, large non-blog ATImages/ATFiles, and
        # large Resource Registry cooked files, which all use the same
        # method to initiate a streamed response.
        s = 'a' * (1 << 16) * 3
        self.portal.manage_addFile('bigfile',
                                   file=StringIO(s),
                                   content_type='application/octet-stream')

        import transaction
        transaction.commit()

        browser = Browser(self.app)
        browser.open(self.portal['bigfile'].absolute_url())
        self.assertEqual('plone.resource', browser.headers['X-Cache-Rule'])
        self.assertEqual('plone.app.caching.strongCaching',
                         browser.headers['X-Cache-Operation'])
        # This should use cacheInBrowserAndProxy
        self.assertEqual('max-age=86400, proxy-revalidate, public',
                         browser.headers['Cache-Control'])
        # remove this when the next line works
        self.assertIsNotNone(browser.headers.get('Last-Modified'))
        timedelta = dateutil.parser.parse(browser.headers['Expires']) - now
        self.assertGreater(timedelta, datetime.timedelta(seconds=86390))
示例#50
0
    def test_project_workflow(self):
        # m/c/s/d chain
        app = self.layer['app']
        portal = self.layer['portal']

        browser = Browser(app)
        browser.handleErrors = False
        browser.addHeader(
            'Authorization', 'Basic %s:%s' % (
                TEST_USER_NAME,
                TEST_USER_PASSWORD,
            ))
        import transaction
        transaction.commit()
        page = portal['folder1']['project1'].absolute_url() + '/@@view'

        browser.open(page)
        outstr = "submit to chuyang"

        self.assertTrue(outstr in browser.contents)
        wf = getToolByName(portal, 'portal_workflow')

        wt = wf.emc_project_workflow
        dummy = portal['folder1']['project1']

        wf.notifyCreated(dummy)

        chain = wf.getChainFor(dummy)
        self.failUnless(chain[0] == 'emc_project_workflow')

        review_state = wf.getInfoFor(dummy, 'review_state')
        self.assertEqual(review_state, 'fangan')
        wf.doActionFor(dummy, 'submit2chuyang', comment='submit to chu yang')

        ## available variants is actor,action,comments,time, and review_history
        review_state = wf.getInfoFor(dummy, 'review_state')
        self.assertEqual(review_state, 'chuyang')
        comment = wf.getInfoFor(dummy, 'comments')
        self.assertEqual(comment, 'submit to chu yang')

        browser.open(page)
        outstr = "submit to shiyang"
        self.assertTrue(outstr in browser.contents)

        wf.doActionFor(dummy, 'submit2shiyang', comment='submit to shiyang')
        review_state = wf.getInfoFor(dummy, 'review_state')
        self.assertEqual(review_state, 'shiyang')
        comment = wf.getInfoFor(dummy, 'comments')
        self.assertEqual(comment, 'submit to shiyang')

        browser.open(page)
        outstr = "submit to dingxing"
        self.assertTrue(outstr in browser.contents)

        wf.doActionFor(dummy, 'submit2dingxing', comment='submit to dingxing')
        review_state = wf.getInfoFor(dummy, 'review_state')
        self.assertEqual(review_state, 'dingxing')
        comment = wf.getInfoFor(dummy, 'comments')
        self.assertEqual(comment, 'submit to dingxing')
示例#51
0
class ConstrainControlFunctionalText(unittest.TestCase):

    layer = DEXTERITY_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.folder_fti = add_folder_type(self.portal)
        self.item_fti = add_item_type(self.portal)

        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_overview_folder_view(self):
        url = '/dexterity-types/folder/@@overview'
        self.browser.open(self.portal_url + url)
        self.assertTrue('Filter Contained Types' in self.browser.contents)
        self.assertTrue('No content types' in self.browser.contents)

    def test_overview_item_view(self):
        url = '/dexterity-types/item/@@overview'
        self.browser.open(self.portal_url + url)
        self.assertFalse('Filter Contained Types' in self.browser.contents)
        self.assertFalse('No content types' in self.browser.contents)

    def test_overview_folder_item_view(self):
        # First we access folder content types and check
        # that is possible to fiter content types (as it is a container)
        url = '/dexterity-types/folder/@@overview'
        self.browser.open(self.portal_url + url)
        self.assertTrue('Filter Contained Types' in self.browser.contents)
        self.assertTrue('No content types' in self.browser.contents)

        # Then we access item content types and check
        # that is NOT possible to fiter content types
        url = '/dexterity-types/item/@@overview'
        self.browser.open(self.portal_url + url)
        self.assertFalse('Filter Contained Types' in self.browser.contents)
        self.assertFalse('No content types' in self.browser.contents)

        # Acessing folder content types again
        # and it should be possible to filter content types
        url = '/dexterity-types/folder/@@overview'
        self.browser.open(self.portal_url + url)
        self.assertTrue('Filter Contained Types' in self.browser.contents)
        self.assertTrue('No content types' in self.browser.contents)
示例#52
0
class ViewsFunctionalTest(unittest.TestCase):

    layer = PLONETRAINING_TESTING_FUNCTIONAL_TESTING

    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'])
        api.content.create(self.portal, 'TestingItem', 'foo')
        # needed to "see" this content in the browser
        commit()

        self.browser = Browser(app)
        self.browser.handleErrors = False
        self.browser.addHeader(
            'Authorization',
            'Basic {username}:{password}'.format(username=SITE_OWNER_NAME,
                                                 password=SITE_OWNER_PASSWORD),
        )

    def test_view_without_parameter(self):
        self.browser.open(self.portal_url + '/foo')
        self.assertNotIn(
            '<p>This is the default message: A small message</p>',
            self.browser.contents,
        )
        # because it's not the default view
        self.browser.open(self.portal_url + '/foo/testing-item-view')
        self.assertIn(
            '<p>This is the default message: A small message</p>',
            self.browser.contents,
        )
        self.assertNotIn(
            'This is the custom message',
            self.browser.contents,
        )

    def test_view_with_parameter(self):
        self.browser.open(self.portal_url + '/foo?message=hello')
        self.assertNotIn(
            '<p>This is the default message: A small message</p>',
            self.browser.contents,
        )
        self.assertNotIn(
            'This is the custom message',
            self.browser.contents,
        )
        # because it's not the default view
        self.browser.open(self.portal_url +
                          '/foo/testing-item-view?message=hello')
        self.assertIn(
            '<p>This is the default message: A small message</p>',
            self.browser.contents,
        )
        self.assertIn(
            '<p>This is the custom message: hello</p>',
            self.browser.contents,
        )
 def getBrowser(self, loggedIn=True):
     transaction.commit()
     browser = Browser(self.app)
     if loggedIn:
         user = TEST_USER_NAME
         pwd = default_password
         browser.addHeader('Authorization', 'Basic %s:%s' % (user, pwd))
     return browser
示例#54
0
 def test_added_classes(self):
     browser = Browser(self.layer['app'])
     auth = 'Basic {0}:{1}'.format(TEST_USER_NAME, TEST_USER_PASSWORD)
     browser.addHeader('Authorization', auth)
     browser.open(self.portal.absolute_url() +
                  '/@@collective.sortablequerystring.contentlisting')
     expected = '<p class="discreet">There are currently no items in this folder.</p>'  # noqa
     self.assertIn(expected, browser.contents)
 def get_browser(self):
     browser = Browser(self.layer["app"])
     browser.handleErrors = False
     browser.addHeader(
         "Authorization",
         "Basic {0}:{1}".format(SITE_OWNER_NAME, SITE_OWNER_PASSWORD),
     )
     return browser
示例#56
0
 def test_userid_header_underscore_dash(self):
     self.plugin.userid_header = "REMOTE_USER"
     transaction.commit()
     browser = Browser(self.app)
     browser.handleErrors = False
     browser.addHeader("REMOTE-USER", SITE_OWNER_NAME)
     browser.open(self.portal_url + "/headerlogin")
     self.assertEqual(browser.url, self.portal_url)
示例#57
0
class VideoFunctionalTest(unittest.TestCase):

    layer = MEDIA_FUNCTIONAL_TESTING

    def setUp(self):
        app = self.layer['app']
        self.portal = self.layer['portal']
        settings = GlobalSettings(self.portal)
        settings.additional_video_formats = []
        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,
            ))

    def test_add_video(self):
        self.browser.open(self.portal_url)
        self.browser.getLink('Video').click()
        self.browser.getControl(
            name='form.widgets.IDublinCore.title').value = "My video"
        self.browser.getControl(
            name='form.widgets.IDublinCore.description')\
            .value = "This is my video."
        file_path = os.path.join(test_file_dir, "test.mp4")
        file_ctl = self.browser.getControl(
            name='form.widgets.IVideo.video_file')
        file_ctl.add_file(open(file_path, 'rb'), 'video/mp4', 'test.mp4')
        self.browser.getControl('Save').click()
        self.assertTrue('My video' in self.browser.contents)
        self.assertTrue('This is my video' in self.browser.contents)
        self.assertTrue('<video' in self.browser.contents)
        self.assertIn('++widget++form.widgets.IVideo.video_file/@@stream',
                      self.browser.contents)

    @unittest.skip('Async conversion does not work in py3 yet')
    def test_add_video_creates_three_sources(self):
        self.browser.open(self.portal_url)
        self.browser.getLink('Video').click()
        self.browser.getControl(
            name='form.widgets.IDublinCore.title').value = "My video"
        self.browser.getControl(
            name='form.widgets.IDublinCore.description')\
            .value = "This is my video."
        file_path = os.path.join(test_file_dir, "test.mp4")
        file_ctl = self.browser.getControl(
            name='form.widgets.IVideo.video_file')
        file_ctl.add_file(open(file_path, 'rb'), 'video/mp4', 'test.mp4')
        self.browser.getControl('Save').click()
        self.assertTrue('My video' in self.browser.contents)
        self.assertTrue('This is my video' in self.browser.contents)
        self.assertTrue('<video' in self.browser.contents)
        self.assertEqual(self.browser.contents.count('<source'), 3)
        self.assertIn('++widget++form.widgets.IVideo.video_file/@@stream',
                      self.browser.contents)
def get_browser(layer):
    api.user.create(username='******',
                    password='******',
                    email='*****@*****.**',
                    roles=('Manager', ))
    transaction.commit()
    browser = Browser(layer['app'])
    browser.addHeader('Authorization', 'Basic adm:secret')
    return browser
示例#59
0
def setUp(doctest):
    layer = doctest.globs['layer']
    app = layer['app']
    portal = layer['portal']
    anon_browser = Browser(app)
    admin_browser = Browser(app)
    admin_browser.addHeader('Authorization', 'Basic admin:secret')
    admin_browser.open(portal.absolute_url())

    user_id = TEST_USER_NAME
    user_password = TEST_USER_PASSWORD

    def config_property(**kw):
        for key, value in kw.items():
            try:
                registry = getUtility(IRegistry)
                settings = registry.forInterface(
                    ILoginLockoutSettings, prefix="Products.LoginLockout")
                setattr(settings, key, value)
                continue
            except ComponentLookupError:
                pass
            try:
                p_tool = getToolByName(portal, 'portal_properties')
                p_tool.loginlockout_properties.setProperty(key, value)
                continue
            except AttributeError:
                raise
        commit()

    def get_loginlockout_settings():
        registry = getUtility(IRegistry)
        settings = registry.forInterface(ILoginLockoutSettings,
                                         prefix="Products.LoginLockout")
        return settings

    doctest.globs.update(locals())
    #
    #     def afterSetUp(self):
    #        # sm = getSiteManager(context=self.portal)
    #         # sm.unregisterUtility(provided=IMailHost)
    #         # sm.registerUtility(mailhost, provided=IMailHost)
    #     #
    #     # def setStatusCode(self, key, value):
    #     #     from ZPublisher import HTTPResponse
    #     #     HTTPResponse.status_codes[key.lower()] = value
    #
    anon_browser.handleErrors = False
    portal.error_log._ignored_exceptions = ('Unauthorized', )

    def raising(self, info):
        import traceback
        traceback.print_tb(info[2])
        print info[1]

    from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
    SiteErrorLog.raising = raising
示例#60
0
 def test_traverse_occurrence(self):
     transaction.commit()
     browser = Browser(self.app)
     browser.addHeader('Authorization',
                       'Basic %s:%s' % (TEST_USER_ID, TEST_USER_PASSWORD))
     url = '/'.join([self.now_event.absolute_url(), '2013-05-07'])
     browser.open(url)
     title = self.now_event.title.encode('ascii')
     self.assertTrue(title in browser.contents)