160 lines
6.0 KiB
Python
160 lines
6.0 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from helpers import seed_state
|
||
|
|
|
||
|
|
from slack_mock.server import archive_channel, create_channel, list_channels, rename_channel, set_channel_topic
|
||
|
|
from slack_mock.state import get_state
|
||
|
|
|
||
|
|
|
||
|
|
def setup_function() -> None:
|
||
|
|
seed_state(
|
||
|
|
{
|
||
|
|
"users": {"U001": {"id": "U001", "name": "alice"}},
|
||
|
|
"channels": {
|
||
|
|
"C001": {
|
||
|
|
"id": "C001",
|
||
|
|
"name": "general",
|
||
|
|
"name_normalized": "general",
|
||
|
|
"is_general": True,
|
||
|
|
"context_team_id": "T_MOCK",
|
||
|
|
"updated": 1700000000,
|
||
|
|
"creator": "U001",
|
||
|
|
"num_members": 5,
|
||
|
|
"previous_names": [],
|
||
|
|
"topic": {"value": "General chat", "creator": "U001", "last_set": 1700000000},
|
||
|
|
"purpose": {"value": "Team comms", "creator": "U001", "last_set": 1700000000},
|
||
|
|
},
|
||
|
|
"C002": {
|
||
|
|
"id": "C002",
|
||
|
|
"name": "random",
|
||
|
|
"name_normalized": "random",
|
||
|
|
"is_archived": True,
|
||
|
|
"context_team_id": "T_MOCK",
|
||
|
|
"updated": 1700000000,
|
||
|
|
"creator": "U001",
|
||
|
|
"num_members": 3,
|
||
|
|
"previous_names": [],
|
||
|
|
"topic": {"value": "", "creator": "", "last_set": 0},
|
||
|
|
"purpose": {"value": "", "creator": "", "last_set": 0},
|
||
|
|
},
|
||
|
|
"C003": {
|
||
|
|
"id": "C003",
|
||
|
|
"name": "external",
|
||
|
|
"context_team_id": "T_MOCK",
|
||
|
|
"is_member": False,
|
||
|
|
},
|
||
|
|
"D001": {
|
||
|
|
"id": "D001",
|
||
|
|
"name": "alice",
|
||
|
|
"context_team_id": "T_MOCK",
|
||
|
|
"is_channel": False,
|
||
|
|
"is_im": True,
|
||
|
|
"is_private": True,
|
||
|
|
"user": "U001",
|
||
|
|
},
|
||
|
|
"G001": {
|
||
|
|
"id": "G001",
|
||
|
|
"name": "private",
|
||
|
|
"context_team_id": "T_MOCK",
|
||
|
|
"is_channel": False,
|
||
|
|
"is_group": True,
|
||
|
|
"is_private": True,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
"messages": {"C001": [], "C002": [], "C003": [], "D001": [], "G001": []},
|
||
|
|
"counters": {"channelId": 1000},
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_list_channels_filters_to_active_channel_memberships() -> None:
|
||
|
|
listed = await list_channels()
|
||
|
|
|
||
|
|
assert listed["ok"] is True
|
||
|
|
assert [channel["id"] for channel in listed["channels"]] == ["C001", "G001"]
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_create_channel_public_private_and_messages() -> None:
|
||
|
|
public = await create_channel("engineering")
|
||
|
|
private = await create_channel("secret", is_private=True)
|
||
|
|
|
||
|
|
assert public["ok"] is True
|
||
|
|
assert public["channel"]["name"] == "engineering"
|
||
|
|
assert public["channel"]["is_private"] is False
|
||
|
|
assert public["channel"]["is_channel"] is True
|
||
|
|
assert get_state().messages[public["channel"]["id"]] == []
|
||
|
|
|
||
|
|
assert private["ok"] is True
|
||
|
|
assert private["channel"]["is_private"] is True
|
||
|
|
assert private["channel"]["is_group"] is True
|
||
|
|
assert private["channel"]["is_channel"] is False
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_create_channel_normalizes_and_rejects_bad_names() -> None:
|
||
|
|
normalized = await create_channel("MyChannel")
|
||
|
|
duplicate = await create_channel("general")
|
||
|
|
empty = await create_channel(" ")
|
||
|
|
second = await create_channel("chan-b")
|
||
|
|
|
||
|
|
assert normalized["channel"]["name"] == "mychannel"
|
||
|
|
assert normalized["channel"]["name_normalized"] == "mychannel"
|
||
|
|
assert duplicate["ok"] is False
|
||
|
|
assert duplicate["error"] == "name_taken"
|
||
|
|
assert empty["ok"] is False
|
||
|
|
assert empty["error"] == "invalid_name"
|
||
|
|
assert normalized["channel"]["id"] != second["channel"]["id"]
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_archive_channel() -> None:
|
||
|
|
before = get_state().channels["C001"].updated
|
||
|
|
archived = await archive_channel("C001")
|
||
|
|
already = await archive_channel("C002")
|
||
|
|
missing = await archive_channel("INVALID")
|
||
|
|
|
||
|
|
assert archived["ok"] is True
|
||
|
|
assert get_state().channels["C001"].is_archived is True
|
||
|
|
assert get_state().channels["C001"].updated >= before
|
||
|
|
assert already == {"ok": False, "error": "already_archived"}
|
||
|
|
assert missing == {"ok": False, "error": "channel_not_found"}
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_rename_channel() -> None:
|
||
|
|
renamed = await rename_channel("C001", "announcements")
|
||
|
|
normalized = await rename_channel("C001", "NewName")
|
||
|
|
duplicate = await rename_channel("C001", "random")
|
||
|
|
missing = await rename_channel("INVALID", "test")
|
||
|
|
empty = await rename_channel("C001", " ")
|
||
|
|
|
||
|
|
assert renamed["ok"] is True
|
||
|
|
assert renamed["channel"]["name"] == "announcements"
|
||
|
|
previous_names = get_state().channels["C001"].previous_names
|
||
|
|
assert previous_names is not None
|
||
|
|
assert "general" in previous_names
|
||
|
|
assert normalized["channel"]["name"] == "newname"
|
||
|
|
assert duplicate["error"] == "name_taken"
|
||
|
|
assert missing["error"] == "channel_not_found"
|
||
|
|
assert empty["error"] == "invalid_name"
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_set_channel_topic_and_purpose() -> None:
|
||
|
|
topic = await set_channel_topic("C001", topic="New topic")
|
||
|
|
assert topic["ok"] is True
|
||
|
|
assert topic["channel"]["topic"]["value"] == "New topic"
|
||
|
|
assert topic["channel"]["topic"]["creator"] == "U_MOCK_BOT"
|
||
|
|
assert topic["channel"]["purpose"]["value"] == "Team comms"
|
||
|
|
|
||
|
|
purpose = await set_channel_topic("C001", purpose="New purpose")
|
||
|
|
assert purpose["channel"]["purpose"]["value"] == "New purpose"
|
||
|
|
|
||
|
|
both = await set_channel_topic("C001", topic="T", purpose="P")
|
||
|
|
assert both["channel"]["topic"]["value"] == "T"
|
||
|
|
assert both["channel"]["purpose"]["value"] == "P"
|
||
|
|
assert (await set_channel_topic("INVALID", topic="test"))["error"] == "channel_not_found"
|