• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / Products.CMFCore / 6246931310

20 Sep 2023 09:54AM UTC coverage: 86.008% (-0.3%) from 86.266%
6246931310

Pull #131

github

mauritsvanrees
gha: don't need setup-python on 27 as we use the 27 container.
Pull Request #131: Make decodeFolderFilter and encodeFolderFilter non-public.

2466 of 3689 branches covered (0.0%)

Branch coverage included in aggregate %.

6 of 6 new or added lines in 1 file covered. (100.0%)

17297 of 19289 relevant lines covered (89.67%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.92
/src/Products/CMFCore/tests/test_FSPythonScript.py
1
##############################################################################
2
#
3
# Copyright (c) 2002 Zope Foundation and Contributors.
4
#
5
# This software is subject to the provisions of the Zope Public License,
6
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
7
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10
# FOR A PARTICULAR PURPOSE.
11
#
12
##############################################################################
13
""" Unit tests for FSPythonScript module.
1✔
14
"""
15

16
import os
1✔
17
import unittest
1✔
18
import warnings
1✔
19
from os.path import join
1✔
20
from sys import exc_info
1✔
21
from time import sleep
1✔
22

23
from six.moves._thread import start_new_thread
1✔
24

25
from Acquisition import aq_base
1✔
26
from DateTime.DateTime import DateTime
1✔
27
from OFS.Folder import Folder
1✔
28
from OFS.SimpleItem import SimpleItem
1✔
29
from Testing import ZopeTestCase
1✔
30
from zope.testing.cleanup import cleanUp
1✔
31

32
from Products.StandardCacheManagers import RAMCacheManager
1✔
33

34
from ..FSMetadata import FSMetadata
1✔
35
from ..FSPythonScript import FSPythonScript
1✔
36
from .base.testcase import FSDVTest
1✔
37
from .base.testcase import SecurityTest
1✔
38

39

40
ZopeTestCase.installProduct('PythonScripts', 1)
1✔
41

42

43
class FSPSMaker(FSDVTest):
1✔
44

45
    def _makeOne(self, id, filename):
1✔
46
        path = join(self.skin_path_name, filename)
1✔
47
        metadata = FSMetadata(path)
1✔
48
        metadata.read()
1✔
49
        return FSPythonScript(id, path, properties=metadata.getProperties())
1✔
50

51

52
class FSPythonScriptTests(FSPSMaker):
1✔
53

54
    def test_get_size(self):
1✔
55
        # Test get_size returns correct value
56
        script = self._makeOne('test1', 'test1.py')
1✔
57
        self.assertEqual(len(script.read()), script.get_size())
1✔
58

59
    def test_getModTime(self):
1✔
60
        script = self._makeOne('test1', 'test1.py')
1✔
61
        self.assertTrue(isinstance(script.getModTime(), DateTime))
1✔
62
        self.assertEqual(script.getModTime(),
1✔
63
                         DateTime(os.stat(script._filepath).st_mtime))
64

65
    def test_bobobase_modification_time(self):
1✔
66
        script = self._makeOne('test1', 'test1.py')
1✔
67
        self.assertTrue(isinstance(script.bobobase_modification_time(),
1✔
68
                                   DateTime))
69
        self.assertEqual(script.bobobase_modification_time(),
1✔
70
                         DateTime(os.stat(script._filepath).st_mtime))
71

72
    def test_initialization_race_condition(self):
1✔
73
        # Tries to exercise a former race condition where
74
        # FSObject._updateFromFS() set self._parsed before the
75
        # object was really parsed.
76
        for _n in range(10):
1✔
77
            f = Folder()
1✔
78
            script = self._makeOne('test1', 'test1.py').__of__(f)
1✔
79
            res = []
1✔
80

81
            def call_script(script=script, res=res):
1✔
82
                try:
1✔
83
                    res.append(script())
1✔
84
                except Exception:
×
85
                    res.append('%s: %s' % exc_info()[:2])
×
86

87
            start_new_thread(call_script, ())
1✔
88
            call_script()
1✔
89
            while len(res) < 2:
1✔
90
                sleep(0.05)
1✔
91
            self.assertEqual(res, ['test1', 'test1'], res)
1✔
92

93
    def test_foreign_line_endings(self):
1✔
94
        # Load the various line ending files and get their output
95
        container = Folder('container_for_execution')
1✔
96
        for fformat in ('unix', 'dos', 'mac'):
1✔
97
            container._setObject(fformat,
1✔
98
                                 self._makeOne(fformat,
99
                                               'test_%s.py' % fformat))
100
            script = getattr(container, fformat)
1✔
101
            self.assertEqual(script(), fformat)
1✔
102

103

104
class FSPythonScriptCustomizationTests(SecurityTest, FSPSMaker):
1✔
105

106
    def setUp(self):
1✔
107
        FSPSMaker.setUp(self)
1✔
108
        SecurityTest.setUp(self)
1✔
109

110
    def tearDown(self):
1✔
111
        cleanUp()
1✔
112
        SecurityTest.tearDown(self)
1✔
113
        FSPSMaker.tearDown(self)
1✔
114

115
    def test_customize(self):
1✔
116
        from ..FSPythonScript import CustomizedPythonScript
1✔
117

118
        _stool, custom, _fsdir, fsPS = self._makeContext('test6', 'test6.py')
1✔
119

120
        fsPS.manage_doCustomize(folder_path='custom')
1✔
121

122
        self.assertEqual(len(custom.objectIds()), 1)
1✔
123
        self.assertTrue('test6' in custom.objectIds())
1✔
124

125
        test6 = custom._getOb('test6')
1✔
126

127
        self.assertTrue(isinstance(test6, CustomizedPythonScript))
1✔
128
        self.assertEqual(test6.original_source, fsPS.read())
1✔
129

130
    def test_customize_alternate_root(self):
1✔
131
        _stool, custom, _fsdir, fsPS = self._makeContext('test6', 'test6.py')
1✔
132
        self.app.other = Folder('other')
1✔
133

134
        fsPS.manage_doCustomize(folder_path='other', root=self.app)
1✔
135

136
        self.assertFalse('test6' in custom.objectIds())
1✔
137
        self.assertTrue('test6' in self.app.other.objectIds())
1✔
138

139
    def test_customize_fspath_as_dot(self):
1✔
140
        stool, custom, _fsdir, fsPS = self._makeContext('test6', 'test6.py')
1✔
141

142
        fsPS.manage_doCustomize(folder_path='.')
1✔
143

144
        self.assertFalse('test6' in custom.objectIds())
1✔
145
        self.assertTrue('test6' in stool.objectIds())
1✔
146

147
    def test_customize_manual_clone(self):
1✔
148
        _stool, custom, _fsdir, fsPS = self._makeContext('test6', 'test6.py')
1✔
149
        clone = Folder('test6')
1✔
150

151
        fsPS.manage_doCustomize(folder_path='custom', obj=clone)
1✔
152

153
        self.assertTrue('test6' in custom.objectIds())
1✔
154
        self.assertTrue(aq_base(custom._getOb('test6')) is clone)
1✔
155

156
    def test_customize_caching(self):
1✔
157
        # Test to ensure that cache manager associations survive customizing
158
        _stool, custom, _fsdir, fsPS = self._makeContext('test6', 'test6.py')
1✔
159

160
        cache_id = 'gofast'
1✔
161
        RAMCacheManager.manage_addRAMCacheManager(self.app, cache_id,
1✔
162
                                                  REQUEST=None)
163
        fsPS.ZCacheable_setManagerId(cache_id, REQUEST=None)
1✔
164

165
        self.assertEqual(fsPS.ZCacheable_getManagerId(), cache_id)
1✔
166

167
        fsPS.manage_doCustomize(folder_path='custom')
1✔
168
        custom_ps = custom.test6
1✔
169

170
        self.assertEqual(custom_ps.ZCacheable_getManagerId(), cache_id)
1✔
171

172
    def test_customize_proxyroles(self):
1✔
173
        # Test to ensure that proxy roles survive customizing
174
        _stool, custom, _fsdir, fsPS = self._makeContext('test6', 'test6.py')
1✔
175

176
        fsPS._proxy_roles = ('Manager', 'Anonymous')
1✔
177
        self.assertTrue(fsPS.manage_haveProxy('Anonymous'))
1✔
178
        self.assertTrue(fsPS.manage_haveProxy('Manager'))
1✔
179

180
        fsPS.manage_doCustomize(folder_path='custom')
1✔
181
        custom_ps = custom.test6
1✔
182
        self.assertTrue(custom_ps.manage_haveProxy('Anonymous'))
1✔
183
        self.assertTrue(custom_ps.manage_haveProxy('Manager'))
1✔
184

185
    def test_customization_permissions(self):
1✔
186
        # Test to ensure that permission settings survive customizing
187
        _stool, custom, _fsdir, fsPS = self._makeContext('test6', 'test6.py')
1✔
188
        perm = 'View management screens'
1✔
189

190
        # First, set a permission to an odd role and verify
191
        fsPS.manage_permission(perm, roles=('Anonymous',), acquire=0)
1✔
192
        rop = fsPS.rolesOfPermission(perm)
1✔
193
        for rop_info in rop:
1✔
194
            if rop_info['name'] == 'Anonymous':
1✔
195
                self.assertFalse(rop_info['selected'] == '')
1✔
196
            else:
197
                self.assertTrue(rop_info['selected'] == '')
1✔
198

199
        # Now customize and verify again
200
        fsPS.manage_doCustomize(folder_path='custom')
1✔
201
        custom_ps = custom.test6
1✔
202
        rop = custom_ps.rolesOfPermission(perm)
1✔
203
        for rop_info in rop:
1✔
204
            if rop_info['name'] == 'Anonymous':
1✔
205
                self.assertFalse(rop_info['selected'] == '')
1✔
206
            else:
207
                self.assertTrue(rop_info['selected'] == '')
1✔
208

209

210
_ORIGINAL_TEXT = """\
1✔
211
## Script (Python) "cps"
212
##bind container=container
213
##bind context=context
214
##bind namespace=
215
##bind script=script
216
##bind subpath=traverse_subpath
217
##parameters=
218
##title=
219
##
220
return 'cps'
221
"""
222

223
_REPLACEMENT_TEXT = """\
1✔
224
## Script (Python) "cps"
225
##bind container=container
226
##bind context=context
227
##bind namespace=
228
##bind script=script
229
##bind subpath=traverse_subpath
230
##parameters=
231
##title=
232
##
233
return 'cps -- replaced'
234
"""
235

236
_DIFF_TEXT = """\
1✔
237
--- original
238
+++ modified
239
@@ -7,4 +7,4 @@
240
 ##parameters=
241
 ##title=
242
 ##
243
-return 'cps'
244
+return 'cps -- replaced'
245
"""
246

247

248
class CustomizedPythonScriptTests(unittest.TestCase):
1✔
249

250
    def _getTargetClass(self):
1✔
251
        from ..FSPythonScript import CustomizedPythonScript
1✔
252
        return CustomizedPythonScript
1✔
253

254
    def _makeOne(self, id, text):
1✔
255
        return self._getTargetClass()(id, text)
1✔
256

257
    def test_write_leaves_original_source(self):
1✔
258
        cps = self._makeOne('cps', _ORIGINAL_TEXT)
1✔
259
        self.assertEqual(cps.read(), _ORIGINAL_TEXT)
1✔
260
        self.assertEqual(cps.original_source, _ORIGINAL_TEXT)
1✔
261
        cps.write(_REPLACEMENT_TEXT)
1✔
262
        self.assertEqual(cps.read(), _REPLACEMENT_TEXT)
1✔
263
        self.assertEqual(cps.original_source, _ORIGINAL_TEXT)
1✔
264

265
    def test_getDiff(self):
1✔
266
        cps = self._makeOne('cps', _ORIGINAL_TEXT)
1✔
267
        self.assertEqual(len(list(cps.getDiff())), 0)
1✔
268

269
        cps.write(_REPLACEMENT_TEXT)
1✔
270
        self.assertEqual([line.rstrip() for line in cps.getDiff()],
1✔
271
                         _DIFF_TEXT.splitlines())
272

273

274
class WarnMe(SimpleItem):
1✔
275
    """Emits a UserWarning when called"""
276

277
    def __init__(self, stacklevel):
1✔
278
        self._stacklevel = stacklevel
1✔
279

280
    def __call__(self):
1✔
281
        warnings.warn('foo', stacklevel=self._stacklevel)
1✔
282

283

284
class FSPythonScriptWarningsTests(SecurityTest, FSPSMaker):
1✔
285

286
    def setUp(self):
1✔
287
        SecurityTest.setUp(self)
1✔
288
        FSPSMaker.setUp(self)
1✔
289

290
    def tearDown(self):
1✔
291
        FSPSMaker.tearDown(self)
1✔
292
        SecurityTest.tearDown(self)
1✔
293

294
    def testFSPSWarn(self):
1✔
295
        self.app._setObject('warn_me', WarnMe(2))
1✔
296
        self.app._setObject('warn1', self._makeOne('warn1', 'test_warn.py'))
1✔
297
        # This used to raise an error:
298
        #   File "/usr/local/python2.3/lib/python2.3/warnings.py", line 63,
299
        #   in warn_explicit
300
        #     if module[-3:].lower() == ".py":
301
        # TypeError: unsubscriptable object
302
        with warnings.catch_warnings():
1✔
303
            warnings.simplefilter('ignore')
1✔
304
            self.app.warn_me()
1✔
305
            self.app.warn1()
1✔
306

307

308
def test_suite():
1✔
309
    return unittest.TestSuite((
1✔
310
        unittest.makeSuite(FSPythonScriptTests),
311
        unittest.makeSuite(FSPythonScriptCustomizationTests),
312
        unittest.makeSuite(CustomizedPythonScriptTests),
313
        unittest.makeSuite(FSPythonScriptWarningsTests),
314
        ))
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc