Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ jobs:
- name: Generate rest sync code and tests
run: uv run unasync
- name: Test with pytest
run: uv run pytest --verbose --tb=short --reruns 3
run: uv run pytest -s --verbose --tb=short --reruns 3
2 changes: 1 addition & 1 deletion ably/realtime/realtimepresence.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ async def subscribe(self, *args) -> None:
"""
# RTP6d: Implicitly attach
if self.channel.state in [ChannelState.INITIALIZED, ChannelState.DETACHED, ChannelState.DETACHING]:
asyncio.create_task(self.channel.attach())
await self.channel.attach()

# Parse arguments: similar to channel subscribe
if len(args) == 1:
Expand Down
94 changes: 58 additions & 36 deletions test/ably/realtime/realtimepresence_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,26 @@ class TestRealtimePresenceBasics(BaseAsyncTestCase):
"""Test basic presence operations: enter, leave, update."""

@pytest.fixture(autouse=True)
async def setup(self, use_binary_protocol):
async def setup(self, use_binary_protocol, request):
"""Set up test fixtures."""
self.test_vars = await TestApp.get_test_vars()
self.use_binary_protocol = use_binary_protocol
test_instance = request.instance

self.client1 = await TestApp.get_ably_realtime(
test_instance.test_vars = await TestApp.get_test_vars()
test_instance.use_binary_protocol = use_binary_protocol

test_instance.client1 = await TestApp.get_ably_realtime(
client_id='client1',
use_binary_protocol=use_binary_protocol
)
self.client2 = await TestApp.get_ably_realtime(
test_instance.client2 = await TestApp.get_ably_realtime(
client_id='client2',
use_binary_protocol=use_binary_protocol
)

yield

await self.client1.close()
await self.client2.close()
await test_instance.client1.close()
await test_instance.client2.close()

async def test_presence_enter_without_attach(self):
"""
Expand Down Expand Up @@ -188,24 +190,26 @@ class TestRealtimePresenceGet(BaseAsyncTestCase):
"""Test presence.get() functionality."""

@pytest.fixture(autouse=True)
async def setup(self, use_binary_protocol):
async def setup(self, use_binary_protocol, request):
"""Set up test fixtures."""
self.test_vars = await TestApp.get_test_vars()
self.use_binary_protocol = use_binary_protocol
test_instance = request.instance

test_instance.test_vars = await TestApp.get_test_vars()
test_instance.use_binary_protocol = use_binary_protocol

self.client1 = await TestApp.get_ably_realtime(
test_instance.client1 = await TestApp.get_ably_realtime(
client_id='client1',
use_binary_protocol=use_binary_protocol
)
self.client2 = await TestApp.get_ably_realtime(
test_instance.client2 = await TestApp.get_ably_realtime(
client_id='client2',
use_binary_protocol=use_binary_protocol
)

yield

await self.client1.close()
await self.client2.close()
await test_instance.client1.close()
await test_instance.client2.close()

async def test_presence_enter_get(self):
"""
Expand Down Expand Up @@ -282,24 +286,32 @@ class TestRealtimePresenceSubscribe(BaseAsyncTestCase):
"""Test presence.subscribe() functionality."""

@pytest.fixture(autouse=True)
async def setup(self, use_binary_protocol):
async def setup(self, use_binary_protocol, request):
"""Set up test fixtures."""
self.test_vars = await TestApp.get_test_vars()
self.use_binary_protocol = use_binary_protocol
protocol = 'msgpack' if use_binary_protocol else 'json'
test_instance = request.instance
print(f"[{protocol}] FIXTURE: request.instance = {test_instance}, id = {id(test_instance) if test_instance else 'None'}")

if test_instance is None:
raise RuntimeError(f"[{protocol}] FIXTURE ERROR: request.instance is None!")

self.client1 = await TestApp.get_ably_realtime(
test_instance.test_vars = await TestApp.get_test_vars()
test_instance.use_binary_protocol = use_binary_protocol

test_instance.client1 = await TestApp.get_ably_realtime(
client_id='client1',
use_binary_protocol=use_binary_protocol
)
self.client2 = await TestApp.get_ably_realtime(

test_instance.client2 = await TestApp.get_ably_realtime(
client_id='client2',
use_binary_protocol=use_binary_protocol
)

yield

await self.client1.close()
await self.client2.close()
await test_instance.client1.close()
await test_instance.client2.close()

async def test_presence_subscribe_unattached(self):
"""
Expand Down Expand Up @@ -348,28 +360,32 @@ def on_presence(msg):
await channel1.presence.enter()

msg = await asyncio.wait_for(received, timeout=5.0)
assert msg.action == PresenceAction.ENTER
# RTP8c: Should receive ENTER action since we're entering for the first time
assert msg.action == PresenceAction.ENTER, \
f"Expected ENTER action, got {msg.action}"


@pytest.mark.parametrize('use_binary_protocol', [True, False], ids=['msgpack', 'json'])
class TestRealtimePresenceEnterClient(BaseAsyncTestCase):
"""Test enterClient/updateClient/leaveClient functionality."""

@pytest.fixture(autouse=True)
async def setup(self, use_binary_protocol):
async def setup(self, use_binary_protocol, request):
"""Set up test fixtures."""
self.test_vars = await TestApp.get_test_vars()
self.use_binary_protocol = use_binary_protocol
test_instance = request.instance

test_instance.test_vars = await TestApp.get_test_vars()
test_instance.use_binary_protocol = use_binary_protocol

# Use wildcard auth for enterClient
self.client = await TestApp.get_ably_realtime(
test_instance.client = await TestApp.get_ably_realtime(
client_id='*',
use_binary_protocol=use_binary_protocol
)

yield

await self.client.close()
await test_instance.client.close()

async def test_enter_client_multiple(self):
"""
Expand Down Expand Up @@ -441,10 +457,12 @@ class TestRealtimePresenceConnectionLifecycle(BaseAsyncTestCase):
"""Test presence behavior during connection lifecycle events."""

@pytest.fixture(autouse=True)
async def setup(self, use_binary_protocol):
async def setup(self, use_binary_protocol, request):
"""Set up test fixtures."""
self.test_vars = await TestApp.get_test_vars()
self.use_binary_protocol = use_binary_protocol
test_instance = request.instance

test_instance.test_vars = await TestApp.get_test_vars()
test_instance.use_binary_protocol = use_binary_protocol
yield

async def test_presence_enter_without_connect(self):
Expand Down Expand Up @@ -569,10 +587,12 @@ class TestRealtimePresenceAutoReentry(BaseAsyncTestCase):
"""Test automatic re-entry of presence after connection suspension."""

@pytest.fixture(autouse=True)
async def setup(self, use_binary_protocol):
async def setup(self, use_binary_protocol, request):
"""Set up test fixtures."""
self.test_vars = await TestApp.get_test_vars()
self.use_binary_protocol = use_binary_protocol
test_instance = request.instance

test_instance.test_vars = await TestApp.get_test_vars()
test_instance.use_binary_protocol = use_binary_protocol
yield

async def test_presence_auto_reenter_after_suspend(self):
Expand Down Expand Up @@ -728,10 +748,12 @@ class TestRealtimePresenceSyncBehavior(BaseAsyncTestCase):
"""Test presence SYNC behavior and state management."""

@pytest.fixture(autouse=True)
async def setup(self, use_binary_protocol):
async def setup(self, use_binary_protocol, request):
"""Set up test fixtures."""
self.test_vars = await TestApp.get_test_vars()
self.use_binary_protocol = use_binary_protocol
test_instance = request.instance

test_instance.test_vars = await TestApp.get_test_vars()
test_instance.use_binary_protocol = use_binary_protocol
yield

async def test_presence_refresh_on_detach(self):
Expand Down
Loading