# HG changeset patch # User Philippe Pepiot # Date 1552997867 -3600 # Node ID aff5d3498f68502f7963edd2cd45b4c83a2520ed # Parent 12e8b65146d989ae2d2c5856aaad7c90db865ed2 [web/test] drop dependency on third party cubes Drop dependency on cubicweb-file, cubicweb-blog and cubicweb-tag for cubicweb/web/test Copy required parts of cubes (schema, entities, views and hooks) into cubicweb/web/test/data/cubicweb- that make tests pass. diff -r 12e8b65146d9 -r aff5d3498f68 MANIFEST.in --- a/MANIFEST.in Fri Mar 15 18:07:18 2019 +0100 +++ b/MANIFEST.in Tue Mar 19 13:17:47 2019 +0100 @@ -68,6 +68,8 @@ recursive-include cubicweb/server/test/data-schemaserial *.py include cubicweb/web/test/testutils.js recursive-include cubicweb/web/test *.py +include cubicweb/web/test/data/cubicweb_file/data/file.png +include cubicweb/web/test/data/cubicweb_file/wdoc/toc.xml recursive-include cubicweb/web/test/data bootstrap_cubes pouet.css *.py recursive-include cubicweb/web/test/data/static/jstests *.js *.html *.json recursive-include cubicweb/wsgi/test *.py diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_blog/__init__.py diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_blog/__pkginfo__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_blog/__pkginfo__.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,2 @@ +numversion = (1, 2, 3) +version = "1.2.3" diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_blog/entities.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_blog/entities.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,7 @@ +from cubicweb.entities import AnyEntity, fetch_config + + +class BlogEntry(AnyEntity): + __regid__ = 'BlogEntry' + fetch_attrs, cw_fetch_order = fetch_config( + ['creation_date', 'title'], order='DESC') diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_blog/schema.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_blog/schema.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,22 @@ +from yams.buildobjs import EntityType, String, RichString, SubjectRelation +from cubicweb.schema import WorkflowableEntityType, ERQLExpression + + +class Blog(EntityType): + title = String(maxsize=50, required=True) + description = RichString() + rss_url = String(maxsize=128, description=( + 'blog\'s rss url (useful for when using external site such as feedburner)')) + + +class BlogEntry(WorkflowableEntityType): + __permissions__ = { + 'read': ('managers', 'users', ERQLExpression('X in_state S, S name "published"'),), + 'add': ('managers', 'users'), + 'update': ('managers', 'owners'), + 'delete': ('managers', 'owners') + } + title = String(required=True, fulltextindexed=True, maxsize=256) + content = RichString(required=True, fulltextindexed=True) + entry_of = SubjectRelation('Blog') + same_as = SubjectRelation('ExternalUri') diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/__init__.py diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/__pkginfo__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_file/__pkginfo__.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,2 @@ +numversion = (1, 2, 3) +version = "1.2.3" diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/data/file.png diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/entities.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_file/entities.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,51 @@ +from six import text_type +from logilab.mtconverter import guess_mimetype_and_encoding +from cubicweb.entities import AnyEntity, fetch_config + + +class File(AnyEntity): + """customized class for File entities""" + __regid__ = 'File' + fetch_attrs, cw_fetch_order = fetch_config(['data_name', 'title']) + + def set_format_and_encoding(self): + """try to set format and encoding according to known values (filename, + file content, format, encoding). + + This method must be called in a before_[add|update]_entity hook else it + won't have any effect. + """ + assert 'data' in self.cw_edited, "missing mandatory attribute data" + if self.cw_edited.get('data'): + if (hasattr(self.data, 'filename') + and not self.cw_edited.get('data_name')): + self.cw_edited['data_name'] = self.data.filename + else: + self.cw_edited['data_format'] = None + self.cw_edited['data_encoding'] = None + self.cw_edited['data_name'] = None + return + if 'data_format' in self.cw_edited: + format = self.cw_edited.get('data_format') + else: + format = None + if 'data_encoding' in self.cw_edited: + encoding = self.cw_edited.get('data_encoding') + else: + encoding = None + if not (format and encoding): + format, encoding = guess_mimetype_and_encoding( + data=self.cw_edited.get('data'), + # use get and not get_value since data has changed, we only + # want to consider explicitly specified values, not old ones + filename=self.cw_edited.get('data_name'), + format=format, encoding=encoding, + fallbackencoding=self._cw.encoding) + if format: + self.cw_edited['data_format'] = text_type(format) + if encoding: + self.cw_edited['data_encoding'] = text_type(encoding) + + +class UnResizeable(Exception): + pass diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/hooks.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_file/hooks.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,69 @@ +import os + +from cubicweb.server import hook +from cubicweb.predicates import is_instance +from cubicweb.entities import adapters + +from cubicweb_file.entities import UnResizeable + + +class UpdateFileHook(hook.Hook): + """a file has been updated, check data_format/data_encoding consistency + """ + __regid__ = 'updatefilehook' + __select__ = hook.Hook.__select__ & is_instance('File') + events = ('before_add_entity', 'before_update_entity',) + order = -1 # should be run before other hooks + category = 'hash' + + def __call__(self): + edited = self.entity.cw_edited + if 'data' in edited: + self.entity.set_format_and_encoding() + maxsize = None + if maxsize and self.entity.data_format.startswith('image/'): + iimage = self.entity.cw_adapt_to('IImage') + try: + edited['data'] = iimage.resize(maxsize) + except UnResizeable: + # if the resize fails for some reason, do nothing + # (original image will be stored) + pass + + # thumbnail cache invalidation + if 'update' in self.event and 'data' in edited: + thumb = self.entity.cw_adapt_to('IThumbnail') + if not thumb: + return + thumbpath = thumb.thumbnail_path() + if thumbpath: + try: + os.unlink(thumbpath) + except Exception as exc: + self.warning( + 'could not invalidate thumbnail file `%s` ' + '(cause: %s)', + thumbpath, exc) + + +class FileIDownloadableAdapter(adapters.IDownloadableAdapter): + __select__ = is_instance('File') + + # IDownloadable + def download_url(self, **kwargs): + # include filename in download url for nicer url + name = self._cw.url_quote(self.download_file_name()) + path = '%s/raw/%s' % (self.entity.rest_path(), name) + return self._cw.build_url(path, **kwargs) + + def download_content_type(self): + return self.entity.data_format + + def download_encoding(self): + return self.entity.data_encoding + + def download_file_name(self): + return self.entity.data_name + + def download_data(self): + return self.entity.data.getvalue() diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/schema.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_file/schema.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,27 @@ +from yams.buildobjs import EntityType, String, Bytes, RichString + + +class File(EntityType): + """a downloadable file which may contains binary data""" + title = String(fulltextindexed=True, maxsize=256) + data = Bytes(required=True, description='file to upload') + data_format = String( + required=True, maxsize=128, + description=('MIME type of the file. Should be dynamically set ' + 'at upload time.')) + data_encoding = String( + maxsize=32, + description=('encoding of the file when it applies (e.g. text). ' + 'Should be dynamically set at upload time.')) + data_name = String( + required=True, fulltextindexed=True, + description=('name of the file. Should be dynamically set ' + 'at upload time.')) + data_hash = String( + maxsize=256, # max len of currently available hash alg + prefix is 140 + description=('hash of the file. May be set at upload time.'), + __permissions__={'read': ('managers', 'users', 'guests'), + 'add': (), + 'update': ()}) + description = RichString(fulltextindexed=True, internationalizable=True, + default_format='text/rest') diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/uiprops.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_file/uiprops.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,1 @@ +FILE_ICON = data('file.png') # noqa: F821 diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/views.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_file/views.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,9 @@ +from cubicweb.web import formwidgets as wdgs +from cubicweb.web.views import uicfg + +# fields required in the schema but automatically set by hooks. Tell about that +# to the ui +_pvdc = uicfg.autoform_field_kwargs +_pvdc.tag_attribute(('File', 'data_name'), { + 'required': False, 'widget': wdgs.TextInput({'size': 45})}) +_pvdc.tag_attribute(('File', 'data_format'), {'required': False}) diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_file/wdoc/toc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_file/wdoc/toc.xml Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,6 @@ + +
+ Add an attachement + Ajouter un fichier +
+
diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_tag/__init__.py diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_tag/__pkginfo__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_tag/__pkginfo__.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,2 @@ +numversion = (1, 2, 3) +version = "1.2.3" diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_tag/schema.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_tag/schema.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,17 @@ +from yams.buildobjs import EntityType, String, SubjectRelation, RelationType + + +class Tag(EntityType): + """tags are used by users to mark entities. + When you include the Tag entity, all application specific entities + may then be tagged using the "tags" relation. + """ + name = String(required=True, fulltextindexed=True, unique=True, + maxsize=128) + # when using this component, add the Tag tag X relation for each type that + # should be taggeable + tags = SubjectRelation('Tag', description="tagged objects") + + +class tags(RelationType): + """indicates that an entity is classified by a given tag""" diff -r 12e8b65146d9 -r aff5d3498f68 cubicweb/web/test/data/cubicweb_tag/views.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/test/data/cubicweb_tag/views.py Tue Mar 19 13:17:47 2019 +0100 @@ -0,0 +1,28 @@ +from cubicweb.web import component +from cubicweb.web.views import ajaxcontroller + + +@ajaxcontroller.ajaxfunc +def tag_entity(self, eid, taglist): + execute = self._cw.execute + # get list of tag for this entity + tagged_by = set(tagname for (tagname,) in + execute('Any N WHERE T name N, T tags X, X eid %(x)s', + {'x': eid})) + for tagname in taglist: + tagname = tagname.strip() + if not tagname or tagname in tagged_by: + continue + tagrset = execute('Tag T WHERE T name %(name)s', {'name': tagname}) + if tagrset: + rql = 'SET T tags X WHERE T eid %(t)s, X eid %(x)s' + execute(rql, {'t': tagrset[0][0], 'x': eid}) + else: + rql = 'INSERT Tag T: T name %(name)s, T tags X WHERE X eid %(x)s' + execute(rql, {'name': tagname, 'x': eid}) + + +class TagsBox(component.AjaxEditRelationCtxComponent): + __regid__ = 'tags_box' + rtype = 'tags' + role = 'object' diff -r 12e8b65146d9 -r aff5d3498f68 requirements/test-web.txt --- a/requirements/test-web.txt Fri Mar 15 18:07:18 2019 +0100 +++ b/requirements/test-web.txt Tue Mar 19 13:17:47 2019 +0100 @@ -2,6 +2,3 @@ Twisted < 16.0.0 requests webtest -cubicweb-blog -cubicweb-file >= 2.0.0 -cubicweb-tag