pytest_plugin.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # Copyright (c) Jupyter Development Team.
  2. # Distributed under the terms of the Modified BSD License.
  3. import urllib.parse
  4. import pytest
  5. from jupyter_server.utils import url_path_join
  6. from jupyterlab_server import LabConfig
  7. from tornado.escape import url_escape
  8. from traitlets import Unicode
  9. from jupyterlab.labapp import LabApp
  10. def mkdir(tmp_path, *parts):
  11. path = tmp_path.joinpath(*parts)
  12. if not path.exists():
  13. path.mkdir(parents=True)
  14. return path
  15. app_settings_dir = pytest.fixture(lambda tmp_path: mkdir(tmp_path, "app_settings"))
  16. user_settings_dir = pytest.fixture(lambda tmp_path: mkdir(tmp_path, "user_settings"))
  17. schemas_dir = pytest.fixture(lambda tmp_path: mkdir(tmp_path, "schemas"))
  18. workspaces_dir = pytest.fixture(lambda tmp_path: mkdir(tmp_path, "workspaces"))
  19. @pytest.fixture
  20. def make_lab_app(
  21. jp_root_dir, jp_template_dir, app_settings_dir, user_settings_dir, schemas_dir, workspaces_dir
  22. ):
  23. def _make_lab_app(**kwargs):
  24. class TestLabApp(LabApp):
  25. base_url = "/lab"
  26. extension_url = "/lab"
  27. default_url = Unicode("/", help="The default URL to redirect to from `/`")
  28. lab_config = LabConfig(
  29. app_name="JupyterLab Test App",
  30. static_dir=str(jp_root_dir),
  31. templates_dir=str(jp_template_dir),
  32. app_url="/lab",
  33. app_settings_dir=str(app_settings_dir),
  34. user_settings_dir=str(user_settings_dir),
  35. schemas_dir=str(schemas_dir),
  36. workspaces_dir=str(workspaces_dir),
  37. )
  38. app = TestLabApp()
  39. return app
  40. # Create the index files.
  41. index = jp_template_dir.joinpath("index.html")
  42. index.write_text(
  43. """
  44. <!DOCTYPE html>
  45. <html>
  46. <head>
  47. <title>{{page_config['appName'] | e}}</title>
  48. </head>
  49. <body>
  50. {# Copy so we do not modify the page_config with updates. #}
  51. {% set page_config_full = page_config.copy() %}
  52. {# Set a dummy variable - we just want the side effect of the update. #}
  53. {% set _ = page_config_full.update(baseUrl=base_url, wsUrl=ws_url) %}
  54. <script id="jupyter-config-data" type="application/json">
  55. {{ page_config_full | tojson }}
  56. </script>
  57. <script src="{{page_config['fullStaticUrl'] | e}}/bundle.js" main="index"></script>
  58. <script type="text/javascript">
  59. /* Remove token from URL. */
  60. (function () {
  61. var parsedUrl = new URL(window.location.href);
  62. if (parsedUrl.searchParams.get('token')) {
  63. parsedUrl.searchParams.delete('token');
  64. window.history.replaceState({ }, '', parsedUrl.href);
  65. }
  66. })();
  67. </script>
  68. </body>
  69. </html>
  70. """
  71. )
  72. return _make_lab_app
  73. @pytest.fixture
  74. def labapp(jp_serverapp, make_lab_app):
  75. app = make_lab_app()
  76. app._link_jupyter_server_extension(jp_serverapp)
  77. app.initialize()
  78. return app
  79. @pytest.fixture
  80. def fetch_long(http_server_client, jp_auth_header, jp_base_url):
  81. """fetch fixture that handles auth, base_url, and path"""
  82. def client_fetch(*parts, headers=None, params=None, **kwargs):
  83. # Handle URL strings
  84. path_url = url_escape(url_path_join(*parts), plus=False)
  85. path_url = url_path_join(jp_base_url, path_url)
  86. params_url = urllib.parse.urlencode(params or {})
  87. url = path_url + "?" + params_url
  88. # Add auth keys to header
  89. headers = headers or {}
  90. headers.update(jp_auth_header)
  91. # Make request.
  92. return http_server_client.fetch(url, headers=headers, request_timeout=250, **kwargs)
  93. return client_fetch