diff --git a/docs/configuration/hosting-docs.rst b/docs/configuration/hosting-docs.rst index c823ef048..698af510a 100644 --- a/docs/configuration/hosting-docs.rst +++ b/docs/configuration/hosting-docs.rst @@ -104,3 +104,8 @@ For example, if your dbt project directory is ``/usr/local/airflow/dags/my_dbt_p .. code-block:: shell AIRFLOW__COSMOS__DBT_DOCS_DIR="/usr/local/airflow/dags/my_dbt_project/target" + +Using docs out of local storage has the downside that some values in the dbt docs can become stale unless the docs are periodically refreshed and redeployed: + +- Counts of the numbers of rows. +- The compiled SQL for incremental models before and after the first run. diff --git a/tests/plugin/test_plugin.py b/tests/plugin/test_plugin.py index ec4b35736..6c8f0e671 100644 --- a/tests/plugin/test_plugin.py +++ b/tests/plugin/test_plugin.py @@ -6,71 +6,61 @@ from airflow.utils.db import initdb, resetdb from airflow.www.app import cached_app from airflow.www.extensions.init_appbuilder import AirflowAppBuilder +from airflow.www.security import AirflowSecurityManager from flask.testing import FlaskClient from cosmos.plugin import dbt_docs_view @pytest.fixture(scope="module") -@patch("airflow.www.auth.managers.fab.fab_auth_manager.FabAuthManager.get_user") -def app(mock_user) -> FlaskClient: +def app(monkey) -> FlaskClient: initdb() app = cached_app(testing=True) + app.config["AUTH_ROLE_PUBLIC"] = "pytest_role" appbuilder: AirflowAppBuilder = app.extensions["appbuilder"] + appbuilder.sm.check_authorization = lambda *args, **kwargs: True + if dbt_docs_view not in appbuilder.baseviews: appbuilder._check_and_init(dbt_docs_view) appbuilder.register_blueprint(dbt_docs_view) - if not appbuilder.sm.find_role("pytest_role"): - appbuilder.sm.add_role("pytest_role", permissions=[(permissions.ACTION_CAN_READ, )]) - - if not appbuilder.sm.find_user("pytest_user"): - mock_user.return_value = appbuilder.sm.add_user( - username="pytest_user", - first_name="J.", - last_name="Doe", - email="jdoe@example.org", - role="pytest_role", - password="pw", - ) - yield app.test_client() resetdb(skip_init=True) -@patch("cosmos.plugin.conf") +@patch("cosmos.plugin.conf.get") @patch("cosmos.plugin.open_file") def test_dbt_docs(mock_open_file, mock_conf, app): - mock_conf.get.return_value = "some_value" + mock_conf.return_value = "some_value" response = app.get("/cosmos/dbt_docs") assert mock_open_file.assert_called_once() assert response.status_code == 200 -@patch("cosmos.plugin.conf") +@patch("cosmos.plugin.conf.get") def test_dbt_docs_not_set_up(mock_conf, app): - mock_conf.get.side_effect = AirflowConfigException + mock_conf.side_effect = AirflowConfigException response = app.get("/cosmos/dbt_docs") assert response.status_code == 500 -@patch("cosmos.plugin.conf") +@patch("cosmos.plugin.conf.get") @patch("cosmos.plugin.open_file") @pytest.mark.parametrize("artifact", ["dbt_docs_index.html", "manifest.json", "catalog.json"]) def test_dbt_docs_artifact(mock_open_file, mock_conf, app, artifact): - mock_conf.get.return_value = "some_value" + mock_conf.return_value = "some_value" response = app.get(f"/cosmos/{artifact}") assert mock_open_file.assert_called_once() assert response.status_code == 200 -@patch("cosmos.plugin.conf") +@patch("cosmos.plugin.conf.get") @patch("cosmos.plugin.open_file") @pytest.mark.parametrize("artifact", ["dbt_docs_index.html", "manifest.json", "catalog.json"]) def test_dbt_docs_artifact_missing(mock_open_file, mock_conf, app, artifact): - mock_conf.get.side_effect = AirflowConfigException + mock_conf.side_effect = AirflowConfigException response = app.get(f"/cosmos/{artifact}") assert response.status_code == 404