# HG changeset patch # User David Douard # Date 1375858967 -7200 # Node ID b4ac21bf6019e432b6d30ec5e1230f0532804659 # Parent ea32e964fbf84aa735e6ac1374c1c0e61c0cba0d# Parent 5b440b87cd2d9cbf34197590793419f8e3c2a15a merge stable in default (3.18) branch diff -r ea32e964fbf8 -r b4ac21bf6019 .hgtags --- a/.hgtags Tue Jul 30 20:31:57 2013 +0200 +++ b/.hgtags Wed Aug 07 09:02:47 2013 +0200 @@ -299,3 +299,9 @@ c7ba8e5d2e45e3d1289c1403df40d7dcb5e62acb cubicweb-version-3.17.4 c7ba8e5d2e45e3d1289c1403df40d7dcb5e62acb cubicweb-debian-version-3.17.4-1 c7ba8e5d2e45e3d1289c1403df40d7dcb5e62acb cubicweb-centos-version-3.17.4-1 +15dd5b37998b8ef5e8fab1ea0491e6bd8e9f3355 cubicweb-centos-version-3.17.5-1 +15dd5b37998b8ef5e8fab1ea0491e6bd8e9f3355 cubicweb-version-3.17.5 +15dd5b37998b8ef5e8fab1ea0491e6bd8e9f3355 cubicweb-debian-version-3.17.5-1 +5b9fedf67a2912a80fe315a477df9e3ab104c734 cubicweb-centos-version-3.17.6-1 +5b9fedf67a2912a80fe315a477df9e3ab104c734 cubicweb-version-3.17.6 +5b9fedf67a2912a80fe315a477df9e3ab104c734 cubicweb-debian-version-3.17.6-1 diff -r ea32e964fbf8 -r b4ac21bf6019 __pkginfo__.py --- a/__pkginfo__.py Tue Jul 30 20:31:57 2013 +0200 +++ b/__pkginfo__.py Wed Aug 07 09:02:47 2013 +0200 @@ -22,7 +22,7 @@ modname = distname = "cubicweb" -numversion = (3, 17, 4) +numversion = (3, 17, 6) version = '.'.join(str(num) for num in numversion) description = "a repository of entities / relations for knowledge management" diff -r ea32e964fbf8 -r b4ac21bf6019 cubicweb.spec --- a/cubicweb.spec Tue Jul 30 20:31:57 2013 +0200 +++ b/cubicweb.spec Wed Aug 07 09:02:47 2013 +0200 @@ -7,7 +7,7 @@ %endif Name: cubicweb -Version: 3.17.4 +Version: 3.17.6 Release: logilab.1%{?dist} Summary: CubicWeb is a semantic web application framework Source0: http://download.logilab.org/pub/cubicweb/cubicweb-%{version}.tar.gz diff -r ea32e964fbf8 -r b4ac21bf6019 debian/changelog --- a/debian/changelog Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/changelog Wed Aug 07 09:02:47 2013 +0200 @@ -1,3 +1,15 @@ +cubicweb (3.17.6-1) unstable; urgency=low + + * new upstream release + + -- David Douard Tue, 06 Aug 2013 11:49:04 +0200 + +cubicweb (3.17.5-1) unstable; urgency=low + + * new upstream release + + -- David Douard Wed, 31 Jul 2013 16:58:19 +0200 + cubicweb (3.17.4-1) unstable; urgency=low * new upstream release diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-common.install.in --- a/debian/cubicweb-common.install.in Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-common.install.in Wed Aug 07 09:02:47 2013 +0200 @@ -1,4 +1,4 @@ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/entities/ usr/lib/PY_VERSION/site-packages/cubicweb -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/ext/ usr/lib/PY_VERSION/site-packages/cubicweb -debian/tmp/usr/share/cubicweb/cubes/ usr/share/cubicweb/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/*.py usr/share/pyshared/cubicweb +usr/lib/PY_VERSION/*-packages/cubicweb/entities/ +usr/lib/PY_VERSION/*-packages/cubicweb/ext/ +usr/share/cubicweb/cubes/ +usr/lib/PY_VERSION/*-packages/cubicweb/*.py diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-ctl.dirs --- a/debian/cubicweb-ctl.dirs Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-ctl.dirs Wed Aug 07 09:02:47 2013 +0200 @@ -1,4 +1,3 @@ -usr/lib/python2.4/site-packages/cubicweb/ etc/init.d etc/cubicweb.d etc/bash_completion.d diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-ctl.install.in --- a/debian/cubicweb-ctl.install.in Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-ctl.install.in Wed Aug 07 09:02:47 2013 +0200 @@ -1,3 +1,3 @@ -debian/tmp/usr/bin/cubicweb-ctl usr/bin/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/cwctl.py usr/lib/PY_VERSION/site-packages/cubicweb -debian/cubicweb-ctl.bash_completion etc/bash_completion.d/cubicweb-ctl +usr/bin/cubicweb-ctl usr/bin/ +usr/lib/PY_VERSION/*-packages/cubicweb/cwctl.py +../cubicweb-ctl.bash_completion etc/bash_completion.d/cubicweb-ctl diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-dev.install.in --- a/debian/cubicweb-dev.install.in Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-dev.install.in Wed Aug 07 09:02:47 2013 +0200 @@ -1,10 +1,10 @@ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/devtools/ usr/lib/PY_VERSION/site-packages/cubicweb/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/skeleton/ usr/lib/PY_VERSION/site-packages/cubicweb/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/test usr/lib/PY_VERSION/site-packages/cubicweb/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/entities/test usr/lib/PY_VERSION/site-packages/cubicweb/entities/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/ext/test usr/lib/PY_VERSION/site-packages/cubicweb/ext/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/server/test usr/lib/PY_VERSION/site-packages/cubicweb/server/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/sobjects/test usr/lib/PY_VERSION/site-packages/cubicweb/sobjects/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/hooks/test usr/lib/PY_VERSION/site-packages/cubicweb/sobjects/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/web/test usr/lib/PY_VERSION/site-packages/cubicweb/web/ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/etwist/test usr/lib/PY_VERSION/site-packages/cubicweb/etwist/ +usr/lib/PY_VERSION/*-packages/cubicweb/devtools/ +usr/lib/PY_VERSION/*-packages/cubicweb/skeleton/ +usr/lib/PY_VERSION/*-packages/cubicweb/test +usr/lib/PY_VERSION/*-packages/cubicweb/entities/test +usr/lib/PY_VERSION/*-packages/cubicweb/ext/test +usr/lib/PY_VERSION/*-packages/cubicweb/server/test +usr/lib/PY_VERSION/*-packages/cubicweb/sobjects/test +usr/lib/PY_VERSION/*-packages/cubicweb/hooks/test +usr/lib/PY_VERSION/*-packages/cubicweb/web/test +usr/lib/PY_VERSION/*-packages/cubicweb/etwist/test diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-documentation.install.in --- a/debian/cubicweb-documentation.install.in Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-documentation.install.in Wed Aug 07 09:02:47 2013 +0200 @@ -1,3 +1,3 @@ -doc/book usr/share/doc/cubicweb-documentation -doc/html usr/share/doc/cubicweb-documentation -debian/cubicweb-doc usr/share/doc-base/cubicweb-doc +../../doc/book usr/share/doc/cubicweb-documentation +../../doc/html usr/share/doc/cubicweb-documentation +../../debian/cubicweb-doc usr/share/doc-base/cubicweb-doc diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-server.install.in --- a/debian/cubicweb-server.install.in Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-server.install.in Wed Aug 07 09:02:47 2013 +0200 @@ -1,5 +1,5 @@ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/server/ usr/lib/PY_VERSION/site-packages/cubicweb -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/hooks/ usr/lib/PY_VERSION/site-packages/cubicweb -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/sobjects/ usr/lib/PY_VERSION/site-packages/cubicweb -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/schemas/ usr/lib/PY_VERSION/site-packages/cubicweb -debian/tmp/usr/share/cubicweb/migration/ usr/share/cubicweb/ +usr/lib/PY_VERSION/*-packages/cubicweb/server/ +usr/lib/PY_VERSION/*-packages/cubicweb/hooks/ +usr/lib/PY_VERSION/*-packages/cubicweb/sobjects/ +usr/lib/PY_VERSION/*-packages/cubicweb/schemas/ +usr/share/cubicweb/migration/ diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-twisted.install.in --- a/debian/cubicweb-twisted.install.in Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-twisted.install.in Wed Aug 07 09:02:47 2013 +0200 @@ -1,1 +1,1 @@ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/etwist/ usr/lib/PY_VERSION/site-packages/cubicweb/ +usr/lib/PY_VERSION/*-packages/cubicweb/etwist/ diff -r ea32e964fbf8 -r b4ac21bf6019 debian/cubicweb-web.install.in --- a/debian/cubicweb-web.install.in Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/cubicweb-web.install.in Wed Aug 07 09:02:47 2013 +0200 @@ -1,3 +1,3 @@ -debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/web usr/lib/PY_VERSION/site-packages/cubicweb -debian/tmp/usr/share/cubicweb/cubes/shared/data usr/share/cubicweb/cubes/shared -debian/tmp/usr/share/cubicweb/cubes/shared/wdoc usr/share/cubicweb/cubes/shared +usr/lib/PY_VERSION/*-packages/cubicweb/web +usr/share/cubicweb/cubes/shared/data +usr/share/cubicweb/cubes/shared/wdoc diff -r ea32e964fbf8 -r b4ac21bf6019 debian/rules --- a/debian/rules Tue Jul 30 20:31:57 2013 +0200 +++ b/debian/rules Wed Aug 07 09:02:47 2013 +0200 @@ -37,27 +37,26 @@ dh_clean dh_installdirs - #python setup.py install_lib --no-compile --install-dir=debian/cubicweb-common/usr/lib/python2.4/site-packages/ NO_SETUPTOOLS=1 python setup.py -q install --no-compile --prefix=debian/tmp/usr # Put all the python library and data in cubicweb-common # and scripts in cubicweb-server - dh_install -vi + dh_install -vi --sourcedir=debian/tmp # cwctl in the cubicweb-ctl package - rm -f debian/cubicweb-common/usr/share/pyshared/cubicweb/cwctl.py + rm -f debian/cubicweb-common/usr/lib/python*/*/cubicweb/cwctl.py # wdoc in the cubicweb-web package rm -rf debian/cubicweb-common/usr/share/cubicweb/cubes/shared/wdoc rm -rf debian/cubicweb-common/usr/share/cubicweb/cubes/shared/data dh_lintian # Remove unittests directory (should be available in cubicweb-dev only) - rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/server/test - rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/hooks/test - rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/sobjects/test - rm -rf debian/cubicweb-web/usr/lib/${PY_VERSION}/site-packages/cubicweb/web/test - rm -rf debian/cubicweb-twisted/usr/lib/${PY_VERSION}/site-packages/cubicweb/etwist/test - rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/ext/test - rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/entities/test + rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/*-packages/cubicweb/server/test + rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/*-packages/cubicweb/hooks/test + rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/*-packages/cubicweb/sobjects/test + rm -rf debian/cubicweb-web/usr/lib/${PY_VERSION}/*-packages/cubicweb/web/test + rm -rf debian/cubicweb-twisted/usr/lib/${PY_VERSION}/*-packages/cubicweb/etwist/test + rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/*-packages/cubicweb/ext/test + rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/*-packages/cubicweb/entities/test %: %.in diff -r ea32e964fbf8 -r b4ac21bf6019 devtools/fill.py --- a/devtools/fill.py Tue Jul 30 20:31:57 2013 +0200 +++ b/devtools/fill.py Wed Aug 07 09:02:47 2013 +0200 @@ -139,7 +139,7 @@ def generate_integer(self, entity, attrname, index): """generates a consistent value for 'attrname' if it's an integer""" return self._constrained_generate(entity, attrname, 0, 1, index) - generate_int = generate_integer + generate_int = generate_bigint = generate_integer def generate_float(self, entity, attrname, index): """generates a consistent value for 'attrname' if it's a float""" diff -r ea32e964fbf8 -r b4ac21bf6019 devtools/test/unittest_testlib.py --- a/devtools/test/unittest_testlib.py Tue Jul 30 20:31:57 2013 +0200 +++ b/devtools/test/unittest_testlib.py Wed Aug 07 09:02:47 2013 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -20,7 +20,9 @@ from cStringIO import StringIO from unittest import TextTestRunner + from logilab.common.testlib import TestSuite, TestCase, unittest_main +from logilab.common.registry import yes from cubicweb.devtools import htmlparser from cubicweb.devtools.testlib import CubicWebTC @@ -172,5 +174,20 @@ self.assertTrue(rdef.permissions['add']) self.assertTrue(rdef.permissions['read'], ()) + def test_temporary_appobjects_registered(self): + class AnAppobject(object): + __registries__ = ('hip',) + __regid__ = 'hop' + __select__ = yes() + registered = None + @classmethod + def __registered__(cls, reg): + cls.registered = reg + + with self.temporary_appobjects(AnAppobject): + self.assertEqual(self.vreg['hip'], AnAppobject.registered) + self.assertIn(AnAppobject, self.vreg['hip']['hop']) + self.assertNotIn(AnAppobject, self.vreg['hip']['hop']) + if __name__ == '__main__': unittest_main() diff -r ea32e964fbf8 -r b4ac21bf6019 devtools/testlib.py --- a/devtools/testlib.py Tue Jul 30 20:31:57 2013 +0200 +++ b/devtools/testlib.py Wed Aug 07 09:02:47 2013 +0200 @@ -461,6 +461,10 @@ self.vreg._loadedmods.setdefault(self.__module__, {}) for obj in appobjects: self.vreg.register(obj) + registered = getattr(obj, '__registered__', None) + if registered: + for registry in obj.__registries__: + registered(self.vreg[registry]) try: yield finally: diff -r ea32e964fbf8 -r b4ac21bf6019 entities/lib.py --- a/entities/lib.py Tue Jul 30 20:31:57 2013 +0200 +++ b/entities/lib.py Wed Aug 07 09:02:47 2013 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -15,14 +15,15 @@ # # You should have received a copy of the GNU Lesser General Public License along # with CubicWeb. If not, see . -"""entity classes for optional library entities +"""entity classes for optional library entities""" -""" __docformat__ = "restructuredtext en" from urlparse import urlsplit, urlunsplit from datetime import datetime +from logilab.mtconverter import xml_escape + from cubicweb import UnknownProperty from cubicweb.entity import _marker from cubicweb.entities import AnyEntity, fetch_config @@ -81,7 +82,10 @@ format='text/html'): """overriden to return displayable address when necessary""" if attr == 'address': - return self.display_address() + address = self.display_address() + if format == 'text/html': + address = xml_escape(address) + return address return super(EmailAddress, self).printable_value(attr, value, attrtype, format) diff -r ea32e964fbf8 -r b4ac21bf6019 entities/test/unittest_base.py --- a/entities/test/unittest_base.py Tue Jul 30 20:31:57 2013 +0200 +++ b/entities/test/unittest_base.py Wed Aug 07 09:02:47 2013 +0200 @@ -82,12 +82,19 @@ self.assertEqual(email.display_address(), 'maarten.ter.huurne@philips.com') self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne@philips.com') self.vreg.config.global_set_option('mangle-emails', True) - self.assertEqual(email.display_address(), 'maarten.ter.huurne at philips dot com') - self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne at philips dot com') - email = self.execute('INSERT EmailAddress X: X address "syt"').get_entity(0, 0) - self.assertEqual(email.display_address(), 'syt') - self.assertEqual(email.printable_value('address'), 'syt') + try: + self.assertEqual(email.display_address(), 'maarten.ter.huurne at philips dot com') + self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne at philips dot com') + email = self.execute('INSERT EmailAddress X: X address "syt"').get_entity(0, 0) + self.assertEqual(email.display_address(), 'syt') + self.assertEqual(email.printable_value('address'), 'syt') + finally: + self.vreg.config.global_set_option('mangle-emails', False) + def test_printable_value_escape(self): + email = self.execute('INSERT EmailAddress X: X address "maarten&ter@philips.com"').get_entity(0, 0) + self.assertEqual(email.printable_value('address'), 'maarten&ter@philips.com') + self.assertEqual(email.printable_value('address', format='text/plain'), 'maarten&ter@philips.com') class CWUserTC(BaseEntityTC): diff -r ea32e964fbf8 -r b4ac21bf6019 server/ssplanner.py --- a/server/ssplanner.py Tue Jul 30 20:31:57 2013 +0200 +++ b/server/ssplanner.py Wed Aug 07 09:02:47 2013 +0200 @@ -101,23 +101,16 @@ Return None when no query actually needed, else the given select node that will be used as substep query. - - When select has nothing selected, search in origrqlst for restriction that - should be considered. """ if origrqlst.where is not None and not select.selection: # no selection, append one randomly by searching for a relation which is - # neither a type restriction (is) nor an eid specification (not neged - # eid with constant node) + # not neged neither a type restriction (is/is_instance_of) for rel in origrqlst.where.iget_nodes(Relation): - if rel.neged(strict=True) or not ( - rel.is_types_restriction() or - (rel.r_type == 'eid' - and isinstance(rel.get_variable_parts()[1], Constant))): + if not (rel.neged(traverse_scope=True) or rel.is_types_restriction()): select.append_selected(rel.children[0].copy(select)) break else: - return + return None if select.selection: if origrqlst.where is not None: select.set_where(origrqlst.where.copy(select)) diff -r ea32e964fbf8 -r b4ac21bf6019 server/test/unittest_msplanner.py --- a/server/test/unittest_msplanner.py Tue Jul 30 20:31:57 2013 +0200 +++ b/server/test/unittest_msplanner.py Wed Aug 07 09:02:47 2013 +0200 @@ -1772,7 +1772,12 @@ repo._type_source_cache[999998] = ('State', 'system', None, 'system') self._test('INSERT Note X: X in_state S, X type "bla", X migrated_from N WHERE S eid %(s)s, N eid %(n)s', [('InsertStep', - [('InsertRelationsStep', [])] + [('InsertRelationsStep', + [('OneFetchStep', + [('Any 999999', [{}])], + None, None, + [self.system], {}, + [])])] )], {'n': 999999, 's': 999998}) diff -r ea32e964fbf8 -r b4ac21bf6019 server/test/unittest_querier.py --- a/server/test/unittest_querier.py Tue Jul 30 20:31:57 2013 +0200 +++ b/server/test/unittest_querier.py Wed Aug 07 09:02:47 2013 +0200 @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -1268,12 +1268,21 @@ newname = self.execute('Any XN WHERE X eid %(x)s, X title XN', {'x': beid})[0][0] self.assertEqual(newname, 'toto-moved') + def test_update_not_exists(self): + rset = self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'") + eid1, eid2 = rset[0][0], rset[0][1] + rset = self.execute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s, " + "NOT EXISTS(Z ecrit_par X)", + {'x': unicode(eid1), 'y': unicode(eid2)}) + self.assertEqual(tuplify(rset.rows), [(eid1, eid2)]) + def test_update_query_error(self): self.execute("INSERT Personne Y: Y nom 'toto'") self.assertRaises(Exception, self.execute, "SET X nom 'toto', X is Personne") self.assertRaises(QueryError, self.execute, "SET X nom 'toto', X has_text 'tutu' WHERE X is Personne") self.assertRaises(QueryError, self.execute, "SET X login 'tutu', X eid %s" % cnx.user(self.session).eid) + # HAVING on write queries test ############################################# def test_update_having(self): diff -r ea32e964fbf8 -r b4ac21bf6019 test/data/entities.py --- a/test/data/entities.py Tue Jul 30 20:31:57 2013 +0200 +++ b/test/data/entities.py Wed Aug 07 09:02:47 2013 +0200 @@ -28,6 +28,9 @@ fetch_attrs, cw_fetch_order = fetch_config(['nom', 'prenom']) rest_attr = 'nom' +class Ami(Societe): + __regid__ = 'Ami' + rest_attr = 'nom' class Note(AnyEntity): __regid__ = 'Note' diff -r ea32e964fbf8 -r b4ac21bf6019 test/data/schema.py --- a/test/data/schema.py Tue Jul 30 20:31:57 2013 +0200 +++ b/test/data/schema.py Wed Aug 07 09:02:47 2013 +0200 @@ -44,6 +44,10 @@ associe = SubjectRelation('Personne', cardinality='1*', constraints=[RQLConstraint('S actionnaire SOC, O actionnaire SOC')]) +class Ami(EntityType): + """A Person, for which surname is not required""" + prenom = String() + nom = String() class Societe(EntityType): nom = String() diff -r ea32e964fbf8 -r b4ac21bf6019 test/unittest_entity.py --- a/test/unittest_entity.py Tue Jul 30 20:31:57 2013 +0200 +++ b/test/unittest_entity.py Wed Aug 07 09:02:47 2013 +0200 @@ -692,16 +692,16 @@ person.cw_clear_all_caches() self.assertEqual(person.rest_path(), unicode(person.eid)) self.assertEqual(person2.rest_path(), unicode(person2.eid)) - # unique attr with None value (wikiid in this case) - card1 = req.create_entity('Card', title=u'hop') - self.assertEqual(card1.rest_path(), unicode(card1.eid)) + # unique attr with None value (nom in this case) + friend = req.create_entity('Ami', prenom=u'bob') + self.assertEqual(friend.rest_path(), unicode(friend.eid)) # don't use rest if we have /, ? or & in the path (breaks mod_proxy) - card2 = req.create_entity('Card', title=u'pod', wikiid=u'zo/bi') - self.assertEqual(card2.rest_path(), unicode(card2.eid)) - card3 = req.create_entity('Card', title=u'pod', wikiid=u'zo&bi') - self.assertEqual(card3.rest_path(), unicode(card3.eid)) - card4 = req.create_entity('Card', title=u'pod', wikiid=u'zo?bi') - self.assertEqual(card4.rest_path(), unicode(card4.eid)) + person3 = req.create_entity('Personne', nom=u'zo/bi') + self.assertEqual(person3.rest_path(), unicode(person3.eid)) + person4 = req.create_entity('Personne', nom=u'zo&bi') + self.assertEqual(person4.rest_path(), unicode(person4.eid)) + person5 = req.create_entity('Personne', nom=u'zo?bi') + self.assertEqual(person5.rest_path(), unicode(person5.eid)) def test_cw_set_attributes(self): diff -r ea32e964fbf8 -r b4ac21bf6019 test/unittest_schema.py --- a/test/unittest_schema.py Tue Jul 30 20:31:57 2013 +0200 +++ b/test/unittest_schema.py Wed Aug 07 09:02:47 2013 +0200 @@ -157,7 +157,7 @@ self.assert_(isinstance(schema, CubicWebSchema)) self.assertEqual(schema.name, 'data') entities = sorted([str(e) for e in schema.entities()]) - expected_entities = ['BaseTransition', 'BigInt', 'Bookmark', 'Boolean', 'Bytes', 'Card', + expected_entities = ['Ami', 'BaseTransition', 'BigInt', 'Bookmark', 'Boolean', 'Bytes', 'Card', 'Date', 'Datetime', 'Decimal', 'CWCache', 'CWConstraint', 'CWConstraintType', 'CWDataImport', 'CWEType', 'CWAttribute', 'CWGroup', 'EmailAddress', 'CWRelation', diff -r ea32e964fbf8 -r b4ac21bf6019 web/formfields.py --- a/web/formfields.py Tue Jul 30 20:31:57 2013 +0200 +++ b/web/formfields.py Wed Aug 07 09:02:47 2013 +0200 @@ -506,7 +506,7 @@ if field is self: try: value = field.process_form_value(form) - if value is None and field.required: + if field.no_value(value) and field.required: raise ProcessFormError(form._cw._("required field")) yield field, value except UnmodifiedField: @@ -517,6 +517,11 @@ for field, value in field.process_posted(form): yield field, value + @staticmethod + def no_value(value): + """return True if the value can be considered as no value for the field""" + return value is None + class StringField(Field): """Use this field to edit unicode string (`String` yams type). This field @@ -1170,6 +1175,12 @@ eids.add(typed_eid) return eids + @staticmethod + def no_value(value): + """return True if the value can be considered as no value for the field""" + # value is None is the 'not yet ready value, consider the empty set + return value is not None and not value + _AFF_KWARGS = uicfg.autoform_field_kwargs diff -r ea32e964fbf8 -r b4ac21bf6019 web/test/data/schema.py --- a/web/test/data/schema.py Tue Jul 30 20:31:57 2013 +0200 +++ b/web/test/data/schema.py Wed Aug 07 09:02:47 2013 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -15,9 +15,6 @@ # # You should have received a copy of the GNU Lesser General Public License along # with CubicWeb. If not, see . -""" - -""" from yams.buildobjs import (EntityType, RelationDefinition, SubjectRelation, String, Int, Datetime, Boolean, Float) diff -r ea32e964fbf8 -r b4ac21bf6019 web/test/unittest_views_basecontrollers.py --- a/web/test/unittest_views_basecontrollers.py Tue Jul 30 20:31:57 2013 +0200 +++ b/web/test/unittest_views_basecontrollers.py Wed Aug 07 09:02:47 2013 +0200 @@ -645,6 +645,34 @@ finally: p.__class__.skip_copy_for = old_skips + def test_regr_inlined_forms(self): + self.schema['described_by_test'].inlined = False + try: + req = self.request() + req.data['eidmap'] = {} + req.data['pending_others'] = set() + req.data['pending_inlined'] = {} + req.form = {'eid': ['X', 'Y'], '__maineid' : 'X', + + '__type:X': 'Salesterm', + '_cw_entity_fields:X': 'described_by_test-subject', + 'described_by_test-subject:X': 'Y', + + '__type:Y': 'File', + '_cw_entity_fields:Y': 'data-subject', + 'data-subject:Y': (u'coucou.txt', Binary('coucou')), + } + values_by_eid = dict((eid, req.extract_entity_params(eid, minparams=2)) + for eid in req.edited_eids()) + editctrl = self.vreg['controllers'].select('edit', req) + # don't call publish to enforce select order + editctrl.errors = [] + editctrl._to_create = {} + editctrl.edit_entity(values_by_eid['X']) # #3064653 raise ValidationError + editctrl.edit_entity(values_by_eid['Y']) + finally: + self.schema['described_by_test'].inlined = False + class ReportBugControllerTC(CubicWebTC):