|
38 | 38 | import requests |
39 | 39 |
|
40 | 40 | from apprise import Apprise, AppriseAttachment, NotifyType |
41 | | -from apprise.plugins.slack import NotifySlack, SlackMode |
| 41 | +from apprise.plugins.slack import NotifySlack |
42 | 42 |
|
43 | 43 | logging.disable(logging.CRITICAL) |
44 | 44 |
|
@@ -565,48 +565,6 @@ def test_plugin_slack_oauth_access_token(mock_request): |
565 | 565 | # We'll fail now because of an internal exception |
566 | 566 | assert obj.send(body="test") is False |
567 | 567 |
|
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 | | - |
610 | 568 |
|
611 | 569 | @mock.patch("requests.request") |
612 | 570 | def test_plugin_slack_webhook_mode(mock_request): |
@@ -1040,3 +998,105 @@ def test_plugin_slack_multiple_thread_reply(mock_request): |
1040 | 998 | assert loads(mock_request.call_args_list[1][1]["data"]).get( |
1041 | 999 | "thread_ts" |
1042 | 1000 | ) == 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 |
0 commit comments