@phase2 @client @websocket Feature: WebSocket updates client As a developer I want a WebSocket client for real-time plan updates So that I can receive status, progress, and log events from the server # --------------------------------------------------------------------------- # Construction # --------------------------------------------------------------------------- Scenario: Create WebSocket client with default settings Given a WebSocketClient with default settings Then the ws_url should be "ws://localhost:8080/ws" And the heartbeat interval should be 30.0 And the dedup capacity should be 1000 Scenario: Create WebSocket client with custom settings Given a WebSocketClient with url "wss://example.com/ws" and token "tok_ws1234567890abcdef" Then the ws_url should be "wss://example.com/ws" # --------------------------------------------------------------------------- # Connection lifecycle # --------------------------------------------------------------------------- Scenario: Connect raises NotImplementedError until real transport is available Given a WebSocketClient with default settings When I attempt to connect the ws client Then a NotImplementedError should be raised from ws client Scenario: Disconnect sets state to disconnected Given a WebSocketClient with default settings And the ws client state is set to connected When I disconnect the ws client Then the ws client should not be connected # --------------------------------------------------------------------------- # Reconnection # --------------------------------------------------------------------------- Scenario: Reconnect increments reconnect counter Given a WebSocketClient with default settings and max_reconnects 5 And the ws client state is set to connected When I simulate a reconnect Then the reconnect count should be 1 And the ws client should be connected Scenario: Reconnect exceeding max raises ServerConnectionError Given a WebSocketClient with default settings and max_reconnects 2 When I exhaust reconnect attempts Then a ServerConnectionError should be raised from ws client # --------------------------------------------------------------------------- # Event processing # --------------------------------------------------------------------------- Scenario: Process event dispatches to subscriber Given a WebSocketClient with a subscriber When I process a plan status event with id "evt-001" Then the subscriber should receive event "evt-001" And the last event id should be "evt-001" Scenario: Process duplicate event is skipped Given a WebSocketClient with a subscriber When I process a plan status event with id "evt-dup-001" And I process a plan status event with id "evt-dup-001" again Then the subscriber should have received 1 event Scenario: Unsubscribe removes callback Given a WebSocketClient with a subscriber When I unsubscribe the callback And I process a plan status event with id "evt-unsub" Then the subscriber should have received 0 events # --------------------------------------------------------------------------- # Heartbeat # --------------------------------------------------------------------------- Scenario: Heartbeat resets reconnect counter Given a WebSocketClient with default settings and max_reconnects 5 And the ws client state is set to connected When I simulate a reconnect And I handle a heartbeat Then the reconnect count should be 0 # --------------------------------------------------------------------------- # Version negotiation # --------------------------------------------------------------------------- Scenario: Version negotiation stores agreed version Given a WebSocketClient with default settings When I negotiate ws version "1.0" Then the negotiated ws version should be "1.0" # --------------------------------------------------------------------------- # EventDeduplicator # --------------------------------------------------------------------------- Scenario: Deduplicator detects duplicates Given an EventDeduplicator with capacity 3 When I check event "a" for duplicate Then the dedup result should be not duplicate When I check event "a" for duplicate Then the dedup result should be duplicate Scenario: Deduplicator evicts oldest when full Given an EventDeduplicator with capacity 2 When I add events "x" and "y" and "z" to the deduplicator Then event "x" should not be tracked And the deduplicator size should be 2 Scenario: Deduplicator clear removes all entries Given an EventDeduplicator with capacity 10 When I add events "a" and "b" and "c" to the deduplicator And I clear the deduplicator Then the deduplicator size should be 0 # --------------------------------------------------------------------------- # ConnectionState # --------------------------------------------------------------------------- Scenario: ConnectionState reset clears all fields Given a ConnectionState with connected true and last_event_id "ev1" When I reset the connection state Then the connection state should be disconnected And the connection state last_event_id should be empty # --------------------------------------------------------------------------- # Backoff helper # --------------------------------------------------------------------------- Scenario: WS backoff delay grows exponentially and is capped When I compute ws backoff delay for attempt 0 base 1.0 max 30.0 Then the ws delay should be 1.0 When I compute ws backoff delay for attempt 10 base 1.0 max 30.0 Then the ws delay should be 30.0