Skip to content

Commit e483ffa

Browse files
committed
improved test coverage
1 parent 8a18e6b commit e483ffa

3 files changed

Lines changed: 142 additions & 48 deletions

File tree

tests/test_plugin_slack.py

Lines changed: 103 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import requests
3939

4040
from apprise import Apprise, AppriseAttachment, NotifyType
41-
from apprise.plugins.slack import NotifySlack, SlackMode
41+
from apprise.plugins.slack import NotifySlack
4242

4343
logging.disable(logging.CRITICAL)
4444

@@ -565,48 +565,6 @@ def test_plugin_slack_oauth_access_token(mock_request):
565565
# We'll fail now because of an internal exception
566566
assert obj.send(body="test") is False
567567

568-
# --- Simulate failure to send file to channel (missing 'files') ---
569-
mock_request.reset_mock()
570-
mock_request.side_effect = [
571-
request, # chat.postMessage
572-
mock.Mock(**{ # getUploadURLExternal
573-
"content": dumps({
574-
"ok": True,
575-
"upload_url": "https://files.slack.com/upload/v1/ABC123",
576-
"file_id": "F123ABC456",
577-
}),
578-
"status_code": requests.codes.ok,
579-
}),
580-
mock.Mock(**{ # File upload
581-
"content": b"OK - 123",
582-
"status_code": requests.codes.ok,
583-
}),
584-
mock.Mock(**{ # completeUploadExternal returns invalid response
585-
"content": dumps({
586-
"ok": True,
587-
"files": [], # <== This triggers the unhit block
588-
}),
589-
"status_code": requests.codes.ok,
590-
}),
591-
]
592-
593-
path = os.path.join(TEST_VAR_DIR, "apprise-test.gif")
594-
attach = AppriseAttachment(path)
595-
596-
# Test via BOT Mode
597-
obj.mode = SlackMode.BOT
598-
599-
# This will now fail on 'response.get("files")' being empty
600-
assert (
601-
obj.notify(
602-
body="body",
603-
title="title",
604-
notify_type=NotifyType.INFO,
605-
attach=attach,
606-
)
607-
is False
608-
)
609-
610568

611569
@mock.patch("requests.request")
612570
def test_plugin_slack_webhook_mode(mock_request):
@@ -1040,3 +998,105 @@ def test_plugin_slack_multiple_thread_reply(mock_request):
1040998
assert loads(mock_request.call_args_list[1][1]["data"]).get(
1041999
"thread_ts"
10421000
) == str(thread_id_2)
1001+
1002+
1003+
@mock.patch("requests.request")
1004+
def test_plugin_slack_file_upload_success(mock_request):
1005+
"""Test Slack BOT attachment upload success path."""
1006+
1007+
token = "xoxb-1234-1234-abc124"
1008+
path = os.path.join(TEST_VAR_DIR, "apprise-test.gif")
1009+
attach = AppriseAttachment(path)
1010+
1011+
# Simulate all successful Slack API responses
1012+
mock_request.side_effect = [
1013+
mock.Mock(**{
1014+
"content": dumps({
1015+
"ok": True,
1016+
"channel": "C123456",
1017+
}),
1018+
"status_code": requests.codes.ok,
1019+
}),
1020+
mock.Mock(**{
1021+
"content": dumps({
1022+
"ok": True,
1023+
"upload_url": "https://files.slack.com/upload/v1/ABC123",
1024+
"file_id": "F123ABC456",
1025+
}),
1026+
"status_code": requests.codes.ok,
1027+
}),
1028+
mock.Mock(**{
1029+
"content": b"OK - 123",
1030+
"status_code": requests.codes.ok,
1031+
}),
1032+
mock.Mock(**{
1033+
"content": dumps({
1034+
"ok": True,
1035+
"files": [{"id": "F123ABC456", "title": "apprise-test"}],
1036+
}),
1037+
"status_code": requests.codes.ok,
1038+
}),
1039+
]
1040+
1041+
obj = NotifySlack(access_token=token, targets=["#general"])
1042+
assert obj.notify(
1043+
body="Success path test",
1044+
title="Slack Upload OK",
1045+
notify_type=NotifyType.INFO,
1046+
attach=attach,
1047+
) is True
1048+
1049+
1050+
@mock.patch("requests.request")
1051+
def test_plugin_slack_file_upload_fails_missing_files(mock_request):
1052+
"""Test that file upload fails when 'files' is missing or empty."""
1053+
1054+
token = "xoxb-1234-1234-abc124"
1055+
path = os.path.join(TEST_VAR_DIR, "apprise-test.gif")
1056+
attach = AppriseAttachment(path)
1057+
1058+
# Mock sequence:
1059+
# 1. chat.postMessage returns valid channel
1060+
# 2. files.getUploadURLExternal returns file_id and upload_url
1061+
# 3. Upload returns 'OK'
1062+
# 4. files.completeUploadExternal returns missing/empty 'files'
1063+
1064+
mock_request.side_effect = [
1065+
mock.Mock(**{
1066+
"content": dumps({
1067+
"ok": True,
1068+
"channel": "C555555",
1069+
}),
1070+
"status_code": requests.codes.ok,
1071+
}),
1072+
mock.Mock(**{
1073+
"content": dumps({
1074+
"ok": True,
1075+
"upload_url": "https://files.slack.com/upload/v1/X99999",
1076+
"file_id": "F999XYZ888",
1077+
}),
1078+
"status_code": requests.codes.ok,
1079+
}),
1080+
mock.Mock(**{
1081+
"content": b"OK - 2048",
1082+
"status_code": requests.codes.ok,
1083+
}),
1084+
# <== This response will trigger the error condition
1085+
mock.Mock(**{
1086+
"content": dumps({
1087+
"ok": True,
1088+
"files": [],
1089+
}),
1090+
"status_code": requests.codes.ok,
1091+
}),
1092+
]
1093+
1094+
obj = NotifySlack(access_token=token, targets=["#fail-channel"])
1095+
result = obj.notify(
1096+
body="This should trigger a failed file upload",
1097+
title="Trigger failure",
1098+
notify_type=NotifyType.INFO,
1099+
attach=attach,
1100+
)
1101+
1102+
assert result is False

tests/test_plugin_syslog.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,45 @@
3535

3636
import apprise
3737

38-
logging.disable(logging.CRITICAL)
38+
try:
39+
import syslog
40+
41+
except ImportError:
42+
# Shim so that test cases can run in environments that
43+
# do not have syslog
44+
import types
45+
syslog = types.SimpleNamespace(
46+
LOG_PID=0x01,
47+
LOG_PERROR=0x02,
48+
LOG_INFO=6,
49+
LOG_NOTICE=5,
50+
LOG_CRIT=2,
51+
LOG_WARNING=4,
52+
LOG_KERN=0,
53+
LOG_USER=1,
54+
LOG_MAIL=2,
55+
LOG_DAEMON=3,
56+
LOG_AUTH=4,
57+
LOG_SYSLOG=5,
58+
LOG_LPR=6,
59+
LOG_NEWS=7,
60+
LOG_UUCP=8,
61+
LOG_CRON=9,
62+
LOG_LOCAL0=16,
63+
LOG_LOCAL1=17,
64+
LOG_LOCAL2=18,
65+
LOG_LOCAL3=19,
66+
LOG_LOCAL4=20,
67+
LOG_LOCAL5=21,
68+
LOG_LOCAL6=22,
69+
LOG_LOCAL7=23,
70+
openlog=lambda *a, **kw: None,
71+
syslog=lambda *a, **kw: None,
72+
)
73+
sys.modules["syslog"] = syslog
3974

40-
# Skip tests when Python environment does not provide the `syslog` package.
41-
if "syslog" not in sys.modules:
42-
pytest.skip("Skipping syslog based tests", allow_module_level=True)
75+
76+
logging.disable(logging.CRITICAL)
4377

4478
from apprise.plugins.syslog import NotifySyslog # noqa E402
4579

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ commands =
9797
find . -type f -name "*.pyc" -delete
9898
find . -type f -name "*.pyo" -delete
9999
find . -type d -name "__pycache__" -delete
100-
rm -rf BUILD SOURCES SRPMS BUILDROOT .ruff_cache .coverage-reports .coverage coverage.xml dist build apprise.egg-info .mypy_cache .pytest_cache
100+
rm -rf BUILD SOURCES SRPMS BUILDROOT .cache .ruff_cache .coverage-reports .coverage coverage.xml dist build apprise.egg-info .mypy_cache .pytest_cache
101101

102102
[testenv:i18n]
103103
description = Extract and update .pot/.po files for translation

0 commit comments

Comments
 (0)