Commit 8e211e3e authored by Arnaud Fontaine's avatar Arnaud Fontaine

ZODB Components: erp5_web: Migrate Documents and Unit Tests (MR !1219).

* Properly override WebSite Document in erp5_web_shadir by creating a new
  version_priority.
* Keep Web{Section,Site}TraversalHook in Product/ERP5/Document as these are
  not ERP5 objects. Also, add `kept_for_backward_compatibility_only` to
  importLocalDocument() to handle pattern where the Document class has been
  migrated but some code remains.
* Move WebSection_get*PrecacheManifestList Python Script from bt5 not depending
  on erp5_web to erp5_web_renderjs as this is required by CodingStyleTest
  (WebSection being now in erp5_web).
parent e57dd4fb
......@@ -2,10 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="WebSite" module="Products.ERP5.Document.WebSite"/>
<tuple/>
</tuple>
<global name="Web Site" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
......@@ -244,10 +241,7 @@
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="WebSiteTraversalHook" module="Products.ERP5.Document.WebSite"/>
<tuple/>
</tuple>
<global name="WebSiteTraversalHook" module="Products.ERP5.Document.WebSite"/>
</pickle>
<pickle>
<dictionary/>
......
erp5_web
\ No newline at end of file
......@@ -70,7 +70,6 @@ class TestERP5WebWithCRM(ERP5TypeTestCase):
"""
Setup Web Site
"""
portal = self.getPortal()
website = self.getPortal().web_site_module.newContent(portal_type='Web Site',
**kw)
websection = website.newContent(portal_type='Web Section', **kw)
......@@ -145,7 +144,6 @@ class TestERP5WebWithCRM(ERP5TypeTestCase):
web_section.WebSection_addWebMessage(**form_kw)
transaction.commit()
# here we check a random bug caused by the ordering of activities
should_stop = [None]
event_module_path_prefix = self.portal.event_module.getPath() + '/'
deprioritize_message_list = []
# we'll stop whenever we find the message that reindex the newly created
......@@ -159,7 +157,8 @@ class TestERP5WebWithCRM(ERP5TypeTestCase):
return True
return False
self.tic(stop_condition=stop_condition)
web_message_reindex_message, = deprioritize_message_list
assert len(deprioritize_message_list) == 1
web_message_reindex_message = deprioritize_message_list[0]
web_message_path = web_message_reindex_message.object_path
self.assertTrue(
self.portal.unrestrictedTraverse(web_message_path).getPortalType(),
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testERP5WebWithCRM</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5.tests.testERP5WebWithCRM</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testERP5WebWithCRM</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
test.erp5.testCRMNotificationTool
test.erp5.testCRMSupportRequest
\ No newline at end of file
test.erp5.testCRMSupportRequest
test.erp5.testERP5WebWithCRM
\ No newline at end of file
erp5_full_text_mroonga_catalog
erp5_core_test
\ No newline at end of file
erp5_core_test
erp5_web
\ No newline at end of file
......@@ -32,7 +32,7 @@ from Acquisition import aq_base
from OFS.Traversable import NotFound
from Products.ERP5.mixin.document_extensible_traversable import DocumentExtensibleTraversableMixin
from Products.ERP5.Document.WebSection import WebSection
from erp5.component.document.WebSection import WebSection
from Products.ERP5Type import Permissions
from webdav.NullResource import NullResource
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>WebSection</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5.Document.WebSection</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5.WebSection</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
##############################################################################
#
# Copyright (c) 2002-2006 Nexedi SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from erp5.component.document.WebSection import WebSection
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.Cache import CachingMethod
from warnings import warn
from zExceptions import Redirect
WEBSITE_KEY = 'web_site_value'
WEBSITE_LANGUAGE_KEY = 'web_site_language'
class WebSite(WebSection):
"""
The Web Site root class is specialises WebSection
by defining a global webmaster user.
"""
# CMF Type Definition
meta_type = 'ERP5 Web Site'
portal_type = 'Web Site'
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.WebSection
, PropertySheet.WebSite
, PropertySheet.Predicate
)
web_section_key = WEBSITE_KEY
security.declareProtected(Permissions.AccessContentsInformation, 'getWebSiteValue')
def getWebSiteValue(self):
"""
Returns the current web site (ie. self) though containment acquisition
"""
return self
# Static Language Selection support
def getExtensibleContent(self, request, name):
language_list = self.getAvailableLanguageList()
if language_list and self.isStaticLanguageSelection():
# Interprete names which could be a language
# as a language selection only if language_list
# was defined or set default language
if name in language_list:
default_language = self.getDefaultAvailableLanguage()
if request.get('AcceptLanguage') is not None:
request['AcceptLanguage'].set(name, 100)
request.set(WEBSITE_LANGUAGE_KEY, name)
if self.isTempObject() or name == default_language:
redirect_path_list = [self.getOriginalDocument().absolute_url()]
if name != default_language:
redirect_path_list.append(name)
redirect_path_list.extend(reversed(request['TraversalRequestNameStack']))
request['minimum_language_redirect_url'] = '/'.join(redirect_path_list)
query_string = request.get('QUERY_STRING')
if query_string:
request['minimum_language_redirect_url'] += '?' + query_string
return self.getOriginalDocument().asContext(id=name, __language_web_site=True)
return WebSection.getExtensibleContent(self, request, name)
security.declarePublic('isSubtreeIndexable')
def isSubtreeIndexable(self):
if self.isTempObject() and getattr(self, '__language_web_site', False):
# temp Web Site used to select a language must not prevent
# document indexation
return self.aq_inner.aq_parent.isSubtreeIndexable()
return super(WebSite, self).isSubtreeIndexable()
def _getExtensibleContent(self, request, name):
"""
Legacy API
"""
warn("_getExtensibleContent() function is deprecated. Use getExtensibleContent() instead.", \
DeprecationWarning, stacklevel=2)
return self.getExtensibleContent(request, name)
def _getTraversalHookClass(self):
from Products.ERP5.Document.WebSite import WebSiteTraversalHook
return WebSiteTraversalHook
def __before_publishing_traverse__(self, self2, request):
redirect_url = request.get('minimum_language_redirect_url')
if redirect_url:
raise Redirect(redirect_url)
return super(WebSite, self).__before_publishing_traverse__(self2, request)
security.declareProtected(Permissions.AccessContentsInformation, 'getPermanentURLList')
def getPermanentURLList(self, document):
"""
Return a list of URLs which exist in the site for
a given document. This could be implemented either
by keep a history of documents which have been
accessed or by parsing all WebSections and listing
all documents in each of them to build a reverse
mapping of getPermanentURL
"""
return [x.getPermanentURL(document) for x in self.getWebSectionValueList(document)]
security.declareProtected(Permissions.AccessContentsInformation, 'getWebSectionValueList')
def getWebSectionValueList(self, document):
"""
Returns a list of sections which a given document is
part of.
This could be implemented either by testing all sections
and building a cache or by using the predicate API
to find which sections apply.
"""
def getWebSectionUidList(section):
# Only return visible web section
if section.isVisible():
result = [section.getUid()]
else:
result = []
for o in section.contentValues(portal_type='Web Section'):
result.extend(getWebSectionUidList(o))
return result
_getWebSectionUidList = CachingMethod(getWebSectionUidList,
id='WebSite._getWebSectionUidList',
cache_factory='erp5_content_medium')
web_section_uid_list = _getWebSectionUidList(self)
if web_section_uid_list:
section_list = self.portal_domains.searchPredicateList(document,
portal_type='Web Section',
uid=web_section_uid_list)
section_dict = {}
for section in section_list:
section_dict[section.getPhysicalPath()] = section
# Eliminate path
for section in section_list:
path = section.getPhysicalPath()
for i in range(0, len(path)):
sub_path = tuple(path[0:i])
if section_dict.has_key(sub_path):
del section_dict[sub_path]
section_list = section_dict.values()
# Sort by Index
section_list.sort(key=lambda x: x.getIntIndex())
return section_list
else:
return []
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>WebSite</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5.Document.WebSite</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5.WebSite</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -109,7 +109,7 @@ class TestWebSiteTraversalHook(WebTraversalHookTestMixin, ERP5TypeTestCase):
self.web_section = self.portal.web_site_module.newContent(
portal_type='Web Site',
)
from Products.ERP5Type.Document.WebSite import WebSiteTraversalHook
from Products.ERP5.Document.WebSite import WebSiteTraversalHook
self.traversal_hook_class = WebSiteTraversalHook
......@@ -121,7 +121,7 @@ class TestWebSectionTraversalHook(WebTraversalHookTestMixin, ERP5TypeTestCase):
)
self.web_section = web_site.newContent(portal_type='Web Section')
from Products.ERP5Type.Document.WebSection import WebSectionTraversalHook
from erp5.component.document.WebSection import WebSectionTraversalHook
self.traversal_hook_class = WebSectionTraversalHook
......@@ -248,7 +248,7 @@ class TestERP5Web(ERP5TypeTestCase):
portal_catalog = self.getCatalogTool()
try:
portal_catalog.catalog_object(web_site)
except:
except Exception:
self.fail('Cataloging of the Web Site failed.')
......@@ -346,10 +346,10 @@ Hé Hé Hé!""", page.asText().strip())
current user selected language in browser.
"""
portal = self.getPortal()
website = self.setupWebSite()
self.setupWebSite()
websection = self.setupWebSection()
page_reference = 'default-webpage'
webpage_list = self.setupWebSitePages(prefix=page_reference)
self.setupWebSitePages(prefix=page_reference)
# set default web page for section
found_by_reference = portal.portal_catalog(reference=page_reference,
......@@ -420,7 +420,7 @@ Hé Hé Hé!""", page.asText().strip())
Note: due to generic ERP5 Web implementation this test highly depends
on WebSection_geDefaulttDocumentValueList
"""
website = self.setupWebSite()
self.setupWebSite()
websection = self.setupWebSection()
publication_section_category_id_list = ['documentation', 'administration']
......@@ -487,7 +487,7 @@ Hé Hé Hé!""", page.asText().strip())
""" Check getting getDocumentValueList from Web Section.
"""
portal = self.getPortal()
website = self.setupWebSite()