def test_add_person_column_later(self): new_type = self.new_temporary_type( behaviors=[IPerson.__identifier__], klass='seantis.people.types.base.PersonBase' ) self.assertEqual(get_columns(new_type.lookupSchema()), []) with self.user('admin'): obj = api.content.create( id='123', type=new_type.id, container=self.new_temporary_folder(), foo='stop', bar='hammertime!' ) # define the metadata after the obj has been created set_columns(new_type.lookupSchema(), [['foo']]) # which leaves the attribute in a missing value state brain = tools.get_brain_by_object(obj, catalog_id) self.assertFalse(hasattr(brain, 'foo')) # until reindexing happens on_type_modified(new_type) brain = tools.get_brain_by_object(obj, catalog_id) self.assertEqual(brain.foo, 'stop')
def test_first_letter_index(self): self.login('admin') new_type = self.new_temporary_type( behaviors=[IPerson.__identifier__], klass='seantis.people.types.base.PersonBase' ) folder = self.new_temporary_folder() create = lambda title: api.content.create( title=title, type=new_type.id, container=folder ) objects = [create(name) for name in ( u'Andrew', u'Beat', u'cesar', u'Dexter', u'', u'ändu', u'Ödipus' )] catalog = api.portal.get_tool(catalog_id) index = catalog._catalog.getIndex('first_letter') values = [ index.getEntryForObject( tools.get_brain_by_object(obj, catalog_id).getRID() ) for obj in objects ] self.assertEqual(sorted(values), [ u'', u'A', u'B', u'C', u'D', u'Ä', u'Ö' ])
def test_membership_changed(self): tools.add_attribute_to_metadata('organizations', catalog_id) organization = self.new_temporary_folder() person = self.get_test_person() memberships = [Membership(person, 'vice-president')] class Source(TestAdapter): def memberships(self, person=None): return {IUUID(organization): memberships} with self.custom_source(Source): catalog = api.portal.get_tool(catalog_id) rid = tools.get_brain_by_object(person, catalog_id).getRID() get_orgs = lambda: catalog.getMetadataForRID(rid)['organizations'] # because the membership source was added after the person # was created, the organizations metadata column is empty self.assertEqual(get_orgs(), []) # after signalling that the membership has changed, the # organizations should be available notify(MembershipChangedEvent(person)) self.assertEqual(get_orgs(), [organization.id])
def test_get_brain_by_object(self): with self.user('admin'): obj = api.content.create( id='test', type=self.new_temporary_type().id, container=self.new_temporary_folder() ) brain = tools.get_brain_by_object(obj) self.assertIs(type(brain.getObject()), type(obj)) self.assertEqual(brain.id, obj.id)
def test_reindex_on_change(self): new_type = self.new_temporary_type( behaviors=[IPerson.__identifier__], klass='seantis.people.types.base.PersonBase' ) set_columns(new_type.lookupSchema(), [['foo']]) on_type_modified(new_type) with self.user('admin'): obj = api.content.create( id='123', type=new_type.id, container=self.new_temporary_folder(), foo='stop', bar='hammertime!' ) brain = tools.get_brain_by_object(obj, catalog_id) self.assertTrue(hasattr(brain, 'foo')) self.assertFalse(hasattr(brain, 'bar')) self.assertEqual(brain.foo, 'stop') set_columns(new_type.lookupSchema(), [['bar']]) # usually the dexterity fti modified event does this on_type_modified(new_type) brain = tools.get_brain_by_object(obj, catalog_id) # The metadata is not deleted at this point because it is impossible # to tell if the metadata is used elsewhere. It's a rather big caveat.. self.assertTrue(hasattr(brain, 'foo')) self.assertTrue(hasattr(brain, 'bar')) self.assertEqual(brain.bar, 'hammertime!')
def test_first_letter_index_update(self): foobar_xml = """<?xml version='1.0' encoding='utf8'?> <model xmlns="http://namespaces.plone.org/supermodel/schema" xmlns:people="http://namespaces.plone.org/supermodel/people"> <schema> <people:order> <people:item>foo</people:item> <people:item>bar</people:item> </people:order> </schema> </model>""" self.login('admin') foobar = self.new_temporary_type( behaviors=[IPerson.__identifier__], model_source=foobar_xml, klass='seantis.people.types.base.PersonBase' ) obj = api.content.create( title='test', type=foobar.id, container=self.new_temporary_folder() ) catalog = api.portal.get_tool(catalog_id) index = catalog._catalog.getIndex('first_letter') get_index_value = lambda: index.getEntryForObject( tools.get_brain_by_object(obj, catalog_id).getRID() ) self.assertEqual(get_index_value(), u'T') obj.title = 'asdf' obj.reindexObject() self.assertEqual(get_index_value(), u'A') obj.bar = 'bar' obj.reindexObject() self.assertEqual(get_index_value(), u'B') obj.foo = u'ähm' obj.reindexObject() self.assertEqual(get_index_value(), u'Ä')
def test_get_parent(self): folder = self.new_temporary_folder(title='parent') new_type = self.new_temporary_type() with self.user('admin'): obj = api.content.create( id='test', type=new_type.id, container=folder ) brain = tools.get_brain_by_object(obj) self.assertEqual(tools.get_parent(brain).Title, 'parent') self.assertEqual(tools.get_parent(obj).title, 'parent') self.assertTrue(ICatalogBrain.providedBy(tools.get_parent(brain))) self.assertTrue(isinstance(tools.get_parent(obj), folder.__class__))
def test_order(self): new_type = self.new_temporary_type( behaviors=[IPerson.__identifier__], klass='seantis.people.types.base.PersonBase' ) set_order(new_type.lookupSchema(), ['bar', 'foo']) with self.user('admin'): obj = api.content.create( id='123', type=new_type.id, container=self.new_temporary_folder(), foo='stop', bar='hammertime!' ) brain = tools.get_brain_by_object(obj, catalog_id) catalog = api.portal.get_tool(catalog_id) self.assertEqual( catalog.getIndexDataForRID(brain.getRID())['sortable_title'], tools.unicode_collate_sortkey()('hammertime! stop') )
def test_add_person_column_first(self): new_type = self.new_temporary_type( behaviors=[IPerson.__identifier__], klass='seantis.people.types.base.PersonBase' ) set_columns(new_type.lookupSchema(), [['foo']]) on_type_modified(new_type) with self.user('admin'): obj = api.content.create( id='123', type=new_type.id, container=self.new_temporary_folder(), foo='stop', bar='hammertime!' ) brain = tools.get_brain_by_object(obj, catalog_id) self.assertTrue(hasattr(brain, 'foo')) self.assertFalse(hasattr(brain, 'bar')) self.assertEqual(brain.foo, 'stop')
def test_organization_activation(self): browser = self.new_admin_browser() anonymous = self.new_browser() browser.open(self.infolder('/++add++seantis.kantonsrat.organization')) # by default, organizations are active browser.getControl('Title').value = u'NSA' browser.getControl('Description').value = u'Spying and stuff' browser.getControl('Save').click() browser.open(self.infolder( '/nsa/content_status_modify?workflow_action=publish' )) # at this point both manager and anonymous see the same browser.open(self.infolder('/organization_listing')) self.assertIn('<dt class="active">', browser.contents) self.assertNotIn('<dt class="inactive">', browser.contents) anonymous.open(self.infolder('/organization_listing')) self.assertIn('<dt class="active">', anonymous.contents) self.assertNotIn('<dt class="inactive">', anonymous.contents) # deactivating an organization tags it in the list and removes # it for anonymous users. It also won't show up in the navigation browser.open(self.infolder('/nsa/edit')) browser.set_date('start', date.today() + timedelta(days=1)) browser.getControl('Save').click() # managers now see the inactive organizations browser.open(self.infolder('/organization_listing')) self.assertIn('<dt class="inactive">', browser.contents) self.assertNotIn('<dt class="active">', browser.contents) # while anonymous users do not anonymous.open(self.infolder('/organization_listing')) self.assertNotIn('<dt class="active">', anonymous.contents) self.assertNotIn('<dt class="inactive">', anonymous.contents) # unfortunately, using a date to trigger the state is not automatic. # a cronjob as to be used for this (which calls a view) last_week = date.today() - timedelta(days=7) last_year = date.today() - timedelta(days=365) with freeze_time(last_week): browser.open(self.infolder('/nsa/edit')) browser.set_date('start', last_year) browser.set_date('end', last_week) browser.getControl('Save').click() # the view is always up to date browser.open(self.infolder('/organization_listing')) self.assertIn('<dt class="inactive">', browser.contents) self.assertNotIn('<dt class="active">', browser.contents) # but the navigation isn't.. unfortunately I cannot get the # portlets to work here, so we have to peek into the brain # to see the actual state browser.open(self.infolder('/nsa/uuid')) uuid = browser.contents brain = tools.get_brain_by_object(api.content.get(UID=uuid)) self.assertEqual(brain.exclude_from_nav, False) # trigger the state and this will change browser.open(self.infolder('/trigger-state')) brain = tools.get_brain_by_object(api.content.get(UID=uuid)) self.assertEqual(brain.exclude_from_nav, True)