1##############################################################################
2#
3# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
4# All Rights Reserved.
5#
6# This software is subject to the provisions of the Zope Public License,
7# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11# FOR A PARTICULAR PURPOSE.
12#
13##############################################################################
14"""'browser' namespace directive tests
15
16$Id: test_directives.py 103138 2009-08-24 11:37:52Z nadako $
17"""
18
19import os
20import unittest
21from cStringIO import StringIO
22
23from zope import component
24from zope.interface import Interface, implements, directlyProvides, providedBy
25
26import zope.security.management
27from zope.configuration.xmlconfig import xmlconfig, XMLConfig
28from zope.configuration.exceptions import ConfigurationError
29from zope.publisher.browser import TestRequest
30from zope.publisher.interfaces import IDefaultViewName
31from zope.publisher.interfaces.browser import IBrowserPublisher
32from zope.publisher.interfaces.browser import IBrowserRequest
33from zope.publisher.interfaces.browser import IBrowserSkinType, IDefaultSkin
34from zope.security.proxy import removeSecurityProxy, ProxyFactory
35from zope.security.permission import Permission
36from zope.security.interfaces import IPermission
37from zope.traversing.adapters import DefaultTraversable
38from zope.traversing.interfaces import ITraversable
39
40import zope.publisher.defaultview
41import zope.browserresource
42from zope.component import provideAdapter, provideUtility
43from zope.component.testfiles.views import R1, IV
44from zope.browserresource.file import FileResource
45from zope.browserresource.i18nfile import I18nFileResource
46from zope.browserresource.directory import DirectoryResource
47from zope.testing import cleanup
48
49tests_path = os.path.join(
50    os.path.dirname(zope.browserresource.__file__),
51    'tests')
52
53template = """<configure
54   xmlns='http://namespaces.zope.org/zope'
55   xmlns:browser='http://namespaces.zope.org/browser'
56   i18n_domain='zope'>
57   %s
58   </configure>"""
59
60
61request = TestRequest()
62
63class ITestLayer(IBrowserRequest):
64    """Test Layer."""
65
66class ITestSkin(ITestLayer):
67    """Test Skin."""
68
69
70class MyResource(object):
71
72    def __init__(self, request):
73        self.request = request
74
75
76class Test(cleanup.CleanUp, unittest.TestCase):
77
78    def setUp(self):
79        super(Test, self).setUp()
80        XMLConfig('meta.zcml', zope.browserresource)()
81        provideAdapter(DefaultTraversable, (None,), ITraversable)
82
83    def tearDown(self):
84        super(Test, self).tearDown()
85
86    def testI18nResource(self):
87        self.assertEqual(component.queryAdapter(request, name='test'), None)
88
89        path1 = os.path.join(tests_path, 'testfiles', 'test.pt')
90        path2 = os.path.join(tests_path, 'testfiles', 'test2.pt')
91
92        xmlconfig(StringIO(template % (
93            '''
94            <browser:i18n-resource name="test" defaultLanguage="fr">
95              <browser:translation language="en" file="%s" />
96              <browser:translation language="fr" file="%s" />
97            </browser:i18n-resource>
98            ''' % (path1, path2)
99            )))
100
101        v = component.getAdapter(request, name='test')
102        self.assertEqual(
103            component.queryAdapter(request, name='test').__class__,
104            I18nFileResource)
105        self.assertEqual(v._testData('en'), open(path1, 'rb').read())
106        self.assertEqual(v._testData('fr'), open(path2, 'rb').read())
107
108        # translation must be provided for the default language
109        config = StringIO(template % (
110            '''
111            <browser:i18n-resource name="test" defaultLanguage="fr">
112              <browser:translation language="en" file="%s" />
113              <browser:translation language="lt" file="%s" />
114            </browser:i18n-resource>
115            ''' % (path1, path2)
116            ))
117        self.assertRaises(ConfigurationError, xmlconfig, config)
118
119    def testFactory(self):
120        self.assertEqual(
121            component.queryAdapter(request, name='index.html'), None)
122
123        xmlconfig(StringIO(template %
124            '''
125            <browser:resource
126                name="index.html"
127                factory="
128                  zope.browserresource.tests.test_directives.MyResource"
129                />
130            '''
131            ))
132
133        r = component.getAdapter(request, name='index.html')
134        self.assertEquals(r.__class__, MyResource)
135        r = ProxyFactory(r)
136        self.assertEqual(r.__name__, "index.html")
137
138    def testFile(self):
139        path = os.path.join(tests_path, 'testfiles', 'test.pt')
140
141        self.assertEqual(component.queryAdapter(request, name='test'), None)
142
143        xmlconfig(StringIO(template %
144            '''
145            <browser:resource
146                name="index.html"
147                file="%s"
148                />
149            ''' % path
150            ))
151
152        r = component.getAdapter(request, name='index.html')
153        self.assertTrue(isinstance(r, FileResource))
154        r = ProxyFactory(r)
155        self.assertEqual(r.__name__, "index.html")
156
157        # Make sure we can access available attrs and not others
158        for n in ('GET', 'HEAD', 'publishTraverse', 'request', '__call__'):
159            getattr(r, n)
160
161        self.assertRaises(Exception, getattr, r, '_testData')
162
163        r = removeSecurityProxy(r)
164        self.assertEqual(r._testData(), open(path, 'rb').read())
165
166
167    def testPluggableFactory(self):
168
169        class ImageResource(object):
170            def __init__(self, image, request):
171                pass
172
173        class ImageResourceFactory(object):
174            def __init__(self, path, checker, name):
175                pass
176            def __call__(self, request):
177                return ImageResource(None, request)
178
179        from zope.browserresource.interfaces import IResourceFactoryFactory
180        component.provideUtility(ImageResourceFactory, IResourceFactoryFactory,
181                                 name='gif')
182
183        xmlconfig(StringIO(template %
184            '''
185            <browser:resource
186                name="test.gif"
187                file="%s"
188                />
189            ''' % os.path.join(tests_path, 'testfiles', 'test.gif')
190            ))
191
192        r = component.getAdapter(request, name='test.gif')
193        self.assertTrue(isinstance(r, ImageResource))
194
195    def testDirectory(self):
196        path = os.path.join(tests_path, 'testfiles', 'subdir')
197
198        self.assertEqual(component.queryAdapter(request, name='dir'), None)
199
200        xmlconfig(StringIO(template %
201            '''
202            <browser:resourceDirectory
203                name="dir"
204                directory="%s"
205                />
206            ''' % path
207            ))
208
209        r = component.getAdapter(request, name='dir')
210        self.assertTrue(isinstance(r, DirectoryResource))
211        r = ProxyFactory(r)
212        self.assertEqual(r.__name__, "dir")
213
214        # Make sure we can access available attrs and not others
215        for n in ('publishTraverse', 'browserDefault', 'request', '__call__',
216                  'get', '__getitem__'):
217            getattr(r, n)
218
219        self.assertRaises(Exception, getattr, r, 'directory_factory')
220
221        inexistent_dir = StringIO(template %
222            '''
223            <browser:resourceDirectory
224                name="dir"
225                directory="does-not-exist"
226                />
227            ''')
228
229        self.assertRaises(ConfigurationError, xmlconfig, inexistent_dir)
230
231    def test_SkinResource(self):
232        self.assertEqual(component.queryAdapter(request, name='test'), None)
233
234        path = os.path.join(tests_path, 'testfiles', 'test.pt')
235        xmlconfig(StringIO(template % (
236            '''
237            <browser:resource
238                name="test"
239                file="%s"
240                layer="
241                  zope.browserresource.tests.test_directives.ITestLayer"
242                />
243            ''' % path
244            )))
245
246        self.assertEqual(component.queryAdapter(request, name='test'), None)
247
248        r = component.getAdapter(TestRequest(skin=ITestSkin), name='test')
249        self.assertEqual(r._testData(), open(path, 'rb').read())
250
251
252def test_suite():
253    return unittest.makeSuite(Test)
254