Exemplo n.º 1
0
    def setUp(self):
        s = Store()
        installOn(QuotientPreferenceCollection(store=s), s)
        installOn(people.Organizer(store=s), s)

        self.store = s
        self.md = MessageDetail(Message(store=s, subject=u'a/b/c', sender=u''))
Exemplo n.º 2
0
 def getMessageDetail(self, key):
     """
     Return the MessageDetail widget with the given webID.
     """
     detail = MessageDetail(self.messages[key])
     detail.setFragmentParent(self)
     return detail
Exemplo n.º 3
0
    def setUp(self, peopleAddresses, sender, recipient, cc):
        """
        Setup & populate a store with a L{xquotient.exmess.Message} which has
        correspondents set to the values of C{cc} and C{recipient}, and a
        person for each email address in C{peopleAddresses}

        @param sender: address to use as the value of the C{from} header
        @type cc: C{unicode}

        @param recipient: address to use as the value of the C{recipient}
        attribute
        @type cc: C{unicode}

        @param cc: addresses to use as the value of the C{cc} header
        @type cc: C{unicode}

        @type headers: C{dict} of C{unicode}
        """
        headers = {u'from': sender}
        if cc:
            headers[u'cc'] = cc
        msg = self._setUpMsg(headers)
        msg.recipient = recipient
        for addr in peopleAddresses:
            people.EmailAddress(
                store=msg.store,
                address=addr,
                person=people.Person(
                    store=msg.store,
                    organizer=self.organizer))
        f = MessageDetail(msg)
        f.setFragmentParent(self)
        f.docFactory = getLoader(f.fragmentName)
        return f
 def getMessageDetail(self, key):
     """
     Return the MessageDetail widget with the given webID.
     """
     detail = MessageDetail(self.messages[key])
     detail.setFragmentParent(self)
     return detail
Exemplo n.º 5
0
    def setUp(self):
        # XXX Incorrect setup.  See xquotient.test.test_compose.CompositionTestMixin
        self.store = Store(self.mktemp())

        LoginMethod(store=self.store,
                    internal=False,
                    protocol=u'email',
                    localpart=u'recipient',
                    domain=u'host',
                    verified=True,
                    account=self.store)

        self.fromAddr = smtpout.FromAddress(address=u'recipient@host',
                                            store=self.store)
        self.inbox = inbox.Inbox(store=self.store)
        installOn(self.inbox, self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)
        self.defaultFromAddress = self.store.findUnique(
            smtpout.FromAddress, smtpout.FromAddress._address == None)

        self.message = testMessageFactory(
            store=self.store,
            spam=False,
            impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.messageDetail = MessageDetail(self.message)
Exemplo n.º 6
0
class PersonStanTestCase(TestCase):
    """
    Tests for L{xquotient.exmess.MessageDetail.personStanFromEmailAddress}
    """
    def setUp(self):
        s = Store()
        installOn(QuotientPreferenceCollection(store=s), s)
        installOn(people.Organizer(store=s), s)

        self.store = s
        self.md = MessageDetail(Message(store=s, subject=u'a/b/c', sender=u''))

    def _checkNoAddressBookStan(self, stan, email):
        """
        Check that C{stan} looks like something sane to display for email
        address C{email} address when there is no addressbook

        @type stan: some stan
        @param email: the email address that the stan is a representation of
        @type email: L{xquotient.mimeutil.EmailAddress}
        """
        self.assertEqual(stan.attributes['title'], email.email)
        self.assertEqual(stan.children, [email.anyDisplayName()])

    def test_noOrganizer(self):
        """
        Test L{xquotient.exmess.MessageDetail.personStanFromEmailAddress} when
        there is no L{xmantissa.people.Organizer} in the store
        """
        self.md.organizer = None

        email = mimeutil.EmailAddress('foo@bar', mimeEncoded=False)
        stan = self.md.personStanFromEmailAddress(email)
        self._checkNoAddressBookStan(stan, email)

    def test_notAPerson(self):
        """
        Test L{xquotient.exmess.MessageDetail.personStanFromEmailAddress} when
        there is a L{xmantissa.people.Organizer}, but the email we give isn't
        assigned to a person
        """
        email = mimeutil.EmailAddress('foo@bar', mimeEncoded=False)
        res = self.md.personStanFromEmailAddress(email)
        self.failUnless(isinstance(res, SenderPersonFragment))

    def test_aPerson(self):
        """
        Test L{xquotient.exmess.MessageDetail.personStanFromEmailAddress} when
        there is a L{xmantissa.people.Organizer}, and the email we give is
        assigned to a person
        """
        email = mimeutil.EmailAddress('foo@bar', mimeEncoded=False)

        people.EmailAddress(store=self.store,
                            address=u'foo@bar',
                            person=people.Person(store=self.store))

        res = self.md.personStanFromEmailAddress(email)
        self.failUnless(isinstance(res, people.PersonFragment))
Exemplo n.º 7
0
 def setUp(self):
     """
     Setup & populate a store, and render a
     L{xquotient.exmess.MessageDetail}
     """
     f = MessageDetail(self._setUpMsg())
     f.setFragmentParent(self)
     f.docFactory = getLoader(f.fragmentName)
     return f
Exemplo n.º 8
0
 def test_inlineMessageAttachments(self):
     """
     Test that message/rfc822 parts get rendered inline in message
     detail.
     """
     mr = self.setUpMailStuff()
     msg = mr.feedStringNow(messageWithEmbeddedMessage).message
     md = MessageDetail(msg)
     am = list(md.render_attachedMessages(None, None))
     self.assertEqual(len(am), 1)
     self.assertEqual(type(am[0]), ActionlessMessageDetail)
Exemplo n.º 9
0
 def test_inlineMessageAttachments(self):
     """
     Test that message/rfc822 parts get rendered inline in message
     detail.
     """
     mr = self.setUpMailStuff()
     msg = mr.feedStringNow(messageWithEmbeddedMessage).message
     md = MessageDetail(msg)
     am = list(md.render_attachedMessages(None, None))
     self.assertEqual(len(am), 1)
     self.assertEqual(type(am[0]), ActionlessMessageDetail)
Exemplo n.º 10
0
 def setUp(self, key):
     """
     Setup & populate a store, and render a
     L{xquotient.exmess.MessageDetail}
     """
     msg = self._setUpMsg()
     self._stores[key] = msg.store
     f = MessageDetail(msg)
     f.setFragmentParent(self)
     f.docFactory = getLoader(f.fragmentName)
     return f
Exemplo n.º 11
0
    def setUp(self, headers):
        """
        Setup & populate a store with a L{xquotient.exmess.Message} which has
        the headers in C{headers} set to the given values

        @type headers: C{dict} of C{unicode}
        """
        msg = self._setUpMsg(headers)
        f = MessageDetail(msg)
        f.setFragmentParent(self)
        f.docFactory = getLoader(f.fragmentName)
        return f
Exemplo n.º 12
0
 def test_messageRendering(self):
     """
     Test rendering of message detail for an extremely complex message.
     """
     msg = self.substore.findUnique(Message)
     msg.classifyClean()
     return renderLivePage(ThemedFragmentWrapper(MessageDetail(msg)))
Exemplo n.º 13
0
class MoreComposeActionsTestCase(TestCase):
    """
    Test compose-action related stuff that requires an on-disk store.
    """
    def setUp(self):
        self.store = Store(dbdir=self.mktemp())

        installOn(inbox.Inbox(store=self.store), self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)

        LoginMethod(store=self.store,
                    internal=False,
                    protocol=u'email',
                    localpart=u'recipient',
                    domain=u'host',
                    verified=True,
                    account=self.store)

        self.msg = testMessageFactory(
            store=self.store,
            spam=False,
            impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.msgDetail = MessageDetail(self.msg)

    def test_setStatus(self):
        """
        Test that statuses requested for parent messages get set after
        the created message is sent.
        """
        # (bypass Item.__setattr__)
        object.__setattr__(self.composer, 'sendMessage',
                           lambda fromA, toA, msg: None)

        class MsgStub:
            impl = MIMEPart()
            statuses = None

            def addStatus(self, status):
                if self.statuses is None:
                    self.statuses = [status]
                else:
                    self.statuses.append(status)

        parent = MsgStub()
        parent.impl.headers = [
            Header("message-id", "<*****@*****.**>"),
            Header("references", "<*****@*****.**>"),
            Header("references", "<*****@*****.**>")
        ]

        toAddresses = [
            mimeutil.EmailAddress('*****@*****.**', mimeEncoded=False)
        ]
        cf = self.msgDetail._composeSomething(toAddresses, u'Sup dood',
                                              u'A body', [], parent,
                                              REPLIED_STATUS)
        cf._sendOrSave(self.store.findFirst(smtpout.FromAddress), toAddresses,
                       u'Sup dood', u'A body', [], [], [], False)
        self.assertEqual(parent.statuses, [REPLIED_STATUS])
Exemplo n.º 14
0
    def setUp(self):
        s = Store()
        installOn(QuotientPreferenceCollection(store=s), s)
        installOn(people.Organizer(store=s), s)

        self.store = s
        self.md = MessageDetail(
            Message(store=s, subject=u'a/b/c', sender=u''))
Exemplo n.º 15
0
 def setUp(self):
     """
     Create an entirely fake MessageDetail, circumventing the rather complex
     constructor, so we can call the one method we're interested in.
     """
     self.messageDetail = MessageDetail.__new__(MessageDetail)
     self.messageDetail.original = self
     self.messageDetail.translator = self
     self.storeID = 1234
Exemplo n.º 16
0
 def setUp(self):
     """
     Create an entirely fake MessageDetail, circumventing the rather complex
     constructor, so we can call the one method we're interested in.
     """
     self.messageDetail = MessageDetail.__new__(MessageDetail)
     self.messageDetail.original = self
     self.messageDetail.translator = self
     self.storeID = 1234
Exemplo n.º 17
0
class MoreComposeActionsTestCase(TestCase):
    """
    Test compose-action related stuff that requires an on-disk store.
    """

    def setUp(self):
        self.store = Store(dbdir=self.mktemp())

        installOn(inbox.Inbox(store=self.store), self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)

        LoginMethod(store=self.store, internal=False, protocol=u'email',
                localpart=u'recipient', domain=u'host', verified=True,
                account=self.store)

        self.msg = testMessageFactory(
                    store=self.store,
                    spam=False,
                    impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.msgDetail = MessageDetail(self.msg)



    def test_setStatus(self):
        """
        Test that statuses requested for parent messages get set after
        the created message is sent.
        """
        # (bypass Item.__setattr__)
        object.__setattr__(self.composer, 'sendMessage',
                           lambda fromA, toA, msg: None)
        class MsgStub:
            impl = MIMEPart()
            statuses = None
            def addStatus(self, status):
                if self.statuses is None:
                    self.statuses = [status]
                else:
                    self.statuses.append(status)

        parent = MsgStub()
        parent.impl.headers = [Header("message-id", "<*****@*****.**>"),
                               Header("references", "<*****@*****.**>"),
                               Header("references", "<*****@*****.**>")]

        toAddresses = [mimeutil.EmailAddress(
            '*****@*****.**',
            mimeEncoded=False)]
        cf = self.msgDetail._composeSomething(
            toAddresses,
            u'Sup dood', u'A body', [], parent, REPLIED_STATUS)
        cf._sendOrSave(self.store.findFirst(smtpout.FromAddress),
                       toAddresses, u'Sup dood', u'A body',
                       [], [], [], False)
        self.assertEqual(parent.statuses, [REPLIED_STATUS])
Exemplo n.º 18
0
 def testZipFileName(self):
     """
     Test L{xquotient.exmess.MessageDetail._getZipFileName}
     """
     s = Store()
     installOn(PrivateApplication(store=s), s)
     installOn(QuotientPreferenceCollection(store=s), s)
     md = MessageDetail(
         Message(store=s, subject=u'a/b/c', sender=u'foo@bar'))
     self.assertEqual(md.zipFileName, '*****@*****.**')
Exemplo n.º 19
0
    def setUp(self):
        self.store = Store(dbdir=self.mktemp())

        installOn(inbox.Inbox(store=self.store), self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)

        LoginMethod(store=self.store,
                    internal=False,
                    protocol=u'email',
                    localpart=u'recipient',
                    domain=u'host',
                    verified=True,
                    account=self.store)

        self.msg = testMessageFactory(
            store=self.store,
            spam=False,
            impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.msgDetail = MessageDetail(self.msg)
Exemplo n.º 20
0
    def setUp(self):
        self.store = Store(dbdir=self.mktemp())

        installOn(inbox.Inbox(store=self.store), self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)

        LoginMethod(store=self.store, internal=False, protocol=u'email',
                localpart=u'recipient', domain=u'host', verified=True,
                account=self.store)

        self.msg = testMessageFactory(
                    store=self.store,
                    spam=False,
                    impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.msgDetail = MessageDetail(self.msg)
Exemplo n.º 21
0
    def setUp(self):
        # XXX Incorrect setup.  See xquotient.test.test_compose.CompositionTestMixin
        self.store = Store(self.mktemp())

        LoginMethod(store=self.store, internal=False, protocol=u'email',
                localpart=u'recipient', domain=u'host', verified=True,
                account=self.store)

        self.fromAddr = smtpout.FromAddress(
            address=u'recipient@host', store=self.store)
        self.inbox = inbox.Inbox(store=self.store)
        installOn(self.inbox, self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)
        self.defaultFromAddress = self.store.findUnique(
            smtpout.FromAddress, smtpout.FromAddress._address == None)

        self.message = testMessageFactory(
                    store=self.store,
                    spam=False,
                    impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.messageDetail = MessageDetail(self.message)
Exemplo n.º 22
0
class PersonStanTestCase(TestCase):
    """
    Tests for L{xquotient.exmess.MessageDetail.personStanFromEmailAddress}
    """
    def setUp(self):
        s = Store()
        installOn(QuotientPreferenceCollection(store=s), s)
        installOn(people.Organizer(store=s), s)

        self.store = s
        self.md = MessageDetail(
            Message(store=s, subject=u'a/b/c', sender=u''))

    def _checkNoAddressBookStan(self, stan, email):
        """
        Check that C{stan} looks like something sane to display for email
        address C{email} address when there is no addressbook

        @type stan: some stan
        @param email: the email address that the stan is a representation of
        @type email: L{xquotient.mimeutil.EmailAddress}
        """
        self.assertEqual(stan.attributes['title'], email.email)
        self.assertEqual(stan.children, [email.anyDisplayName()])

    def test_noOrganizer(self):
        """
        Test L{xquotient.exmess.MessageDetail.personStanFromEmailAddress} when
        there is no L{xmantissa.people.Organizer} in the store
        """
        self.md.organizer = None

        email = mimeutil.EmailAddress('foo@bar', mimeEncoded=False)
        stan = self.md.personStanFromEmailAddress(email)
        self._checkNoAddressBookStan(stan, email)

    def test_notAPerson(self):
        """
        Test L{xquotient.exmess.MessageDetail.personStanFromEmailAddress} when
        there is a L{xmantissa.people.Organizer}, but the email we give isn't
        assigned to a person
        """
        email = mimeutil.EmailAddress('foo@bar', mimeEncoded=False)
        res = self.md.personStanFromEmailAddress(email)
        self.failUnless(isinstance(res, SenderPersonFragment))

    def test_aPerson(self):
        """
        Test L{xquotient.exmess.MessageDetail.personStanFromEmailAddress} when
        there is a L{xmantissa.people.Organizer}, and the email we give is
        assigned to a person
        """
        email = mimeutil.EmailAddress('foo@bar', mimeEncoded=False)

        people.EmailAddress(
            store=self.store,
            address=u'foo@bar',
            person=people.Person(store=self.store))

        res = self.md.personStanFromEmailAddress(email)
        self.failUnless(isinstance(res, people.PersonFragment))
Exemplo n.º 23
0
class ComposeActionsTestCase(TestCase):
    """
    Tests for the compose-related actions of L{xquotient.exmess.MessageDetail}
    (reply, forward, etc) and related functionality
    """
    def setUp(self):
        # XXX Incorrect setup.  See xquotient.test.test_compose.CompositionTestMixin
        self.store = Store(self.mktemp())

        LoginMethod(store=self.store, internal=False, protocol=u'email',
                localpart=u'recipient', domain=u'host', verified=True,
                account=self.store)

        self.fromAddr = smtpout.FromAddress(
            address=u'recipient@host', store=self.store)
        self.inbox = inbox.Inbox(store=self.store)
        installOn(self.inbox, self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)
        self.defaultFromAddress = self.store.findUnique(
            smtpout.FromAddress, smtpout.FromAddress._address == None)

        self.message = testMessageFactory(
                    store=self.store,
                    spam=False,
                    impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.messageDetail = MessageDetail(self.message)


    def _recipientsToStrings(self, recipients):
        """
        Convert a mapping of "strings to lists of
        L{xquotient.mimeutil.EmailAddress} instances" into a mapping of
        "strings to lists of string email addresses"
        """
        result = {}
        for (k, v) in recipients.iteritems():
            result[k] = list(e.email for e in v)
        return result


    def test_replyToAll(self):
        """
        Test L{xquotient.exmess.MessageDetail.replyAll}
        """
        self.assertEquals(
            self._recipientsToStrings(
                self.messageDetail.replyAll().recipients),
            {'bcc': ['blind-copy@host'],
             'cc': ['copy@host'],
             'to': ['sender@host', 'recipient2@host']})


    def test_replyToAllFromAddress(self):
        """
        Test that L{xquotient.exmess.MessageDetail.replyAll} doesn't include
        addresses of L{xquotient.smtpout.FromAddress} items that exist in the
        same store as the message that is being replied to
        """
        addrs = set(u'blind-copy@host copy@host sender@host recipient2@host'.split())
        for addr in addrs:
            fromAddr = smtpout.FromAddress(address=addr, store=self.message.store)
            gotAddrs = set()
            for l in self.messageDetail.replyAll().recipients.itervalues():
                gotAddrs.update(e.email for e in l)
            self.assertEquals(
                gotAddrs,
                addrs - set([addr]))
            fromAddr.deleteFromStore()


    def test_createDraftComposeFragment(self):
        """
        Verify that an instance of L{DraftComposeFragment} which refers
        to the correct draft item is returned by L{InboxScreen.editDraft}.
        """
        fragment = self.messageDetail.editDraft()
        self.failUnless(
            isinstance(fragment, compose.DraftComposeFragment),
            "Got %r instead of DraftComposeFragment" % (fragment,))
        self.assertIdentical(fragment._savedDraft, self.message)


    def test_slotData(self):
        """
        Verify that L{DraftComposeFragment.slotData} returns a dictionary
        which reflects the message which was used as the draft.
        """
        subject = u'subject text'
        body = u'hello, world?\n'
        to = u'*****@*****.**'
        cc = u'*****@*****.**'
        bcc = u'*****@*****.**'
        message = createMessage(
            self.composer,
            None,
            None,
            self.defaultFromAddress,
            [mimeutil.EmailAddress(to, mimeEncoded=False)],
            subject,
            body,
            [mimeutil.EmailAddress(cc, mimeEncoded=False)],
            [mimeutil.EmailAddress(bcc, mimeEncoded=False)],
            [],
            )
        fragment = self.messageDetail._composeSomething(draft=message)
        slotData = fragment.slotData()
        self.assertEqual(slotData['to'], to)
        self.assertEqual(slotData['from'][0], self.defaultFromAddress)
        self.assertEqual(slotData['subject'], subject)
        self.assertEqual(slotData['message-body'], body)
        self.assertEqual(slotData['cc'], cc)

        # XXX This assertion should succeed.
        # self.assertEqual(slotData['bcc'], bcc)



    def test_addPersonForm(self):
        """
        Test that the add-person form is created correctly.
        """
        installOn(people.AddPerson(store=self.store), self.store)
        apf = self.messageDetail.render_addPersonFragment(None, None)
        self.assertEquals(apf.organizer,
                          self.store.findUnique(people.Organizer))
Exemplo n.º 24
0
class ComposeActionsTestCase(TestCase):
    """
    Tests for the compose-related actions of L{xquotient.exmess.MessageDetail}
    (reply, forward, etc) and related functionality
    """
    def setUp(self):
        # XXX Incorrect setup.  See xquotient.test.test_compose.CompositionTestMixin
        self.store = Store(self.mktemp())

        LoginMethod(store=self.store,
                    internal=False,
                    protocol=u'email',
                    localpart=u'recipient',
                    domain=u'host',
                    verified=True,
                    account=self.store)

        self.fromAddr = smtpout.FromAddress(address=u'recipient@host',
                                            store=self.store)
        self.inbox = inbox.Inbox(store=self.store)
        installOn(self.inbox, self.store)
        self.composer = compose.Composer(store=self.store)
        installOn(self.composer, self.store)
        self.defaultFromAddress = self.store.findUnique(
            smtpout.FromAddress, smtpout.FromAddress._address == None)

        self.message = testMessageFactory(
            store=self.store,
            spam=False,
            impl=DummyMessageImplWithABunchOfAddresses(store=self.store))
        self.messageDetail = MessageDetail(self.message)

    def _recipientsToStrings(self, recipients):
        """
        Convert a mapping of "strings to lists of
        L{xquotient.mimeutil.EmailAddress} instances" into a mapping of
        "strings to lists of string email addresses"
        """
        result = {}
        for (k, v) in recipients.iteritems():
            result[k] = list(e.email for e in v)
        return result

    def test_replyToAll(self):
        """
        Test L{xquotient.exmess.MessageDetail.replyAll}
        """
        self.assertEquals(
            self._recipientsToStrings(
                self.messageDetail.replyAll().recipients), {
                    'bcc': ['blind-copy@host'],
                    'cc': ['copy@host'],
                    'to': ['sender@host', 'recipient2@host']
                })

    def test_replyToAllFromAddress(self):
        """
        Test that L{xquotient.exmess.MessageDetail.replyAll} doesn't include
        addresses of L{xquotient.smtpout.FromAddress} items that exist in the
        same store as the message that is being replied to
        """
        addrs = set(
            u'blind-copy@host copy@host sender@host recipient2@host'.split())
        for addr in addrs:
            fromAddr = smtpout.FromAddress(address=addr,
                                           store=self.message.store)
            gotAddrs = set()
            for l in self.messageDetail.replyAll().recipients.itervalues():
                gotAddrs.update(e.email for e in l)
            self.assertEquals(gotAddrs, addrs - set([addr]))
            fromAddr.deleteFromStore()

    def test_createDraftComposeFragment(self):
        """
        Verify that an instance of L{DraftComposeFragment} which refers
        to the correct draft item is returned by L{InboxScreen.editDraft}.
        """
        fragment = self.messageDetail.editDraft()
        self.failUnless(
            isinstance(fragment, compose.DraftComposeFragment),
            "Got %r instead of DraftComposeFragment" % (fragment, ))
        self.assertIdentical(fragment._savedDraft, self.message)

    def test_slotData(self):
        """
        Verify that L{DraftComposeFragment.slotData} returns a dictionary
        which reflects the message which was used as the draft.
        """
        subject = u'subject text'
        body = u'hello, world?\n'
        to = u'*****@*****.**'
        cc = u'*****@*****.**'
        bcc = u'*****@*****.**'
        message = createMessage(
            self.composer,
            None,
            None,
            self.defaultFromAddress,
            [mimeutil.EmailAddress(to, mimeEncoded=False)],
            subject,
            body,
            [mimeutil.EmailAddress(cc, mimeEncoded=False)],
            [mimeutil.EmailAddress(bcc, mimeEncoded=False)],
            [],
        )
        fragment = self.messageDetail._composeSomething(draft=message)
        slotData = fragment.slotData()
        self.assertEqual(slotData['to'], to)
        self.assertEqual(slotData['from'][0], self.defaultFromAddress)
        self.assertEqual(slotData['subject'], subject)
        self.assertEqual(slotData['message-body'], body)
        self.assertEqual(slotData['cc'], cc)

        # XXX This assertion should succeed.
        # self.assertEqual(slotData['bcc'], bcc)

    def test_addPersonForm(self):
        """
        Test that the add-person form is created correctly.
        """
        installOn(people.AddPerson(store=self.store), self.store)
        apf = self.messageDetail.render_addPersonFragment(None, None)
        self.assertEquals(apf.organizer,
                          self.store.findUnique(people.Organizer))