|
@@ -0,0 +1,216 @@
|
|
1
|
+# -*- coding: utf-8 -*-
|
|
2
|
+import time
|
|
3
|
+
|
|
4
|
+from depot.fields.upload import UploadedFile
|
|
5
|
+from nose.tools import ok_
|
|
6
|
+from nose.tools import raises
|
|
7
|
+from sqlalchemy.sql.elements import and_
|
|
8
|
+from sqlalchemy.testing import eq_
|
|
9
|
+
|
|
10
|
+# from tracim.lib.content import ContentApi
|
|
11
|
+from tracim.exceptions import ContentRevisionUpdateError
|
|
12
|
+from tracim.models import Content
|
|
13
|
+from tracim.models.revision_protection import new_revision
|
|
14
|
+from tracim.models import User
|
|
15
|
+from tracim.models.data import ActionDescription
|
|
16
|
+from tracim.models.data import ContentRevisionRO
|
|
17
|
+from tracim.models.data import ContentType
|
|
18
|
+from tracim.models.data import Workspace
|
|
19
|
+from tracim.tests import BaseTest
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+class TestContent(BaseTest):
|
|
23
|
+
|
|
24
|
+ @raises(ContentRevisionUpdateError)
|
|
25
|
+ def test_update_without_prepare(self):
|
|
26
|
+ content1 = self.test_create()
|
|
27
|
+ content1.description = 'FOO' # Raise ContentRevisionUpdateError because revision can't be updated
|
|
28
|
+
|
|
29
|
+ # TODO - G.M - 28-03-2018 - Reenable this test when libContent is available
|
|
30
|
+ # def test_query(self):
|
|
31
|
+ # content1 = self.test_create()
|
|
32
|
+ # with new_revision(content1):
|
|
33
|
+ # content1.description = 'TEST_CONTENT_DESCRIPTION_1_UPDATED'
|
|
34
|
+ # DBSession.flush()
|
|
35
|
+ #
|
|
36
|
+ # content2 = self.test_create(key='2')
|
|
37
|
+ # with new_revision(content2):
|
|
38
|
+ # content2.description = 'TEST_CONTENT_DESCRIPTION_2_UPDATED'
|
|
39
|
+ # DBSession.flush()
|
|
40
|
+ #
|
|
41
|
+ # workspace1 = DBSession.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_1').one()
|
|
42
|
+ # workspace2 = DBSession.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_2').one()
|
|
43
|
+ #
|
|
44
|
+ # # To get Content in database we have to join Content and ContentRevisionRO with particular condition:
|
|
45
|
+ # # Join have to be on most recent revision
|
|
46
|
+ # join_sub_query = DBSession.query(ContentRevisionRO.revision_id)\
|
|
47
|
+ # .filter(ContentRevisionRO.content_id == Content.id)\
|
|
48
|
+ # .order_by(ContentRevisionRO.revision_id.desc())\
|
|
49
|
+ # .limit(1)\
|
|
50
|
+ # .correlate(Content)
|
|
51
|
+ #
|
|
52
|
+ # base_query = DBSession.query(Content)\
|
|
53
|
+ # .join(ContentRevisionRO, and_(Content.id == ContentRevisionRO.content_id,
|
|
54
|
+ # ContentRevisionRO.revision_id == join_sub_query))
|
|
55
|
+ #
|
|
56
|
+ # pattern = 'TEST_CONTENT_DESCRIPTION_%_UPDATED'
|
|
57
|
+ # eq_(2, base_query.filter(Content.description.like(pattern)).count())
|
|
58
|
+ #
|
|
59
|
+ # eq_(1, base_query.filter(Content.workspace == workspace1).count())
|
|
60
|
+ # eq_(1, base_query.filter(Content.workspace == workspace2).count())
|
|
61
|
+ #
|
|
62
|
+ # content1_from_query = base_query.filter(Content.workspace == workspace1).one()
|
|
63
|
+ # eq_(content1.id, content1_from_query.id)
|
|
64
|
+ # eq_('TEST_CONTENT_DESCRIPTION_1_UPDATED', content1_from_query.description)
|
|
65
|
+ #
|
|
66
|
+ # user_admin = DBSession.query(User).filter(User.email == 'admin@admin.admin').one()
|
|
67
|
+ #
|
|
68
|
+ # api = ContentApi(None)
|
|
69
|
+ #
|
|
70
|
+ # content1_from_api = api.get_one(content1.id, ContentType.Page, workspace1)
|
|
71
|
+
|
|
72
|
+ def test_update(self):
|
|
73
|
+ created_content = self.test_create()
|
|
74
|
+ content = self.session.query(Content).filter(Content.id == created_content.id).one()
|
|
75
|
+ eq_(1, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1').count())
|
|
76
|
+
|
|
77
|
+ with new_revision(content):
|
|
78
|
+ time.sleep(0.00001)
|
|
79
|
+ content.description = 'TEST_CONTENT_DESCRIPTION_1_UPDATED'
|
|
80
|
+ self.session.flush()
|
|
81
|
+
|
|
82
|
+ eq_(2, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1').count())
|
|
83
|
+ eq_(1, self.session.query(Content).filter(Content.id == created_content.id).count())
|
|
84
|
+
|
|
85
|
+ with new_revision(content):
|
|
86
|
+ time.sleep(0.00001)
|
|
87
|
+ content.description = 'TEST_CONTENT_DESCRIPTION_1_UPDATED_2'
|
|
88
|
+ content.label = 'TEST_CONTENT_1_UPDATED_2'
|
|
89
|
+ self.session.flush()
|
|
90
|
+
|
|
91
|
+ eq_(1, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1_UPDATED_2').count())
|
|
92
|
+ eq_(1, self.session.query(Content).filter(Content.id == created_content.id).count())
|
|
93
|
+
|
|
94
|
+ revision_1 = self.session.query(ContentRevisionRO)\
|
|
95
|
+ .filter(ContentRevisionRO.description == 'TEST_CONTENT_DESCRIPTION_1').one()
|
|
96
|
+ revision_2 = self.session.query(ContentRevisionRO)\
|
|
97
|
+ .filter(ContentRevisionRO.description == 'TEST_CONTENT_DESCRIPTION_1_UPDATED').one()
|
|
98
|
+ revision_3 = self.session.query(ContentRevisionRO)\
|
|
99
|
+ .filter(ContentRevisionRO.description == 'TEST_CONTENT_DESCRIPTION_1_UPDATED_2').one()
|
|
100
|
+
|
|
101
|
+ # Updated dates must be different
|
|
102
|
+ ok_(revision_1.updated < revision_2.updated < revision_3.updated)
|
|
103
|
+ # Created dates must be equal
|
|
104
|
+ ok_(revision_1.created == revision_2.created == revision_3.created)
|
|
105
|
+
|
|
106
|
+ def test_creates(self):
|
|
107
|
+ eq_(0, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1').count())
|
|
108
|
+ eq_(0, self.session.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_1').count())
|
|
109
|
+
|
|
110
|
+ user_admin = self.session.query(User).filter(User.email == 'admin@admin.admin').one()
|
|
111
|
+ workspace = Workspace(label="TEST_WORKSPACE_1")
|
|
112
|
+ self.session.add(workspace)
|
|
113
|
+ self.session.flush()
|
|
114
|
+ eq_(1, self.session.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_1').count())
|
|
115
|
+
|
|
116
|
+ first_content = self._create_content(
|
|
117
|
+ owner=user_admin,
|
|
118
|
+ workspace=workspace,
|
|
119
|
+ type=ContentType.Page,
|
|
120
|
+ label='TEST_CONTENT_1',
|
|
121
|
+ description='TEST_CONTENT_DESCRIPTION_1',
|
|
122
|
+ revision_type=ActionDescription.CREATION,
|
|
123
|
+ is_deleted=False,
|
|
124
|
+ is_archived=False,
|
|
125
|
+ )
|
|
126
|
+
|
|
127
|
+ eq_(1, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_1').count())
|
|
128
|
+
|
|
129
|
+ content = self.session.query(Content).filter(Content.id == first_content.id).one()
|
|
130
|
+ eq_('TEST_CONTENT_1', content.label)
|
|
131
|
+ eq_('TEST_CONTENT_DESCRIPTION_1', content.description)
|
|
132
|
+
|
|
133
|
+ # Create a second content
|
|
134
|
+ second_content = self._create_content(
|
|
135
|
+ owner=user_admin,
|
|
136
|
+ workspace=workspace,
|
|
137
|
+ type=ContentType.Page,
|
|
138
|
+ label='TEST_CONTENT_2',
|
|
139
|
+ description='TEST_CONTENT_DESCRIPTION_2',
|
|
140
|
+ revision_type=ActionDescription.CREATION
|
|
141
|
+ )
|
|
142
|
+
|
|
143
|
+ eq_(1, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_2').count())
|
|
144
|
+
|
|
145
|
+ content = self.session.query(Content).filter(Content.id == second_content.id).one()
|
|
146
|
+ eq_('TEST_CONTENT_2', content.label)
|
|
147
|
+ eq_('TEST_CONTENT_DESCRIPTION_2', content.description)
|
|
148
|
+
|
|
149
|
+ def test_create(self, key='1'):
|
|
150
|
+ eq_(0, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_%s' % key).count())
|
|
151
|
+ eq_(0, self.session.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_%s' % key).count())
|
|
152
|
+
|
|
153
|
+ user_admin = self.session.query(User).filter(User.email == 'admin@admin.admin').one()
|
|
154
|
+ workspace = Workspace(label="TEST_WORKSPACE_%s" % key)
|
|
155
|
+ self.session.add(workspace)
|
|
156
|
+ self.session.flush()
|
|
157
|
+ eq_(1, self.session.query(Workspace).filter(Workspace.label == 'TEST_WORKSPACE_%s' % key).count())
|
|
158
|
+
|
|
159
|
+ created_content = self._create_content(
|
|
160
|
+ owner=user_admin,
|
|
161
|
+ workspace=workspace,
|
|
162
|
+ type=ContentType.Page,
|
|
163
|
+ label='TEST_CONTENT_%s' % key,
|
|
164
|
+ description='TEST_CONTENT_DESCRIPTION_%s' % key,
|
|
165
|
+ revision_type=ActionDescription.CREATION
|
|
166
|
+ )
|
|
167
|
+
|
|
168
|
+ eq_(1, self.session.query(ContentRevisionRO).filter(ContentRevisionRO.label == 'TEST_CONTENT_%s' % key).count())
|
|
169
|
+
|
|
170
|
+ content = self.session.query(Content).filter(Content.id == created_content.id).one()
|
|
171
|
+ eq_('TEST_CONTENT_%s' % key, content.label)
|
|
172
|
+ eq_('TEST_CONTENT_DESCRIPTION_%s' % key, content.description)
|
|
173
|
+
|
|
174
|
+ return created_content
|
|
175
|
+
|
|
176
|
+ def _get_user(self):
|
|
177
|
+ email = 'admin@admin.admin'
|
|
178
|
+ user_query = self.session.query(User)
|
|
179
|
+ user_filter = user_query.filter(User.email == email)
|
|
180
|
+ user = user_filter.one()
|
|
181
|
+ return user
|
|
182
|
+
|
|
183
|
+ def _create_content(self, *args, **kwargs):
|
|
184
|
+ content = Content(*args, **kwargs)
|
|
185
|
+ self.session.add(content)
|
|
186
|
+ self.session.flush()
|
|
187
|
+ return content
|
|
188
|
+
|
|
189
|
+ def _create_content_from_nothing(self):
|
|
190
|
+ user_admin = self._get_user()
|
|
191
|
+ workspace = Workspace(label="TEST_WORKSPACE_1")
|
|
192
|
+ content = self._create_content(
|
|
193
|
+ owner=user_admin,
|
|
194
|
+ workspace=workspace,
|
|
195
|
+ type=ContentType.File,
|
|
196
|
+ label='TEST_CONTENT_1',
|
|
197
|
+ description='TEST_CONTENT_DESCRIPTION_1',
|
|
198
|
+ revision_type=ActionDescription.CREATION,
|
|
199
|
+ )
|
|
200
|
+ return content
|
|
201
|
+
|
|
202
|
+ def test_unit__content_depot_file(self):
|
|
203
|
+ """ Depot file access thought content property methods. """
|
|
204
|
+ content = self._create_content_from_nothing()
|
|
205
|
+ # tests uninitialized depot file
|
|
206
|
+ eq_(content.depot_file, None)
|
|
207
|
+ # initializes depot file
|
|
208
|
+ # which is able to behave like a python file object
|
|
209
|
+ content.depot_file = b'test'
|
|
210
|
+ # tests initialized depot file
|
|
211
|
+ ok_(content.depot_file)
|
|
212
|
+ # tests type of initialized depot file
|
|
213
|
+ eq_(type(content.depot_file), UploadedFile)
|
|
214
|
+ # tests content of initialized depot file
|
|
215
|
+ # using depot_file.file of type StoredFile to fetch content back
|
|
216
|
+ eq_(content.depot_file.file.read(), b'test')
|