def add_rows(self): portal = self.layer['portal'] storage = IDataStorage(portal.table_page1) data = { '__creator__': 'user1', 'col_a': 'Lorem ipsum', '__uuid__': 'aaa' } storage.add(data) self.tp_catalog.catalog_row(portal.table_page1, data) data = { '__creator__': 'user1', 'col_a': 'dolor sit amet', '__uuid__': 'bbb' } storage.add(data) self.tp_catalog.catalog_row(portal.table_page1, data) # another TP storage = IDataStorage(portal.table_page2) data = { '__creator__': 'user1', 'col_a': 'consectetur adipisicing elit', '__uuid__': 'ccc' } storage.add(data) self.tp_catalog.catalog_row(portal.table_page2, data) data = { '__creator__': 'user1', 'col_a': 'sed do eiusmod tempor', '__uuid__': 'ddd' } storage.add(data) self.tp_catalog.catalog_row(portal.table_page2, data)
def setUp(self): portal = self.layer['portal'] self.tp_catalog = portal.tablepage_catalog login(portal, TEST_USER_NAME) portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = portal.table_page tp.edit(pageColumns=[{'id': 'foo_field', 'label': 'Foo field', 'description': '', 'type': 'String', 'vocabulary': '', 'options': []}, ], batchSize=10) tp.edit(searchConfig=[{'id': 'foo_field', 'label': '', 'description': '', 'additionalConfiguration': ['SearchableText']}]) self.tp = tp self.storage = IDataStorage(tp) self._addRows(35) # now adding another tablepage: this must be always ignored by searches portal.invokeFactory(type_name='TablePage', id='table_page2', title="Another Table Document") portal.table_page2.edit(pageColumns=[{'id': 'foo_field', 'label': 'Foo field', 'description': '', 'type': 'String', 'vocabulary': '', 'options': []}, ], batchSize=10) storage2 = IDataStorage(portal.table_page2) storage2.add({'__label__': 'A Label', '__uuid__': 'l2l2l2'}) storage2.add({'foo_field': 'aa001', '__uuid__': '010'}) portal.portal_workflow.doActionFor(tp, 'publish') self.tp_catalog.clearFindAndRebuild() logout()
def _get_row_data(self, row): """Return a dict of data taken from other row values""" # First of all: if this is a catalog brain, let's load the "real object" # BBB: can't check for ICatalogBrain until Plone 3.3 support will be dropped if isinstance(row, AbstractCatalogBrain): storage = IDataStorage(self.context) row = storage[row.getObjPositionInParent - 1] results = {} utils = {} configuration = self.context.getPageColumns() for col_index, conf in enumerate(configuration): col_type = conf['type'] # let's cache (or use cached) utility cache = IAnnotations(self.request) cached = cache.get('colum-handle-%s' % col_type) if not cached: try: utils[col_type] = getUtility(IComputedColumnHandler, name=col_type) except ComponentLookupError: utils[col_type] = getUtility(IComputedColumnHandler) cache['colum-handle-%s' % col_type] = utils[col_type] else: utils[col_type] = cached if not col_type or col_type == 'Computed': continue id = configuration[col_index]['id'] data = row.get(id) or None results[id] = utils[col_type](data) return results
def test_encoding_on_rendering(self): """Be sure that we have no problems with non-ASCII chars""" self.portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = self.portal.table_page tp.edit(textBefore='<p>L\xc3\xb2r\xc3\xa8m Ips\xc3\xb9m</p>', pageColumns=[{ 'id': 'col_a', 'label': 'Col A', 'description': 'Th\xc3\xacs data is futile', 'type': 'String', 'vocabulary': '', 'options': [] }]) storage = IDataStorage(tp) storage.add({ '__creator__': 'user1', 'col_a': 'F\xc3\xb2\xc3\xb2 data from user1', '__uuid__': 'aaa' }) adapter = getMultiAdapter((tp, self.request), interface=IColumnField, name=u'String') adapter.configuration = tp.getPageColumns()[0] try: adapter.render_edit('F\xc3\xb2\xc3\xb2 data from user1') except UnicodeDecodeError: self.fail("getText() raised UnicodeDecodeError unexpectedly!")
def setUp(self): portal = self.layer['portal'] login(portal, TEST_USER_NAME) portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = portal.table_page tp.edit(pageColumns=[{ 'id': 'col_a', 'label': 'Col A', 'description': '', 'type': 'String', 'vocabulary': '', 'options': [] }]) storage = IDataStorage(tp) storage.add({ '__creator__': 'user1', 'col_a': 'Lorem', '__uuid__': 'aaa' }) storage.add({ '__creator__': 'user1', 'col_a': 'Ipsum', '__uuid__': 'bbb' }) storage.add({ '__creator__': 'user1', 'col_a': 'Sit', '__uuid__': 'ccc' }) self.tp_catalog = getToolByName(portal, 'tablepage_catalog') self.tp_catalog.manage_catalogRebuild()
def setUp(self): portal = self.layer['portal'] login(portal, TEST_USER_NAME) portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = portal.table_page tp.edit(pageColumns=[{ 'id': 'col_a', 'label': 'Col A', 'description': 'Th\xc3\xacs data is futile', 'type': 'String', 'vocabulary': '', 'options': [] }]) storage = IDataStorage(tp) storage.add({ '__creator__': 'user1', 'col_a': 'F\xc3\xb2\xc3\xb2 data from user1', '__uuid__': 'aaa' }) storage.add({'__label__': 'A label'}) storage.add({ '__creator__': 'user1', 'col_a': 'Other data from user1', '__uuid__': 'bbb' }) storage.add({ '__creator__': 'user1', 'col_a': 'Again data from user1', '__uuid__': 'ccc' }) self.storage = storage
def __call__(self, *args, **kwargs): context = self.context request = self.request catalog = getToolByName(context, config.CATALOG_ID) storage = IDataStorage(context) # now we load the tabel view and rebuild all rows by using the ignore_cache parameter table_view = getMultiAdapter((context, request), name=u'view-table') table_view.rows(ignore_cache=True) for index, row in enumerate(storage): uuid = row.get('__uuid__') if not uuid: # this should not happen logger.warning( "Row without an uuid! index %d, document at %s" % (index, context.absolute_url_path())) continue catalog.reindex_rows(context, uuid, storage) if index and index % 100 == 0: logger.info("Refreshing catalog (%d)" % index) transaction.savepoint() logger.info("Refreshing catalog and caches: done") getToolByName(context, 'plone_utils').addPortalMessage( _('reindex_performed_message', u'$count rows has been updated', mapping={'count': index + 1})) request.response.redirect('%s/edit-table' % context.absolute_url())
def test_catalog_reindex_rows(self): portal = self.layer['portal'] self.add_rows() tp = portal.table_page1 storage = IDataStorage(tp) portal = self.layer['portal'] data = { '__creator__': 'user1', 'col_a': 'Proin elementum', '__uuid__': 'ccc' } storage.add(data) self.tp_catalog.catalog_row(tp, data) self.assertEqual(len(list(self.tp_catalog.searchTablePage(tp))), 3) self.assertEqual( self.tp_catalog.searchTablePage(tp)[0]._unrestrictedGetObject() ['col_a'], 'Lorem ipsum') self.assertEqual( self.tp_catalog.searchTablePage(tp)[1]._unrestrictedGetObject() ['col_a'], 'dolor sit amet') self.assertEqual( self.tp_catalog.searchTablePage(tp)[2]._unrestrictedGetObject() ['col_a'], 'Proin elementum') data = storage.get('bbb') del storage['bbb'] storage.add(data, 2) self.tp_catalog.reindex_rows(tp, ['bbb', 'ccc']) self.assertEqual( self.tp_catalog.searchTablePage(tp)[1]._unrestrictedGetObject() ['col_a'], 'Proin elementum') self.assertEqual( self.tp_catalog.searchTablePage(tp)[2]._unrestrictedGetObject() ['col_a'], 'dolor sit amet')
def test_encoding(self): """Be sure that we have no problems with non-ASCII chars""" portal = self.layer['portal'] portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = portal.table_page tp.edit(textBefore='<p>L\xc3\xb2r\xc3\xa8m Ips\xc3\xb9m</p>', pageColumns=[{ 'id': 'col_a', 'label': 'Col A', 'description': 'Th\xc3\xacs data is futile', 'type': 'String', 'vocabulary': '', 'options': [] }]) storage = IDataStorage(tp) storage.add({ '__creator__': 'user1', 'col_a': 'F\xc3\xb2\xc3\xb2 data from user1', '__uuid__': 'aaa' }) try: tp.getText() except UnicodeDecodeError: self.fail("getText() raised UnicodeDecodeError unexpectedly!")
def test_file_creation_2(self): """When title is not provided, file id is used and we can't add multiple files (same as Plone)""" portal = self.layer['portal'] request = self.layer['request'] tp = portal.table_page folder = portal.folder tp.manage_setLocalRoles('user0', ('Contributor', )) with open(__file__) as f: file = StringIO(f.read()) filename = os.path.basename(__file__) file.filename = filename request.form['att'] = file request.form['form.submitted'] = "1" view = getMultiAdapter((tp, request), name='edit-record') view() file_content = folder[filename] self.assertTrue(file_content.getId() in folder.objectIds()) self.assertEqual(len(folder.objectIds()), 2) file.seek(0) request.form['att'] = file request.form['form.submitted'] = "1" view() # we still have two files self.assertEqual(len(folder.objectIds()), 2) storage = IDataStorage(tp) self.assertEqual(storage[0]['att'], storage[1]['att'])
def test_computed_file_access(self): portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'column_file': portal.file1.UID()}) configuration = tp.getPageColumns() configuration[-1]['vocabulary'] = 'row/column_file/Title' field = self._getField() self.assertEquals(field.render_view('foo', 0).strip(), 'One file')
def test_computed_general_tal_access(self): portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'simple_column': 'Lorem ipsum'}) configuration = tp.getPageColumns() configuration[-1]['vocabulary'] = 'portal/title' field = self._getField() self.assertEquals(field.render_view('foo', 0).strip(), 'Plone site')
def test_computed_multiple_files_access(self): portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'column_files': "%s\n%s" % (portal.file1.UID(), portal.file2.UID())}) configuration = tp.getPageColumns() configuration[-1]['vocabulary'] = "python:row['column_files'][1].Title()" field = self._getField() self.assertEquals(field.render_view('foo', 0).strip(), 'Another file')
def setUp(self): portal = self.layer['portal'] login(portal, TEST_USER_NAME) portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = portal.table_page tp.edit(pageColumns=[{'id': 'the_html_data', 'label': 'A text', 'description': '', 'type': 'Html', 'vocabulary': '', 'options': []} ]) self.storage = IDataStorage(tp)
def test_reference_save(self): portal = self.layer['portal'] request = self.layer['request'] tp = portal.table_page request.form['internal_link'] = portal.document.UID() request.form['form.submitted'] = '1' view = getMultiAdapter((tp, request), name=u'edit-record') view() storage = IDataStorage(tp) self.assertEqual(storage[0]['link'], portal.document.UID())
def test_url_save(self): portal = self.layer['portal'] request = self.layer['request'] tp = portal.table_page request.form['external_link'] = 'http://mycompany.com/' request.form['form.submitted'] = '1' view = getMultiAdapter((tp, request), name=u'edit-record') view() storage = IDataStorage(tp) self.assertEqual(storage[0]['link'], 'http://mycompany.com/')
def setUp(self): portal = self.layer['portal'] login(portal, TEST_USER_NAME) portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = portal.table_page tp.edit(pageColumns=[{'id': 'foo', 'label': 'Select one', 'description': '', 'type': 'Select', 'vocabulary': 'Lorem\nIpsum\ndolor\nsit\n amet', 'options': []} ]) self.storage = IDataStorage(tp)
def test_catalog_rows_on_add(self): portal = self.layer['portal'] self.add_rows() storage = IDataStorage(portal.table_page1) self.assertEqual(len(self.tp_catalog()), 4) self.assertEqual( len(list(self.tp_catalog.searchTablePage(portal.table_page1))), 2) self.assertEqual( self.tp_catalog.searchTablePage( portal.table_page1)[0]._unrestrictedGetObject()['col_a'], storage[0]['col_a'])
def setUp(self): portal = self.layer['portal'] login(portal, TEST_USER_NAME) portal.invokeFactory(type_name='TablePage', id='table_page', title="The Table Document") tp = portal.table_page tp.edit(pageColumns=[{'id': 'foo_field', 'label': 'Foo field', 'description': '', 'type': 'String', 'vocabulary': '', 'options': []}, ], batchSize=10) self.tp = tp self.storage = IDataStorage(tp)
def test_computed_link_access(self): portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'column_link': portal.document.UID()}) storage.add({'column_link': 'http://plone.org/'}) configuration = tp.getPageColumns() configuration[-1]['vocabulary'] = "row/column_link/Title|row/column_link" field = self._getField() self.assertEquals(field.render_view('foo', 0).strip(), 'A document to reference') self.assertEquals(field.render_view('foo', 1).strip(), 'http://plone.org/')
def test_modify_his_row(self): """user2 can't modify other user's data""" portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'__creator__': 'user1', 'col_a': 'foo data from user1', '__uuid__': 'aaa'}) login(portal, 'user2') view = tp.restrictedTraverse('@@edit-record') view.request.form['row-index'] = 0 self.assertRaises(Unauthorized, view)
def test_move_my_row(self): """Owners normally can't move rows""" portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'__creator__': 'user1', 'col_a': 'foo data from user1', '__uuid__': 'aaa'}) storage.add({'__creator__': 'user1', 'col_a': 'some other futile data', '__uuid__': 'bbb'}) login(portal, 'user1') self.assertRaises(Unauthorized, tp.restrictedTraverse, '@@move-record')
def test_editor_modify_his_row(self): """user3 can modify other user's data""" portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'__creator__': 'user1', 'col_a': 'foo data from user1', '__uuid__': 'aaa'}) login(portal, 'user3') view = tp.restrictedTraverse('@@edit-record') view.request.form['row-index'] = 0 self.assertTrue('Edit row' in view()) self.assertTrue('foo data from user1' in view())
def test_delete_my_row(self): """Owners can delete proper rows""" portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'__creator__': 'user1', 'col_a': 'foo data from user1', '__uuid__': 'aaa'}) login(portal, 'user1') view = tp.restrictedTraverse('@@delete-record') view.request.form['row-index'] = 0 view() self.assertEqual(len(storage), 0)
def test_rows_var_access(self): portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'simple_column': 'Lorem ipsum'}) configuration = tp.getPageColumns() configuration[-1]['vocabulary'] = "python:rows.get(0)['simple_column']" field = self._getField() self.assertEquals(field.render_view('foo', 0).strip(), 'Lorem ipsum') storage.add({'simple_column': 'dolor sit amet'}) field = self._getField() self.assertEquals(field.render_view('foo', 1).strip(), 'Lorem ipsum')
def test_editor_move_his_row(self): """Editor can move rows""" portal = self.layer['portal'] tp = portal.table_page storage = IDataStorage(tp) storage.add({'__creator__': 'user1', 'col_a': 'foo data from user1', '__uuid__': 'aaa'}) storage.add({'__creator__': 'user1', 'col_a': 'some other futile data', '__uuid__': 'bbb'}) login(portal, 'user3') view = tp.restrictedTraverse('@@move-record') view.request.form['row-index'] = 0 view.request.form['direction'] = 'down' view() self.assertEqual(storage[0].get('col_a'), 'some other futile data')
def test_url_edit(self): portal = self.layer['portal'] request = self.layer['request'] tp = portal.table_page storage = IDataStorage(tp) storage.add({ '__creator__': TEST_USER_NAME, 'link': 'http://foo.com/', '__uuid__': 'aaa' }) request.form['row-index'] = 0 view = getMultiAdapter((tp, request), name=u'edit-record') self.assertTrue('http://foo.com/' in view())
def test_foo_data_saved_however(self): portal = self.layer['portal'] request = self.layer['request'] tp = portal.table_page request.form['external_link'] = 'this is not an url' request.form['internal_link'] = 'this is not an uid' request.form['form.submitted'] = '1' view = getMultiAdapter((tp, request), name=u'edit-record') view() storage = IDataStorage(tp) self.assertEqual(storage[0]['link'], 'this is not an uid') output = tp() self.assertFalse('this is not an uid' in output)
def test_rebuild_catalog(self): portal = self.layer['portal'] request = self.layer['request'] self.add_rows() tp = portal.table_page1 storage = IDataStorage(tp) storage[1]['col_a'] = 'foo bar baz' self.tp_catalog.manage_catalogReindex(request, request.response, self.tp_catalog.absolute_url()) self.assertEqual(len(list(self.tp_catalog())), 4) self.assertEqual(len(self.tp_catalog.searchTablePage(tp)), 2) self.assertEqual( self.tp_catalog.searchTablePage(tp)[1]._unrestrictedGetObject() ['col_a'], 'foo bar baz')
def test_reference_document_edit(self): portal = self.layer['portal'] request = self.layer['request'] tp = portal.table_page storage = IDataStorage(tp) storage.add({ '__creator__': TEST_USER_NAME, 'link': portal.document.UID(), '__uuid__': 'aaa' }) request.form['row-index'] = 0 view = getMultiAdapter((tp, request), name=u'edit-record') self.assertTrue('value="%s"' % portal.document.Title().decode('utf-8') in view())