浏览代码

add retrocompatibility with old 'page' slug + tests

Guénaël Muller 6 年前
父节点
当前提交
e58d96135c

+ 1 - 0
tracim/lib/core/content.py 查看文件

104
         ContentType.Comment,
104
         ContentType.Comment,
105
         ContentType.Thread,
105
         ContentType.Thread,
106
         ContentType.Page,
106
         ContentType.Page,
107
+        ContentType.PageLegacy,
107
         ContentType.MarkdownPage,
108
         ContentType.MarkdownPage,
108
     )
109
     )
109
 
110
 

+ 5 - 1
tracim/lib/utils/authorization.py 查看文件

6
 from zope.interface import implementer
6
 from zope.interface import implementer
7
 
7
 
8
 from tracim.models.contents import NewContentType
8
 from tracim.models.contents import NewContentType
9
+from tracim.models.context_models import ContentInContext
9
 
10
 
10
 try:
11
 try:
11
     from json.decoder import JSONDecodeError
12
     from json.decoder import JSONDecodeError
12
 except ImportError:  # python3.4
13
 except ImportError:  # python3.4
13
     JSONDecodeError = ValueError
14
     JSONDecodeError = ValueError
14
 
15
 
16
+from tracim.models.contents import ContentTypeLegacy as ContentType
15
 from tracim.exceptions import InsufficientUserWorkspaceRole
17
 from tracim.exceptions import InsufficientUserWorkspaceRole
16
 from tracim.exceptions import ContentTypeNotAllowed
18
 from tracim.exceptions import ContentTypeNotAllowed
17
 from tracim.exceptions import InsufficientUserProfile
19
 from tracim.exceptions import InsufficientUserProfile
142
         @functools.wraps(func)
144
         @functools.wraps(func)
143
         def wrapper(self, context, request: 'TracimRequest'):
145
         def wrapper(self, context, request: 'TracimRequest'):
144
             content = request.current_content
146
             content = request.current_content
145
-            if content.type in [content.slug for content in content_types]:
147
+            current_content_type_slug = ContentType(content.type).slug
148
+            content_types_slug = [content_type.slug for content_type in content_types]
149
+            if current_content_type_slug in content_types_slug:
146
                 return func(self, context, request)
150
                 return func(self, context, request)
147
             raise ContentTypeNotAllowed()
151
             raise ContentTypeNotAllowed()
148
         return wrapper
152
         return wrapper

+ 1 - 0
tracim/models/contents.py 查看文件

228
     File = file_type.slug
228
     File = file_type.slug
229
     Thread = thread_type.slug
229
     Thread = thread_type.slug
230
     Page = html_documents_type.slug
230
     Page = html_documents_type.slug
231
+    PageLegacy = 'page'
231
     MarkdownPage = markdownpluspage_type.slug
232
     MarkdownPage = markdownpluspage_type.slug
232
 
233
 
233
     def __init__(self, slug: str):
234
     def __init__(self, slug: str):

+ 11 - 2
tracim/models/context_models.py 查看文件

12
 from tracim.models.data import Workspace, UserRoleInWorkspace
12
 from tracim.models.data import Workspace, UserRoleInWorkspace
13
 from tracim.models.workspace_menu_entries import default_workspace_menu_entry
13
 from tracim.models.workspace_menu_entries import default_workspace_menu_entry
14
 from tracim.models.workspace_menu_entries import WorkspaceMenuEntry
14
 from tracim.models.workspace_menu_entries import WorkspaceMenuEntry
15
+from tracim.models.contents import ContentTypeLegacy as ContentType
15
 
16
 
16
 
17
 
17
 class MoveParams(object):
18
 class MoveParams(object):
365
 
366
 
366
     @property
367
     @property
367
     def content_type(self) -> str:
368
     def content_type(self) -> str:
368
-        return self.content.type
369
+        content_type = ContentType(self.content.type)
370
+        if content_type:
371
+            return content_type.slug
372
+        else:
373
+            return None
369
 
374
 
370
     @property
375
     @property
371
     def sub_content_types(self) -> typing.List[str]:
376
     def sub_content_types(self) -> typing.List[str]:
470
 
475
 
471
     @property
476
     @property
472
     def content_type(self) -> str:
477
     def content_type(self) -> str:
473
-        return self.revision.type
478
+        content_type = ContentType(self.revision.type)
479
+        if content_type:
480
+            return content_type.slug
481
+        else:
482
+            return None
474
 
483
 
475
     @property
484
     @property
476
     def sub_content_types(self) -> typing.List[str]:
485
     def sub_content_types(self) -> typing.List[str]:

+ 29 - 4
tracim/tests/__init__.py 查看文件

8
 from pyramid import testing
8
 from pyramid import testing
9
 from sqlalchemy.exc import IntegrityError
9
 from sqlalchemy.exc import IntegrityError
10
 
10
 
11
-from tracim.command.database import InitializeDBCommand
12
 from tracim.lib.core.content import ContentApi
11
 from tracim.lib.core.content import ContentApi
13
 from tracim.lib.core.workspace import WorkspaceApi
12
 from tracim.lib.core.workspace import WorkspaceApi
14
-from tracim.models import get_engine, DeclarativeBase, get_session_factory, \
15
-    get_tm_session
16
-from tracim.models.data import Workspace, ContentType
13
+from tracim.models import get_engine
14
+from tracim.models import DeclarativeBase
15
+from tracim.models import get_session_factory
16
+from tracim.models import get_tm_session
17
+from tracim.models.data import Workspace
18
+from tracim.models.data import ContentType
19
+from tracim.models.data import ContentRevisionRO
17
 from tracim.models.data import Content
20
 from tracim.models.data import Content
18
 from tracim.lib.utils.logger import logger
21
 from tracim.lib.utils.logger import logger
19
 from tracim.fixtures import FixturesLoader
22
 from tracim.fixtures import FixturesLoader
28
     # TODO - G.M - 05-04-2018 - Remove this when all old nose code is removed
31
     # TODO - G.M - 05-04-2018 - Remove this when all old nose code is removed
29
     assert a == b, msg or "%r != %r" % (a, b)
32
     assert a == b, msg or "%r != %r" % (a, b)
30
 
33
 
34
+# TODO - G.M - 2018-06-179 - Refactor slug change function
35
+#  as a kind of pytest fixture ?
36
+
37
+
38
+def set_html_document_slug_to_legacy(session_factory) -> None:
39
+    """
40
+    Simple function to help some functional test. This modify "html-documents"
41
+    type content in database to legacy "page" slug.
42
+    :param session_factory: session factory of the test
43
+    :return: Nothing.
44
+    """
45
+    dbsession = get_tm_session(
46
+        session_factory,
47
+        transaction.manager
48
+    )
49
+    content_query = dbsession.query(ContentRevisionRO).filter(ContentRevisionRO.type == 'page').filter(ContentRevisionRO.content_id == 6)  # nopep8
50
+    assert content_query.count() == 0
51
+    html_documents_query = dbsession.query(ContentRevisionRO).filter(ContentRevisionRO.type == 'html-documents')  # nopep8
52
+    html_documents_query.update({ContentRevisionRO.type: 'page'})
53
+    transaction.commit()
54
+    assert content_query.count() > 0
55
+
31
 
56
 
32
 class FunctionalTest(unittest.TestCase):
57
 class FunctionalTest(unittest.TestCase):
33
 
58
 

+ 43 - 0
tracim/tests/functional/test_contents.py 查看文件

1
 # -*- coding: utf-8 -*-
1
 # -*- coding: utf-8 -*-
2
 from tracim.tests import FunctionalTest
2
 from tracim.tests import FunctionalTest
3
+from tracim.tests import set_html_document_slug_to_legacy
3
 from tracim.fixtures.content import Content as ContentFixtures
4
 from tracim.fixtures.content import Content as ContentFixtures
4
 from tracim.fixtures.users_and_groups import Base as BaseFixture
5
 from tracim.fixtures.users_and_groups import Base as BaseFixture
5
 
6
 
28
             status=400
29
             status=400
29
         )   # nopep8
30
         )   # nopep8
30
 
31
 
32
+    def test_api__get_html_document__ok_200__legacy_slug(self) -> None:
33
+        """
34
+        Get one html document of a content
35
+        """
36
+        self.testapp.authorization = (
37
+            'Basic',
38
+            (
39
+                'admin@admin.admin',
40
+                'admin@admin.admin'
41
+            )
42
+        )
43
+        set_html_document_slug_to_legacy(self.session_factory)
44
+        res = self.testapp.get(
45
+            '/api/v2/workspaces/2/html-documents/6',
46
+            status=200
47
+        )   # nopep8
48
+        content = res.json_body
49
+        assert content['content_type'] == 'html-documents'
50
+        assert content['content_id'] == 6
51
+        assert content['is_archived'] is False
52
+        assert content['is_deleted'] is False
53
+        assert content['label'] == 'Tiramisu Recipe'
54
+        assert content['parent_id'] == 3
55
+        assert content['show_in_ui'] is True
56
+        assert content['slug'] == 'tiramisu-recipe'
57
+        assert content['status'] == 'open'
58
+        assert content['workspace_id'] == 2
59
+        assert content['current_revision_id'] == 27
60
+        # TODO - G.M - 2018-06-173 - check date format
61
+        assert content['created']
62
+        assert content['author']
63
+        assert content['author']['user_id'] == 1
64
+        assert content['author']['avatar_url'] is None
65
+        assert content['author']['public_name'] == 'Global manager'
66
+        # TODO - G.M - 2018-06-173 - check date format
67
+        assert content['modified']
68
+        assert content['last_modifier'] != content['author']
69
+        assert content['last_modifier']['user_id'] == 3
70
+        assert content['last_modifier']['public_name'] == 'Bob i.'
71
+        assert content['last_modifier']['avatar_url'] is None
72
+        assert content['raw_content'] == '<p>To cook a great Tiramisu, you need many ingredients.</p>'  # nopep8
73
+
31
     def test_api__get_html_document__ok_200__nominal_case(self) -> None:
74
     def test_api__get_html_document__ok_200__nominal_case(self) -> None:
32
         """
75
         """
33
         Get one html document of a content
76
         Get one html document of a content

+ 64 - 0
tracim/tests/functional/test_workspaces.py 查看文件

3
 Tests for /api/v2/workspaces subpath endpoints.
3
 Tests for /api/v2/workspaces subpath endpoints.
4
 """
4
 """
5
 from tracim.tests import FunctionalTest
5
 from tracim.tests import FunctionalTest
6
+from tracim.tests import set_html_document_slug_to_legacy
6
 from tracim.fixtures.content import Content as ContentFixtures
7
 from tracim.fixtures.content import Content as ContentFixtures
7
 from tracim.fixtures.users_and_groups import Base as BaseFixture
8
 from tracim.fixtures.users_and_groups import Base as BaseFixture
8
 
9
 
273
         assert content['workspace_id'] == 1
274
         assert content['workspace_id'] == 1
274
 
275
 
275
     # Root related
276
     # Root related
277
+    def test_api__get_workspace_content__ok_200__get_all_root_content__legacy_html_slug(self):
278
+        """
279
+        Check obtain workspace all root contents
280
+        """
281
+        set_html_document_slug_to_legacy(self.session_factory)
282
+        params = {
283
+            'parent_id': 0,
284
+            'show_archived': 1,
285
+            'show_deleted': 1,
286
+            'show_active': 1,
287
+        }
288
+        self.testapp.authorization = (
289
+            'Basic',
290
+            (
291
+                'bob@fsf.local',
292
+                'foobarbaz'
293
+            )
294
+        )
295
+        res = self.testapp.get(
296
+            '/api/v2/workspaces/3/contents',
297
+            status=200,
298
+            params=params,
299
+        ).json_body  # nopep8
300
+        # TODO - G.M - 30-05-2018 - Check this test
301
+        assert len(res) == 4
302
+        content = res[1]
303
+        assert content['content_type'] == 'html-documents'
304
+        assert content['content_id'] == 15
305
+        assert content['is_archived'] is False
306
+        assert content['is_deleted'] is False
307
+        assert content['label'] == 'New Fruit Salad'
308
+        assert content['parent_id'] is None
309
+        assert content['show_in_ui'] is True
310
+        assert content['slug'] == 'new-fruit-salad'
311
+        assert content['status'] == 'open'
312
+        assert set(content['sub_content_types']) == {'thread', 'html-documents', 'folder', 'file'}  # nopep8
313
+        assert content['workspace_id'] == 3
314
+
315
+        content = res[2]
316
+        assert content['content_type'] == 'html-documents'
317
+        assert content['content_id'] == 16
318
+        assert content['is_archived'] is True
319
+        assert content['is_deleted'] is False
320
+        assert content['label'].startswith('Fruit Salad')
321
+        assert content['parent_id'] is None
322
+        assert content['show_in_ui'] is True
323
+        assert content['slug'].startswith('fruit-salad')
324
+        assert content['status'] == 'open'
325
+        assert set(content['sub_content_types']) == {'thread', 'html-documents', 'folder', 'file'}  # nopep8
326
+        assert content['workspace_id'] == 3
327
+
328
+        content = res[3]
329
+        assert content['content_type'] == 'html-documents'
330
+        assert content['content_id'] == 17
331
+        assert content['is_archived'] is False
332
+        assert content['is_deleted'] is True
333
+        assert content['label'].startswith('Bad Fruit Salad')
334
+        assert content['parent_id'] is None
335
+        assert content['show_in_ui'] is True
336
+        assert content['slug'].startswith('bad-fruit-salad')
337
+        assert content['status'] == 'open'
338
+        assert set(content['sub_content_types']) == {'thread', 'html-documents', 'folder', 'file'}  # nopep8
339
+        assert content['workspace_id'] == 3
276
 
340
 
277
     def test_api__get_workspace_content__ok_200__get_all_root_content(self):
341
     def test_api__get_workspace_content__ok_200__get_all_root_content(self):
278
         """
342
         """