How to use a test tornado server handler that authenticates a user via a secure cookie

后端 未结 3 1958
孤街浪徒
孤街浪徒 2021-02-04 15:40

How can I write a unit test for a tornado handler that authenticates a user via a secure cookie? Here is the code (and sudo code) for a dummy test that I\'d like to make pass. I

3条回答
  •  北海茫月
    2021-02-04 16:14

    If you want to import excel through tornado REST API or want to do Unit Test the handler this may be helpful to you.It's working perfectly form my application. Here I am passing excel through form-data header in REST.

    If want to write test cases for other Rest API's using cookies then it may be helpful.

    import json
    import os.path
    import requests
    import sys
    import time
    import tornado.testing
    import tornado.web
    import unittest
    import unittest.mock as mock
    from http import cookies
    from tornado.options import define, options, parse_command_line
    
    from portal.handlers import ListHandler,excelimportHandler   # handlers created in tornado
    
    APP_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))  # root location where your file is existing
    sys.path.append(os.path.join(APP_ROOT, '..'))  # joining file with root path
    
    from portal.library.helpers import get_env_conf, read_env_conf  # functionality to get and resd the the environment config file.
    os.environ["ASYNC_TEST_TIMEOUT"] = str(60)  # It will wait for the API for response
    
    LIST = '/data/list'
    IMPORT_EXCEL = '/import/excel'
    
    class ProxyServerAPITest(tornado.testing.AsyncHTTPTestCase):
        def __init__(self, *rest):
            self.cookie = cookies.SimpleCookie()
            define("env", default="localtest", help="Environment")
            define("env_conf_path", default="", help="Environment config file path")
            parse_command_line()
            '''
            reading the env config file for unit test cases
            '''
            if options.env_conf_path:
                env_conf_path = options.env_conf_path
                env_conf = read_env_conf(env_conf_path)
            else:
                env_conf = get_env_conf(options.env)
            self.api_engine_address = env_conf.get("api_engine_address")
            self.api_token = env_conf.get("api_token")
            self.api_username = env_conf.get("api_username")
            self.elasticsearch_index = env_conf.get("elasticsearch_index")
    
            tornado.testing.AsyncHTTPTestCase.__init__(self, *rest)
    
        def get_app(self):
    
            env = mock.MagicMock(return_value='xyz') # mocking config file
    
            def get(key):
                """
                whenever in handlers, if these parameters will be called from there config files
                it will take the parameters
                of config file of unit test cases.
                """
                if key == "api_username":
                    return self.api_username
                elif key == "api_engine_address":
                    return self.api_engine_address
                elif key == 'api_token':
                    return self.api_token
                elif key == 'elasticsearch_index':
                    return self.elasticsearch_index
            env.get = get
            application = tornado.web.Application(
                [
                 (LIST, ListHandler, dict(env_conf=env)),
                 (IMPORT_EXCEL, excelimportHandler, dict(env_conf=env)),
                 ],
                cookie_secret="cookie-secret")
            return application
    
        def _update_cookies(self, headers):
            """
            It will take the cookies that will be passed in whole application.
            """
            try:
                sc = headers['Set-Cookie']
                tempcookies = tornado.escape.native_str(sc)
                tempcookies_dict = tempcookies.split('/,')
                self.cookie.update(
                    cookies.SimpleCookie(tempcookies_dict[0].split(';')[0] + ';' + tempcookies_dict[1].split(';')[0] + ';' +
                                         tempcookies_dict[2].split(';')[0]))
            except KeyError:
                return
    
        def fetch(self, url, new_headers=None, *r, **kw):
            """
            This function will set the headers and cookies for the Tornado application
            """
            if 'follow_redirects' not in kw:
                kw['follow_redirects'] = False
    
            header = {}
            hs = self.cookie.output()
            header['Cookie'] = hs
            if hs != '':
                hs = hs.split('\r\n')
                hs = hs[0].split('-Cookie:')[1] + ";" + hs[1].split('-Cookie:')[1] + ";" + hs[2].split('-Cookie:')[1]
                header['Cookie'] = hs
            if new_headers:
                """
                These headers will be used if we wiil deal with excel file.
                """
                header.update(new_headers)
    
            resp = tornado.testing.AsyncHTTPTestCase.fetch(self, url, headers=header, *r, **kw)
            self._update_cookies(resp.headers)
            return resp
        def find_body_headers_of_excel(self, file_name):
            """
            This function will provide the encrypted form of the excel in body and proper headers
            that to be passed in API to import the excel using REST.
            """
            fpath = os.path.join(os.path.dirname(__file__), file_name)
            f = open(fpath, 'rb')
            files = {"file": f}
            data = {}
    
            a = requests.Request(method='POST', url="http://abc/img/test",
                                 files=files, data=data)
            prepare = a.prepare()
            content_type = prepare.headers.get('Content-Type')
            body = prepare.body
    
            headers = {
                "Content-Type": content_type,
            }
            return headers, body
        def test_proxy_api(self):
    
            headers, body = self.find_body_headers_of_excel('excel.xlsx')
            resp = self.fetch(IMPORT_EXCEL, method='POST', body=body, connect_timeout=1000, request_timeout=1000,
                              new_headers=headers)
            self.assertEqual(200, resp.code)
            resp = self.fetch(LIST, method='GET', connect_timeout=1000, request_timeout=1000)
            self.assertEqual(200, resp.code)
    
    if __name__ == '__main__':
        unittest.main()
    
    

提交回复
热议问题