mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
feat: action links send+redirect to Discord, no result page; 10-min dedup window
This commit is contained in:
+54
-6
@@ -121,22 +121,41 @@ class TestLinkFormActionValidation:
|
||||
# ── redirect_to_original execution ────────────────────────────────────────────
|
||||
|
||||
class TestRedirectAction:
|
||||
def test_action_link_executes_and_renders_result(self, action_link):
|
||||
def test_action_link_executes_and_redirects(self, action_link):
|
||||
"""成功:发送消息并 302 跳转 Discord,不渲染页面。"""
|
||||
client = Client()
|
||||
with patch('links.actions.send_discord_message') as mock_send:
|
||||
resp = client.get(f'/testaction/今天有什么新闻/')
|
||||
assert resp.status_code == 200
|
||||
resp = client.get('/testaction/今天有什么新闻/')
|
||||
assert resp.status_code == 302
|
||||
assert resp['Location'].startswith('https://discord.com/channels/')
|
||||
mock_send.assert_called_once_with('@小黑 今天有什么新闻')
|
||||
assert 'links/action_result.html' in [t.name for t in resp.templates]
|
||||
assert '今天有什么新闻' in resp.content.decode()
|
||||
|
||||
def test_action_link_with_query_param(self, action_link):
|
||||
client = Client()
|
||||
with patch('links.actions.send_discord_message') as mock_send:
|
||||
resp = client.get('/testaction/', {'q': '用查询参数提问'})
|
||||
assert resp.status_code == 200
|
||||
assert resp.status_code == 302
|
||||
mock_send.assert_called_once_with('@小黑 用查询参数提问')
|
||||
|
||||
def test_action_link_dedup_same_query_in_window(self, action_link, monkeypatch):
|
||||
"""10 分钟内同一 query 只发一次,刷新不重复发送。"""
|
||||
monkeypatch.setenv('DISCORD_WEBHOOK_URL', 'https://example.com/hook')
|
||||
client = Client()
|
||||
with patch('links.actions.requests.post') as mock_post:
|
||||
resp1 = client.get('/testaction/相同问题/')
|
||||
resp2 = client.get('/testaction/相同问题/') # 刷新/重复访问
|
||||
assert resp1.status_code == 302
|
||||
assert resp2.status_code == 302
|
||||
assert mock_post.call_count == 1, '同一问题 10 分钟内只应发送一次'
|
||||
|
||||
def test_action_link_different_query_not_deduped(self, action_link, monkeypatch):
|
||||
monkeypatch.setenv('DISCORD_WEBHOOK_URL', 'https://example.com/hook')
|
||||
client = Client()
|
||||
with patch('links.actions.requests.post') as mock_post:
|
||||
client.get('/testaction/问题甲/')
|
||||
client.get('/testaction/问题乙/')
|
||||
assert mock_post.call_count == 2, '不同问题应各自发送'
|
||||
|
||||
def test_action_link_webhook_failure_shows_error(self, action_link, monkeypatch):
|
||||
import requests as req_lib
|
||||
monkeypatch.setenv('DISCORD_WEBHOOK_URL', 'https://example.com/hook')
|
||||
@@ -145,6 +164,7 @@ class TestRedirectAction:
|
||||
resp = client.get('/testaction/测试/')
|
||||
assert resp.status_code == 200
|
||||
assert '发送到 Discord 失败' in resp.content.decode()
|
||||
assert '打开 Discord' not in resp.content.decode()
|
||||
|
||||
def test_normal_link_unaffected(self, db):
|
||||
Link.objects.create(alias='plainlink', link_type=Link.LinkType.LINK, original_url='https://example.com/path')
|
||||
@@ -152,3 +172,31 @@ class TestRedirectAction:
|
||||
resp = client.get('/plainlink/')
|
||||
assert resp.status_code in (301, 302)
|
||||
assert resp['Location'] == 'https://example.com/path'
|
||||
|
||||
|
||||
# ── /ask/ 路由(带问题 = 发送+跳转;不带 = 输入页)─────────────────────────
|
||||
|
||||
class TestAskRoute:
|
||||
def test_ask_with_question_redirects(self, monkeypatch):
|
||||
monkeypatch.setenv('DISCORD_WEBHOOK_URL', 'https://example.com/hook')
|
||||
client = Client()
|
||||
with patch('links.actions.requests.post') as mock_post:
|
||||
resp = client.get('/ask/今天有什么新闻/')
|
||||
assert resp.status_code == 302
|
||||
assert resp['Location'].startswith('https://discord.com/channels/')
|
||||
body = mock_post.call_args.kwargs['json']['content']
|
||||
assert '今天有什么新闻' in body
|
||||
|
||||
def test_ask_with_question_dedup(self, monkeypatch):
|
||||
monkeypatch.setenv('DISCORD_WEBHOOK_URL', 'https://example.com/hook')
|
||||
client = Client()
|
||||
with patch('links.actions.requests.post') as mock_post:
|
||||
client.get('/ask/相同问题/')
|
||||
client.get('/ask/相同问题/')
|
||||
assert mock_post.call_count == 1
|
||||
|
||||
def test_ask_empty_renders_input_page(self):
|
||||
client = Client()
|
||||
resp = client.get('/ask/')
|
||||
assert resp.status_code == 200
|
||||
assert '问小黑' in resp.content.decode()
|
||||
|
||||
Reference in New Issue
Block a user