|
3 | 3 | import time |
4 | 4 |
|
5 | 5 | import pytest |
| 6 | +from unittest.mock import AsyncMock, Mock |
6 | 7 | from slack_sdk.signature import SignatureVerifier |
7 | 8 | from slack_sdk.web.async_client import AsyncWebClient |
8 | 9 |
|
@@ -56,6 +57,10 @@ def build_request_from_body(self, message_body: dict) -> AsyncBoltRequest: |
56 | 57 | timestamp, body = str(int(time.time())), json.dumps(message_body) |
57 | 58 | return AsyncBoltRequest(body=body, headers=self.build_headers(timestamp, body)) |
58 | 59 |
|
| 60 | + def setup_time_mocks(self, *, monkeypatch: pytest.MonkeyPatch, time_mock: Mock, sleep_mock: AsyncMock): |
| 61 | + monkeypatch.setattr(time, "time", time_mock) |
| 62 | + monkeypatch.setattr(asyncio, "sleep", sleep_mock) |
| 63 | + |
59 | 64 | @pytest.mark.asyncio |
60 | 65 | async def test_mock_server_is_running(self): |
61 | 66 | resp = await self.web_client.api_test() |
@@ -130,19 +135,47 @@ async def test_auto_acknowledge_false_with_acknowledging(self): |
130 | 135 | await assert_auth_test_count_async(self, 1) |
131 | 136 |
|
132 | 137 | @pytest.mark.asyncio |
133 | | - async def test_auto_acknowledge_false_without_acknowledging(self, caplog): |
| 138 | + async def test_auto_acknowledge_false_without_acknowledging(self, caplog, monkeypatch): |
134 | 139 | app = AsyncApp( |
135 | 140 | client=self.web_client, |
136 | 141 | signing_secret=self.signing_secret, |
137 | 142 | ) |
138 | 143 | app.function("reverse", auto_acknowledge=False)(just_no_ack) |
139 | | - |
140 | 144 | request = self.build_request_from_body(function_body) |
| 145 | + self.setup_time_mocks( |
| 146 | + monkeypatch=monkeypatch, |
| 147 | + time_mock=Mock(side_effect=[current_time for current_time in range(100)]), |
| 148 | + sleep_mock=AsyncMock(), |
| 149 | + ) |
141 | 150 | response = await app.async_dispatch(request) |
142 | 151 | assert response.status == 404 |
143 | 152 | await assert_auth_test_count_async(self, 1) |
144 | 153 | assert f"WARNING {just_no_ack.__name__} didn't call ack()" in caplog.text |
145 | 154 |
|
| 155 | + @pytest.mark.asyncio |
| 156 | + async def test_function_handler_timeout(self, monkeypatch): |
| 157 | + app = AsyncApp( |
| 158 | + client=self.web_client, |
| 159 | + signing_secret=self.signing_secret, |
| 160 | + ) |
| 161 | + app.function("reverse", auto_acknowledge=False)(just_no_ack) |
| 162 | + request = self.build_request_from_body(function_body) |
| 163 | + |
| 164 | + sleep_mock = AsyncMock() |
| 165 | + self.setup_time_mocks( |
| 166 | + monkeypatch=monkeypatch, |
| 167 | + time_mock=Mock(side_effect=[current_time for current_time in range(100)]), |
| 168 | + sleep_mock=sleep_mock, |
| 169 | + ) |
| 170 | + |
| 171 | + response = await app.async_dispatch(request) |
| 172 | + |
| 173 | + assert response.status == 404 |
| 174 | + await assert_auth_test_count_async(self, 1) |
| 175 | + assert ( |
| 176 | + sleep_mock.call_count == 5 |
| 177 | + ), f"Expected handler to time out after calling time.sleep 5 times, but it was called {sleep_mock.call_count} times" |
| 178 | + |
146 | 179 |
|
147 | 180 | function_body = { |
148 | 181 | "token": "verification_token", |
|
0 commit comments