blob: 3fbe8d6309cb83adc8edb6f97e24e86679318949 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import annotations
from unittest import mock
import pytest
from pendulum import DateTime
from pendulum.tz.timezone import Timezone
from airflow.api_connexion.exceptions import BadRequest
from airflow.api_connexion.parameters import (
check_limit,
format_datetime,
format_parameters,
validate_istimezone,
)
from airflow.utils import timezone
from tests.test_utils.config import conf_vars
class TestValidateIsTimezone:
def setup_method(self) -> None:
from datetime import datetime
self.naive = datetime.now()
self.timezoned = datetime.now(tz=timezone.utc)
def test_gives_400_for_naive(self):
with pytest.raises(BadRequest):
validate_istimezone(self.naive)
def test_timezone_passes(self):
assert validate_istimezone(self.timezoned) is None
class TestDateTimeParser:
def setup_method(self) -> None:
self.default_time = "2020-06-13T22:44:00+00:00"
self.default_time_2 = "2020-06-13T22:44:00Z"
def test_works_with_datestring_ending_00_00(self):
datetime = format_datetime(self.default_time)
datetime2 = timezone.parse(self.default_time)
assert datetime == datetime2
assert datetime.isoformat() == self.default_time
def test_works_with_datestring_ending_with_zed(self):
datetime = format_datetime(self.default_time_2)
datetime2 = timezone.parse(self.default_time_2)
assert datetime == datetime2
assert datetime.isoformat() == self.default_time # python uses +00:00 instead of Z
def test_raises_400_for_invalid_arg(self):
invalid_datetime = "2020-06-13T22:44:00P"
with pytest.raises(BadRequest):
format_datetime(invalid_datetime)
class TestMaximumPagelimit:
@conf_vars({("api", "maximum_page_limit"): "320"})
def test_maximum_limit_return_val(self):
limit = check_limit(300)
assert limit == 300
@conf_vars({("api", "maximum_page_limit"): "320"})
def test_maximum_limit_returns_configured_if_limit_above_conf(self):
limit = check_limit(350)
assert limit == 320
@conf_vars({("api", "maximum_page_limit"): "1000"})
def test_limit_returns_set_max_if_give_limit_is_exceeded(self):
limit = check_limit(1500)
assert limit == 1000
@conf_vars({("api", "fallback_page_limit"): "100"})
def test_limit_of_zero_returns_default(self):
limit = check_limit(0)
assert limit == 100
@conf_vars({("api", "maximum_page_limit"): "1500"})
def test_negative_limit_raises(self):
with pytest.raises(BadRequest):
check_limit(-1)
class TestFormatParameters:
def test_should_works_with_datetime_formatter(self):
decorator = format_parameters({"param_a": format_datetime})
endpoint = mock.MagicMock()
decorated_endpoint = decorator(endpoint)
decorated_endpoint(param_a="2020-01-01T0:0:00+00:00")
endpoint.assert_called_once_with(param_a=DateTime(2020, 1, 1, 0, tzinfo=Timezone("UTC")))
def test_should_propagate_exceptions(self):
decorator = format_parameters({"param_a": format_datetime})
endpoint = mock.MagicMock()
decorated_endpoint = decorator(endpoint)
with pytest.raises(BadRequest):
decorated_endpoint(param_a="XXXXX")
@conf_vars({("api", "maximum_page_limit"): "100"})
def test_should_work_with_limit(self):
decorator = format_parameters({"limit": check_limit})
endpoint = mock.MagicMock()
decorated_endpoint = decorator(endpoint)
decorated_endpoint(limit=89)
endpoint.assert_called_once_with(limit=89)