示例#1
0
def test_roles_edit_unauthorized(app, viewer_client, non_exist_role_name, exist_role_name, exist_role):
    resp = viewer_client.post(
        f"roles/edit/{exist_role.id}", data={'name': non_exist_role_name}, follow_redirects=True
    )
    check_content_in_response('Access is Denied', resp)
    assert app.appbuilder.sm.find_role(exist_role_name)
    assert app.appbuilder.sm.find_role(non_exist_role_name) is None
示例#2
0
def test_get_logs_with_metadata_success(request, client):
    resp = request.getfixturevalue(client).get(
        GET_LOGS_WITH_METADATA_URL,
        follow_redirects=True,
    )
    check_content_in_response('"message":', resp)
    check_content_in_response('"metadata":', resp)
def test_trigger_dag_params_conf(admin_client, request_conf, expected_conf):
    """
    Test that textarea in Trigger DAG UI is pre-populated
    with json config when the conf URL parameter is passed,
    or if a params dict is passed in the DAG

        1. Conf is not included in URL parameters -> DAG.conf is in textarea
        2. Conf is passed as a URL parameter -> passed conf json is in textarea
    """
    test_dag_id = "example_bash_operator"
    doc_md = "Example Bash Operator"

    if not request_conf:
        resp = admin_client.get(f'trigger?dag_id={test_dag_id}')
    else:
        test_request_conf = json.dumps(request_conf, indent=4)
        resp = admin_client.get(
            f'trigger?dag_id={test_dag_id}&conf={test_request_conf}&doc_md={doc_md}'
        )

    expected_dag_conf = json.dumps(expected_conf,
                                   indent=4).replace("\"", """)

    check_content_in_response(
        f'<textarea class="form-control" name="conf" id="json">{expected_dag_conf}</textarea>',
        resp,
    )
示例#4
0
def test_code_from_db(admin_client):
    dag = DagBag(include_examples=True).get_dag("example_bash_operator")
    DagCode(dag.fileloc, DagCode._get_code_from_file(dag.fileloc)).sync_to_db()
    url = 'code?dag_id=example_bash_operator'
    resp = admin_client.get(url)
    check_content_not_in_response('Failed to load file', resp)
    check_content_in_response('example_bash_operator', resp)
示例#5
0
def test_odd_name(session, admin_client, pool):
    pool['pool'] = 'test-pool<script></script>'
    session.add(Pool(**pool))
    session.commit()
    resp = admin_client.get('/pool/list/')
    check_content_in_response('test-pool&lt;script&gt;', resp)
    check_content_not_in_response('test-pool<script>', resp)
示例#6
0
def test_run_with_not_runnable_states(_, admin_client, session, state):
    assert state not in RUNNABLE_STATES

    task_id = 'runme_0'
    session.query(TaskInstance).filter(TaskInstance.task_id == task_id).update(
        {
            'state': state,
            'end_date': timezone.utcnow()
        })
    session.commit()

    form = dict(
        task_id=task_id,
        dag_id="example_bash_operator",
        ignore_all_deps="false",
        ignore_ti_state="false",
        execution_date=DEFAULT_DATE,
        origin='/home',
    )
    resp = admin_client.post('run', data=form, follow_redirects=True)
    check_content_in_response('', resp)

    msg = (
        f"Task is in the &#39;{state}&#39; state which is not a valid state for "
        f"execution. The task must be cleared in order to be run")
    assert re.search(msg, resp.get_data(as_text=True))
示例#7
0
def test_page_instance_name_xss_prevention(admin_client):
    xss_string = "<script>alert('Give me your credit card number')</script>"
    with conf_vars({('webserver', 'instance_name'): xss_string}):
        resp = admin_client.get('home', follow_redirects=True)
        escaped_xss_string = "&lt;script&gt;alert(&#39;Give me your credit card number&#39;)&lt;/script&gt;"
        check_content_in_response(escaped_xss_string, resp)
        check_content_not_in_response(xss_string, resp)
示例#8
0
def test_delete_user(app, admin_client, exist_username):
    user = app.appbuilder.sm.find_user(exist_username)
    resp = admin_client.post(
        f"users/delete/{user.id}",
        follow_redirects=True,
    )
    check_content_in_response("Deleted Row", resp)
示例#9
0
def test_edit_myuserinfo(admin_client):
    resp = admin_client.post(
        "userinfoeditview/form",
        data={'first_name': 'new_first_name', 'last_name': 'new_last_name'},
        follow_redirects=True,
    )
    check_content_in_response("User information changed", resp)
示例#10
0
def test_dag_autocomplete_success(client_all_dags):
    resp = client_all_dags.get(
        'dagmodel/autocomplete?query=example_bash',
        follow_redirects=False,
    )
    check_content_in_response('example_bash_operator', resp)
    check_content_not_in_response('example_subdag_operator', resp)
示例#11
0
def test_configuration_expose_config(admin_client):
    # make sure config is initialized (without unit test mote)
    initialize_config()
    with conf_vars({('webserver', 'expose_config'): 'True'}):
        resp = admin_client.get('configuration', follow_redirects=True)
    check_content_in_response(
        ['Airflow Configuration', 'Running Configuration'], resp)
示例#12
0
def test_redoc_should_render_template(capture_templates, admin_client):
    with capture_templates() as templates:
        resp = admin_client.get('redoc')
        check_content_in_response('Redoc', resp)

    assert len(templates) == 1
    assert templates[0].name == 'airflow/redoc.html'
    assert templates[0].local_context == {'openapi_spec_url': '/api/v1/openapi.yaml'}
示例#13
0
def test_create_pool_with_same_name(admin_client, pool):
    # create test pool
    resp = admin_client.post('/pool/add', data=pool, follow_redirects=True)
    check_content_in_response('Added Row', resp)

    # create pool with the same name
    resp = admin_client.post('/pool/add', data=pool, follow_redirects=True)
    check_content_in_response('Already exists.', resp)
def test_trigger_endpoint_uses_existing_dagbag(admin_client):
    """
    Test that Trigger Endpoint uses the DagBag already created in views.py
    instead of creating a new one.
    """
    url = 'trigger?dag_id=example_bash_operator'
    resp = admin_client.post(url, data={}, follow_redirects=True)
    check_content_in_response('example_bash_operator', resp)
示例#15
0
def test_edit_user(app, admin_client, exist_username):
    user = app.appbuilder.sm.find_user(exist_username)
    resp = admin_client.post(
        f"users/edit/{user.id}",
        data={"first_name": "new_first_name"},
        follow_redirects=True,
    )
    check_content_in_response("new_first_name", resp)
示例#16
0
def test_create_pool_with_empty_name(admin_client):
    resp = admin_client.post(
        '/pool/add',
        data={
            **POOL, "pool": ""
        },
        follow_redirects=True,
    )
    check_content_in_response('This field is required.', resp)
示例#17
0
def test_calendar(admin_client, dagruns):
    url = 'calendar?dag_id=example_bash_operator'
    resp = admin_client.get(url, follow_redirects=True)

    bash_dagrun, _, _ = dagruns

    datestr = bash_dagrun.execution_date.date().isoformat()
    expected = rf'{{\"date\":\"{datestr}\",\"state\":\"running\",\"count\":1}}'
    check_content_in_response(expected, resp)
示例#18
0
def test_delete_dag_button_for_dag_on_scheduler_only(
        admin_client, new_id_example_bash_operator):
    # Test for JIRA AIRFLOW-3233 (PR 4069):
    # The delete-dag URL should be generated correctly for DAGs
    # that exist on the scheduler (DB) but not the webserver DagBag
    test_dag_id = new_id_example_bash_operator
    resp = admin_client.get('/', follow_redirects=True)
    check_content_in_response(f'/delete?dag_id={test_dag_id}', resp)
    check_content_in_response(
        f"return confirmDeleteDag(this, '{test_dag_id}')", resp)
示例#19
0
def test_import_variables_success(session, admin_client):
    assert session.query(Variable).count() == 0

    content = '{"str_key": "str_value", "int_key": 60, "list_key": [1, 2], "dict_key": {"k_a": 2, "k_b": 3}}'
    bytes_content = io.BytesIO(bytes(content, encoding='utf-8'))

    resp = admin_client.post('/variable/varimport',
                             data={'file': (bytes_content, 'test.json')},
                             follow_redirects=True)
    check_content_in_response('4 variable(s) successfully updated.', resp)
示例#20
0
def test_set_dag_runs_action_fails(admin_client, action, expected_message):
    resp = admin_client.post(
        "/dagrun/action_post",
        data={
            "action": action,
            "rowid": ["0"]
        },
        follow_redirects=True,
    )
    check_content_in_response(expected_message, resp)
示例#21
0
def test_doc_urls(admin_client):
    resp = admin_client.get('/', follow_redirects=True)
    if "dev" in version.version:
        airflow_doc_site = (
            "http://apache-airflow-docs.s3-website.eu-central-1.amazonaws.com/docs/apache-airflow/"
        )
    else:
        airflow_doc_site = f'https://airflow.apache.org/docs/apache-airflow/{version.version}'

    check_content_in_response(airflow_doc_site, resp)
    check_content_in_response("/api/v1/ui", resp)
def test_trigger_dag_form_origin_url(admin_client, test_origin,
                                     expected_origin):
    test_dag_id = "example_bash_operator"

    resp = admin_client.get(
        f'trigger?dag_id={test_dag_id}&origin={test_origin}')
    check_content_in_response(
        '<button type="button" class="btn" onclick="location.href = \'{}\'; return false">'
        .format(expected_origin),
        resp,
    )
示例#23
0
def test_code_no_file(admin_client):
    url = 'code?dag_id=example_bash_operator'
    mock_open_patch = unittest.mock.mock_open(read_data='')
    mock_open_patch.side_effect = FileNotFoundError
    with unittest.mock.patch('builtins.open',
                             mock_open_patch), unittest.mock.patch(
                                 "airflow.models.dagcode.STORE_DAG_CODE",
                                 False):
        resp = admin_client.get(url, follow_redirects=True)
        check_content_in_response('Failed to load file', resp)
        check_content_in_response('example_bash_operator', resp)
def test_trigger_dag_conf_malformed(admin_client):
    test_dag_id = "example_bash_operator"

    response = admin_client.post(f'trigger?dag_id={test_dag_id}',
                                 data={'conf': '{"a": "b"'})
    check_content_in_response('Invalid JSON configuration', response)

    with create_session() as session:
        run = session.query(DagRun).filter(
            DagRun.dag_id == test_dag_id).first()
    assert run is None
示例#25
0
def test_configuration_do_not_expose_config(admin_client):
    with conf_vars({('webserver', 'expose_config'): 'False'}):
        resp = admin_client.get('configuration', follow_redirects=True)
    check_content_in_response(
        [
            'Airflow Configuration',
            '# Your Airflow administrator chose not to expose the configuration, '
            'most likely for security reasons.',
        ],
        resp,
    )
示例#26
0
def test_task_instance_set_state_failure(admin_client, action):
    rowid = '["12345"]'  # F.A.B. crashes if the rowid is *too* invalid.
    resp = admin_client.post(
        "/taskinstance/action_post",
        data={
            "action": action,
            "rowid": rowid
        },
        follow_redirects=True,
    )
    assert resp.status_code == 200
    check_content_in_response("Failed to set state", resp)
示例#27
0
def test_escape_in_tree_view(app, admin_client, test_str, expected_text):
    app.dag_bag.get_dag('test_tree_view').create_dagrun(
        execution_date=DEFAULT_DATE,
        start_date=timezone.utcnow(),
        run_type=DagRunType.MANUAL,
        state=State.RUNNING,
        conf={"abc": test_str},
    )

    url = 'tree?dag_id=test_tree_view'
    resp = admin_client.get(url, follow_redirects=True)
    check_content_in_response(expected_text, resp)
示例#28
0
def test_failed_success(client_all_dags_edit_tis):
    form = dict(
        task_id="run_this_last",
        dag_id="example_bash_operator",
        execution_date=DEFAULT_DATE,
        upstream="false",
        downstream="false",
        future="false",
        past="false",
    )
    resp = client_all_dags_edit_tis.post('failed', data=form)
    check_content_in_response('example_bash_operator', resp)
示例#29
0
def test_import_variables_failed(session, admin_client):
    content = '{"str_key": "str_value"}'

    with mock.patch('airflow.models.Variable.set') as set_mock:
        set_mock.side_effect = UnicodeEncodeError
        assert session.query(Variable).count() == 0

        bytes_content = io.BytesIO(bytes(content, encoding='utf-8'))

        resp = admin_client.post('/variable/varimport',
                                 data={'file': (bytes_content, 'test.json')},
                                 follow_redirects=True)
        check_content_in_response('1 variable(s) failed to be updated.', resp)
示例#30
0
def test_pool_muldelete_default(session, admin_client, pool_factory):
    pool = pool_factory(pool="default_pool")

    resp = admin_client.post(
        "/pool/action_post",
        data={
            "action": "muldelete",
            "rowid": [pool.id]
        },
        follow_redirects=True,
    )
    check_content_in_response("default_pool cannot be deleted", resp)
    assert session.query(Pool).filter(Pool.id == pool.id).count() == 1