cubicweb/web/test/unittest_idownloadable.py
changeset 11057 0b59724cb3f2
parent 10731 0736e31f8644
child 11241 a2091fa8cb2c
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
       
     1 # -*- coding: utf-8 -*-
       
     2 # copyright 2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     3 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     4 #
       
     5 # This file is part of CubicWeb.
       
     6 #
       
     7 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     8 # terms of the GNU Lesser General Public License as published by the Free
       
     9 # Software Foundation, either version 2.1 of the License, or (at your option)
       
    10 # any later version.
       
    11 #
       
    12 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    14 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    15 # details.
       
    16 #
       
    17 # You should have received a copy of the GNU Lesser General Public License along
       
    18 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    19 
       
    20 from functools import partial
       
    21 
       
    22 from logilab.common.testlib import unittest_main
       
    23 
       
    24 from cubicweb.devtools.testlib import CubicWebTC, real_error_handling
       
    25 from cubicweb import view
       
    26 from cubicweb.predicates import is_instance
       
    27 
       
    28 class IDownloadableUser(view.EntityAdapter):
       
    29     __regid__ = 'IDownloadable'
       
    30     __select__ = is_instance('CWUser')
       
    31 
       
    32     def download_content_type(self):
       
    33         """return MIME type of the downloadable content"""
       
    34         return 'text/plain'
       
    35 
       
    36     def download_encoding(self):
       
    37         """return encoding of the downloadable content"""
       
    38         return 'ascii'
       
    39 
       
    40     def download_file_name(self):
       
    41         """return file name of the downloadable content"""
       
    42         return  self.entity.name() + '.txt'
       
    43 
       
    44     def download_data(self):
       
    45         return b'Babar is not dead!'
       
    46 
       
    47 
       
    48 class BrokenIDownloadableGroup(IDownloadableUser):
       
    49     __regid__ = 'IDownloadable'
       
    50     __select__ = is_instance('CWGroup')
       
    51 
       
    52     def download_file_name(self):
       
    53         return  self.entity.name + '.txt'
       
    54 
       
    55     def download_data(self):
       
    56         raise IOError()
       
    57 
       
    58 class IDownloadableTC(CubicWebTC):
       
    59 
       
    60     def setUp(self):
       
    61         super(IDownloadableTC, self).setUp()
       
    62         self.vreg.register(IDownloadableUser)
       
    63         self.addCleanup(partial(self.vreg.unregister, IDownloadableUser))
       
    64 
       
    65     def test_header_simple_case(self):
       
    66         with self.admin_access.web_request() as req:
       
    67             req.form['vid'] = 'download'
       
    68             req.form['eid'] = str(req.user.eid)
       
    69             data = self.ctrl_publish(req, 'view')
       
    70             get = req.headers_out.getRawHeaders
       
    71             self.assertEqual(['attachment;filename="admin.txt"'],
       
    72                              get('content-disposition'))
       
    73             self.assertEqual(['text/plain;charset=ascii'],
       
    74                              get('content-type'))
       
    75             self.assertEqual(b'Babar is not dead!', data)
       
    76 
       
    77     def test_header_with_space(self):
       
    78         with self.admin_access.web_request() as req:
       
    79             self.create_user(req, login=u'c c l a', password='babar')
       
    80             req.cnx.commit()
       
    81         with self.new_access(u'c c l a').web_request() as req:
       
    82             req.form['vid'] = 'download'
       
    83             req.form['eid'] = str(req.user.eid)
       
    84             data = self.ctrl_publish(req,'view')
       
    85             get = req.headers_out.getRawHeaders
       
    86             self.assertEqual(['attachment;filename="c c l a.txt"'],
       
    87                              get('content-disposition'))
       
    88             self.assertEqual(['text/plain;charset=ascii'],
       
    89                              get('content-type'))
       
    90             self.assertEqual(b'Babar is not dead!', data)
       
    91 
       
    92     def test_header_with_space_and_comma(self):
       
    93         with self.admin_access.web_request() as req:
       
    94             self.create_user(req, login=u'c " l\\ a', password='babar')
       
    95             req.cnx.commit()
       
    96         with self.new_access(u'c " l\\ a').web_request() as req:
       
    97             req.form['vid'] = 'download'
       
    98             req.form['eid'] = str(req.user.eid)
       
    99             data = self.ctrl_publish(req,'view')
       
   100             get = req.headers_out.getRawHeaders
       
   101             self.assertEqual([r'attachment;filename="c \" l\\ a.txt"'],
       
   102                              get('content-disposition'))
       
   103             self.assertEqual(['text/plain;charset=ascii'],
       
   104                              get('content-type'))
       
   105             self.assertEqual(b'Babar is not dead!', data)
       
   106 
       
   107     def test_header_unicode_filename(self):
       
   108         with self.admin_access.web_request() as req:
       
   109             self.create_user(req, login=u'cécilia', password='babar')
       
   110             req.cnx.commit()
       
   111         with self.new_access(u'cécilia').web_request() as req:
       
   112             req.form['vid'] = 'download'
       
   113             req.form['eid'] = str(req.user.eid)
       
   114             self.ctrl_publish(req,'view')
       
   115             get = req.headers_out.getRawHeaders
       
   116             self.assertEqual(['''attachment;filename="ccilia.txt";filename*=utf-8''c%C3%A9cilia.txt'''],
       
   117                              get('content-disposition'))
       
   118 
       
   119     def test_header_unicode_long_filename(self):
       
   120         name = u'Bèrte_hô_grand_nôm_ça_va_totallement_déborder_de_la_limite_là'
       
   121         with self.admin_access.web_request() as req:
       
   122             self.create_user(req, login=name, password='babar')
       
   123             req.cnx.commit()
       
   124         with self.new_access(name).web_request() as req:
       
   125             req.form['vid'] = 'download'
       
   126             req.form['eid'] = str(req.user.eid)
       
   127             self.ctrl_publish(req,'view')
       
   128             get = req.headers_out.getRawHeaders
       
   129             self.assertEqual(["""attachment;filename="Brte_h_grand_nm_a_va_totallement_dborder_de_la_limite_l.txt";filename*=utf-8''B%C3%A8rte_h%C3%B4_grand_n%C3%B4m_%C3%A7a_va_totallement_d%C3%A9border_de_la_limite_l%C3%A0.txt"""],
       
   130                              get('content-disposition'))
       
   131 
       
   132 
       
   133     def test_download_data_error(self):
       
   134         self.vreg.register(BrokenIDownloadableGroup)
       
   135         self.addCleanup(partial(self.vreg.unregister, BrokenIDownloadableGroup))
       
   136         with self.admin_access.web_request() as req:
       
   137             req.form['vid'] = 'download'
       
   138             req.form['eid'] = str(req.execute('CWGroup X WHERE X name "managers"')[0][0])
       
   139             with real_error_handling(self.app):
       
   140                 data = self.app_handle_request(req)
       
   141             get = req.headers_out.getRawHeaders
       
   142             self.assertEqual(['text/html;charset=UTF-8'],
       
   143                              get('content-type'))
       
   144             self.assertEqual(None,
       
   145                              get('content-disposition'))
       
   146             self.assertEqual(req.status_out, 500)
       
   147 
       
   148 if __name__ == '__main__':
       
   149     unittest_main()