Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

FIx alias and unique field names #200

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 63 additions & 25 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,66 +8,104 @@ matrix:
env: TOX_ENV='flake8'
- python: 3.5
env: TOX_ENV='isort'
# Django 1.11

# python 3.5 + Django 1.11 + CMS 34, 35, 36, 37, 40
- python: 3.5
env: DJANGO='dj111' CMS='cms34'
- python: 3.5
env: DJANGO='dj111' CMS='cms35'
- python: 3.5
env: DJANGO='dj111' CMS='cms36'
- python: 3.5
env: DJANGO='dj111' CMS='cms37'
- python: 3.5
env: DJANGO='dj111' CMS='cms40'

- python: 3.4
# python 3.6 + Django 1.11 + CMS 34, 35, 36, 37, 40
- python: 3.6
env: DJANGO='dj111' CMS='cms34'
- python: 3.4
- python: 3.6
env: DJANGO='dj111' CMS='cms35'
- python: 3.4
- python: 3.6
env: DJANGO='dj111' CMS='cms36'
- python: 3.4
- python: 3.6
env: DJANGO='dj111' CMS='cms37'
- python: 3.6
env: DJANGO='dj111' CMS='cms40'

- python: 2.7
# python 3.7 + Django 1.11 + CMS 34, 35, 36, 37, 40
- python: 3.7
env: DJANGO='dj111' CMS='cms34'
- python: 2.7
- python: 3.7
env: DJANGO='dj111' CMS='cms35'
- python: 2.7
- python: 3.7
env: DJANGO='dj111' CMS='cms36'
- python: 2.7
- python: 3.7
env: DJANGO='dj111' CMS='cms37'
- python: 3.7
env: DJANGO='dj111' CMS='cms40'
# Django 2.0
- python: 3.4
env: DJANGO='dj20' CMS='cms36'
# python 3.8 + Django 1.11 + CMS 34, 35, 36, 37, 40
- python: 3.8
env: DJANGO='dj111' CMS='cms34'
- python: 3.8
env: DJANGO='dj111' CMS='cms35'
- python: 3.8
env: DJANGO='dj111' CMS='cms36'
- python: 3.8
env: DJANGO='dj111' CMS='cms37'
- python: 3.8
env: DJANGO='dj111' CMS='cms40'

# python 3.5 + Django 2.0 + CMS 36, 37
- python: 3.5
env: DJANGO='dj20' CMS='cms36'
- python: 3.5
env: DJANGO='dj20' CMS='cms37'
# python 3.6 + Django 2.0 + CMS 36, 37
- python: 3.6
env: DJANGO='dj20' CMS='cms36'
- python: 3.4
env: DJANGO='dj20' CMS='cms40'
- python: 3.5
env: DJANGO='dj20' CMS='cms40'
- python: 3.6
env: DJANGO='dj20' CMS='cms40'
# Django 2.1
env: DJANGO='dj20' CMS='cms37'
# python 3.7 + Django 2.0 + CMS 36, 37
- python: 3.7
env: DJANGO='dj20' CMS='cms36'
- python: 3.7
env: DJANGO='dj20' CMS='cms37'
# python 3.8 + Django 2.0 + CMS 36, 37
- python: 3.8
env: DJANGO='dj20' CMS='cms36'
- python: 3.8
env: DJANGO='dj20' CMS='cms37'

# python 3.5 + Django 2.1 + CMS 36, 37
- python: 3.5
env: DJANGO='dj21' CMS='cms36'
- python: 3.5
env: DJANGO='dj21' CMS='cms37'
# python 3.6 + Django 2.1 + CMS 36, 37
- python: 3.6
env: DJANGO='dj21' CMS='cms36'
- python: 3.5
env: DJANGO='dj21' CMS='cms40'
- python: 3.6
env: DJANGO='dj21' CMS='cms40'
env: DJANGO='dj21' CMS='cms37'
# python 3.7 + Django 2.1 + CMS 36, 37
- python: 3.7
env: DJANGO='dj21' CMS='cms36'
- python: 3.7
env: DJANGO='dj21' CMS='cms37'
# python 3.8 + Django 2.1 + CMS 36, 37
- python: 3.8
env: DJANGO='dj21' CMS='cms36'
- python: 3.8
env: DJANGO='dj21' CMS='cms37'

cache:
directories:
- $HOME/.wheelhouse

install:
- pip install coverage isort tox
- "if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then export PY_VER=py27; fi"
- "if [[ $TRAVIS_PYTHON_VERSION == '3.4' ]]; then export PY_VER=py34; fi"
- "if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then export PY_VER=py35; fi"
- "if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then export PY_VER=py36; fi"
- "if [[ $TRAVIS_PYTHON_VERSION == '3.7' ]]; then export PY_VER=py37; fi"
- "if [[ $TRAVIS_PYTHON_VERSION == '3.8' ]]; then export PY_VER=py38; fi"
- "if [[ ${DJANGO}z != 'z' ]]; then export TOX_ENV=$PY_VER-$DJANGO-$CMS; fi"

script:
Expand Down
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. image:: https://secure.travis-ci.org/zbohm/aldryn-forms.png?branch=alias_and_unique_field_names
:target: http://travis-ci.com/zbohm/aldryn-forms

================
Aldryn Forms App
================
Expand Down
6 changes: 5 additions & 1 deletion aldryn_forms/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from cms.cms_plugins import AliasPlugin


def get_user_name(user):
Expand All @@ -17,5 +18,8 @@ def is_form_element(plugin):
# cms_plugins.CMSPlugin subclass
cms_plugin = plugin.get_plugin_class_instance(None)
is_orphan_plugin = cms_plugin.model != plugin.__class__
is_element_subclass = issubclass(plugin.get_plugin_class(), FormElement)
plugin_class = plugin.get_plugin_class()
if plugin.get_plugin_class() == AliasPlugin:
plugin_class = plugin.plugin.get_plugin_class()
is_element_subclass = issubclass(plugin_class, FormElement)
return (not is_orphan_plugin) and is_element_subclass
28 changes: 22 additions & 6 deletions aldryn_forms/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import warnings
from collections import OrderedDict, defaultdict, namedtuple
from distutils.version import LooseVersion
from functools import partial

from django.conf import settings
Expand All @@ -12,6 +13,8 @@
from django.utils.six import text_type
from django.utils.translation import ugettext_lazy as _

import cms
from cms.cms_plugins import AliasPlugin
from cms.models.fields import PageField
from cms.models.pluginmodel import CMSPlugin
from cms.utils.plugins import downcast_plugins
Expand All @@ -27,6 +30,7 @@
)


CMS_LESS_THAN_4_0 = LooseVersion(cms.__version__) < LooseVersion('4.0')
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')


Expand Down Expand Up @@ -244,11 +248,15 @@ def get_form_fields(self):
field_type_occurrences = defaultdict(lambda: 1)

form_elements = self.get_form_elements()
field_plugins = [
plugin for plugin in form_elements
if issubclass(plugin.get_plugin_class(), Field)
]

field_plugins = []
for plugin in form_elements:
if issubclass(plugin.get_plugin_class(), Field):
field_plugins.append(plugin)
elif issubclass(plugin.get_plugin_class(), AliasPlugin) and \
issubclass(plugin.plugin.get_plugin_class(), Field):
field_plugins.append(plugin.plugin.get_plugin_instance()[0])

unique_field_names = []
for field_plugin in field_plugins:
field_type = field_plugin.field_type

Expand All @@ -271,6 +279,11 @@ def get_form_fields(self):
if field_id in field_occurrences:
field_occurrences[field_id] += 1

# Make filed names unique.
while field_name in unique_field_names:
field_name += "_"
unique_field_names.append(field_name)

field = FormField(
name=field_name,
label=field_label,
Expand Down Expand Up @@ -307,7 +320,10 @@ def get_form_elements(self):
from .utils import get_nested_plugins

if self.child_plugin_instances is None:
descendants = self.get_descendants().order_by('path')
if CMS_LESS_THAN_4_0:
descendants = self.get_descendants().order_by('path')
else:
descendants = self.get_descendants().order_by('position')
# Set parent_id to None in order to
# fool the build_plugin_tree function.
# This is sadly necessary to avoid getting all nodes
Expand Down
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@


REQUIREMENTS = [
'django>=2.0',
'django>=1.11,<2.2',
'aldryn-boilerplates>=0.7.5',
'django-cms>=3.5',
'django-cms>=3.5,<4.0',
'django-emailit',
'djangocms-text-ckeditor',
'djangocms-attributes-field>=1.0.0',
Expand All @@ -34,6 +34,8 @@
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Software Development',
Expand Down
1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ tox>=2.9.1
coverage>=4.4.2
django-polymorphic>=1.3,<2.0
djangocms-text-ckeditor>=3.7.0
django-simple-captcha
flake8
isort
38 changes: 38 additions & 0 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from distutils.version import LooseVersion

import cms
from cms.api import add_plugin, create_page
from cms.test_utils.testcases import CMSTestCase

from aldryn_forms.helpers import is_form_element


CMS_3_6 = LooseVersion(cms.__version__) < LooseVersion('4.0')


class HelpersTest(CMSTestCase):

def setUp(self):
page = create_page('test page', 'test_page.html', 'en')
if CMS_3_6:
self.placeholder = page.placeholders.get(slot='content')
else:
self.placeholder = page.get_placeholders('en').get(slot='content')

def test_is_form_element_is_field(self):
plugin = add_plugin(self.placeholder, 'EmailField', 'en', name="email")
self.assertTrue(is_form_element(plugin))

def test_is_form_element_is_not_field(self):
plugin = add_plugin(self.placeholder, 'TextPlugin', 'en')
self.assertFalse(is_form_element(plugin))

def test_is_form_element_alias_with_field(self):
field = add_plugin(self.placeholder, 'EmailField', 'en', name="email")
plugin = add_plugin(self.placeholder, 'AliasPlugin', 'en', plugin=field)
self.assertTrue(is_form_element(plugin))

def test_is_form_element_alias_without_field(self):
field = add_plugin(self.placeholder, 'TextPlugin', 'en')
plugin = add_plugin(self.placeholder, 'AliasPlugin', 'en', plugin=field)
self.assertFalse(is_form_element(plugin))
48 changes: 45 additions & 3 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# -*- coding: utf-8 -*-
from __future__ import division, print_function, unicode_literals
from distutils.version import LooseVersion

from django.db import IntegrityError
from django.test import TestCase

from cms.api import add_plugin
import cms
from cms.api import add_plugin, create_page
from cms.models import Placeholder
from cms.test_utils.testcases import CMSTestCase

from aldryn_forms.models import Option


CMS_3_6 = LooseVersion(cms.__version__) < LooseVersion('4.0')


class OptionTestCase(TestCase):

def setUp(self):
super(TestCase, self).setUp()
self.placeholder = Placeholder.objects.create(slot='test')
Expand Down Expand Up @@ -90,3 +95,40 @@ def test_position_is_not_nullable(self):
self.assertEquals(option1.position, 960) # We force a value for it on Option.save

self.assertRaises(IntegrityError, Option.objects.update, position=None) # See? Not nullable


class FormPluginTestGetFormFields(CMSTestCase):

def setUp(self):
page = create_page('test page', 'test_page.html', 'en')
if CMS_3_6:
self.placeholder = page.placeholders.get(slot='content')
else:
self.placeholder = page.get_placeholders('en').get(slot='content')
self.form = add_plugin(self.placeholder, 'FormPlugin', 'en')

def test_field_with_different_names(self):
add_plugin(self.form.placeholder, 'EmailField', 'en', target=self.form, name="email-1")
add_plugin(self.form.placeholder, 'EmailField', 'en', target=self.form, name="email-2")
self.assertEquals([fld.name for fld in self.form.get_form_fields()], ['email-1', 'email-2'])

def test_field_with_duplicate_names(self):
add_plugin(self.form.placeholder, 'EmailField', 'en', target=self.form, name="email")
add_plugin(self.form.placeholder, 'EmailField', 'en', target=self.form, name="email")
self.assertEquals([fld.name for fld in self.form.get_form_fields()], ['email', 'email_'])

def test_alias_with_field(self):
field = add_plugin(self.placeholder, 'EmailField', 'en', name="email")
add_plugin(self.form.placeholder, 'AliasPlugin', 'en', plugin=field, target=self.form)
self.assertEquals([fld.name for fld in self.form.get_form_fields()], ['email'])

def test_alias_without_field(self):
field = add_plugin(self.placeholder, 'TextPlugin', 'en')
add_plugin(self.form.placeholder, 'AliasPlugin', 'en', plugin=field, target=self.form)
self.assertEquals([fld.name for fld in self.form.get_form_fields()], [])

def test_alias_with_field_and_duplicate_name(self):
add_plugin(self.form.placeholder, 'EmailField', 'en', target=self.form, name="email")
field = add_plugin(self.placeholder, 'EmailField', 'en', name="email")
add_plugin(self.form.placeholder, 'AliasPlugin', 'en', plugin=field, target=self.form)
self.assertEquals([fld.name for fld in self.form.get_form_fields()], ['email', 'email_'])
Loading