test.erp5.testERP5Web.py 93.3 KB
Newer Older
1
# -*- coding: utf-8 -*-
2 3
##############################################################################
#
4
# Copyright (c) 2004, 2005, 2006 Nexedi SARL and Contributors.
5 6 7 8
# All Rights Reserved.
#          Romain Courteaud <romain@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
9
# programmers who take the whole responsibility of assessing all potential
10 11
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
12
# guarantees and support are strongly adviced to contract a Free Software
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
# 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.
#
##############################################################################

31
import re
32
import time
33
from unittest import expectedFailure, skip
34 35
from StringIO import StringIO
from urllib import urlencode
36
from AccessControl import Unauthorized
37
from Testing import ZopeTestCase
38
from DateTime import DateTime
39
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
40
from Products.ERP5Type.tests.utils import DummyLocalizer
41
from Products.ERP5Type.tests.utils import createZODBPythonScript
42

Rafael Monnerat's avatar
Rafael Monnerat committed
43
LANGUAGE_LIST = ('en', 'fr', 'de', 'bg', )
44 45
HTTP_OK = 200
MOVED_TEMPORARILY = 302
46

Rafael Monnerat's avatar
Rafael Monnerat committed
47

48 49 50 51
class DummyTraversalHook(object):
  def __call__(self, container, request):
    return

52

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
class WebTraversalHookTestMixin(object):
  """Mixin class to test the WebSiteTraversalHook on both websection and website.
  """
  def getBusinessTemplateList(self):
    return ('erp5_base', 'erp5_web', )

  def test_TraversalHook_on_newContent(self):
    """a WebSiteTraversalHook is added on websections and websites automatically.
    """
    self.assertEquals(1, len(self.web_section.__before_traverse__))
    self.assertIsInstance(
      self.web_section.__before_traverse__.values()[0],
      self.traversal_hook_class)

  def test_TraversalHook_on_clone(self):
    """a WebSiteTraversalHook is correctly updated after cloning a websection/website.
    """
    cloned_web_section = self.web_section.Base_createCloneDocument(batch_mode=True)
    self.assertEquals(1, len(cloned_web_section.__before_traverse__))

  def test_TraversalHook_on_change_id(self):
    """a TraversalHook is correctly updated after changing websection id.
    """
    self.tic()
    self.web_section.setId("new_id")
    self.assertEquals(1, len(self.web_section.__before_traverse__))

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  def test_TraversalHook_cleanup_on_edit(self):
    """Old traversal hooks from cloned objects are automatically cleaned up
    when section is edited.
    """
    # artificially put this websection in a similar state that websection were before
    # we fix the bug keeping traversal hooks on clone.
    from ZPublisher import BeforeTraverse
    handle = '%s/different_id_than_%s' % (self.web_section.meta_type, self.web_section.getId())
    BeforeTraverse.registerBeforeTraverse(self.web_section, self.traversal_hook_class(), handle)

    BeforeTraverse.registerBeforeTraverse(
      self.web_section,
      DummyTraversalHook(),
      'unrelated_traversal_hook_that_should_be_kept')
    self.assertEquals(3, len(self.web_section.__before_traverse__))

    self.tic()
    self.web_section.edit(title=self.id())
    # We have cleaned up the useless before traversal hook, but keep the unrelated one
    self.assertEquals(2, len(self.web_section.__before_traverse__))
    self.assertEquals(1, len([hook for hook in
      self.web_section.__before_traverse__.values() if isinstance(hook, self.traversal_hook_class)]))
    self.assertEquals(1, len([hook for hook in
      self.web_section.__before_traverse__.values() if isinstance(hook, DummyTraversalHook)]))


106 107 108 109 110 111
class TestWebSiteTraversalHook(WebTraversalHookTestMixin, ERP5TypeTestCase):
  def afterSetUp(self):
    super(TestWebSiteTraversalHook, self).afterSetUp()
    self.web_section = self.portal.web_site_module.newContent(
      portal_type='Web Site',
    )
112
    from Products.ERP5.Document.WebSite import WebSiteTraversalHook
113 114
    self.traversal_hook_class = WebSiteTraversalHook

115

116 117 118 119 120 121 122 123
class TestWebSectionTraversalHook(WebTraversalHookTestMixin, ERP5TypeTestCase):
  def afterSetUp(self):
    super(TestWebSectionTraversalHook, self).afterSetUp()
    web_site = self.portal.web_site_module.newContent(
      portal_type='Web Site',
    )
    self.web_section = web_site.newContent(portal_type='Web Section')

124
    from erp5.component.document.WebSection import WebSectionTraversalHook
125 126 127
    self.traversal_hook_class = WebSectionTraversalHook


128
class TestERP5Web(ERP5TypeTestCase):
129 130 131 132
  """Test for erp5_web business template.
  """
  manager_username = 'zope'
  manager_password = 'zope'
133
  website_id = 'test'
134
  credential = '%s:%s' % (manager_username, manager_password)
Rafael Monnerat's avatar
Rafael Monnerat committed
135

136 137 138 139 140 141 142
  def getTitle(self):
    return "ERP5Web"

  def getBusinessTemplateList(self):
    """
    Return the list of required business templates.
    """
143 144
    return ('erp5_core_proxy_field_legacy',
            'erp5_base',
145
            'erp5_jquery',
146 147
            'erp5_web',
            )
148 149

  def afterSetUp(self):
150
    portal = self.getPortal()
151 152

    uf = portal.acl_users
Rafael Monnerat's avatar
Rafael Monnerat committed
153 154 155
    uf._doAddUser(self.manager_username,
                  self.manager_password,
                  ['Manager'], [])
156
    self.loginByUserName(self.manager_username)
157

158 159
    self.web_page_module = self.portal.getDefaultModule('Web Page Module')
    self.web_site_module = self.portal.getDefaultModule('Web Site Module')
Rafael Monnerat's avatar
Rafael Monnerat committed
160
    portal.Localizer.manage_changeDefaultLang(language='en')
161 162
    self.portal_id = self.portal.getId()

163 164 165 166
  def clearModule(self, module):
    module.manage_delObjects(list(module.objectIds()))
    self.tic()

167
  def beforeTearDown(self):
168 169
    self.clearModule(self.portal.web_site_module)
    self.clearModule(self.portal.web_page_module)
170
    self.clearModule(self.portal.person_module)
171

172
  def setupWebSite(self, **kw):
173
    """
174 175 176
      Setup Web Site
    """
    portal = self.getPortal()
177

178 179 180
    # add supported languages for Localizer
    localizer = portal.Localizer
    for language in LANGUAGE_LIST:
Rafael Monnerat's avatar
Rafael Monnerat committed
181
      localizer.manage_addLanguage(language=language)
182

183 184 185
    # create website
    if hasattr(self.web_site_module, self.website_id):
      self.web_site_module.manage_delObjects(self.website_id)
Rafael Monnerat's avatar
Rafael Monnerat committed
186 187 188
    website = self.web_site_module.newContent(portal_type='Web Site',
                                              id=self.website_id,
                                              **kw)
189
    website.publish()
190
    self.tic()
191
    return website
192

193
  def setupWebSection(self, **kw):
194
    """
195 196
      Setup Web Section
    """
Rafael Monnerat's avatar
Rafael Monnerat committed
197
    website = self.web_site_module[self.website_id]
198
    websection = website.newContent(portal_type='Web Section', **kw)
199
    self.websection = websection
Rafael Monnerat's avatar
Rafael Monnerat committed
200
    kw = dict(criterion_property_list='portal_type',
201 202
              membership_criterion_base_category_list='',
              membership_criterion_category_list='')
203
    websection.edit(**kw)
204 205
    websection.setCriterion(property='portal_type',
                            identity=['Web Page'],
206
                            max='',
207
                            min='')
208

209
    self.tic()
210 211
    return websection

212
  def setupWebSitePages(self, prefix, suffix=None, version='0.1',
213
                        language_list=LANGUAGE_LIST, **kw):
214 215 216 217 218 219 220
    """
      Setup some Web Pages.
    """
    webpage_list = []
    # create sample web pages
    for language in language_list:
      if suffix is not None:
221
        reference = '%s-%s' % (prefix, language)
222 223
      else:
        reference = prefix
224
      webpage = self.web_page_module.newContent(portal_type='Web Page',
225 226 227 228
                                                reference=reference,
                                                version=version,
                                                language=language,
                                                **kw)
229
      webpage.publish()
230
      self.tic()
231 232 233 234
      self.assertEqual(language, webpage.getLanguage())
      self.assertEqual(reference, webpage.getReference())
      self.assertEqual(version, webpage.getVersion())
      self.assertEqual('published', webpage.getValidationState())
235
      webpage_list.append(webpage)
236

237
    return webpage_list
238

239
  def test_01_WebSiteRecatalog(self):
240 241 242 243
    """
      Test that a recataloging works for Web Site documents
    """
    self.setupWebSite()
Rafael Monnerat's avatar
Rafael Monnerat committed
244
    web_site = self.web_site_module[self.website_id]
245

246 247 248 249 250
    self.assertTrue(web_site is not None)
    # Recatalog the Web Site document
    portal_catalog = self.getCatalogTool()
    try:
      portal_catalog.catalog_object(web_site)
251
    except Exception:
252 253
      self.fail('Cataloging of the Web Site failed.')

254 255


256
  def test_02_EditSimpleWebPage(self):
257 258
    """
      Simple Case of creating a web page.
259 260 261
    """
    page = self.web_page_module.newContent(portal_type='Web Page')
    page.edit(text_content='<b>OK</b>')
262 263
    self.assertEqual('text/html', page.getContentType())
    self.assertEqual('<b>OK</b>', page.getTextContent())
264

265 266
  def test_WebPageAsTextUTF8(self):
    """Check if Web Page's asText() returns utf-8 string correctly
267 268
    """
    page = self.web_page_module.newContent(portal_type='Web Page')
269
    page.edit(text_content='<p>Hé Hé Hé!</p>', content_type='text/html')
270
    self.tic()
271
    self.assertEqual('Hé Hé Hé!', page.asText().strip())
272 273 274 275 276 277 278 279 280 281 282 283 284 285

  def test_WebPageAsTextHTMLEntities(self):
    """Check if Web Page's asText() converts html entities properly
    """
    page = self.web_page_module.newContent(portal_type='Web Page')
    page.edit(text_content='<p>H&eacute;!</p>', content_type='text/html')
    self.tic()
    self.assertEqual('Hé!', page.asText().strip())

  def test_WebPageAsTextWrap(self):
    """Check if Web Page's asText() is wrapped by certain column width.
    """
    page = self.web_page_module.newContent(portal_type='Web Page')

286
    page.edit(text_content='<p>Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé!</p>')
287
    self.tic()
288
    self.assertEqual("""Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé
289 290
Hé Hé Hé!""", page.asText().strip())

291
  @skip('WebSite_createWebSiteAccount is disabled by default.')
292
  def test_03_CreateWebSiteUser(self):
293 294 295
    """
      Create Web site User.
    """
296
    self.setupWebSite()
297 298
    portal = self.getPortal()
    request = self.app.REQUEST
Rafael Monnerat's avatar
Rafael Monnerat committed
299 300 301 302 303 304
    kw = dict(reference='web',
              first_name='TestFN',
              last_name='TestLN',
              default_email_text='test@test.com',
              password='abc',
              password_confirm='abc',)
305
    for key, item in kw.items():
Rafael Monnerat's avatar
Rafael Monnerat committed
306 307
      request.set('field_your_%s' % key, item)
    website = self.web_site_module[self.website_id]
308
    website.WebSite_createWebSiteAccount('WebSite_viewRegistrationDialog')
309

310
    self.tic()
311

312
    # find person object by reference
313
    person = website.Base_getUserValueByUserId(kw['reference'])
314 315 316 317 318
    self.assertEqual(person.getReference(), kw['reference'])
    self.assertEqual(person.getFirstName(), kw['first_name'])
    self.assertEqual(person.getLastName(), kw['last_name'])
    self.assertEqual(person.getDefaultEmailText(), kw['default_email_text'])
    self.assertEqual(person.getValidationState(), 'validated')
319

320
    # check if user account is 'loggable'
321
    uf = portal.acl_users
Rafael Monnerat's avatar
Rafael Monnerat committed
322
    user = uf.getUserById(kw['reference'])
323
    self.assertEqual(user.getIdOrUserName(), kw['reference'])
324
    self.assertEqual(1, user.has_role(('Member', 'Authenticated',)))
325
    self.loginByUserName(kw['reference'])
326
    self.assertEqual(kw['reference'],
327
                     portal.portal_membership.getAuthenticatedMember().getIdOrUserName())
328 329 330

    # test redirection to person oobject
    path = website.absolute_url_path() + '/WebSite_redirectToUserView'
Rafael Monnerat's avatar
Rafael Monnerat committed
331
    response = self.publish(path, '%s:%s' % (kw['reference'], kw['password']))
332
    self.assertTrue(person.getRelativeUrl() in response.getHeader("Location"))
Rafael Monnerat's avatar
Rafael Monnerat committed
333

334 335
    # test redirecting to new Person preference
    path = website.absolute_url_path() + '/WebSite_redirectToUserPreference'
Rafael Monnerat's avatar
Rafael Monnerat committed
336
    response = self.publish(path, '%s:%s' % (kw['reference'], kw['password']))
337 338
    self.assertTrue('portal_preferences' in response.getHeader("Location"))
    # one preference should be created for user
339
    self.assertEqual(1,
Rafael Monnerat's avatar
Rafael Monnerat committed
340 341
        self.portal.portal_catalog.countResults(**{'portal_type': 'Preference',
                                              'owner': kw['reference']})[0][0])
342

343
  def test_04_WebPageTranslation(self):
344
    """
345
      Simple Case of showing the proper Web Page based on
346 347 348
      current user selected language in browser.
    """
    portal = self.getPortal()
349
    self.setupWebSite()
350 351
    websection = self.setupWebSection()
    page_reference = 'default-webpage'
352
    self.setupWebSitePages(prefix=page_reference)
353

354
    # set default web page for section
355
    found_by_reference = portal.portal_catalog(reference=page_reference,
Rafael Monnerat's avatar
Rafael Monnerat committed
356 357 358 359
                                               portal_type='Web Page')
    found = found_by_reference[0].getObject()
    websection.edit(categories_list=['aggregate/%s' % found.getRelativeUrl()])
    self.assertEqual([found.getReference()],
360 361 362
                      websection.getAggregateReferenceList())
    # even though we create many pages we should get only one
    # this is the most recent one since all share the same reference
363
    self.assertEqual(1, len(websection.getDocumentValueList()))
364

365
    # use already created few pages in different languages with same reference
366
    # and check that we always get the right one based on selected
367 368 369
    # by us language
    for language in LANGUAGE_LIST:
      # set default language in Localizer only to check that we get
370
      # the corresponding web page for language.
371
      # XXX: Extend API so we can select language from REQUEST
Rafael Monnerat's avatar
Rafael Monnerat committed
372
      portal.Localizer.manage_changeDefaultLang(language=language)
373
      default_document = websection.getDefaultDocumentValue()
374
      self.assertEqual(language, default_document.getLanguage())
375

376
  def test_05_WebPageTextContentSubstitutions(self):
377
    """
Rafael Monnerat's avatar
Rafael Monnerat committed
378 379
      Simple Case of showing the proper text content with and without a
      substitution mapping method.
380
      In case of asText, the content should be replaced too
381 382
    """
    content = '<a href="${toto}">$titi</a>'
383
    asText_content = '$titi\n'
384
    substituted_content = '<a href="foo">bar</a>'
385
    substituted_asText_content = 'bar\n'
386 387 388
    mapping = dict(toto='foo', titi='bar')

    portal = self.getPortal()
389
    document = portal.web_page_module.newContent(portal_type='Web Page',
390
            text_content=content)
391

392
    # No substitution should occur.
393 394
    self.assertEqual(document.asStrippedHTML(), content)
    self.assertEqual(document.asText(), asText_content)
395 396 397 398 399 400

    klass = document.__class__
    klass.getTestSubstitutionMapping = lambda self, **kw: mapping
    document.setTextContentSubstitutionMappingMethodId('getTestSubstitutionMapping')

    # Substitutions should occur.
401 402
    self.assertEqual(document.asStrippedHTML(), substituted_content)
    self.assertEqual(document.asText(), substituted_asText_content)
403 404 405 406

    klass._getTestSubstitutionMapping = klass.getTestSubstitutionMapping
    document.setTextContentSubstitutionMappingMethodId('_getTestSubstitutionMapping')

Rafael Monnerat's avatar
Rafael Monnerat committed
407 408
    # Even with the same callable object, a restricted method
    # id should not be callable.
409 410
    self.assertRaises(Unauthorized, document.asStrippedHTML)

411
  def test_06_DefaultDocumentForWebSection(self):
412 413 414 415
    """
      Testing the default document for a Web Section.

      If a Web Section has a default document defined and if that default
416 417
      document is published, then getDefaultDocumentValue on that
      web section should return the latest version in the most
418
      appropriate language of that default document.
419 420

      Note: due to generic ERP5 Web implementation this test highly depends
421
      on WebSection_geDefaulttDocumentValueList
Ivan Tyagov's avatar
Ivan Tyagov committed
422
    """
423
    self.setupWebSite()
Ivan Tyagov's avatar
Ivan Tyagov committed
424
    websection = self.setupWebSection()
Rafael Monnerat's avatar
Rafael Monnerat committed
425
    publication_section_category_id_list = ['documentation', 'administration']
426

Ivan Tyagov's avatar
Ivan Tyagov committed
427
    # create pages belonging to this publication_section 'documentation'
Rafael Monnerat's avatar
Rafael Monnerat committed
428 429 430 431 432 433
    web_page_en = self.web_page_module.newContent(
             portal_type='Web Page',
             id='section_home',
             language='en',
             reference='NXD-DDP',
             publication_section_list=publication_section_category_id_list[:1])
Ivan Tyagov's avatar
Ivan Tyagov committed
434
    websection.setAggregateValue(web_page_en)
435
    self.tic()
436
    self.assertEqual(None, websection.getDefaultDocumentValue())
Ivan Tyagov's avatar
Ivan Tyagov committed
437 438
    # publish it
    web_page_en.publish()
439
    self.tic()
440 441 442 443
    self.assertEqual(web_page_en, websection.getDefaultDocumentValue())
    # and make sure that the base meta tag which is generated
    # uses the web section rather than the portal
    html_page = websection()
444
    from erp5.component.document.Document import Document
445 446
    base_list = re.findall(Document.base_parser, str(html_page))
    base_url = base_list[0]
Rafael Monnerat's avatar
Rafael Monnerat committed
447 448
    self.assertEqual(base_url, "%s/%s/" % (websection.absolute_url(),
                                           web_page_en.getReference()))
449

450
  def test_06b_DefaultDocumentForWebSite(self):
451 452 453 454
    """
      Testing the default document for a Web Site.

      If a Web Section has a default document defined and if that default
455 456
      document is published, then getDefaultDocumentValue on that
      web section should return the latest version in the most
457
      appropriate language of that default document.
458 459

      Note: due to generic ERP5 Web implementation this test highly depends
460 461 462
      on WebSection_geDefaulttDocumentValueList
    """
    website = self.setupWebSite()
Rafael Monnerat's avatar
Rafael Monnerat committed
463
    publication_section_category_id_list = ['documentation', 'administration']
464

465
    # create pages belonging to this publication_section 'documentation'
Rafael Monnerat's avatar
Rafael Monnerat committed
466
    web_page_en = self.web_page_module.newContent(portal_type = 'Web Page',
467
                                                 id='site_home',
468 469 470
                                                 language = 'en',
                                                 reference='NXD-DDP-Site',
                                                 publication_section_list=publication_section_category_id_list[:1])
471
    website.setAggregateValue(web_page_en)
472
    self.tic()
473 474 475
    self.assertEqual(None, website.getDefaultDocumentValue())
    # publish it
    web_page_en.publish()
476
    self.tic()
477 478 479 480
    self.assertEqual(web_page_en, website.getDefaultDocumentValue())
    # and make sure that the base meta tag which is generated
    # uses the web site rather than the portal
    html_page = website()
481
    from erp5.component.document.Document import Document
482 483
    base_list = re.findall(Document.base_parser, str(html_page))
    base_url = base_list[0]
484
    self.assertEqual(base_url, "%s/%s/" % (website.absolute_url(), web_page_en.getReference()))
485

486
  def test_07_getDocumentValueList(self):
487 488 489
    """ Check getting getDocumentValueList from Web Section.
    """
    portal = self.getPortal()
490
    self.setupWebSite()
491
    websection = self.setupWebSection()
Rafael Monnerat's avatar
Rafael Monnerat committed
492
    publication_section_category_id_list = ['documentation', 'administration']
493

494
    #set predicate on web section using 'publication_section'
495
    websection.edit(membership_criterion_base_category = ['publication_section'],
496 497
                     membership_criterion_category=['publication_section/%s' \
                                                    % publication_section_category_id_list[0]])
498 499 500
    # clean up
    self.web_page_module.manage_delObjects(list(self.web_page_module.objectIds()))
    portal.portal_categories.publication_section.manage_delObjects(
501
                                      list(portal.portal_categories.publication_section.objectIds()))
502 503
    # create categories
    for category_id in publication_section_category_id_list:
504
      portal.portal_categories.publication_section.newContent(portal_type = 'Category',
505 506
                                                              id = category_id)

Rafael Monnerat's avatar
Rafael Monnerat committed
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
    property_dict = {'01': dict(language='en', version="1", reference="A"),
                     '02': dict(language='en', version="2", reference="B"),
                     '03': dict(language='en', version="3", reference="C"),
                     '04': dict(language='pt', version="1", reference="A"),
                     '05': dict(language='pt', version="2", reference="C"),
                     '06': dict(language='pt', version="3", reference="B"),
                     '07': dict(language='ja', version="1", reference="C"),
                     '08': dict(language='ja', version="2", reference="A"),
                     '09': dict(language='ja', version="3", reference="B"),
                     '10': dict(language='en', version="2", reference="D"),
                     '11': dict(language='ja', version="3", reference="E"),
                     '12': dict(language='pt', version="3", reference="F"),
                     '13': dict(language='en', version="3", reference="D"),
                     '14': dict(language='ja', version="2", reference="E"),
                     '15': dict(language='pt', version="2", reference="F"),
                     '16': dict(language='', version="1", reference="A"),
523 524
                    }
    sequence_one = property_dict.keys()
Rafael Monnerat's avatar
Rafael Monnerat committed
525 526 527 528
    sequence_two = ['01', '13', '12', '09', '06', '15', '04', '11', '02',
                    '05', '03', '07', '10', '08', '14', '16']
    sequence_three = ['05', '12', '13', '14', '06', '09', '10', '07',
                      '03', '01', '02', '11', '04', '08', '15', '16']
529

530
    sequence_count = 0
Rafael Monnerat's avatar
Rafael Monnerat committed
531
    for sequence in [sequence_one, sequence_two, sequence_three]:
532
      sequence_count += 1
533
      message = '\ntest_07_getDocumentValueList (Sequence %s)' \
534 535
                                                              % (sequence_count)
      ZopeTestCase._print(message)
536

537
      web_page_list = []
538
      for key in sequence:
Rafael Monnerat's avatar
Rafael Monnerat committed
539
        web_page = self.web_page_module.newContent(
540
                                  title=key,
541 542
                                  portal_type = 'Web Page',
                                  publication_section_list=publication_section_category_id_list[:1])
543

544
        web_page.edit(**property_dict[key])
545
        self.tic()
546
        web_page_list.append(web_page)
547

548
      self.tic()
549
      # in draft state, no documents should belong to this Web Section
550
      self.assertEqual(0, len(websection.getDocumentValueList()))
551

552
      # when published, all web pages should belong to it
553 554
      for web_page in web_page_list:
        web_page.publish()
555
      self.tic()
556

557
      # Test for limit parameter
558
      self.assertEqual(2, len(websection.getDocumentValueList(limit=2)))
559 560

      # Testing for language parameter
561
      self.assertEqual(4, len(websection.getDocumentValueList()))
Rafael Monnerat's avatar
Rafael Monnerat committed
562 563
      self.assertEqual(['en', 'en', 'en', 'en'],
                       [w.getLanguage() for w in websection.getDocumentValueList()])
564

565 566 567 568 569
      # Check that receiving an empty string as language parameter (as done
      # when using listbox search) correctly returns user language documents.
      default_document_value_list = websection.getDocumentValueList(language='')
      self.assertEqual(4, len(default_document_value_list))
      self.assertEqual(['en', 'en', 'en', 'en'],
Rafael Monnerat's avatar
Rafael Monnerat committed
570
                       [w.getLanguage() for w in default_document_value_list])
571

572
      pt_document_value_list = websection.getDocumentValueList(language='pt')
573
      self.assertEqual(4, len(pt_document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
574 575
      self.assertEqual(['pt', 'pt', 'pt', 'pt'],
                           [w.getObject().getLanguage() for w in pt_document_value_list])
576

577
      ja_document_value_list = websection.getDocumentValueList(language='ja')
578
      self.assertEqual(4, len(ja_document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
579 580
      self.assertEqual(['ja', 'ja', 'ja', 'ja'],
                           [w.getLanguage() for w in ja_document_value_list])
581

582 583 584
      bg_document_value_list = websection.getDocumentValueList(language='bg')
      self.assertEqual(1, len(bg_document_value_list))
      self.assertEqual([''],
Rafael Monnerat's avatar
Rafael Monnerat committed
585
                       [w.getLanguage() for w in bg_document_value_list])
586

587 588 589
      # Testing for all_versions parameter
      en_document_value_list = websection.getDocumentValueList(all_versions=1)
      self.assertEqual(5, len(en_document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
590 591
      self.assertEqual(['en', 'en', 'en', 'en', 'en'],
                       [w.getLanguage() for w in en_document_value_list])
592 593 594 595

      pt_document_value_list = websection.getDocumentValueList(language='pt',
                                                               all_versions=1)
      self.assertEqual(5, len(pt_document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
596 597
      self.assertEqual(['pt', 'pt', 'pt', 'pt', 'pt'],
                       [w.getObject().getLanguage() for w in pt_document_value_list])
598

599
      ja_document_value_list = websection.getDocumentValueList(language='ja',
600 601
                                                               all_versions=1)
      self.assertEqual(5, len(ja_document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
602 603
      self.assertEqual(['ja', 'ja', 'ja', 'ja', 'ja'],
                           [w.getLanguage() for w in ja_document_value_list])
604

605
      # Tests for all_languages parameter (language parameter is simply ignored)
606
      en_document_value_list = websection.getDocumentValueList(all_languages=1)
607
      self.assertEqual(13, len(en_document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
608
      self.assertEqual(4, len([w.getLanguage() for w in en_document_value_list \
609
                              if w.getLanguage() == 'en']))
610
      self.assertEqual(4, len([w.getLanguage() for w in en_document_value_list \
611
                              if w.getLanguage() == 'pt']))
612
      self.assertEqual(4, len([w.getLanguage() for w in en_document_value_list \
613
                              if w.getLanguage() == 'ja']))
614

615
      pt_document_value_list = websection.getDocumentValueList(all_languages=1,
616
                                                                              language='pt')
617
      self.assertEqual(13, len(pt_document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
618
      self.assertEqual(4, len([w.getLanguage() for w in pt_document_value_list \
619
                              if w.getLanguage() == 'pt']))
620
      self.assertEqual(4, len([w.getLanguage() for w in pt_document_value_list \
621
                              if w.getLanguage() == 'en']))
622
      self.assertEqual(4, len([w.getLanguage() for w in pt_document_value_list \
623 624
                              if w.getLanguage() == 'ja']))

625
      # Tests for all_languages and all_versions
626 627
      en_document_value_list = websection.getDocumentValueList(all_languages=1,
                                                               all_versions=1)
628

629 630 631
      pt_document_value_list = websection.getDocumentValueList(all_languages=1,
                                                               all_versions=1,
                                                               language='pt')
632

633 634 635
      ja_document_value_list = websection.getDocumentValueList(all_languages=1,
                                                               all_versions=1,
                                                               language='ja')
636

Rafael Monnerat's avatar
Rafael Monnerat committed
637
      for document_value_list in [en_document_value_list, pt_document_value_list,
638 639
                                   ja_document_value_list]:

640
        self.assertEqual(16, len(document_value_list))
Rafael Monnerat's avatar
Rafael Monnerat committed
641
        self.assertEqual(5, len([w.getLanguage() for w in document_value_list \
642
                                if w.getLanguage() == 'en']))
Rafael Monnerat's avatar
Rafael Monnerat committed
643
        self.assertEqual(5, len([w.getLanguage() for w in en_document_value_list \
644
                                if w.getLanguage() == 'pt']))
Rafael Monnerat's avatar
Rafael Monnerat committed
645
        self.assertEqual(5, len([w.getLanguage() for w in en_document_value_list \
646 647
                                if w.getLanguage() == 'ja']))

648 649 650 651 652 653 654
      # Tests for strict_language=False
      fallback_document_value_list = websection.getDocumentValueList(strict_language=False, language='ja')
      self.assertEqual(
        [('en', 'D'), ('ja', 'A'), ('ja', 'B'), ('ja', 'C'), ('ja', 'E'), ('pt', 'F')],
        sorted([(x.getLanguage(), x.getReference()) for x in fallback_document_value_list])
      )

655
      # Tests for sort_on parameter
Rafael Monnerat's avatar
Rafael Monnerat committed
656 657
      self.assertEqual(['A', 'B', 'C', 'D'],
                       [w.getReference() for w in \
658 659
                         websection.getDocumentValueList(sort_on=[('reference', 'ASC')])])

Rafael Monnerat's avatar
Rafael Monnerat committed
660 661
      self.assertEqual(['01', '02', '03', '13'],
                       [w.getTitle() for w in \
662 663
                         websection.getDocumentValueList(sort_on=[('title', 'ASC')])])

Rafael Monnerat's avatar
Rafael Monnerat committed
664 665
      self.assertEqual(['D', 'C', 'B', 'A'],
                       [w.getReference() for w in \
666 667
                         websection.getDocumentValueList(sort_on=[('reference', 'DESC')])])

Rafael Monnerat's avatar
Rafael Monnerat committed
668 669
      self.assertEqual(['13', '03', '02', '01'],
                       [w.getTitle() for w in \
670 671
                         websection.getDocumentValueList(sort_on=[('reference', 'DESC')])])

672
      self.assertEqual(['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'D', 'E', 'F'],
Rafael Monnerat's avatar
Rafael Monnerat committed
673
                       [w.getReference() for w in \
674
                         websection.getDocumentValueList(all_languages=1,
675
                                            sort_on=[('reference', 'ASC')])])
676

677
      self.assertEqual(['01', '02', '03', '04', '05', '06', '07', '08', '09', '11', '12', '13', '16'],
Rafael Monnerat's avatar
Rafael Monnerat committed
678
                       [w.getTitle() for w in \
679
                         websection.getDocumentValueList(all_languages=1,
680 681
                                            sort_on=[('title', 'ASC')])])

682 683
      self.assertEqual(['F', 'E', 'D', 'C', 'C', 'C', 'B', 'B', 'B', 'A', 'A', 'A', 'A'],
                                              [w.getReference() for w in \
684
                         websection.getDocumentValueList(all_languages=1,
685 686
                                            sort_on=[('reference', 'DESC')])])

687
      self.assertEqual(['16', '13', '12', '11', '09', '08', '07', '06', '05', '04', '03', '02', '01'],
Rafael Monnerat's avatar
Rafael Monnerat committed
688
                       [w.getTitle() for w in \
689
                         websection.getDocumentValueList(all_languages=1,
690 691
                                            sort_on=[('title', 'DESC')])])

692
      self.web_page_module.manage_delObjects(list(self.web_page_module.objectIds()))
693

694
  def test_08_AcquisitionWrappers(self):
695 696 697 698 699 700 701 702 703 704 705 706
    """Test acquisition wrappers of documents.
    Check if documents obtained by getDefaultDocumentValue, getDocumentValue
    and getDocumentValueList are wrapped appropriately.
    """
    portal = self.getPortal()

    # Make its own publication section category.
    publication_section = portal.portal_categories['publication_section']
    if publication_section._getOb('my_test_category', None) is None:
      publication_section.newContent(portal_type='Category',
                                     id='my_test_category',
                                     title='Test')
707
      self.tic()
708 709 710 711 712 713

    website = self.setupWebSite()
    websection = self.setupWebSection(
            membership_criterion_base_category_list=('publication_section',),
            membership_criterion_category=('publication_section/my_test_category',),
            )
714

715 716 717 718 719
    # Create at least two documents which belong to the publication section
    # category.
    web_page_list = self.setupWebSitePages('test1',
            language_list=('en',),
            publication_section_list=('my_test_category',))
720
    self.setupWebSitePages('test2',
721 722 723 724 725
            language_list=('en',),
            publication_section_list=('my_test_category',))

    # We need a default document.
    websection.setAggregateValue(web_page_list[0])
726
    self.tic()
727

728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
    # Obtain documens in various ways.
    default_document = websection.getDefaultDocumentValue()
    self.assertNotEquals(default_document, None)

    document1 = websection.getDocumentValue('test1')
    self.assertNotEquals(document1, None)
    document2 = websection.getDocumentValue('test2')
    self.assertNotEquals(document2, None)

    document_list = websection.getDocumentValueList()
    self.assertNotEquals(document_list, None)
    self.assertNotEquals(len(document_list), 0)

    # Check if they have good acquisition wrappers.
    for doc in (default_document, document1, document2) + tuple(document_list):
743 744
      self.assertEqual(doc.aq_parent, websection)
      self.assertEqual(doc.aq_parent.aq_parent, website)
745

746
  def test_09_WebSiteSkinSelection(self):
747 748 749 750 751 752 753 754 755
    """Test skin selection through a Web Site.
    Check if a Web Site can change a skin selection based on a property.
    """
    portal = self.getPortal()
    ps = portal.portal_skins
    website = self.setupWebSite()

    # First, make sure that we use the default skin selection.
    portal.changeSkin(ps.getDefaultSkin())
756
    self.tic()
757 758 759 760 761 762 763 764 765 766

    # Make some skin stuff.
    if ps._getOb('test_erp5_web', None) is not None:
      ps.manage_delObjects(['test_erp5_web'])

    addFolder = ps.manage_addProduct['OFSP'].manage_addFolder
    addFolder(id='test_erp5_web')

    if ps.getSkinPath('Test ERP5 Web') is not None:
      ps.manage_skinLayers(del_skin=1, chosen=('Test ERP5 Web',))
767

768 769 770 771 772 773 774 775 776 777 778 779 780
    path = ps.getSkinPath(ps.getDefaultSkin())
    self.assertNotEquals(path, None)
    ps.manage_skinLayers(add_skin=1, skinname='Test ERP5 Web',
            skinpath=['test_erp5_web'] + path.split(','))

    # Now we need skins which don't conflict with any other.
    createZODBPythonScript(ps.erp5_web,
            'WebSite_test_13_WebSiteSkinSelection',
            '', 'return "foo"')
    createZODBPythonScript(ps.test_erp5_web,
            'WebSite_test_13_WebSiteSkinSelection',
            '', 'return "bar"')

781
    self.tic()
782 783 784 785 786 787

    path = website.absolute_url_path() + '/WebSite_test_13_WebSiteSkinSelection'
    request = portal.REQUEST

    # With the default skin.
    request['PARENTS'] = [self.app]
788
    self.assertEqual(request.traverse(path)(), 'foo')
789 790 791

    # With the test skin.
    website.setSkinSelectionName('Test ERP5 Web')
792
    self.tic()
793 794

    request['PARENTS'] = [self.app]
795
    self.assertEqual(request.traverse(path)(), 'bar')
796

797
  def test_10_getDocumentValueList(self):
798 799 800 801 802 803 804
    """Make sure that getDocumentValueList works."""
    self.setupWebSite()
    website = self.web_site_module[self.website_id]
    website.getDocumentValueList(
      portal_type='Document',
      sort_on=[('translated_portal_type', 'ascending')])

805
  def test_11_getWebSectionValueList(self):
806 807 808 809 810 811 812 813 814
    """ Check getWebSectionValueList from Web Site.
    Only visible web section should be returned.
    """
    portal = self.getPortal()
    web_site_portal_type = 'Web Site'
    web_section_portal_type = 'Web Section'
    web_page_portal_type = 'Web Page'

    # Create web site and web section
Rafael Monnerat's avatar
Rafael Monnerat committed
815
    web_site = self.web_site_module.newContent(portal_type=web_site_portal_type)
816 817 818 819
    web_section = web_site.newContent(portal_type=web_section_portal_type)
    sub_web_section = web_section.newContent(portal_type=web_section_portal_type)

    # Create a document
Rafael Monnerat's avatar
Rafael Monnerat committed
820
    web_page = self.web_page_module.newContent(portal_type=web_page_portal_type)
821 822 823 824

    # Commit transaction
    def _commit():
      portal.portal_caches.clearAllCache()
825
      self.tic()
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840

    # By default, as now Web Section is visible, nothing should be returned
    _commit()
    self.assertSameSet([], web_site.getWebSectionValueList(web_page))

    # Explicitely set both web section invisible
    web_section.setVisible(0)
    sub_web_section.setVisible(0)
    _commit()
    self.assertSameSet([], web_site.getWebSectionValueList(web_page))

    # Set parent web section visible
    web_section.setVisible(1)
    sub_web_section.setVisible(0)
    _commit()
841
    self.assertSameSet([web_section],
842 843 844 845 846 847 848
                       web_site.getWebSectionValueList(web_page))

    # Set both web section visible
    # Only leaf web section is returned
    web_section.setVisible(1)
    sub_web_section.setVisible(1)
    _commit()
849
    self.assertSameSet([sub_web_section],
850 851
                       web_site.getWebSectionValueList(web_page))

Romain Courteaud's avatar
Romain Courteaud committed
852 853
    # Set leaf web section visible, which should be returned even if parent is
    # not visible
854 855 856
    web_section.setVisible(0)
    sub_web_section.setVisible(1)
    _commit()
857
    self.assertSameSet([sub_web_section],
858 859
                       web_site.getWebSectionValueList(web_page))

860
  def test_12_getWebSiteValue(self):
861
    """
862 863
      Test that getWebSiteValue() and getWebSectionValue() always
      include selected Language.
864
    """
865
    website_id = self.setupWebSite(default_available_language='en').getId()
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
    website = self.portal.restrictedTraverse(
      'web_site_module/%s' % website_id)
    website_relative_url = website.absolute_url(relative=1)
    website_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/fr' % website_id)
    website_relative_url_fr = '%s/fr' % website_relative_url

    websection_id = self.setupWebSection().getId()
    websection = self.portal.restrictedTraverse(
      'web_site_module/%s/%s' % (website_id, websection_id))
    websection_relative_url = websection.absolute_url(relative=1)
    websection_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/fr/%s' % (website_id, websection_id))
    websection_relative_url_fr = '%s/%s' % (website_relative_url_fr,
                                            websection.getId())

    page_ref = 'foo'
883 884 885 886
    page = self.web_page_module.newContent(portal_type='Web Page',
                                           reference='foo',
                                           text_content='<b>OK</b>')
    page.publish()
887
    self.tic()
888

889 890 891 892 893 894 895 896 897 898
    webpage = self.portal.restrictedTraverse(
      'web_site_module/%s/%s' % (website_id, page_ref))
    webpage_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/fr/%s' % (website_id, page_ref))

    webpage_module = self.portal.restrictedTraverse(
      'web_site_module/%s/web_page_module' % website_id)
    webpage_module_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/fr/web_page_module' % website_id)

899
    self.assertEqual(website_relative_url,
900
                      website.getWebSiteValue().absolute_url(relative=1))
901
    self.assertEqual(website_relative_url_fr,
902
                      website_fr.getWebSiteValue().absolute_url(relative=1))
903
    self.assertEqual(website_relative_url,
904
                      webpage.getWebSiteValue().absolute_url(relative=1))
905
    self.assertEqual(website_relative_url_fr,
906
                      webpage_fr.getWebSiteValue().absolute_url(relative=1))
907
    self.assertEqual(website_relative_url,
908
                      webpage_module.getWebSiteValue().absolute_url(relative=1))
909
    self.assertEqual(website_relative_url_fr,
910 911 912 913 914 915 916 917 918 919 920 921
                      webpage_module_fr.getWebSiteValue().absolute_url(relative=1))

    webpage = self.portal.restrictedTraverse(
      'web_site_module/%s/%s/%s' % (website_id, websection_id, page_ref))
    webpage_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/fr/%s/%s' % (website_id, websection_id, page_ref))

    webpage_module = self.portal.restrictedTraverse(
      'web_site_module/%s/%s/web_page_module' % (website_id, websection_id))
    webpage_module_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/fr/%s/web_page_module' % (website_id, websection_id))

922
    self.assertEqual(websection_relative_url,
923
                      websection.getWebSectionValue().absolute_url(relative=1))
924
    self.assertEqual(websection_relative_url_fr,
925
                      websection_fr.getWebSectionValue().absolute_url(relative=1))
926
    self.assertEqual(websection_relative_url,
927
                      webpage.getWebSectionValue().absolute_url(relative=1))
928
    self.assertEqual(websection_relative_url_fr,
929
                      webpage_fr.getWebSectionValue().absolute_url(relative=1))
930
    self.assertEqual(websection_relative_url,
931
                      webpage_module.getWebSectionValue().absolute_url(relative=1))
932
    self.assertEqual(websection_relative_url_fr,
933
                      webpage_module_fr.getWebSectionValue().absolute_url(relative=1))
934

935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
    # several languages in URL
    website_bg_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/fr' % website_id)
    self.assertEqual(website_bg_fr.getOriginalDocument(), website)
    websection_bg_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/fr/%s' % (website_id, websection_id))
    webpage_bg_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/fr/%s/%s' % (website_id, websection_id, page_ref))

    # change language without referer
    request = self.portal.REQUEST
    request['HTTP_REFERER'] = ''
    website_absolute_url = website.absolute_url()
    self.assertEqual(website_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    self.assertEqual(websection_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    self.assertEqual(webpage_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    self.assertEqual(website_fr.Base_doLanguage('en'), website_absolute_url)
    self.assertEqual(websection_fr.Base_doLanguage('en'), website_absolute_url)
    self.assertEqual(webpage_fr.Base_doLanguage('en'), website_absolute_url)
    self.assertEqual(website_bg_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    self.assertEqual(websection_bg_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    self.assertEqual(webpage_bg_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    self.assertEqual(website_bg_fr.Base_doLanguage('en'), website_absolute_url)
    self.assertEqual(websection_bg_fr.Base_doLanguage('en'), website_absolute_url)
    self.assertEqual(webpage_bg_fr.Base_doLanguage('en'), website_absolute_url)

    # change language with referer
    request['HTTP_REFERER'] = website_fr.absolute_url()
    self.assertEqual(website_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    request['HTTP_REFERER'] = websection_fr.absolute_url()
    self.assertEqual(websection_fr.Base_doLanguage('de'), websection_fr.absolute_url().replace('/fr/', '/de/'))
    request['HTTP_REFERER'] = webpage_fr.absolute_url()
    self.assertEqual(webpage_fr.Base_doLanguage('de'), webpage_fr.absolute_url().replace('/fr/', '/de/'))
    request['HTTP_REFERER'] = website_bg_fr.absolute_url()
    self.assertEqual(website_bg_fr.Base_doLanguage('de'), '%s/de' % website_absolute_url)
    request['HTTP_REFERER'] = websection_bg_fr.absolute_url()
    self.assertEqual(websection_bg_fr.Base_doLanguage('de'), websection_bg_fr.absolute_url().replace('/bg/fr/', '/de/'))
    request['HTTP_REFERER'] = webpage_bg_fr.absolute_url()
    self.assertEqual(webpage_bg_fr.Base_doLanguage('de'), webpage_bg_fr.absolute_url().replace('/bg/fr/', '/de/'))

975 976 977 978 979 980 981 982 983 984 985 986 987
    # /bg/en/fr/xxx should be redirected to /fr/xxx
    website_bg_en_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/en/fr' % website_id)
    websection_bg_en_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/en/fr/%s' % (website_id, websection_id))
    webpage_bg_en_fr = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/en/fr/%s/%s' % (website_id, websection_id, page_ref))
    self.assertEqual(self.publish(website_bg_en_fr.absolute_url(relative=1)).getHeader('location'),
                     website_fr.absolute_url())
    self.assertEqual(self.publish(websection_bg_en_fr.absolute_url(relative=1)).getHeader('location'),
                     websection_fr.absolute_url())
    self.assertEqual(self.publish(webpage_bg_en_fr.absolute_url(relative=1)).getHeader('location'),
                     webpage_fr.absolute_url())
988 989
    self.assertEqual(self.publish(website_bg_en_fr.absolute_url(relative=1)+'?a=b&c=d').getHeader('location'),
                     website_fr.absolute_url()+'?a=b&c=d')
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003

    # /bg/en/xxx should be redirected to /xxx where en is the default language
    website_bg_en = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/en' % website_id)
    websection_bg_en = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/en/%s' % (website_id, websection_id))
    webpage_bg_en = self.portal.restrictedTraverse(
      'web_site_module/%s/bg/en/%s/%s' % (website_id, websection_id, page_ref))
    self.assertEqual(self.publish(website_bg_en.absolute_url(relative=1)).getHeader('location'),
                     website.absolute_url())
    self.assertEqual(self.publish(websection_bg_en.absolute_url(relative=1)).getHeader('location'),
                     websection.absolute_url())
    self.assertEqual(self.publish(webpage_bg_en.absolute_url(relative=1)).getHeader('location'),
                     webpage.absolute_url())
1004 1005
    self.assertEqual(self.publish(websection_bg_en.absolute_url(relative=1)+'?a=b&c=d').getHeader('location'),
                     websection.absolute_url()+'?a=b&c=d')
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

    # /en/xxx should be redirected to /xxx where en is the default language
    website_en = self.portal.restrictedTraverse(
      'web_site_module/%s/en' % website_id)
    websection_en = self.portal.restrictedTraverse(
      'web_site_module/%s/en/%s' % (website_id, websection_id))
    webpage_en = self.portal.restrictedTraverse(
      'web_site_module/%s/en/%s/%s' % (website_id, websection_id, page_ref))
    self.assertEqual(self.publish(website_en.absolute_url(relative=1)).getHeader('location'),
                     website.absolute_url())
    self.assertEqual(self.publish(websection_en.absolute_url(relative=1)).getHeader('location'),
                     websection.absolute_url())
    self.assertEqual(self.publish(webpage_en.absolute_url(relative=1)).getHeader('location'),
                     webpage.absolute_url())
1020 1021
    self.assertEqual(self.publish(webpage_en.absolute_url(relative=1)+'?a=b&c=d').getHeader('location'),
                     webpage.absolute_url()+'?a=b&c=d')
1022

1023
  def test_13_DocumentCache(self):
1024
    """
1025
      Test that when a document is modified, it can be accessed through a
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
      web_site, a web_section or wathever and display the last content (not an
      old cache value of the document).
    """
    portal = self.getPortal()
    request = portal.REQUEST
    request['PARENTS'] = [self.app]
    website = self.setupWebSite()
    web_section_portal_type = 'Web Section'
    web_section = website.newContent(portal_type=web_section_portal_type)

    content = '<p>initial text</p>'
    new_content = '<p>modified text<p>'
    document = portal.web_page_module.newContent(portal_type='Web Page',
            id='document_cache',
            reference='NXD-Document.Cache',
            text_content=content)
    document.publish()
1043
    self.tic()
1044
    self.assertEqual(document.asText().strip(), 'initial text')
1045

1046 1047 1048 1049 1050 1051 1052
    # First make sure conversion already exists on the web site
    web_document = website.restrictedTraverse('NXD-Document.Cache')
    self.assertTrue(web_document.hasConversion(format='txt'))
    web_document = web_section.restrictedTraverse('NXD-Document.Cache')
    self.assertTrue(web_document.hasConversion(format='txt'))

    # Through the web_site.
1053
    path = website.absolute_url_path() + '/NXD-Document.Cache'
1054
    response = self.publish(path, self.credential)
1055
    self.assertNotEquals(response.getBody().find(content), -1)
1056

1057
    # Through a web_section.
1058
    path = web_section.absolute_url_path() + '/NXD-Document.Cache'
1059
    response = self.publish(path, self.credential)
1060
    self.assertNotEquals(response.getBody().find(content), -1)
1061 1062 1063

    # modified the web_page content
    document.edit(text_content=new_content)
1064
    self.assertEqual(document.asText().strip(), 'modified text')
1065
    self.tic()
1066

1067 1068
    # check the cache doesn't send again the old content
    # Through the web_site.
1069
    path = website.absolute_url_path() + '/NXD-Document.Cache'
1070 1071
    response = self.publish(path, self.credential)
    self.assertNotEquals(response.getBody().find(new_content), -1)
1072

1073
    # Through a web_section.
1074
    path = web_section.absolute_url_path() + '/NXD-Document.Cache'
1075 1076
    response = self.publish(path, self.credential)
    self.assertNotEquals(response.getBody().find(new_content), -1)
1077

1078
  def test_13a_DocumentMovedCache(self):
1079
    """
1080
      What happens to the cache if document is moved
1081
      with a new ID. Can we still access content,
1082
      or is the cache emptied. There is no reason
1083
      that the cache should be regenerated or that the
1084
      previous cache would not be emptied.
1085 1086 1087 1088 1089 1090 1091 1092 1093

      Here, we test that the cache is not regenerated,
      not emptied, and still available.
    """
    portal = self.getPortal()
    request = portal.REQUEST
    request['PARENTS'] = [self.app]
    website = self.setupWebSite()
    web_section_portal_type = 'Web Section'
1094
    website.newContent(portal_type=web_section_portal_type)
1095 1096 1097 1098 1099 1100 1101

    content = '<p>initial text</p>'
    document = portal.web_page_module.newContent(portal_type='Web Page',
            id='document_original_cache',
            reference='NXD-Document.Cache',
            text_content=content)
    document.publish()
1102
    self.tic()
1103
    self.assertEqual(document.asText().strip(), 'initial text')
1104 1105 1106

    # Make sure document cache keeps converted content even if ID changes
    self.assertTrue(document.hasConversion(format='txt'))
1107
    document.setId('document_new_cache')
1108
    self.assertTrue(document.hasConversion(format='txt'))
1109
    document.setId('document_original_cache')
1110 1111
    self.assertTrue(document.hasConversion(format='txt'))

1112
  def test_13b_DocumentEditCacheKey(self):
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
    """
      What happens if a web page is edited on a web site ?
      Is converted content cleared and updated ? Or
      is a wrong cache key created ? Here, we make sure
      that the content is updated and the cache cleared
      and reset.
    """
    portal = self.getPortal()
    request = portal.REQUEST
    request['PARENTS'] = [self.app]
    website = self.setupWebSite()
    web_section_portal_type = 'Web Section'
    web_section = website.newContent(portal_type=web_section_portal_type)

    content = '<p>initial text</p>'
1128
    new_content = '<p>modified text</p>'
1129 1130 1131 1132 1133
    document = portal.web_page_module.newContent(portal_type='Web Page',
            id='document_cache',
            reference='NXD-Document.Cache',
            text_content=content)
    document.publish()
1134
    self.tic()
1135
    self.assertEqual(document.asText().strip(), 'initial text')
1136 1137 1138

    # Through the web_site.
    path = website.absolute_url_path() + '/NXD-Document.Cache'
1139
    response = self.publish(path, self.credential)
1140
    self.assertNotEquals(response.getBody().find(content), -1)
1141 1142
    # Through a web_section.
    path = web_section.absolute_url_path() + '/NXD-Document.Cache'
1143
    response = self.publish(path, self.credential)
1144
    self.assertNotEquals(response.getBody().find(content), -1)
1145 1146 1147

    # Modify the web_page content
    # Use unrestrictedTraverse (XXX-JPS reason unknown)
1148
    web_document = website.unrestrictedTraverse('web_page_module/%s' % document.getId())
1149 1150 1151 1152 1153
    web_document.edit(text_content=new_content)
    # Make sure cached is emptied
    self.assertFalse(web_document.hasConversion(format='txt'))
    self.assertFalse(document.hasConversion(format='txt'))
    # Make sure cache is regenerated
1154
    self.assertEqual(web_document.asText().strip(), 'modified text')
1155
    self.tic()
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166

    # First make sure conversion already exists (since it should
    # have been generated previously)
    self.assertTrue(document.hasConversion(format='txt'))
    web_document = web_section.restrictedTraverse('NXD-Document.Cache')
    self.assertTrue(web_document.hasConversion(format='txt'))
    web_document = website.restrictedTraverse('NXD-Document.Cache')
    self.assertTrue(web_document.hasConversion(format='txt'))

    # check the cache doesn't send again the old content
    # test this fist on the initial document
1167
    self.assertEqual(document.asText().strip(), 'modified text')
1168 1169 1170

    # Through a web_section.
    web_document = web_section.restrictedTraverse('NXD-Document.Cache')
1171
    self.assertEqual(web_document.asText().strip(), 'modified text')
1172
    path = web_section.absolute_url_path() + '/NXD-Document.Cache'
1173
    response = self.publish(path, self.credential)
1174
    self.assertNotEquals(response.getBody().find(new_content), -1)
1175 1176 1177

    # Through a web_site.
    web_document = website.restrictedTraverse('NXD-Document.Cache')
1178
    self.assertEqual(web_document.asText().strip(), 'modified text')
1179
    path = website.absolute_url_path() + '/NXD-Document.Cache'
1180
    response = self.publish(path, self.credential)
1181
    self.assertNotEquals(response.getBody().find(new_content), -1)
1182

1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
  def test_14_AccessWebSiteForWithDifferentUserPreferences(self):
    """Check that Ram Cache Manager do not mix websection
    rendering between users.
    This test enable different preferences per users and check that
    those preferences doesn't affect rendering for other users.
    user          | preference

    administrator | developper_mode activated
    webeditor     | translator_mode activated
    anonymous     | developper_mode & translator_mode disabled

    The Signature used to detect enabled preferences in HTML Body are
    manage_main for developper_mode
    manage_messages for translator_mode
    """
    user = self.createUser('administrator')
    self.createUserAssignement(user, {})
    user = self.createUser('webeditor')
    self.createUserAssignement(user, {})
1202
    self.tic()
1203 1204 1205
    preference_tool = self.getPreferenceTool()
    isTransitionPossible = self.portal.portal_workflow.isTransitionPossible

1206
    # create or edit preference for administrator
1207 1208 1209 1210
    administrator_preference = self.portal.portal_catalog.getResultValue(
                                                 portal_type='Preference',
                                                 owner='administrator')
    if administrator_preference is None:
1211
      self.loginByUserName('administrator')
1212 1213 1214 1215 1216 1217 1218 1219
      administrator_preference = preference_tool.newContent(
                                              portal_type='Preference')
    if isTransitionPossible(administrator_preference, 'enable_action'):
      administrator_preference.enable()

    administrator_preference.setPreferredHtmlStyleDevelopperMode(True)
    administrator_preference.setPreferredHtmlStyleTranslatorMode(False)

1220
    # create or edit preference for webeditor
1221 1222 1223 1224
    webeditor_preference = self.portal.portal_catalog.getResultValue(
                                                  portal_type='Preference',
                                                  owner='webeditor')
    if webeditor_preference is None:
1225
      self.loginByUserName('webeditor')
1226 1227 1228 1229 1230 1231 1232 1233
      webeditor_preference = preference_tool.newContent(
                                              portal_type='Preference')
    if isTransitionPossible(webeditor_preference, 'enable_action'):
      webeditor_preference.enable()

    webeditor_preference.setPreferredHtmlStyleDevelopperMode(False)
    webeditor_preference.setPreferredHtmlStyleTranslatorMode(True)
    self.login()
1234
    self.tic()
1235

1236
    self.setupWebSite()
1237 1238 1239 1240
    websection = self.setupWebSection()

    websection_url = '%s/%s' % (self.portal.getId(), websection.getRelativeUrl())

1241
    # connect as administrator and check that only developper_mode is enable
1242 1243 1244 1245
    response = self.publish(websection_url, 'administrator:administrator')
    self.assertTrue('manage_main' in response.getBody())
    self.assertTrue('manage_messages' not in response.getBody())

1246
    # connect as webeditor and check that only translator_mode is enable
1247 1248 1249 1250
    response = self.publish(websection_url, 'webeditor:webeditor')
    self.assertTrue('manage_main' not in response.getBody())
    self.assertTrue('manage_messages' in response.getBody())

1251
    # anonymous user doesn't exists, check anonymous access without preferences
1252 1253 1254 1255
    response = self.publish(websection_url, 'anonymous:anonymous')
    self.assertTrue('manage_main' not in response.getBody())
    self.assertTrue('manage_messages' not in response.getBody())

1256
  def test_15_Check_LastModified_Header(self):
Nicolas Delaby's avatar
Nicolas Delaby committed
1257
    """Checks that Last-Modified header set by caching policy manager
1258
    is correctly filled with getModificationDate of content.
1259
    This test check 2 Policy installed by erp5_web:
1260 1261 1262 1263 1264
    Policy ID - unauthenticated web pages
                authenticated
    """
    website = self.setupWebSite()
    web_section_portal_type = 'Web Section'
1265
    website.newContent(portal_type=web_section_portal_type)
1266 1267 1268 1269 1270 1271 1272

    content = '<p>initial text</p>'
    document = self.portal.web_page_module.newContent(portal_type='Web Page',
            id='document_cache',
            reference='NXD-Document.Cache',
            text_content=content)
    document.publish()
1273 1274
    # clear cache used in Base_getWebDocumentDrivenModificationDate
    self.portal.portal_caches.clearAllCache()
1275
    self.tic()
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295
    path = website.absolute_url_path() + '/NXD-Document.Cache'
    # test Different Policy installed by erp5_web
    # unauthenticated web pages
    response = self.publish(path)
    last_modified_header = response.getHeader('Last-Modified')
    self.assertTrue(last_modified_header)
    from App.Common import rfc1123_date
    # Convert the Date into string according RFC 1123 Time Format
    modification_date = rfc1123_date(document.getModificationDate())
    self.assertEqual(modification_date, last_modified_header)

    # authenticated
    user = self.createUser('webmaster')
    self.createUserAssignement(user, {})
    response = self.publish(path, 'webmaster:webmaster')
    last_modified_header = response.getHeader('Last-Modified')
    self.assertTrue(last_modified_header)
    # Convert the Date into string according RFC 1123 Time Format
    modification_date = rfc1123_date(document.getModificationDate())
    self.assertEqual(modification_date, last_modified_header)
1296

1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311
  def test_15a_CheckCachingPolicyManager(self):
    """
    Check if caching_policy_manager is well applied even if custom
    render method is used in Web Site or Web Section.
    """
    web_site = self.setupWebSite()
    web_section_portal_type = 'Web Section'
    web_section = web_site.newContent(portal_type=web_section_portal_type)
    self.assertTrue(self.publish(web_site.absolute_url_path()).getHeader('X-Cache-Headers-Set-By'))
    web_site.setCustomRenderMethodId('WebSection_viewAsWeb')
    self.assertTrue(self.publish(web_site.absolute_url_path()).getHeader('X-Cache-Headers-Set-By'))
    self.assertTrue(self.publish(web_section.absolute_url_path()).getHeader('X-Cache-Headers-Set-By'))
    web_section.setCustomRenderMethodId('WebSection_viewAsWeb')
    self.assertTrue(self.publish(web_section.absolute_url_path()).getHeader('X-Cache-Headers-Set-By'))

1312
  def test_16_404ErrorPageIsReturned(self):
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
    """
      Test that when we try to access a non existing url trought a web site, a
      404 error page is returned
    """
    portal = self.getPortal()
    request = portal.REQUEST
    request['PARENTS'] = [self.app]
    website = self.setupWebSite()
    path = website.absolute_url_path() + '/a_non_existing_page'
    request = portal.REQUEST

    # Check a Not Found page is returned
    self.assertTrue('Not Found' in request.traverse(path)())
    # Check that we try to display a page with 404.error.page reference
    self.assertEqual(request.traverse(path).absolute_url().split('/')[-1],
    '404.error.page')
1329

1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
  @expectedFailure
  def test_17_WebSectionEditionWithLanguageInURL(self):
    """
    Check that editing a web section with the language in the URL
    does not prevent indexation.

    - Create a web site
    - Activate the language in the URL
    - Create a web section
    - Access it using another language and edit it
    - Check that web section is correctly indexed
    """
    language = 'de'

    website = self.setupWebSite()
    # Check that language in defined in the URL
1346
    self.assertEqual(True, website.getStaticLanguageSelection())
1347 1348 1349
    self.assertNotEquals(language, website.getDefaultAvailableLanguage())

    websection = self.setupWebSection()
1350
    self.assertEqual(websection.getId(), websection.getTitle())
1351

1352
    self.tic()
1353
    response = self.publish('/%s/%s/%s/%s/Base_editAndEditAsWeb' % \
Rafael Monnerat's avatar
Rafael Monnerat committed
1354
                    (self.portal.getId(), website.getRelativeUrl(),
1355 1356 1357
                     language, websection.getId()),
                     basic='ERP5TypeTestCase:',
                     request_method='POST',
1358
                     stdin=StringIO(urlencode({
1359 1360 1361 1362 1363 1364
                       'form_id': 'WebSection_view',
                       'form_action': 'Base_edit',
                       'edit_document_url': '%s/%s/%s/WebSection_view' % \
                           (website.absolute_url(), language,
                             websection.getId()),
                       'field_my_title': '%s_edited' % websection.getId(),
1365
                     }))
1366
                    )
Rafael Monnerat's avatar
Rafael Monnerat committed
1367

1368
    self.assertEqual(MOVED_TEMPORARILY, response.getStatus())
1369 1370 1371
    new_location = response.getHeader('Location')
    new_location = new_location.split('/', 3)[-1]

1372
    self.tic()
1373 1374

    response = self.publish(new_location, basic='ERP5TypeTestCase:',)
1375 1376
    self.assertEqual(HTTP_OK, response.getStatus())
    self.assertEqual('text/html; charset=utf-8',
1377 1378 1379
                      response.getHeader('content-type'))
    self.assertTrue("Data updated." in response.getBody())

1380
    self.tic()
1381

1382 1383
    self.assertEqual('%s_edited' % websection.getId(), websection.getTitle())
    self.assertEqual(1, len(self.portal.portal_catalog(
Rafael Monnerat's avatar
Rafael Monnerat committed
1384
                                    relative_url=websection.getRelativeUrl(),
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
                                    title=websection.getTitle())))

  @expectedFailure
  def test_18_WebSiteEditionWithLanguageInURL(self):
    """
    Check that editing a web section with the language in the URL
    does not prevent indexation.

    - Create a web site
    - Activate the language in the URL
    - Access it using another language and edit it
    - Check that web site is correctly modified
    """
    language = 'de'

    website = self.setupWebSite()
    # Check that language in defined in the URL
1402
    self.assertEqual(True, website.getStaticLanguageSelection())
1403 1404
    self.assertNotEquals(language, website.getDefaultAvailableLanguage())

1405
    self.assertEqual(website.getId(), website.getTitle())
1406

1407
    self.tic()
1408 1409

    response = self.publish('/%s/%s/%s/Base_editAndEditAsWeb' % \
Rafael Monnerat's avatar
Rafael Monnerat committed
1410
                    (self.portal.getId(), website.getRelativeUrl(),
1411 1412 1413
                     language),
                     basic='ERP5TypeTestCase:',
                     request_method='POST',
1414
                     stdin=StringIO(urlencode({
1415 1416 1417 1418 1419 1420
                       'form_id': 'WebSite_view',
                       'form_action': 'Base_edit',
                       'edit_document_url': '%s/%s/WebSite_view' % \
                           (website.absolute_url(), language),
                       'field_my_title': '%s_edited' % website.getId(),
                       'field_my_id': language,
1421
                     }))
1422
                    )
Rafael Monnerat's avatar
Rafael Monnerat committed
1423

1424
    self.assertEqual(MOVED_TEMPORARILY, response.getStatus())
1425 1426 1427
    new_location = response.getHeader('Location')
    new_location = new_location.split('/', 3)[-1]

1428
    self.tic()
1429 1430

    response = self.publish(new_location, basic='ERP5TypeTestCase:',)
1431 1432
    self.assertEqual(HTTP_OK, response.getStatus())
    self.assertEqual('text/html; charset=utf-8',
1433 1434 1435
                      response.getHeader('content-type'))
    self.assertTrue("Data updated." in response.getBody())

1436
    self.tic()
1437

1438 1439
    self.assertEqual('%s_edited' % website.getId(), website.getTitle())
    self.assertEqual(1, len(self.portal.portal_catalog(
Rafael Monnerat's avatar
Rafael Monnerat committed
1440
                                    relative_url=website.getRelativeUrl(),
1441 1442
                                    title=website.getTitle())))

1443 1444
  def test_19_WebModeAndEditableMode(self):
    """
Rafael Monnerat's avatar
Rafael Monnerat committed
1445
    Check if isWebMode & isEditableMode API works.
1446 1447 1448
    """
    request = self.app.REQUEST
    website = self.setupWebSite()
Rafael Monnerat's avatar
Rafael Monnerat committed
1449

1450
    # web mode
1451 1452 1453
    self.assertEqual(False, self.portal.person_module.isWebMode())
    self.assertEqual(True, website.isWebMode())
    self.assertEqual(True, getattr(website, 'person_module').isWebMode())
Rafael Monnerat's avatar
Rafael Monnerat committed
1454

1455
    # editable mode
1456 1457 1458
    self.assertEqual(False, self.portal.person_module.isEditableMode())
    self.assertEqual(False, website.isEditableMode())
    self.assertEqual(False, getattr(website, 'person_module').isEditableMode())
Rafael Monnerat's avatar
Rafael Monnerat committed
1459

1460
    request.set('editable_mode', 1)
1461 1462 1463
    self.assertEqual(1, self.portal.person_module.isEditableMode())
    self.assertEqual(1, website.isEditableMode())
    self.assertEqual(1, getattr(website, 'person_module').isEditableMode())
1464 1465 1466

  def test_20_reStructuredText(self):
    web_page = self.portal.web_page_module.newContent(portal_type='Web Page',
1467 1468
                                                      content_type='text/x-rst')
    web_page.edit(text_content="`foo`")
1469 1470 1471
    self.assertTrue('<cite>foo</cite>' in web_page.asEntireHTML(charset='utf-8'))
    self.assertTrue('<cite>foo</cite>' in web_page.asEntireHTML())

Ivan Tyagov's avatar
Ivan Tyagov committed
1472 1473 1474 1475 1476
  def test_21_WebSiteMap(self):
    """
      Test Web Site map script.
    """
    website = self.setupWebSite()
Rafael Monnerat's avatar
Rafael Monnerat committed
1477

Ivan Tyagov's avatar
Ivan Tyagov committed
1478 1479
    website.setSiteMapSectionParent(1)
    websection1 = website.newContent(portal_type='Web Section',
Rafael Monnerat's avatar
Rafael Monnerat committed
1480 1481
                                     title='Section 1',
                                     site_map_section_parent=1,
Ivan Tyagov's avatar
Ivan Tyagov committed
1482 1483
                                     visible=1)
    websection1_1 = websection1.newContent(portal_type='Web Section',
Rafael Monnerat's avatar
Rafael Monnerat committed
1484 1485 1486
                                     title='Section 1.1',
                                     site_map_section_parent=1,
                                     visible=1)
1487
    self.tic()
Rafael Monnerat's avatar
Rafael Monnerat committed
1488 1489
    site_map = website.WebSection_getSiteMapTree(depth=5, include_subsection=1)
    self.assertSameSet([websection1.getTitle()],
Ivan Tyagov's avatar
Ivan Tyagov committed
1490
                       [x['translated_title'] for x in site_map])
Rafael Monnerat's avatar
Rafael Monnerat committed
1491
    self.assertSameSet([websection1_1.getTitle()],
Ivan Tyagov's avatar
Ivan Tyagov committed
1492
                       [x['translated_title'] for x in site_map[0]['subsection']])
Rafael Monnerat's avatar
Rafael Monnerat committed
1493 1494 1495
    self.assertEqual(1, site_map[0]['level'])
    self.assertEqual(2, site_map[0]['subsection'][0]['level'])

Ivan Tyagov's avatar
Ivan Tyagov committed
1496
    # check depth works
Rafael Monnerat's avatar
Rafael Monnerat committed
1497
    site_map = website.WebSection_getSiteMapTree(depth=1, include_subsection=1)
Ivan Tyagov's avatar
Ivan Tyagov committed
1498
    self.assertEqual(None, site_map[0]['subsection'])
Rafael Monnerat's avatar
Rafael Monnerat committed
1499
    self.assertSameSet([websection1.getTitle()],
Ivan Tyagov's avatar
Ivan Tyagov committed
1500
                       [x['translated_title'] for x in site_map])
Rafael Monnerat's avatar
Rafael Monnerat committed
1501

Ivan Tyagov's avatar
Ivan Tyagov committed
1502 1503
    # hide subsections
    websection1_1.setSiteMapSectionParent(0)
Rafael Monnerat's avatar
Rafael Monnerat committed
1504
    websection1_1.setVisible(0)
1505
    self.tic()
Rafael Monnerat's avatar
Rafael Monnerat committed
1506 1507
    site_map = website.WebSection_getSiteMapTree(depth=5, include_subsection=1)
    self.assertSameSet([websection1.getTitle()],
Ivan Tyagov's avatar
Ivan Tyagov committed
1508
                       [x['translated_title'] for x in site_map])
Rafael Monnerat's avatar
Rafael Monnerat committed
1509
    self.assertEqual(None, site_map[0]['subsection'])
Ivan Tyagov's avatar
Ivan Tyagov committed
1510

1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572
  def test_future_publication_date_not_visible(self):
    portal = self.portal
    reference = 'test_future_publication_date_not_visible'
    newContent = portal.web_page_module.newContent
    date1 = DateTime()
    date2 = date1 + 1
    date3 = date2 + 1
    date4 = date3 + 1

    def new(**kw):
      result = newContent(
        portal_type='Web Page',
        reference=reference,
        **kw
      )
      self.tic()
      result.publish()
      self.tic()
      return result
    document1 = new(version=1)
    document2 = new(version=2, effective_date=date2)
    # Some more documents which should never be visible.
    # Bind them to local variables for quicker debugging, if needed.
    # Later than document2.
    document3 = new(version=3, effective_date=date4)
    # Like document1, but not published
    document4 = newContent(
      portal_type='Web Page',
      reference=reference,
    )
    # Like document2, but not published
    document5 = newContent(
      portal_type='Web Page',
      reference=reference,
      effective_date=date2,
    )
    self.tic()
    site = portal.web_site_module.newContent(
      portal_type='Web Site',
    )
    site.publish()
    section = site.newContent(
      portal_type='Web Section',
    )
    section.setCriterionProperty('reference')
    section.setCriterion(
      'reference',
      max='',
      identity=[reference],
      min='',
    )
    self.tic()

    self.assertEqual(document1.getValidationState(), 'published')
    self.assertEqual(document2.getValidationState(), 'published')
    self.assertEqual(document3.getValidationState(), 'published')
    self.assertEqual(document4.getValidationState(), 'draft')
    self.assertEqual(document5.getValidationState(), 'draft')
    def check(expected_document, date):
      document = section.WebSection_getDocumentValue(reference, now=date)
      self.assertNotEqual(document, None)
      self.assertEqual(document.getPath(), expected_document.getPath())
1573
      document_list = section.getDocumentValueList(now=date)
1574 1575 1576 1577 1578 1579 1580
      self.assertEqual(len(document_list), 1)
      self.assertEqual(document_list[0].getPath(), expected_document.getPath())
    # document1 is visible & listed before date2
    check(document1, date1)
    # document2 is visible & listed at and above date2
    check(document2, date2)
    check(document2, date3)
1581

1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628
  def test_translatable_path(self):
    portal = self.portal
    website = self.setupWebSite(
      static_language_selection=1,
    )
    section1 = self.setupWebSection(
      id='aaa',
    )
    page1 = portal.web_page_module.newContent(
      portal_type='Web Page',
      reference='page1',
      language='en',
      text_content='page1 in English',
    )
    page1.publish()
    page1_fr = portal.web_page_module.newContent(
      portal_type='Web Page',
      reference='page1',
      language='fr',
      text_content='page1 in French',
    )
    page1_fr.publish()
    section1.setAggregateValue(page1)
    section2 = self.setupWebSection(
      id='bbb',
    )
    page2 = portal.web_page_module.newContent(
      portal_type='Web Page',
      reference='page2',
      language='en',
      text_content='page2',
    )
    page2.publish()
    page2_fr = portal.web_page_module.newContent(
      portal_type='Web Page',
      reference='page2',
      language='fr',
      text_content='page2 in French',
    )
    page2_fr.publish()
    section2.setAggregateValue(page2)
    section2.setFrTranslatedTranslatableId('aaa')
    # Only setting /fr/aaa => /bbb will conflict with /aaa having no translated path yet.
    self.assertRaises(ValueError, self.commit)
    # After setting /fr/ccc => /aaa as well, we have no conflict.
    section1.setFrTranslatedTranslatableId('ccc')
    self.tic()
1629
    website_absolute_url = website.absolute_url()
1630 1631 1632
    website_path = website.absolute_url_path()
    # /fr/ccc/ is /aaa/
    response = self.publish(website_path + '/fr/ccc/')
1633
    self.assertEqual(HTTP_OK, response.status)
1634 1635 1636
    self.assertIn('page1 in French', response.getBody())
    # /fr/aaa/ is /bbb/
    response = self.publish(website_path + '/fr/aaa/')
1637
    self.assertEqual(HTTP_OK, response.status)
1638 1639 1640
    self.assertIn('page2 in French', response.getBody())
    # /fr/bbb/ should be redirected to /fr/aaa/
    response = self.publish(website_path + '/fr/bbb/')
1641
    self.assertEqual(MOVED_TEMPORARILY, response.status)
1642 1643 1644 1645 1646 1647
    self.assertEqual(website_absolute_url + '/fr/aaa/', response.getHeader('Location'))
    # check absolute_translated_url()
    with self.portal.Localizer.translationContext('fr'):
      self.assertEqual(website_absolute_url + '/fr', website.absolute_translated_url())
      self.assertEqual(website_absolute_url + '/fr/ccc', website['aaa'].absolute_translated_url())
      self.assertEqual(website_absolute_url + '/fr/aaa', website['bbb'].absolute_translated_url())
1648

1649 1650 1651 1652 1653 1654 1655
class TestERP5WebWithSimpleSecurity(ERP5TypeTestCase):
  """
  Test for erp5_web with simple security.
  """

  def getBusinessTemplateList(self):
    return ('erp5_base',
1656
            'erp5_pdm',
1657
            'erp5_simulation',
1658 1659
            'erp5_trade',
            'erp5_project',
1660 1661 1662 1663 1664 1665
            'erp5_web',
            )

  def getTitle(self):
    return "Web"

1666
  def createUser(self, name, role_list): # pylint: disable=arguments-differ
1667 1668 1669 1670
    user_folder = self.getPortal().acl_users
    user_folder._doAddUser(name, 'password', role_list, [])

  def afterSetUp(self):
1671
    self.web_site_module = self.portal.web_site_module
1672 1673 1674
    self.portal.Localizer = DummyLocalizer()
    self.createUser('admin', ['Manager'])
    self.createUser('erp5user', ['Auditor', 'Author'])
1675
    self.createUser('webmaster', ['Assignor'])
1676 1677
    self.tic()

1678 1679 1680 1681
  def clearModule(self, module):
    module.manage_delObjects(list(module.objectIds()))
    self.tic()

1682
  def beforeTearDown(self):
1683 1684
    self.clearModule(self.portal.web_site_module)
    self.clearModule(self.portal.web_page_module)
1685

1686
  def test_01_AccessWebPageByReference(self):
1687
    self.loginByUserName('admin')
1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698
    site = self.portal.web_site_module.newContent(portal_type='Web Site',
                                                  id='site')
    section = site.newContent(portal_type='Web Section', id='section')

    self.tic()

    section.setCriterionProperty('portal_type')
    section.setCriterion('portal_type', max='', identity=['Web Page'], min='')

    self.tic()

1699
    self.loginByUserName('erp5user')
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730
    page_en = self.portal.web_page_module.newContent(portal_type='Web Page')
    page_en.edit(reference='my-first-web-page',
                 language='en',
                 version='1',
                 text_format='text/plain',
                 text_content='Hello, World!')

    self.tic()

    page_en.publish()

    self.tic()

    page_ja = self.portal.web_page_module.newContent(portal_type='Web Page')
    page_ja.edit(reference='my-first-web-page',
                 language='ja',
                 version='1',
                 text_format='text/plain',
                 text_content='こんにちは、世界!')

    self.tic()

    page_ja.publish()

    self.tic()

    # By Anonymous
    self.logout()

    self.portal.Localizer.changeLanguage('en')

1731
    target = self.portal.unrestrictedTraverse('web_site_module/site/section/my-first-web-page')
1732 1733 1734 1735
    self.assertEqual('Hello, World!', target.getTextContent())

    self.portal.Localizer.changeLanguage('ja')

1736
    target = self.portal.unrestrictedTraverse('web_site_module/site/section/my-first-web-page')
1737
    self.assertEqual('こんにちは、世界!', target.getTextContent())
1738

1739
  def test_02_LocalRolesFromRoleDefinition(self):
1740 1741 1742 1743 1744 1745
    """ Test setting local roles on Web Site/ Web Sectio using ERP5 Role Definition objects . """
    portal = self.portal
    person_reference = 'webuser'
    site = portal.web_site_module.newContent(portal_type='Web Site',
                                                  id='site')
    section = site.newContent(portal_type='Web Section', id='section')
1746
    person = portal.person_module.newContent(portal_type = 'Person',
1747
                                             reference = person_reference)
1748
    person_user_id = person.Person_getUserId()
1749
    # add Role Definition for site and section
1750 1751
    site_role_definition = site.newContent(portal_type = 'Role Definition',
                                           role_name = 'Assignee',
1752
                                           agent = person.getRelativeUrl())
1753 1754
    section_role_definition = section.newContent(portal_type = 'Role Definition',
                                                 role_name = 'Associate',
1755
                                                 agent = person.getRelativeUrl())
1756 1757
    self.tic()
    # check if Role Definition have create local roles
1758
    self.assertSameSet(('Assignee',),
1759
                          site.get_local_roles_for_userid(person_user_id))
1760
    self.assertSameSet(('Associate',),
1761
                          section.get_local_roles_for_userid(person_user_id))
1762 1763
    self.assertRaises(Unauthorized, site_role_definition.edit,
                      role_name='Manager')
1764

1765 1766 1767 1768
    # delete Role Definition and check again (local roles must be gone too)
    site.manage_delObjects(site_role_definition.getId())
    section.manage_delObjects(section_role_definition.getId())
    self.tic()
1769
    self.assertSameSet((),
1770
                       site.get_local_roles_for_userid(person_user_id))
1771
    self.assertSameSet((),
1772
                       section.get_local_roles_for_userid(person_user_id))
1773

1774 1775
  def test_03_getDocumentValueListSecurity(self):
    """ Test getDocumentValueList behaviour and security"""
1776
    self.loginByUserName('admin')
1777
    site = self.portal.web_site_module.newContent(portal_type='Web Site',
1778
                                      id='site')
1779
    site.publish()
1780

1781
    section = site.newContent(portal_type='Web Section',
1782 1783 1784 1785 1786
                              id='section')

    self.tic()

    section.setCriterionProperty('portal_type')
1787
    section.setCriterion('portal_type', max='',
1788 1789 1790 1791
                         identity=['Web Page'], min='')

    self.tic()

1792
    self.loginByUserName('erp5user')
1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820
    page_en_0 = self.portal.web_page_module.newContent(portal_type='Web Page')
    page_en_0.edit(reference='my-first-web-page',
                 language='en',
                 version='1',
                 text_format='text/plain',
                 text_content='Hello, World!')

    page_en_1 = self.portal.web_page_module.newContent(portal_type='Web Page')
    page_en_1.edit(reference='my-first-web-page',
                 language='en',
                 version='2',
                 text_format='text/plain',
                 text_content='Hello, World!')

    page_en_2 = self.portal.web_page_module.newContent(portal_type='Web Page')
    page_en_2.edit(reference='my-second-web-page',
                 language='en',
                 version='2',
                 text_format='text/plain',
                 text_content='Hello, World!')

    page_jp_0 = self.portal.web_page_module.newContent(portal_type='Web Page')
    page_jp_0.edit(reference='my-first-japonese-page',
                 language='jp',
                 version='1',
                 text_format='text/plain',
                 text_content='Hello, World!')

1821
    self.commit()
1822
    self.loginByUserName('erp5user')
1823 1824
    self.tic()
    self.portal.Localizer.changeLanguage('en')
1825

1826
    self.assertEqual(0, len(section.getDocumentValueList()))
1827

1828
    self.loginByUserName('erp5user')
1829 1830 1831 1832
    page_en_0.publish()
    self.tic()

    self.portal.Localizer.changeLanguage('en')
1833
    self.assertEqual(1, len(section.getDocumentValueList()))
1834
    self.assertEqual(page_en_0.getUid(),
1835
                      section.getDocumentValueList()[0].getUid())
1836 1837

    self.portal.Localizer.changeLanguage('jp')
1838
    self.assertEqual(0, len(section.getDocumentValueList()))
1839 1840 1841 1842

    # By Anonymous
    self.logout()
    self.portal.Localizer.changeLanguage('en')
1843
    self.assertEqual(1, len(section.getDocumentValueList()))
1844
    self.assertEqual(page_en_0.getUid(),
1845
                      section.getDocumentValueList()[0].getUid())
1846
    self.portal.Localizer.changeLanguage('jp')
1847
    self.assertEqual(0, len(section.getDocumentValueList()))
1848 1849

    # Second Object
1850
    self.loginByUserName('erp5user')
1851 1852 1853 1854
    page_en_1.publish()
    self.tic()

    self.portal.Localizer.changeLanguage('en')
1855
    self.assertEqual(1, len(section.getDocumentValueList()))
1856
    self.assertEqual(page_en_1.getUid(),
1857
                      section.getDocumentValueList()[0].getUid())
1858
    self.portal.Localizer.changeLanguage('jp')
1859
    self.assertEqual(0, len(section.getDocumentValueList()))
1860 1861 1862 1863

    # By Anonymous
    self.logout()
    self.portal.Localizer.changeLanguage('en')
1864
    self.assertEqual(1, len(section.getDocumentValueList()))
1865
    self.assertEqual(page_en_1.getUid(),
1866
                      section.getDocumentValueList()[0].getUid())
1867 1868

    # Trird Object
1869
    self.loginByUserName('erp5user')
1870 1871 1872 1873
    page_en_2.publish()
    self.tic()

    self.portal.Localizer.changeLanguage('en')
1874
    self.assertEqual(2, len(section.getDocumentValueList()))
1875
    self.portal.Localizer.changeLanguage('jp')
1876
    self.assertEqual(0, len(section.getDocumentValueList()))
1877 1878 1879 1880

    # By Anonymous
    self.logout()
    self.portal.Localizer.changeLanguage('en')
1881
    self.assertEqual(2, len(section.getDocumentValueList()))
1882
    self.portal.Localizer.changeLanguage('jp')
1883
    self.assertEqual(0, len(section.getDocumentValueList()))
1884

1885
    # First Japanese Object
1886
    self.loginByUserName('erp5user')
1887 1888 1889 1890
    page_jp_0.publish()
    self.tic()

    self.portal.Localizer.changeLanguage('en')
1891
    self.assertEqual(2, len(section.getDocumentValueList()))
1892
    self.portal.Localizer.changeLanguage('jp')
1893
    self.assertEqual(1, len(section.getDocumentValueList()))
1894 1895 1896 1897

    # By Anonymous
    self.logout()
    self.portal.Localizer.changeLanguage('en')
1898
    self.assertEqual(2, len(section.getDocumentValueList()))
1899
    self.portal.Localizer.changeLanguage('jp')
1900
    self.assertEqual(1, len(section.getDocumentValueList()))
1901
    self.assertEqual(page_jp_0.getUid(),
1902
                      section.getDocumentValueList()[0].getUid())
1903

1904
  def test_04_ExpireUserAction(self):
1905
    """ Test the expire user action"""
1906
    self.loginByUserName('admin')
1907
    site = self.portal.web_site_module.newContent(portal_type='Web Site', id='site')
1908 1909 1910 1911 1912 1913 1914 1915

    # create websections in a site and in anothers web sections
    section_1 = site.newContent(portal_type='Web Section', id='section_1')
    section_2 = site.newContent(portal_type='Web Section', id='section_2')
    section_3 = site.newContent(portal_type='Web Section', id='section_3')
    section_4 = site.newContent(portal_type='Web Section', id='section_4')
    section_5 = section_3.newContent(portal_type='Web Section', id='section_5')
    section_6 = section_4.newContent(portal_type='Web Section', id='section_6')
1916 1917
    self.tic()

1918 1919 1920 1921 1922 1923
    # test if a manager can expire them
    try:
      section_1.expire()
      section_5.expire()
    except Unauthorized:
      self.fail("Admin should be able to expire a Web Section.")
1924

1925
    # test if a user (ASSIGNOR) can expire them
1926
    self.loginByUserName('webmaster')
1927 1928 1929 1930 1931
    try:
      section_2.expire()
      section_6.expire()
    except Unauthorized:
      self.fail("An user should be able to expire a Web Section.")
1932

1933
  def test_05_createWebSite(self):
1934
    """ Test to create or clone web sites with many users """
1935
    self.loginByUserName('admin')
1936
    web_site_module = self.portal.web_site_module
1937 1938 1939

    # test for admin
    try:
1940
      web_site_module.newContent(portal_type='Web Site', id='site_1')
1941 1942 1943 1944
    except Unauthorized:
      self.fail("Admin should be able to create a Web Site.")

    # test as a web user (assignor)
1945
    self.loginByUserName('webmaster')
1946 1947 1948 1949 1950
    try:
      site_2 = web_site_module.newContent(portal_type='Web Site', id='site_2')
    except Unauthorized:
      self.fail("A webmaster should be able to create a Web Site.")

1951 1952 1953
    site_2_copy = web_site_module.manage_copyObjects(ids=(site_2.getId(),))
    site_2_clone = web_site_module[web_site_module.manage_pasteObjects(
      site_2_copy)[0]['new_id']]
1954
    self.assertEqual(site_2_clone.getPortalType(), 'Web Site')
1955

1956
  def test_06_createWebSection(self):
1957
    """ Test to create or clone web sections with many users """
1958
    self.loginByUserName('admin')
1959
    site = self.portal.web_site_module.newContent(portal_type='Web Site', id='site')
1960

1961 1962 1963 1964 1965 1966 1967
    # test for admin
    try:
      section_1 = site.newContent(portal_type='Web Section', id='section_1')
      section_2 = section_1.newContent(portal_type='Web Section', id='section_2')
    except Unauthorized:
      self.fail("Admin should be able to create a Web Section.")

1968
    # test as a webmaster (assignor)
1969
    self.loginByUserName('webmaster')
1970 1971 1972 1973
    try:
      section_2 = site.newContent(portal_type='Web Section', id='section_2')
      section_3 = section_2.newContent(portal_type='Web Section', id='section_3')
    except Unauthorized:
1974
      self.fail("A webmaster should be able to create a Web Section.")
1975 1976 1977
    section_2_copy = site.manage_copyObjects(ids=(section_2.getId(),))
    section_2_clone = site[site.manage_pasteObjects(
      section_2_copy)[0]['new_id']]
1978
    self.assertEqual(section_2_clone.getPortalType(), 'Web Section')
1979 1980 1981
    section_3_copy = section_2.manage_copyObjects(ids=(section_3.getId(),))
    section_3_clone = section_2[section_2.manage_pasteObjects(
      section_3_copy)[0]['new_id']]
1982
    self.assertEqual(section_3_clone.getPortalType(), 'Web Section')
1983

1984
  def test_07_createCategory(self):
1985
    """ Test to create or clone categories with many users """
1986
    self.loginByUserName('admin')
1987 1988 1989 1990 1991
    portal_categories = self.portal.portal_categories
    publication_section = portal_categories.publication_section

    # test for admin
    try:
1992
      portal_categories.newContent(portal_type='Base Category', id='base_category_1')
1993 1994 1995 1996 1997 1998 1999 2000 2001 2002
    except Unauthorized:
      self.fail("Admin should be able to create a Base Category.")
    try:
      category_1 = publication_section.newContent(portal_type='Category', id='category_1')
      category_2 = category_1.newContent(portal_type='Category', id='category_3')
    except Unauthorized:
      self.fail("Admin should be able to create a Category.")
    category_1_copy = publication_section.manage_copyObjects(ids=(category_1.getId(),))
    category_1_clone = publication_section[publication_section.manage_pasteObjects(
      category_1_copy)[0]['new_id']]
2003
    self.assertEqual(category_1_clone.getPortalType(), 'Category')
2004 2005 2006
    category_2_copy = category_1.manage_copyObjects(ids=(category_2.getId(),))
    category_2_clone = category_1[category_1.manage_pasteObjects(
      category_2_copy)[0]['new_id']]
2007
    self.assertEqual(category_2_clone.getPortalType(), 'Category')
2008 2009

    # test as a web user (assignor)
2010
    self.loginByUserName('webmaster')
2011
    try:
2012
      portal_categories.newContent(portal_type='Base Category', id='base_category_2')
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025
      self.fail("A webmaster should not be able to create a Base Category.")
    except Unauthorized:
      pass
    try:
      category_3 = publication_section.newContent(portal_type='Category', id='category_3')
      category_4 = category_3.newContent(portal_type='Category', id='category_4')
    except Unauthorized:
      self.fail("A webmaster should be able to create a Category.")
    # try to clone a sub category of the same owner whose parent is a
    # base category.
    category_3_copy = publication_section.manage_copyObjects(ids=(category_3.getId(),))
    category_3_clone = publication_section[publication_section.manage_pasteObjects(
      category_3_copy)[0]['new_id']]
2026
    self.assertEqual(category_3_clone.getPortalType(), 'Category')
2027 2028 2029 2030
    # try to clone a sub category of the different owner
    category_2_copy = category_1.manage_copyObjects(ids=(category_2.getId(),))
    category_2_clone = category_1[category_1.manage_pasteObjects(
      category_2_copy)[0]['new_id']]
2031
    self.assertEqual(category_2_clone.getPortalType(), 'Category')
2032 2033 2034 2035
    # try to clone a sub category of the same owner
    category_4_copy = category_3.manage_copyObjects(ids=(category_4.getId(),))
    category_4_clone = category_3[category_3.manage_pasteObjects(
      category_4_copy)[0]['new_id']]
2036
    self.assertEqual(category_4_clone.getPortalType(), 'Category')
2037

2038
  def test_08_createAndrenameCategory(self):
2039
    """ Test to create or rename categories with many users """
2040
    self.loginByUserName('admin')
2041 2042
    portal_categories = self.portal.portal_categories
    publication_section = portal_categories.publication_section
2043

2044 2045
    # test for admin
    try:
2046
      portal_categories.newContent(portal_type='Base Category', id='new_base_category_1')
2047 2048 2049 2050 2051
    except Unauthorized:
      self.fail("Admin should be able to create a Base Category.")
    try:
      new_category_1 = publication_section.newContent(portal_type='Category', id='new_category_1')
      new_category_2 = new_category_1.newContent(portal_type='Category',
2052
      id='new_category_2')
2053 2054 2055 2056
    except Unauthorized:
      self.fail("Admin should be able to create a Category.")
    self.tic()
    try:
2057 2058
      new_category_1.edit(id='new_cat_1_renamed')
      new_category_2.edit(id='new_cat_2_renamed')
2059 2060 2061
    except Unauthorized:
      self.fail("Admin should be able to rename a Category.")
    # test as a web user (assignor)
2062
    self.loginByUserName('webmaster')
2063
    try:
2064
      portal_categories.newContent(portal_type='Base Category', id='base_category_2')
2065 2066 2067 2068 2069
      self.fail("A webmaster should not be able to create a Base Category.")
    except Unauthorized:
      pass
    try:
      new_category_3 = publication_section.newContent(
Rafael Monnerat's avatar
Rafael Monnerat committed
2070
      portal_type='Category', id='new_category_3')
2071
      new_category_4 = new_category_3.newContent(portal_type='Category',
2072
          id='new_category_4')
2073 2074 2075 2076
    except Unauthorized:
      self.fail("A webmaster should be able to create a Category.")
    self.tic()
    try:
2077 2078
      new_category_3.edit(id='new_cat_3_renamed')
      new_category_4.edit(id='new_cat_4_renamed')
2079 2080
    except Unauthorized:
      self.fail("A webmaster should be able to rename a Category.")
2081

2082 2083 2084 2085 2086
  def test_getDocumentValueList_AnonymousUser(self):
    """
      For a given Web Site with Predicates:
      - membership_criterion_base_category: follow_up
      - membership_criterion_document_list: follow_up/project/object_id
2087

2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
      When you access website/WebSection_viewContentListAsRSS:
      - with super user you get the correct result
      - with anonymous user you do not get the correct result

      In this case, both Web Pages are returned for Anonymous user and this
      it not the expected behavior.

      Note: The ListBox into WebSection_viewContentListAsRSS has
            getDocumentValueList defined as ListMethod.
    """
    project = self.portal.project_module.newContent(portal_type='Project')
    project.validate()
2100
    self.tic()
2101

2102
    website = self.portal.web_site_module.newContent(portal_type='Web Site',
2103
                                                     id='site')
2104
    website.publish()
2105 2106 2107
    website.setMembershipCriterionBaseCategory('follow_up')
    website.setMembershipCriterionDocumentList(['follow_up/%s' %
                                                  project.getRelativeUrl()])
2108
    self.tic()
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118

    web_page_module = self.portal.web_page_module
    web_page_follow_up = web_page_module.newContent(portal_type="Web Page",
                                      follow_up=project.getRelativeUrl(),
                                      id='test_web_page_with_follow_up',
                                      reference='NXD-Document.Follow.Up.Test',
                                      version='001',
                                      language='en',
                                      text_content='test content')
    web_page_follow_up.publish()
2119
    self.tic()
2120

2121 2122 2123 2124 2125 2126 2127
    web_page_no_follow_up = web_page_module.newContent(portal_type="Web Page",
                                      id='test_web_page_no_follow_up',
                                      reference='NXD-Document.No.Follow.Up.Test',
                                      version='001',
                                      language='en',
                                      text_content='test content')
    web_page_no_follow_up.publish()
2128
    self.tic()
2129

2130
    self.assertEqual(1, len(website.getDocumentValueList()))
2131 2132

    self.logout()
2133
    self.assertEqual(1, len(website.getDocumentValueList()))
2134

2135 2136
  def test_WebSiteModuleDefaultSecurity(self):
    """
2137
      Test that by default Anonymous User cannot access Web Site Module
2138 2139
    """
    self.logout()
2140
    self.assertRaises(Unauthorized, self.portal.web_site_module.view)
2141

2142

2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172
class TestERP5WebCategoryPublicationWorkflow(ERP5TypeTestCase):
  """Tests possible transitions for category_publication_workflow"""
  def getBusinessTemplateList(self):
    return ('erp5_base',
            'erp5_web',
            )

  def afterSetUp(self):
    base_category = self.getPortal().portal_categories\
        .newContent(portal_type='Base Category')
    self.doActionFor = self.getPortal().portal_workflow.doActionFor
    self.category = base_category.newContent(portal_type='Category')
    self.assertEqual('embedded', self.category.getValidationState())

  def test_category_embedded_expired(self):
    self.doActionFor(self.category, 'expire_action')
    self.assertEqual('expired', self.category.getValidationState())

  def test_category_embedded_protected_expired(self):
    self.doActionFor(self.category, 'protect_action')
    self.assertEqual('protected', self.category.getValidationState())
    self.doActionFor(self.category, 'expire_action')
    self.assertEqual('expired_protected', self.category.getValidationState())

  def test_category_embedded_published_expired(self):
    self.doActionFor(self.category, 'publish_action')
    self.assertEqual('published', self.category.getValidationState())
    self.doActionFor(self.category, 'expire_action')
    self.assertEqual('expired_published', self.category.getValidationState())

2173 2174 2175 2176 2177 2178
  def test_category_embedded_delete(self):
    """On category publication workflow, deletion are "real"
    """
    self.doActionFor(self.category, 'delete_action')
    self.assertEqual([], self.category.getParentValue().contentValues())

Rafael Monnerat's avatar
Rafael Monnerat committed
2179

2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226
class ERP5WebUpgraderMixin(object):
  """Test mixin that checks that web site or web sections are upgraded.

  Subclasses must set `upgraded` attribute.
  """
  upgraded = None # type: erp5.portal_type.WebSection
  def getBusinessTemplateList(self):
    return ('erp5_base', 'erp5_web', )

  def test_empty_constraint(self):
    self.assertEqual(
        [], [str(m.getMessage()) for m in self.upgraded.checkConsistency()])

  def test_upgrader_fix_modification_date(self):
    # Upgrader sets the modification date on the web section if
    # it's older than its default page.
    html_page = self.portal.web_page_module.newContent(
        portal_type='Web Page',
        reference=self.id(),
    )
    html_page.publish()
    self.tic()

    self.upgraded.edit(aggregate_value=html_page)
    self.tic()
    time.sleep(1)
    html_page.edit(text_content="<p>Hello again</p>")
    self.tic()
    self.assertLess(
        self.upgraded.getModificationDate(),
        html_page.getModificationDate()
        )
    self.assertEqual(
        ['Web Section {} is older than default page'.format(self.upgraded.getRelativeUrl())],
        [str(m.getMessage()) for m in self.upgraded.checkConsistency()])
    self.upgraded.fixConsistency()
    self.tic()

    self.assertEqual(
        [], [str(m.getMessage()) for m in self.upgraded.checkConsistency()])
    self.assertGreater(
        self.upgraded.getModificationDate(),
        html_page.getModificationDate())


class TestERP5WebSiteUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
  def afterSetUp(self):
2227
    super(TestERP5WebSiteUpgrader, self).afterSetUp()
2228 2229 2230 2231 2232 2233 2234
    self.upgraded = self.portal.web_site_module.newContent(
        portal_type='Web Site',
    )


class TestERP5WebSectionUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
  def afterSetUp(self):
2235
    super(TestERP5WebSectionUpgrader, self).afterSetUp()
2236 2237 2238 2239 2240 2241 2242 2243
    self.upgraded = self.portal.web_site_module.newContent(
        portal_type='Web Site',
    ).newContent(
        portal_type='Web Section',
    )

class TestERP5StaticWebSiteUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
  def afterSetUp(self):
2244
    super(TestERP5StaticWebSiteUpgrader, self).afterSetUp()
2245 2246 2247 2248 2249 2250 2251
    self.upgraded = self.portal.web_site_module.newContent(
        portal_type='Static Web Site',
    )


class TestERP5StaticWebSectionUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
  def afterSetUp(self):
2252
    super(TestERP5StaticWebSectionUpgrader, self).afterSetUp()
2253 2254 2255 2256 2257
    self.upgraded = self.portal.web_site_module.newContent(
        portal_type='Web Site',
    ).newContent(
        portal_type='Static Web Section',
    )