Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 14 additions & 35 deletions airflow-core/tests/unit/api_fastapi/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from __future__ import annotations

import datetime
import json
import os
from typing import TYPE_CHECKING
from unittest import mock
Expand All @@ -30,12 +31,10 @@
from airflow.api_fastapi.app import create_app
from airflow.api_fastapi.auth.managers.simple.user import SimpleAuthManagerUser
from airflow.dag_processing.bundles.manager import DagBundlesManager
from airflow.models import Connection
from airflow.providers.git.bundles.git import GitDagBundle
from airflow.providers.standard.operators.empty import EmptyOperator

from tests_common.test_utils.config import conf_vars
from tests_common.test_utils.db import clear_db_connections, parse_and_sync_to_db
from tests_common.test_utils.db import parse_and_sync_to_db

if TYPE_CHECKING:
from airflow.api_fastapi.auth.managers.simple.simple_auth_manager import SimpleAuthManager
Expand Down Expand Up @@ -197,43 +196,23 @@ def create_test_client(apps="all"):


@pytest.fixture
def configure_git_connection_for_dag_bundle(session):
clear_db_connections(False)
# Git connection is required for the bundles to have a url.
connection = Connection(
conn_id="git_default",
conn_type="git",
description="default git connection",
host="http://test_host.github.com",
port=8081,
login="",
)
session.add(connection)
with (
conf_vars(
{
(
"dag_processor",
"dag_bundle_config_list",
): '[{ "name": "dag_maker", "classpath": "airflow.providers.git.bundles.git.GitDagBundle", "kwargs": {"subdir": "dags", "tracking_ref": "main", "refresh_interval": 0}}, { "name": "another_bundle_name", "classpath": "airflow.providers.git.bundles.git.GitDagBundle", "kwargs": {"subdir": "dags", "tracking_ref": "main", "refresh_interval": 0}}]'
}
),
mock.patch("airflow.providers.git.bundles.git.GitHook") as mock_git_hook,
mock.patch.object(GitDagBundle, "get_current_version") as mock_get_current_version,
):
mock_get_current_version.return_value = "some_commit_hash"
mock_git_hook.return_value.repo_url = connection.host
def configure_dag_bundles_with_view_url():
# Rendering a per-version link only needs the URL template a remote bundle would supply.
bundle_config = [
{
"name": name,
"classpath": "airflow.dag_processing.bundles.local.LocalDagBundle",
"kwargs": {"view_url_template": "http://test_host.github.com/tree/{version}/dags"},
}
for name in ("dag_maker", "another_bundle_name")
]
with conf_vars({("dag_processor", "dag_bundle_config_list"): json.dumps(bundle_config)}):
DagBundlesManager().sync_bundles_to_db()
yield
# in case no flush or commit was executed after the "session.add" above, we need to flush the session
# manually here to make sure that the added connection will be deleted by query(Connection).delete()
# in the`clear_db_connections` function below
session.flush()
clear_db_connections(False)


@pytest.fixture
def make_dag_with_multiple_versions(dag_maker, configure_git_connection_for_dag_bundle, session):
def make_dag_with_multiple_versions(dag_maker, configure_dag_bundles_with_view_url, session):
"""
Create DAG with multiple versions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2262,7 +2262,7 @@ def create_dags(self, setup, dag_maker, session):
EmptyOperator(task_id="task")
session.commit()

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
@mock.patch(
"airflow.api_fastapi.auth.managers.simple.user.SimpleAuthManagerUser.get_display_name",
return_value="Jane Doe",
Expand All @@ -2272,7 +2272,7 @@ def test_materialize_records_triggering_user_display_name(self, mock_display_nam
assert response.status_code == 200
assert response.json()["triggering_user_name"] == "Jane Doe"

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
def test_should_respond_200(self, test_client):
response = test_client.post("/assets/1/materialize")
assert response.status_code == 200
Expand Down Expand Up @@ -2302,14 +2302,14 @@ def test_should_respond_200(self, test_client):
"team_name": None,
}

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
def test_should_respond_200_with_partition_key(self, test_client):
partition_key = "2026-03-23"
response = test_client.post("/assets/1/materialize", json={"partition_key": partition_key})
assert response.status_code == 200
assert response.json()["partition_key"] == partition_key

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
def test_should_respond_200_with_trigger_fields(self, test_client):
payload = {
"conf": {"foo": "bar"},
Expand All @@ -2332,7 +2332,7 @@ def test_should_respond_200_with_trigger_fields(self, test_client):
assert response.json()["partition_key"] == "2026-03-23"
assert response.json()["run_type"] == "asset_materialization"

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
def test_should_respond_200_with_trigger_fields_without_dag_run_id(self, test_client):
payload = {
"conf": {"foo": "bar"},
Expand Down Expand Up @@ -2429,7 +2429,7 @@ def test_materialize_allowed_run_types_from_requested_version(self, test_client,
== f"Dag with dag_id: '{self.DAG_ASSET1_ID}' does not allow asset materialization runs"
)

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
def test_should_respond_403_when_user_cannot_trigger_dag(self, test_client):
with mock.patch(
"airflow.api_fastapi.core_api.routes.public.assets.get_auth_manager",
Expand Down Expand Up @@ -2501,7 +2501,7 @@ def test_should_respond_with_bundle_version(self, test_client, session, dag_make
in response.json()["detail"]
)

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
def test_should_respond_400_on_invalid_dag_run_id(self, test_client):
"""A dag_run_id containing '..' triggers ValueError in DagRun.validate_run_id.

Expand All @@ -2514,7 +2514,7 @@ def test_should_respond_400_on_invalid_dag_run_id(self, test_client):
assert response.status_code == 400
assert "must not contain '..'" in response.json()["detail"]

@pytest.mark.usefixtures("configure_git_connection_for_dag_bundle")
@pytest.mark.usefixtures("configure_dag_bundles_with_view_url")
def test_should_respond_200_with_partition_date_for_partitioned_dag(
self, test_client, dag_maker, session
):
Expand Down
Loading