Skip to content

Commit

Permalink
Add CI build for integration with plone.app.contenttypes
Browse files Browse the repository at this point in the history
Even as collective.cover has been in production using plone.app.contenttypes for more than 2 years in many sites, we haven't deal with testing that in CI.

Many changes were made here to achieve compatibility and fix some errors:

- testing content creation was refactored to simplify it
- Dexterity Image content was removed as is no longer necessary (test case is covered by using plone.app.contenttypes)
- a bunch of hacks to deal with Archetypes/Dexterity API incompatibilites were included
- RF collection tile test was refactored and finally fixed (I hope so)
- documentation was updated to include a known good versions of packages involved

This is a huge step in the search of Plone 5 compatibility.
  • Loading branch information
hvelarde committed Mar 3, 2016
1 parent 45d0c3c commit 6138b68
Show file tree
Hide file tree
Showing 33 changed files with 423 additions and 378 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ env:
matrix:
- PLONE_VERSION=4.2
- PLONE_VERSION=4.3
- PLONE_VERSION=4.3 NEW_WIDGETS=true
- PLONE_VERSION=4.3 DEXTERITY_ONLY=true
- PLONE_VERSION=4.3 JQUERY=1.8.3
- PLONE_VERSION=4.3 JQUERY=1.9.1.3
- PLONE_VERSION=4.3 NEW_WIDGETS=true
- PLONE_VERSION=5.0
matrix:
allow_failures:
Expand Down
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ There's a frood who really knows where his towel is.

- Remove hard dependency on plone.app.stagingbehavior as that package is no longer needed in Plone 5.
Under Plone < 5.0 you should now explicitly add it to the `eggs` part of your buildout configuration to avoid issues while upgrading.
Support for checkout and checkin operations will be automatically configured if ``plone.app.stagingbehavior`` is available.
[hvelarde]

- Implement drag and drop among tiles (closes `#487`_).
Expand Down
18 changes: 9 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,22 @@ To enable this package in a buildout-based installation:
...
eggs =
collective.cover
plone.app.stagingbehavior

[versions]
...
collective.js.bootstrap = 2.3.1.1
plone.app.blocks = 2.2.0
plone.app.tiles = 1.0.1

# if you want to use plone.app.widgets
plone.app.widgets = 1.8.0

# if you want to use plone.app.contenttypes
plone.app.contenttypes = 1.1
plone.app.event = 1.1.5
plone.formwidget.datetime = 1.1

#. If you are using Plone 4.2.x you need to add the following also::

[versions]
Expand All @@ -130,15 +139,6 @@ To enable this package in a buildout-based installation:
plone.app.z3cform = 0.6.3
plone.directives.form = 1.1

#. If you are using Plone < 5.0, and you want to use versioning support, you should also add::

[buildout]
...
eggs =
plone.app.stagingbehavior

Support for checkout and checkin operations will be automatically configured if ``plone.app.stagingbehavior`` is available.

#. If you want to use a newer release of ``collective.js.bootstrap``, you will need to update ``plone.app.jquery``::

[versions]
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
'plone.z3cform',
'Products.Archetypes',
'Products.CMFCore',
'Products.CMFPlone >=4.2, <5.0',
'Products.CMFPlone >=4.2',
'Products.GenericSetup',
'setuptools',
'z3c.caching',
Expand All @@ -103,6 +103,7 @@
'plone.cachepurging',
'plone.testing',
'Products.PloneFormGen <1.8.0.alpha1',
'tzlocal',
],
},
entry_points="""
Expand Down
4 changes: 0 additions & 4 deletions src/collective/cover/profiles/testfixture/metadata.xml

This file was deleted.

6 changes: 0 additions & 6 deletions src/collective/cover/profiles/testfixture/structure/.objects
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
my-collection,Collection
my-document,Document
my-file,File
my-folder,Folder
my-image,Image
my-image1,Image
my-image2,Image
my-link,Link
my-news-item,News Item
Empty file.

This file was deleted.

This file was deleted.

This file was deleted.

3 changes: 0 additions & 3 deletions src/collective/cover/profiles/testfixture/structure/my-folder

This file was deleted.

This file was deleted.

This file was deleted.

5 changes: 0 additions & 5 deletions src/collective/cover/profiles/testfixture/types.xml

This file was deleted.

This file was deleted.

77 changes: 43 additions & 34 deletions src/collective/cover/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,41 @@
We have to set different test fixtures depending on Plone versions and
features we want to test:
plone.app.contenttypes:
installed under Plone 4.3, if requested; installed under Plone 5
plone.app.stagingbehavior
installed under Plone 4 only
plone.app.widgets
installed under Plone 4.3, if requested
Products.PloneFormGen
installed under Plone 4 only
"""
from App.Common import package_home
from collective.cover.config import PLONE_VERSION
from PIL import Image
from PIL import ImageChops
from collective.cover.tests.utils import create_standard_content_for_tests
from collective.cover.tests.utils import set_file_field
from collective.cover.tests.utils import set_image_field
from plone.app.robotframework.testing import AUTOLOGIN_LIBRARY_FIXTURE
from plone.app.testing import FunctionalTesting
from plone.app.testing import IntegrationTesting
from plone.app.testing import PLONE_FIXTURE
from plone.app.testing import PloneSandboxLayer
from plone.testing import z2
from StringIO import StringIO

import os
import pkg_resources
import random

try:
pkg_resources.get_distribution('plone.app.contenttypes')
except pkg_resources.DistributionNotFound:
DEXTERITY_ONLY = False
else:
# this environment variable is set in .travis.yml test matrix
DEXTERITY_ONLY = os.environ.get('DEXTERITY_ONLY') is not None

try:
pkg_resources.get_distribution('plone.app.widgets')
except pkg_resources.DistributionNotFound:
Expand All @@ -50,7 +63,6 @@
'News Item',
]


zptlogo = (
'GIF89a\x10\x00\x10\x00\xd5\x00\x00\xff\xff\xff\xff\xff\xfe\xfc\xfd\xfd'
'\xfa\xfb\xfc\xf7\xf9\xfa\xf5\xf8\xf9\xf3\xf6\xf8\xf2\xf5\xf7\xf0\xf4\xf6'
Expand All @@ -72,17 +84,18 @@
)


def loadFile(name, size=0):
"""Load file from testing directory
"""
path = os.path.join(package_home(globals()), 'tests/input', name)
fd = open(path, 'rb')
data = fd.read()
fd.close()
def load_file(name):
"""Load file from testing directory."""
path = os.path.abspath(os.path.dirname(__file__))
filename = os.path.join(path, 'tests/input', name)
with open(filename, 'r') as f:
data = f.read()
return data


def generate_jpeg(width, height):
from PIL import Image
from StringIO import StringIO
# Mandelbrot fractal
# FB - 201003254
# drawing area
Expand Down Expand Up @@ -114,16 +127,6 @@ def generate_jpeg(width, height):
return output


def images_are_equal(str1, str2):
im1 = StringIO()
im2 = StringIO()
im1.write(str1)
im1.seek(0)
im2.write(str2)
im2.seek(0)
return ImageChops.difference(Image.open(im1), Image.open(im2)).getbbox() is None


class Fixture(PloneSandboxLayer):

defaultBases = (PLONE_FIXTURE,)
Expand All @@ -133,6 +136,11 @@ def setUpZope(self, app, configurationContext):
import plone.app.stagingbehavior
self.loadZCML(package=plone.app.stagingbehavior)

if DEXTERITY_ONLY:
import plone.app.contenttypes
self.loadZCML(package=plone.app.contenttypes)
z2.installProduct(app, 'Products.DateRecurringIndex')

if NEW_WIDGETS:
import plone.app.widgets
self.loadZCML(package=plone.app.widgets)
Expand All @@ -154,28 +162,29 @@ def setUpZope(self, app, configurationContext):

def setUpPloneSite(self, portal):
if PLONE_VERSION < '5.0':
if DEXTERITY_ONLY:
self.applyProfile(portal, 'plone.app.contenttypes:default')

if NEW_WIDGETS:
self.applyProfile(portal, 'plone.app.widgets:default')

if HAS_PFG:
self.applyProfile(portal, 'Products.PloneFormGen:default')

# Install into Plone site using portal_setup
self.applyProfile(portal, 'collective.cover:default')
self.applyProfile(portal, 'collective.cover:testfixture')
portal['my-image'].setImage(generate_jpeg(50, 50))
portal['my-image'].reindexObject()
portal['my-image1'].setImage(generate_jpeg(50, 50))
portal['my-image1'].reindexObject()
portal['my-image2'].setImage(generate_jpeg(50, 50))
portal['my-image2'].reindexObject()
portal['my-file'].setFile(loadFile('lorem_ipsum.txt'))
portal['my-file'].reindexObject()
portal['my-news-item'].setImage(generate_jpeg(50, 50))
portal['my-news-item'].reindexObject()

# setup test content
create_standard_content_for_tests(portal)
set_file_field(portal['my-file'], load_file('lorem_ipsum.txt'))
set_image_field(portal['my-image'], generate_jpeg(50, 50))
set_image_field(portal['my-image1'], generate_jpeg(50, 50))
set_image_field(portal['my-image2'], generate_jpeg(50, 50))
set_image_field(portal['my-news-item'], generate_jpeg(50, 50))

portal_workflow = portal.portal_workflow
portal_workflow.setChainForPortalTypes(
['Collection', 'Event'], ['simple_publication_workflow'])
['Collection'], ['simple_publication_workflow'])

# Prevent kss validation errors in Plone 4.2
portal_kss = getattr(portal, 'portal_kss', None)
Expand Down
16 changes: 4 additions & 12 deletions src/collective/cover/tests/test_banner_tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,34 +65,27 @@ def test_populate_with_link_object_unicode(self):
fields to avoid UnicodeDecodeError.
"""
title = u'El veloz murciélago hindú comía feliz cardillo y kiwi'
remote_url = 'http://plone.org'
obj = self.portal['my-link']
obj.setTitle(title)
obj.setRemoteUrl('http://plone.org')
obj.reindexObject()
self.tile.populate_with_object(obj)
self.assertEqual(self.tile.data.get('title'), title)
self.assertIsInstance(self.tile.data.get('title'), unicode)
self.assertFalse(self.tile.has_image)
self.assertEqual(self.tile.getRemoteUrl(), remote_url)
self.assertEqual(self.tile.getRemoteUrl(), 'http://plone.org')

def test_populate_tile_with_link_object_string(self):
"""This test complements test_populate_with_link_object_unicode
using strings instead of unicode objects.
"""
title = 'The quick brown fox jumps over the lazy dog'
remote_url = 'http://plone.org'
obj = self.portal['my-link']
obj.setTitle(title)
obj.setRemoteUrl('http://plone.org')
obj.reindexObject()
self.tile.populate_with_object(obj)
self.assertEqual(
unicode(title, 'utf-8'),
self.tile.data.get('title')
)
self.assertEqual(unicode(title, 'utf-8'), self.tile.data.get('title'))
self.assertFalse(self.tile.has_image)
self.assertEqual(self.tile.getRemoteUrl(), remote_url)
self.assertEqual(self.tile.getRemoteUrl(), 'http://plone.org')

def test_render_empty(self):
msg = 'Drag&amp;drop an image or link here to populate the tile.'
Expand All @@ -116,5 +109,4 @@ def test_render_with_link(self):
self.tile.populate_with_object(obj)
rendered = self.tile()
self.assertNotIn('<img ', rendered)
# FIXME: set remote_url on the object
self.assertIn('<a href="http://">Test link</a>', rendered)
self.assertIn('<a href="http://plone.org">Test link</a>', rendered)
Loading

0 comments on commit 6138b68

Please sign in to comment.