Ejemplo n.º 1
0
 def test_url_microblog_context(self):
     self.portal.invokeFactory('Folder', 'f1', title=u"Folder 1")
     f1 = self.portal['f1']
     alsoProvides(f1, IMicroblogContext)
     su = StatusUpdate('foo bar', microblog_context=f1)
     self.assertEqual(su.absolute_url(),
                      '{}/@@post'.format(f1.absolute_url()))
Ejemplo n.º 2
0
 def __init__(self, text, userid, creator=None):
     StatusUpdate.__init__(self, text)
     self.userid = userid
     if creator:
         self.creator = creator
     else:
         self.creator = userid
Ejemplo n.º 3
0
 def test_edit_sets_edited(self):
     su = StatusUpdate('foo')
     self.assertEqual(su.edited, None)
     su.edit('bar')
     self.assertEqual(str(su.edited.__class__),
                      "<class 'DateTime.DateTime.DateTime'>")
     self.assertNotEqual(su.edited, su.date)
Ejemplo n.º 4
0
    def test_workspace_tile(self):
        ''' This will test the existence of the workspaces.tile
        and its functionality
        '''
        tile = api.content.get_view('workspaces.tile', self.portal,
                                    self.request)
        su = StatusUpdate('Proposal draft V1.0 # This is a mock!!!', **{
            'microblog_context': self.workspace,
        })
        su.id = 123456789L
        su.creator = 'charlotte_holzer'
        su.date = DateTime('2008/02/14 18:43')
        mb = queryUtility(IMicroblogTool)
        mb.add(su)
        workspaces = tile.workspaces(include_activities=True)
        self.assertEqual(len(workspaces), 1)

        demo_ws = workspaces[0]

        activities = demo_ws['activities']
        self.assertEqual(len(activities), 1)
        self.assertDictEqual(
            activities[0], {
                'object': 'Proposal draft V1.0 # This is a mock!!!',
                'subject': 'charlotte_holzer',
                'time': {
                    'datetime': '2008-02-14',
                    'title': '14 February 2008, 18:43'
                },
                'verb': 'posted'
            })
 def test_delete_microblog_context_and_content(self):
     su1 = StatusUpdate('test', content_context=self.document)
     self.container.add(su1)
     su2 = StatusUpdate('foobar', microblog_context=self.microblog_context)
     self.container.add(su2)
     self.portal.manage_delObjects([self.ws_id])
     self.assertEqual([], (list(self.container.values())))
Ejemplo n.º 6
0
 def __init__(self, text, userid, creator=None):
     StatusUpdate.__init__(self, text)
     self.userid = userid
     if creator:
         self.creator = creator
     else:
         self.creator = userid
 def test_delete_content_replies(self):
     su1 = StatusUpdate('test', content_context=self.document)
     self.container.add(su1)
     su2 = StatusUpdate('foobar', thread_id=su1.id)
     self.container.add(su2)
     self.microblog_context.manage_delObjects([self.doc_id])
     self.assertEqual([], (list(self.container.values())))
Ejemplo n.º 8
0
 def test_nonmember_unauthorized_write(self):
     login(self.portal, 'alice_lindstrom')
     su1 = StatusUpdate('test #foo')
     su2 = StatusUpdate('test #foo', self.workspace)
     self.tool.add(su1)
     # should raise, since Alice is not a member of the workspace
     self.assertRaises(Unauthorized, self.tool.add, su2)
Ejemplo n.º 9
0
    def setUp(self):
        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        workflowTool = getToolByName(self.portal, 'portal_workflow')
        workflowTool.setDefaultChain('simple_publication_workflow')
        workflowTool.updateRoleMappings()
        f1 = api.content.create(self.portal, 'Folder', 'f1', title=u'Folder 1')
        alsoProvides(f1, IMicroblogContext)
        f1.reindexObject()
        f2 = api.content.create(self.portal, 'Folder', 'f2', title=u'Folder 2')
        alsoProvides(f2, IMicroblogContext)
        f2.reindexObject()

        api.content.transition(f2, 'publish')
        self.assertEqual(api.content.get_state(f1), 'private')
        self.assertEqual(api.content.get_state(f2), 'published')

        tool = queryUtility(IMicroblogTool)
        self.su1 = su1 = StatusUpdate('test #foo', f1)
        tool.add(su1)
        self.su2 = su2 = StatusUpdate('test #foo', f2)
        tool.add(su2)
        # the tool is queued
        tool.flush_queue()

        # set up new user
        api.user.create('*****@*****.**', username='******', password='******')
Ejemplo n.º 10
0
 def test_member_allowed_write(self):
     login(self.portal, 'allan_neece')
     su1 = StatusUpdate('test #foo')
     su2 = StatusUpdate('test #foo', self.workspace)
     self.tool.add(su1)
     # should NOT raise Unauthorized
     self.tool.add(su2)
Ejemplo n.º 11
0
 def test_thread_microblog_context(self):
     self.portal.invokeFactory('Folder', 'f1', title=u"Folder 1")
     f1 = self.portal['f1']
     alsoProvides(f1, IMicroblogContext)
     su1 = StatusUpdate('foo', microblog_context=f1)
     self.container.add(su1)
     su2 = StatusUpdate('foo', thread_id=su1.id)
     self.assertEqual(f1, su2.microblog_context)
Ejemplo n.º 12
0
def create(
    text,
    context=None,
    thread_id=None,
    mention_ids=None,
    tags=None,
    user=None,
    userid=None,
    time=None,
):
    """Create a status update (post).

    :param text: [required] text of the post
    :type text: Unicode object

    :param context: Container of the post
    :type context: Content object

    :param user: User who should post. By default the current user posts.
    :type user: user object

    :param userid: userid of the user who should post.
    :type userid: string

    :param time: time when the post should happen. By default the current time.
    :type time: datetime object

    :returns: Newly created statusupdate
    :rtype: StatusUpdate object
    """
    status_obj = StatusUpdate(
        text=text,
        context=context,
        thread_id=thread_id,
        mention_ids=mention_ids,
        tags=tags
    )
    # By default the post is done by the current user
    # Passing a userid or user allows to post as a different user
    if user is None and userid is not None:
        user = api.user.get(userid=userid)
    if user is not None:
        status_obj.userid = user.getId()
        status_obj.creator = user.getUserName()

    # By default the post happens now
    # Passing a time (as a datetime-object) the id and the date can be set
    if time is not None:
        assert(isinstance(time, datetime))
        delta = time - datetime.utcfromtimestamp(0)
        status_obj.id = long(delta.total_seconds() * 1e6)
        status_obj.date = DateTime(time)

    status_id = status_obj.id
    microblog = queryUtility(IMicroblogTool)
    microblog.add(status_obj)
    return microblog.get(status_id)
Ejemplo n.º 13
0
 def test_url_content_context(self):
     self.portal.invokeFactory('Folder', 'f1', title=u"Folder 1")
     f1 = self.portal['f1']
     alsoProvides(f1, IMicroblogContext)
     doc = api.content.create(
         container=f1,
         type='Document',
         title='My document',
     )
     su = StatusUpdate('foo bar', content_context=doc)
     self.assertEqual(su.absolute_url(),
                      '{}/view'.format(doc.absolute_url()))
Ejemplo n.º 14
0
 def test_reply_to_contentupdate_is_human_update(self):
     self.portal.invokeFactory('Folder', 'f1', title=u"Folder 1")
     f1 = self.portal['f1']
     alsoProvides(f1, IMicroblogContext)
     doc = api.content.create(
         container=f1,
         type='Document',
         title='My document',
     )
     su1 = StatusUpdate('', content_context=doc)
     self.container.add(su1)
     su2 = StatusUpdate('', thread_id=su1.id)
     self.assertTrue(su2.is_human_update)
Ejemplo n.º 15
0
    def test_like_status_update(self):
        # test statusupdate
        su = StatusUpdate('Some cool news!')
        container = piapi.microblog.get_microblog()
        container.add(su)
        update_id = str(su.id)

        self.request.form['like_button'] = 'like'
        self.request["REQUEST_METHOD"] = "POST"
        view = api.content.get_view('toggle_like_statusupdate',
                                    self.portal, self.request)
        self.assertRaises(KeyError, view)
        view = view.publishTraverse(self.request, update_id)

        # Toggle like for statusupdate on
        output = view()
        self.assertIn('(1)', output)
        self.assertIn('Unlike', output)
        user_likes = self.util.get_likes("update", self.user_id)

        self.assertTrue(
            self.util.is_liked("update", update_id, self.user_id))
        self.assertEqual(len(user_likes), 1)

        # Toggle like for statusupdate off
        output = view()
        user_likes = self.util.get_likes("update", self.user_id)
        self.assertEqual(len(user_likes), 0)
        self.assertIn('(0)', output)
        self.assertIn('Like', output)
 def test_add_multi_portal(self):
     portal = api.portal.get()
     self.assertIsNotNone(portal)
     portal_request = portal.REQUEST
     tool = queryUtility(IMicroblogTool)
     for i in xrange(0, 10):
         su = StatusUpdate('Test {}'.format(str(i + 1)))
         tool.add(su)
     # running in sync mode, no need to sleep
     self.assertEqual(len(request_subscriber.messages), 10)
     self.assertIn(('Test 1', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 2', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 3', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 4', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 5', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 6', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 7', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 8', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 9', portal_request.getURL()),
                   request_subscriber.messages)
     self.assertIn(('Test 10', portal_request.getURL()),
                   request_subscriber.messages)
 def test_add_multi_portal(self):
     portal = api.portal.get()
     self.assertIsNotNone(portal)
     portal_path = '/'.join(portal.getPhysicalPath())
     tool = queryUtility(IMicroblogTool)
     for i in xrange(0, 10):
         su = StatusUpdate('Test {}'.format(str(i + 1)))
         if i == 5:
             time.sleep(1)
         # Next message triggers queue flush
         tool.add(su)
     # Here we need to sleep for some time to give the thread timer
     # queue committer in ploneintranet.microblog
     # time to commit the statuses.
     time.sleep(2)
     self.assertEqual(
         portal_subscriber.messages,
         [
             ('Test 1', portal_path),
             ('Test 2', portal_path),
             ('Test 3', portal_path),
             ('Test 4', portal_path),
             ('Test 5', portal_path),
             ('Test 6', portal_path),
             ('Test 7', portal_path),
             ('Test 8', portal_path),
             ('Test 9', portal_path),
             ('Test 10', portal_path)
         ]
     )
Ejemplo n.º 18
0
 def test_anon_cannot_delete(self):
     logout()
     su = StatusUpdate('foo')
     self.container.add(su)
     login(self.portal, 'user_jane')
     with self.assertRaises(Unauthorized):
         self.container.delete(su.id)
Ejemplo n.º 19
0
 def test_creator_delete(self):
     login(self.portal, 'user_steve')
     su = StatusUpdate('foo')
     self.container.add(su)
     self.container.delete(su.id)
     with self.assertRaises(KeyError):
         self.container.get(su.id)
Ejemplo n.º 20
0
    def test_status_update(self):
        ''' Let's try to create a status_update and inspect the created adapter
        '''
        with api.env.adopt_user('test_user_adapters_'):
            su = StatusUpdate(u'Test à')
            pm = api.portal.get_tool('ploneintranet_microblog')
            pm.add(su)

        pin = api.portal.get_tool('ploneintranet_notifications')
        message = pin.get_user_queue(api.user.get('test_user_adapters_'))[-1]

        self.assertEqual(message.predicate, 'STATUS_UPDATE')

        self.assertDictEqual(
            message.actors[0], {
                'fullname': 'Kelly Sj\xc3\xb6gren',
                'userid': 'test_user_adapters_',
                'email': '*****@*****.**'
            })

        self.assertIsInstance(message.obj['id'], long)
        self.assertEqual(message.obj['title'], u'Test \xe0')
        self.assertEqual(message.obj['url'], 'plone/@@stream/network')
        self.assertEqual(message.obj['read'], False)
        self.assertIsInstance(message.obj['message_last_modification_date'],
                              datetime)
Ejemplo n.º 21
0
 def test_nonmember_secured_read(self):
     login(self.portal, 'allan_neece')
     su = StatusUpdate('test #foo', self.workspace)
     self.tool.add(su)
     logout()
     login(self.portal, 'alice_lindstrom')
     # silently filters all you're not allowed to see
     self.assertFalse(su.id in self.tool.keys())
Ejemplo n.º 22
0
 def test_nonmember_unauthorized_get(self):
     login(self.portal, 'allan_neece')
     su = StatusUpdate('test #foo', self.workspace)
     self.tool.add(su)
     logout()
     login(self.portal, 'alice_lindstrom')
     # should raise, since Alice is not a member of the workspace
     self.assertRaises(Unauthorized, self.tool.get, su.id)
Ejemplo n.º 23
0
 def test_mentions_mapping(self):
     su = StatusUpdate('foo', mention_ids=['user_steve', ])
     self.container.add(su)
     found = [x for x in self.container._mentions_mapping.get('user_steve')]
     self.assertIn(su.id, found)
     self.container.delete(su.id)
     found = [x for x in self.container._mentions_mapping.get('user_steve')]
     self.assertNotIn(su.id, found)
Ejemplo n.º 24
0
 def test_mentions(self):
     test_user = api.user.create(email='*****@*****.**',
                                 username='******',
                                 properties={'fullname': 'Test User'})
     userid = test_user.getId()
     fullname = test_user.getProperty('fullname')
     su = StatusUpdate('foo', mention_ids=[userid])
     self.assertEqual(su.mentions, {userid: fullname})
Ejemplo n.º 25
0
 def test_tag_mapping(self):
     su = StatusUpdate('foo', tags=['foo', 'bar'])
     self.container.add(su)
     found = [x for x in self.container._tag_mapping.get('bar')]
     self.assertIn(su.id, found)
     self.container.delete(su.id)
     found = [x for x in self.container._tag_mapping.get('bar')]
     self.assertNotIn(su.id, found)
Ejemplo n.º 26
0
def create_stream(context, stream, files_dir):
    contexts_cache = {}
    microblog = queryUtility(IMicroblogTool)
    like_tool = getUtility(ILikesTool)
    microblog.clear()
    for status in stream:
        kwargs = {}
        if status['context']:
            if status['context'] not in contexts_cache:
                contexts_cache[status['context']] = api.content.get(
                    path='/' + decode(status['context']).lstrip('/')
                )
            kwargs['context'] = contexts_cache[status['context']]
        status_obj = StatusUpdate(status['text'], **kwargs)
        status_obj.userid = status['user']
        status_obj.creator = api.user.get(
            username=status['user']
        ).getUserName()
        offset_time = status['timestamp'] * 60
        status_obj.id -= int(offset_time * 1e6)
        status_obj.date = DateTime(time.time() - offset_time)
        microblog.add(status_obj)
        # THIS BREAKS BECAUSE DOCCONV. FIX DOCCONV, UNCOMMENT
        # if 'attachment' in status:
        #     attachment_definition = status['attachment']
        #     attachment_filename = os.path.join(
        #         files_dir,
        #         attachment_definition['filename']
        #     )
        #     attachment = context.openDataFile(attachment_filename)
        #     fake_field = FakeFileField(
        #         attachment_definition['filename'],
        #         attachment
        #     )
        #     attachment_obj = create_attachment(fake_field)
        #     attachments = IAttachmentStorage(status_obj)
        #     attachments.add(attachment_obj)

        # like some status-updates
        if 'likes' in status:
            for user_id in status['likes']:
                like_tool.like(
                    item_id=str(status_obj.id),
                    user_id=user_id,
                )
Ejemplo n.º 27
0
def create_stream(context, stream, files_dir):
    contexts_cache = {}
    microblog = queryUtility(IMicroblogTool)
    if len([x for x in microblog.keys()]) > 0:
        log.info("microblog already setup. skipping for speed.")
        return

    like_tool = getUtility(INetworkTool)
    microblog.clear()
    for status in stream:
        kwargs = {}
        microblog_context = status['microblog_context']
        if microblog_context:
            if microblog_context not in contexts_cache:
                contexts_cache[microblog_context] = api.content.get(
                    path='/' + decode(microblog_context).lstrip('/')
                )
            kwargs['microblog_context'] = contexts_cache[microblog_context]
        status_obj = StatusUpdate(status['text'], **kwargs)
        status_obj.userid = status['user']
        status_obj.creator = api.user.get(
            username=status['user']
        ).getUserName()
        offset_time = status['timestamp'] * 60
        status_obj.id -= int(offset_time * 1e6)
        status_obj.date = DateTime(time.time() - offset_time)
        # THIS BREAKS BECAUSE docconv.client.async.queueConversionJob FIXME
        # if 'attachment' in status:
        #     _definition = status['attachment']
        #     _filename = os.path.join(files_dir, _definition['filename'])
        #     _data = context.readDataFile(_filename)
        #     attachment_obj = create_attachment(_filename, _data)
        #     attachments = IAttachmentStorage(status_obj)
        #     attachments.add(attachment_obj)
        microblog.add(status_obj)

        # like some status-updates
        if 'likes' in status:
            for user_id in status['likes']:
                like_tool.like(
                    "update",
                    user_id=user_id,
                    item_id=str(status_obj.id),

                )
Ejemplo n.º 28
0
 def test_user_mapping(self):
     login(self.portal, 'user_steve')
     su = StatusUpdate('foo')
     self.container.add(su)
     found = [x for x in self.container._user_mapping.get('user_steve')]
     self.assertIn(su.id, found)
     self.container.delete(su.id)
     found = [x for x in self.container._user_mapping.get('user_steve')]
     self.assertNotIn(su.id, found)
Ejemplo n.º 29
0
    def test_attachments(self):
        su = StatusUpdate('foo bar')
        attachments = IAttachmentStorage(su)

        f = ATFile('data.dat')
        attachments.add(f)
        self.assertEqual([k for k in attachments.keys()], [f.getId()])
        attachments.remove(f.getId())
        self.assertEqual(len(attachments.keys()), 0)
Ejemplo n.º 30
0
def create_stream(context, stream, files_dir):
    contexts_cache = {}
    microblog = queryUtility(IMicroblogTool)
    if len([x for x in microblog.keys()]) > 0:
        log.info("microblog already setup. skipping for speed.")
        return

    like_tool = getUtility(INetworkTool)
    microblog.clear()
    for status in stream:
        kwargs = {}
        microblog_context = status['microblog_context']
        if microblog_context:
            if microblog_context not in contexts_cache:
                contexts_cache[microblog_context] = api.content.get(
                    path='/' + decode(microblog_context).lstrip('/'))
            kwargs['microblog_context'] = contexts_cache[microblog_context]
        status_obj = StatusUpdate(status['text'], **kwargs)
        status_obj.userid = status['user']
        status_obj.creator = api.user.get(
            username=status['user']).getUserName()
        offset_time = status['timestamp'] * 60
        status_obj.id -= int(offset_time * 1e6)
        status_obj.date = DateTime(time.time() - offset_time)
        # THIS BREAKS BECAUSE docconv.client.async.queueConversionJob FIXME
        # if 'attachment' in status:
        #     _definition = status['attachment']
        #     _filename = os.path.join(files_dir, _definition['filename'])
        #     _data = context.readDataFile(_filename)
        #     attachment_obj = create_attachment(_filename, _data)
        #     attachments = IAttachmentStorage(status_obj)
        #     attachments.add(attachment_obj)
        microblog.add(status_obj)

        # like some status-updates
        if 'likes' in status:
            for user_id in status['likes']:
                like_tool.like(
                    "update",
                    user_id=user_id,
                    item_id=str(status_obj.id),
                )
Ejemplo n.º 31
0
 def test_content_context_init_sets_microblog_context(self):
     self.portal.invokeFactory('Folder', 'f1', title=u"Folder 1")
     f1 = self.portal['f1']
     alsoProvides(f1, IMicroblogContext)
     doc = api.content.create(
         container=f1,
         type='Document',
         title='My document',
     )
     su1 = StatusUpdate('foo', content_context=doc)
     self.assertEqual(f1, su1.microblog_context)
Ejemplo n.º 32
0
 def test_normal_contentupdate_not_is_human_update(self):
     self.portal.invokeFactory('Folder', 'f1', title=u"Folder 1")
     f1 = self.portal['f1']
     alsoProvides(f1, IMicroblogContext)
     doc = api.content.create(
         container=f1,
         type='Document',
         title='My document',
     )
     su1 = StatusUpdate('', content_context=doc)
     self.assertFalse(su1.is_human_update)
Ejemplo n.º 33
0
 def test_thread_content_context(self):
     doc = api.content.create(
         container=self.portal,
         type='Document',
         title='My document',
     )
     api.content.transition(doc, to_state='published')
     found = [x for x in self.container.values()]
     su1 = found[0]
     su2 = StatusUpdate('foo', thread_id=su1.id)
     self.assertEqual(None, su2.microblog_context)
     self.assertEqual(doc, su2.content_context)
Ejemplo n.º 34
0
 def test_extracted_contentupdate_is_human_update(self):
     self.portal.invokeFactory('Folder', 'f1', title=u"Folder 1")
     f1 = self.portal['f1']
     alsoProvides(f1, IMicroblogContext)
     doc = api.content.create(
         container=f1,
         type='Document',
         title='My document',
     )
     su1 = StatusUpdate('I have some text. That makes me human',
                        content_context=doc)
     self.assertTrue(su1.is_human_update)
Ejemplo n.º 35
0
    def test_workspace_tile(self):
        ''' This will test the existence of the workspaces.tile
        and its functionality
        '''
        tile = api.content.get_view(
            'workspaces.tile',
            self.portal,
            self.request
        )
        su = StatusUpdate(
            'Proposal draft V1.0 # This is a mock!!!',
            **{
                'microblog_context': self.workspace,
            }
        )
        su.id = 123456789L
        su.creator = 'charlotte_holzer'
        su.date = DateTime('2008/02/14 18:43')
        mb = queryUtility(IMicroblogTool)
        mb.add(su)
        workspaces = tile.workspaces()
        self.assertEqual(len(workspaces), 1)

        demo_ws = workspaces[0]
        activities = demo_ws['activities']
        self.assertEqual(len(activities), 1)
        self.assertDictEqual(
            activities[0],
            {
                'object': 'Proposal draft V1.0 # This is a mock!!!',
                'subject': 'charlotte_holzer',
                'time': {
                    'datetime': '2008-02-14',
                    'title': '14 February 2008, 18:43'
                },
                'verb': 'posted'
            }
        )
Ejemplo n.º 36
0
def demo(context):

    if context.readDataFile('ploneintranet.socialsuite_demo.txt') is None:
        return

    portal = site = context.getSite()
    avatar_path = os.path.join(context._profile_path, 'avatars')

    # create users
    users = []
    for file_name in os.listdir(avatar_path):
        userid = str(file_name.split('.')[0])
        users.append(userid)
        properties = dict(
            fullname=" ".join([x.capitalize() for x in userid.split("_")]),
            location=random.choice(
                ("New York", "Chicago", "San Francisco",
                 "Paris", "Amsterdam", "Zurich")),
            description=" ".join(loremipsum.get_sentences(2)))
        try:
            api.user.create(email='*****@*****.**' % userid,
                            username=userid,
                            password='******',
                            properties=properties)
        except ValueError:
            user = api.user.get(username=userid)
            user.setMemberProperties(properties)

        portrait = context.openDataFile(file_name, 'avatars')
        scaled, mimetype = scale_image(portrait)
        portrait = Image(id=userid, file=scaled, title='')
        memberdata = getToolByName(site, 'portal_memberdata')
        memberdata._setPortrait(portrait, userid)

    # setup social network
    graph = queryUtility(INetworkGraph)
    graph.clear()
    testusers = ['clare_presler', 'kurt_silvio']
    graph.follow("user", testusers[0], testusers[1])
    # give clare som extra followers
    for fan in ['christian_stoner', 'guy_hachey', 'jamie_jacko']:
        graph.follow("user", testusers[0], fan)
    # fully random followers
    for i in xrange(100):
        followee = random.choice(users)
        follower = random.choice(users)
        if followee in testusers or follower in testusers \
                or followee == follower:
            continue
        else:
            graph.follow("user", followee, follower)

    # setup publicly accessible folder and document
    portal.invokeFactory('Folder', 'public', title=u"Public Folder")
    public = portal['public']
    public.invokeFactory('Document', 'd1', title=u"Public Document")

    # create and fill a local IMicroblogContext workspace
    workspace_users = ['clare_presler',
                       'dollie_nocera',
                       'esmeralda_claassen',
                       'pearlie_whitby']
    if 'workspace' not in portal:
        portal.invokeFactory('Folder', 'workspace',
                             title=u"Secure Workspace")
        # enable local microblog
        directlyProvides(portal.workspace, IMicroblogContext)
        # in testing we don't have the 'normal' default workflow
        workflowTool = getToolByName(portal, 'portal_workflow')
        if workflowTool.getInfoFor(portal.workspace,
                                   'review_state') != 'private':
            workflowTool.doActionFor(portal.workspace, 'hide')
        # share workspace with some users
        for userid in workspace_users:
            api.user.grant_roles(username=userid,
                                 obj=portal.workspace,
                                 roles=['Contributor', 'Reader', 'Editor'])
        # update object_provides + workflow state + sharing indexes
        portal.workspace.reindexObject()

    # microblog random loremipsum
    # prepare microblog
    microblog = queryUtility(IMicroblogTool)
    microblog.clear()  # wipe all
    tags = ("hr", "marketing", "fail", "innovation", "learning", "easy",
            "newbiz", "conference", "help", "checkthisout")
    for i in xrange(100):
        # select random user
        userid = random.choice(users)
        # generate text
        text = " ".join(loremipsum.get_sentences(3))
        if random.choice((True, False)):
            text += " #%s" % random.choice(tags)
        if userid in workspace_users:
            # workspace
            status = StatusUpdate(text, context=portal.workspace,
                                  tags=['girlspace'])
        else:
            # global
            status = StatusUpdate(text)
        status.userid = userid
        status.creator = " ".join([x.capitalize() for x in userid.split("_")])
        # distribute most over last week
        if i < 90:
            offset_time = random.random() * 3600 * 24 * 7
            status.id -= int(offset_time * 1e6)
            status.date = DateTime(time.time() - offset_time)
        microblog.add(status)

    # microblog deterministic test content most recent
    # workspace
    t0 = ('Workspaces can have local microblogs and activitystreams. '
          'Local activitystreams show only local status updates. '
          'Microblog updates will show globally only for users who '
          'have the right permissions. This demo has a #girlspace workspace.')
    s0 = StatusUpdate(t0, context=portal.workspace, tags=['girlspace'])
    s0.userid = workspace_users[0]  # clare
    s0.creator = " ".join([x.capitalize() for x in s0.userid.split("_")])
    microblog.add(s0)
    # global
    t1 = ('The "My Network" section only shows updates '
          'of people you are following.')
    s1 = StatusUpdate(t1)
    s1.userid = testusers[0]  # clare
    s1.creator = " ".join([x.capitalize() for x in s1.userid.split("_")])
    microblog.add(s1)
    t2 = 'The "Explore" section shows all updates of all people.'
    s2 = StatusUpdate(t2)
    s2.userid = testusers[1]  # kurt
    s2.creator = " ".join([x.capitalize() for x in s2.userid.split("_")])
    microblog.add(s2)
    t3 = 'The #demo hashtag demonstrates that you can filter on topic'
    s3 = StatusUpdate(t3, tags=['demo'])
    s3.userid = s2.userid  # kurt
    s3.creator = s2.creator
    microblog.add(s3)

    # commit
    microblog.flush_queue()
    transaction.commit()