############################################################################## # # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """ Unit tests for Document module. $Id: test_Document.py 40450 2005-12-01 16:56:13Z yuppie $ """ import unittest import Testing from os.path import abspath from os.path import dirname from os.path import join as path_join from re import compile from StringIO import StringIO from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate from DocumentTemplate.DT_Util import html_quote from Products.CMFCore.tests.base.content import BASIC_HTML from Products.CMFCore.tests.base.content import BASIC_STRUCTUREDTEXT from Products.CMFCore.tests.base.content import DOCTYPE from Products.CMFCore.tests.base.content import ENTITY_IN_TITLE from Products.CMFCore.tests.base.content import FAUX_HTML_LEADING_TEXT from Products.CMFCore.tests.base.content import HTML_TEMPLATE from Products.CMFCore.tests.base.content import SIMPLE_HTML from Products.CMFCore.tests.base.content import SIMPLE_STRUCTUREDTEXT from Products.CMFCore.tests.base.content import SIMPLE_XHTML from Products.CMFCore.tests.base.content import STX_NO_HEADERS from Products.CMFCore.tests.base.content import STX_NO_HEADERS_BUT_COLON from Products.CMFCore.tests.base.content import STX_WITH_HTML from Products.CMFCore.tests.base.dummy import DummySite from Products.CMFCore.tests.base.testcase import RequestTest from Products.CMFCore.tests.base.tidata import FTIDATA_CMF15 from Products.CMFCore.TypesTool import FactoryTypeInformation as FTI from Products.CMFCore.TypesTool import TypesTool from Products.CMFDefault import utils class RequestTestBase(RequestTest): def _getTargetClass(self): from Products.CMFDefault.Document import Document return Document def _makeOne(self, *args, **kw): return self._getTargetClass()(*args, **kw) class DocumentTests(RequestTestBase): def test_z2interfaces(self): from Interface.Verify import verifyClass from Products.CMFCore.interfaces.Contentish \ import Contentish as IContentish from Products.CMFCore.interfaces.DublinCore \ import CatalogableDublinCore as ICatalogableDublinCore from Products.CMFCore.interfaces.DublinCore \ import DublinCore as IDublinCore from Products.CMFCore.interfaces.DublinCore \ import MutableDublinCore as IMutableDublinCore from Products.CMFCore.interfaces.Dynamic \ import DynamicType as IDynamicType from Products.CMFDefault.Document import Document from Products.CMFDefault.interfaces.Document import IDocument from Products.CMFDefault.interfaces.Document import IMutableDocument verifyClass(ICatalogableDublinCore, Document) verifyClass(IContentish, Document) verifyClass(IDocument, Document) verifyClass(IDublinCore, Document) verifyClass(IDynamicType, Document) verifyClass(IMutableDocument, Document) verifyClass(IMutableDublinCore, Document) def test_z3interfaces(self): from zope.interface.verify import verifyClass from Products.CMFCore.interfaces import ICatalogableDublinCore from Products.CMFCore.interfaces import IContentish from Products.CMFCore.interfaces import IDublinCore from Products.CMFCore.interfaces import IDynamicType from Products.CMFCore.interfaces import IMutableDublinCore from Products.CMFDefault.interfaces import IDocument from Products.CMFDefault.interfaces import IMutableDocument from Products.CMFDefault.Document import Document verifyClass(ICatalogableDublinCore, Document) verifyClass(IContentish, Document) verifyClass(IDocument, Document) verifyClass(IDublinCore, Document) verifyClass(IDynamicType, Document) verifyClass(IMutableDocument, Document) verifyClass(IMutableDublinCore, Document) def test_Empty(self): d = self._makeOne('foo', text_format='structured-text') self.assertEqual( d.title, '' ) self.assertEqual( d.description, '' ) self.assertEqual( d.text, '' ) self.assertEqual( d.text_format, 'structured-text' ) self.assertEqual( d._stx_level, 1 ) self.assertEqual( d.get_size(), 0 ) def test_editBasicHTML(self): d = self._makeOne('foo') d.edit('html', BASIC_HTML) self.failUnless( hasattr(d, 'cooked_text') ) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.text.find(''), -1 ) self.assertEqual( d.cooked_text, '\n

Not a lot here

\n ' ) # Since the format is html, the STX level operands should # have no effect. ct = d.CookedBody(stx_level=3, setlevel=1) self.assertEqual( d._stx_level, 1 ) def test_editSimpleXHTML(self): d = self._makeOne('foo') d.edit('html', SIMPLE_XHTML) self.failUnless( hasattr(d, 'cooked_text') ) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.cooked_text, '\n

Not a lot here

\n ') def test_UpperedHtml(self): self.REQUEST['BODY'] = BASIC_HTML.upper() d = self._makeOne('foo') d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.title, 'TITLE IN TAG' ) self.assertEqual( d.text.find('with a newline') self.assertEqual( d.get_size(), len(PLAIN_TEXT) ) def test_EditStructuredTextWithHTML(self): d = self._makeOne('foo') d.edit(text_format='structured-text', text=STX_WITH_HTML) self.assertEqual( d.Format(), 'text/plain' ) self.assertEqual( d.get_size(), len(STX_WITH_HTML) ) def test_StructuredText(self): self.REQUEST['BODY'] = BASIC_STRUCTUREDTEXT d = self._makeOne('foo') d.PUT(self.REQUEST, self.RESPONSE) self.failUnless( hasattr(d, 'cooked_text') ) self.assertEqual( d.Format(), 'text/plain' ) self.assertEqual( d.Title(), 'My Document' ) self.assertEqual( d.Description(), 'A document by me' ) self.assertEqual( len(d.Contributors()), 3 ) self.failUnless( d.cooked_text.find('

') >= 0 ) self.failUnless( d.CookedBody().find('= 0 ) # Make sure extra HTML is NOT found self.failUnless( d.cooked_text.find('') < 0 ) self.failUnless( d.cooked_text.find('<body>') < 0 ) # test subject/keyword headers subj = list(d.Subject()) self.assertEqual( len(subj), 4 ) subj.sort() self.assertEqual( subj, [ 'content management' , 'framework' , 'unit tests' , 'zope' ] ) def test_STX_Levels(self): d = self._makeOne('foo') d.edit(text_format='structured-text', text=BASIC_STRUCTUREDTEXT) self.assertEqual( d._stx_level, 1 ) ct = d.CookedBody() self.failUnless( d.CookedBody().find('<h1') >= 0 ) self.assertEqual( d._stx_level, 1 ) ct = d.CookedBody(stx_level=2) self.failIf( ct.find('<h1') >= 0 ) self.failUnless( ct.find('<h2') >= 0 ) self.assertEqual( d._stx_level, 1 ) ct = d.CookedBody(stx_level=2, setlevel=1) self.failIf( ct.find('<h1') >= 0 ) self.failUnless( ct.find('<h2') >= 0 ) self.assertEqual( d._stx_level, 2 ) ct = d.CookedBody() self.assertEqual( d._stx_level, 2 ) self.failIf( d.CookedBody().find('<h1') >= 0 ) self.failUnless( d.CookedBody().find('<h2') >= 0 ) def test_Init(self): self.REQUEST['BODY']=BASIC_STRUCTUREDTEXT d = self._makeOne('foo') d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Format(), 'text/plain' ) self.assertEqual( d.Title(), 'My Document' ) self.assertEqual( d.Description(), 'A document by me' ) self.assertEqual( len(d.Contributors()), 3 ) self.failUnless( d.cooked_text.find('<p>') >= 0 ) d = self._makeOne('foo', text='') self.REQUEST['BODY']=BASIC_HTML d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.Title(), 'Title in tag' ) self.assertEqual( len(d.Contributors()), 3 ) d = self._makeOne('foo', text_format='structured-text', title='Foodoc') self.assertEqual( d.text, '' ) self.failIf( d.CookedBody() ) self.assertEqual( d.title, 'Foodoc' ) self.assertEqual( d.Format(), 'text/plain' ) # Tracker issue 435: initial text is not cooked. d = self._makeOne('foo', text_format='structured-text', text=STX_NO_HEADERS) self.assertEqual( d.EditableBody(), STX_NO_HEADERS ) self.failUnless( d.CookedBody() ) self.assertEqual( d.Format(), 'text/plain' ) def test_STX_NoHeaders( self ): self.REQUEST['BODY']=STX_NO_HEADERS d = self._makeOne('foo') d.editMetadata( title="Plain STX" , description="Look, Ma, no headers!" , subject=( "plain", "STX" ) ) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.Title(), 'Plain STX' ) self.assertEqual( d.Description(), 'Look, Ma, no headers!' ) self.assertEqual( len( d.Subject() ), 2 ) self.failUnless( 'plain' in d.Subject() ) self.failUnless( 'STX' in d.Subject() ) d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Format(), 'text/plain' ) self.assertEqual( d.Title(), 'Plain STX' ) self.assertEqual( d.Description(), 'Look, Ma, no headers!' ) self.assertEqual( len( d.Subject() ), 2 ) self.failUnless( 'plain' in d.Subject() ) self.failUnless( 'STX' in d.Subject() ) def test_STX_NoHeaders_but_colon( self ): d = self._makeOne('foo') d.editMetadata( title="Plain STX" , description="Look, Ma, no headers!" , subject=( "plain", "STX" ) ) d.edit(text_format='structured-text', text=STX_NO_HEADERS_BUT_COLON) self.assertEqual( d.EditableBody(), STX_NO_HEADERS_BUT_COLON ) def test_ZMI_edit( self ): d = self._makeOne('foo') d.editMetadata( title="Plain STX" , description="Look, Ma, no headers!" , subject=( "plain", "STX" ) ) d.manage_editDocument( text_format='structured-text' , text=STX_NO_HEADERS_BUT_COLON) self.assertEqual( d.EditableBody(), STX_NO_HEADERS_BUT_COLON ) def test_Format_methods(self): d = self._makeOne('foo') d.setFormat('plain') self.assertEqual( d.text_format, 'plain' ) self.assertEqual( d.Format(), 'text/plain' ) d.setFormat( d.Format() ) self.assertEqual( d.text_format, 'plain' ) d.setFormat('structured-text') self.assertEqual( d.text_format, 'structured-text' ) self.assertEqual( d.Format(), 'text/plain' ) d.setFormat( d.Format() ) self.assertEqual( d.text_format, 'structured-text' ) d.setFormat('html') self.assertEqual( d.text_format, 'html' ) self.assertEqual( d.Format(), 'text/html' ) d.setFormat( d.Format() ) self.assertEqual( d.text_format, 'html' ) d.setFormat('foo') self.assertEqual( d.text_format, 'structured-text' ) def test_default_format( self ): d = self._makeOne('foo', text='') self.assertEqual( d.Format(), 'text/plain' ) self.assertEqual( d.text_format, 'structured-text' ) class DocumentFTPGetTests(RequestTestBase): def setUp(self): RequestTest.setUp(self) self.site = DummySite('site').__of__(self.root) def testHTML( self ): self.REQUEST['BODY']=BASIC_HTML ttool = self.site._setObject( 'portal_types', TypesTool() ) fti = FTIDATA_CMF15[0].copy() del fti['id'] ttool._setObject( 'Document', FTI('Document', **fti) ) zpt = self.site._setObject( 'source_html', ZopePageTemplate('source_html') ) dir = abspath( dirname(utils.__file__) ) _file = path_join(dir, 'skins', 'zpt_content', 'source_html.pt') data = open(_file, 'r').read() zpt.write(data) d = self._makeOne('foo') d._setPortalTypeName('Document') d.PUT(self.REQUEST, self.RESPONSE) rnlinesplit = compile( r'\r?\n?' ) simple_lines = rnlinesplit.split( BASIC_HTML ) get_lines = rnlinesplit.split( d.manage_FTPget() ) # strip off headers meta_pattern = compile( r'meta name="([a-z]*)" ' + r'content="([a-z]*)"' ) title_pattern = compile( r'<title>(.*)' ) simple_headers = [] while simple_lines and simple_lines[0] != '': header = simple_lines[0].strip().lower() match = meta_pattern.search( header ) if match: simple_headers.append( match.groups() ) else: match = title_pattern.search( header ) if match: simple_headers.append( ( 'title', match.group(1) ) ) simple_lines = simple_lines[1:] get_headers = [] while get_lines and get_lines[0] != '': header = get_lines[0].strip().lower() match = meta_pattern.search( header ) if match: get_headers.append( match.groups() ) else: match = title_pattern.search( header ) if match: get_headers.append( ( 'title', match.group(1) ) ) get_lines = get_lines[1:] self.assertEqual( get_lines, simple_lines ) self.failUnless( get_headers ) self.failUnless( simple_headers ) self.failUnless( len( get_headers ) >= len( simple_headers ) ) for header in simple_headers: self.failUnless( header in get_headers ) body1 = d.EditableBody() self.REQUEST['BODY'] = d.manage_FTPget() d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.EditableBody(), body1 ) def testSTX( self ): self.REQUEST['BODY']=SIMPLE_STRUCTUREDTEXT d = self._makeOne('foo') d.PUT(self.REQUEST, self.RESPONSE) rnlinesplit = compile( r'\r?\n?' ) get_text = d.manage_FTPget() simple_lines = rnlinesplit.split( SIMPLE_STRUCTUREDTEXT ) get_lines = rnlinesplit.split( get_text ) # strip off headers simple_headers = [] while simple_lines and simple_lines[0]: simple_headers.append( simple_lines[0] ) simple_lines = simple_lines[1:] get_headers = [] while get_lines and get_lines[0]: get_headers.append( get_lines[0] ) get_lines = get_lines[1:] self.assertEqual( get_lines, simple_lines ) for header in simple_headers: self.failUnless( header in get_headers ) class DocumentPUTTests(RequestTestBase): def test_PUTBasicHTML(self): self.REQUEST['BODY'] = BASIC_HTML d = self._makeOne('foo') r = d.PUT(self.REQUEST, self.RESPONSE) self.failUnless( hasattr(d, 'cooked_text') ) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.title, 'Title in tag' ) self.assertEqual( d.text.find(''), -1 ) self.assertEqual( d.Description(), 'Describe me' ) self.assertEqual( len(d.Contributors()), 3 ) self.assertEqual( d.Contributors()[-1], 'Benotz, Larry J (larry@benotz.stuff)' ) self.assertEqual( d.cooked_text, '\n

Not a lot here

\n ' ) self.assertEqual( r.status, 204 ) subj = list(d.Subject()) self.assertEqual( len(subj), 4 ) subj.sort() self.assertEqual( subj, [ 'content management' , 'framework' , 'unit tests' , 'zope' ] ) def test_PUTSimpleXHTML(self): self.REQUEST['BODY'] = SIMPLE_XHTML d = self._makeOne('foo') r = d.PUT(self.REQUEST, self.RESPONSE) self.failUnless( hasattr(d, 'cooked_text') ) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.Description(), 'Describe me' ) self.assertEqual( d.cooked_text, '\n

Not a lot here

\n ' ) self.assertEqual( r.status, 204 ) def test_PutStructuredTextWithHTML(self): self.REQUEST['BODY'] = STX_WITH_HTML d = self._makeOne('foo') r = d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Format(), 'text/plain' ) self.assertEqual( r.status, 204 ) def test_PutStructuredText(self): self.REQUEST['BODY'] = BASIC_STRUCTUREDTEXT d = self._makeOne('foo') r = d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Format(), 'text/plain' ) self.assertEqual( r.status, 204 ) def test_PutHtmlWithDoctype(self): html = '%s\n\n \n %s' % (DOCTYPE, BASIC_HTML) self.REQUEST['BODY'] = html d = self._makeOne('foo') r = d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.Description(), 'Describe me' ) self.assertEqual( r.status, 204 ) def test_PutHtmlWithoutMetadata(self): html = HTML_TEMPLATE % {'title': 'Foo', 'body': 'Bar'} self.REQUEST['BODY'] = html d = self._makeOne('foo') r = d.PUT(self.REQUEST, self.RESPONSE) self.assertEqual( d.Title(), 'Foo' ) self.assertEqual( d.Format(), 'text/html' ) self.assertEqual( d.Description(), '' ) self.assertEqual( d.Subject(), () ) self.assertEqual( d.Contributors(), () ) self.assertEqual( d.EffectiveDate(), 'None' ) self.assertEqual( d.ExpirationDate(), 'None' ) self.assertEqual( d.Language(), '' ) self.assertEqual( d.Rights(), '' ) self.assertEqual( r.status, 204 ) def test_suite(): return unittest.TestSuite(( unittest.makeSuite(DocumentTests), unittest.makeSuite(DocumentFTPGetTests), unittest.makeSuite(DocumentPUTTests), )) if __name__ == '__main__': unittest.main(defaultTest='test_suite')