fixed test case

pull/1398/head
Chris Caron 2025-08-23 12:11:35 -04:00
parent 96ee18298b
commit 7ad812694e
3 changed files with 86 additions and 22 deletions

View File

@ -898,19 +898,15 @@ class ConfigBase(URLBase):
# Acquire our asset tokens
tokens = result.get("asset", None)
if tokens and isinstance(tokens, dict):
# Prepare our default timezone (if specified)
timezone = str(tokens.get("timezone", tokens.get("tz", "")))
raw_tz = tokens.get("timezone", tokens.get("tz"))
timezone = raw_tz.strip() if isinstance(raw_tz, str) else ""
if timezone:
default_timezone = zoneinfo(re.sub(r"[^\w/-]+", "", timezone))
if not default_timezone:
ConfigBase.logger.warning(
'Ignored invalid timezone "%s"', timezone)
# Restore our timezone back to what was found in the
# asset object
'Ignored invalid timezone "%s"', raw_tz)
default_timezone = asset.tzinfo
else:
# Set our newly specified timezone
asset._tzinfo = default_timezone
# Iterate over remaining tokens

View File

@ -31,7 +31,6 @@ from datetime import tzinfo
from functools import partial
import re
from typing import Any, ClassVar, Optional, TypedDict, Union
from zoneinfo import ZoneInfo
from ..apprise_attachment import AppriseAttachment
from ..common import (
@ -298,7 +297,6 @@ class NotifyBase(URLBase):
# automatically initialized by specifying ?tz= on the Apprise URLs
__tzinfo = None
def __init__(self, **kwargs):
"""Initialize some general configuration that will keep things
consistent when working with the notifiers that will inherit this
@ -350,17 +348,13 @@ class NotifyBase(URLBase):
if "tz" in kwargs:
value = kwargs["tz"]
if isinstance(value, ZoneInfo):
self.__tzinfo = kwargs["tz"]
else:
self.__tzinfo = zoneinfo(value)
if not self.__tzinfo:
err = (
f"An invalid notification timezone ({value}) was "
"specified.")
self.logger.warning(err)
raise TypeError(err) from None
self.__tzinfo = zoneinfo(value)
if not self.__tzinfo:
err = (
f"An invalid notification timezone ({value}) was "
"specified.")
self.logger.warning(err)
raise TypeError(err) from None
if "overflow" in kwargs:
value = kwargs["overflow"]

View File

@ -25,7 +25,7 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from datetime import tzinfo
from datetime import datetime, timezone as _tz, tzinfo
from inspect import cleandoc
# Disable logging for a cleaner testing output
@ -34,7 +34,7 @@ import logging
import pytest
import yaml
from apprise import Apprise, AppriseAsset, ConfigFormat
from apprise import Apprise, AppriseAsset, AppriseConfig, ConfigFormat
from apprise.config import ConfigBase
from apprise.plugins.email import NotifyEmail
from apprise.utils.time import zoneinfo
@ -1592,3 +1592,77 @@ include: [file:///absolute/path/, relative/path, http://test.com]
assert "file:///absolute/path/" in config
assert "relative/path" in config
assert "http://test.com" in config
def test_yaml_asset_timezone_and_asset_tokens(tmpdir):
"""
Covers: valid tz, reserved keys, invalid key, bool coercion, None->"",
invalid type for string, and %z formatting path used later by plugins.
"""
cfg = tmpdir.join("asset-tz.yml")
cfg.write(
"""
version: 1
asset:
tz: " america/toronto " # case-insensitive + whitespace cleanup
_private: "ignored" # reserved (starts with _)
name_: "ignored" # reserved (ends with _)
not_a_field: "ignored" # invalid asset key
secure_logging: "yes" # string -> bool via parse_bool
app_id: null # None becomes empty string
app_desc: [ "list" ] # invalid type for string -> warning path
urls:
- json://localhost
"""
)
ac = AppriseConfig(paths=str(cfg))
# Force a fresh parse and get the loaded plugin
servers = ac.servers()
assert len(servers) == 1
plugin = servers[0]
asset = plugin.asset
# tz was accepted and normalised
assert getattr(asset.tzinfo, "key", None) == "America/Toronto"
# boolean coercion applied
assert asset.secure_logging is True
# None -> ""
assert asset.app_id == ""
def test_yaml_asset_timezone_invalid_and_precedence(tmpdir):
"""
If 'timezone' is present but invalid, it takes precedence over 'tz'
and MUST NOT set the asset to the 'tz' value. We assert that London
was not applied. We deliberately avoid asserting the exact fallback,
since environments may surface a system tz (datetime.timezone) that
lacks a `.key` attribute.
"""
cfg = tmpdir.join("asset-tz-invalid.yml")
cfg.write(
"""
version: 1
asset:
timezone: null # invalid (will be seen as "None")
tz: Europe/London # would be valid, but 'timezone' wins
urls:
- json://localhost
"""
)
base_asset = AppriseAsset(timezone="UTC")
ac = AppriseConfig(paths=str(cfg))
servers = ac.servers(asset=base_asset)
assert len(servers) == 1
tzinfo = servers[0].asset.tzinfo
# The key assertion: 'tz' MUST NOT have been applied
assert getattr(tzinfo, "key", "").lower() != "europe/london"
# Sanity check that something sensible is set
# Compare offsets at a fixed instant instead of object identity
dt = datetime(2024, 1, 1, 12, 0, tzinfo=_tz.utc)
assert tzinfo.utcoffset(dt) is not None