Test that the state proxy works. Args: grandchild_state: A grandchild state. mock_app: An app that will be returned by `get_app()`
(grandchild_state: GrandchildState, mock_app: xt.App)
| 1604 | |
| 1605 | @pytest.mark.asyncio |
| 1606 | async def test_state_proxy(grandchild_state: GrandchildState, mock_app: xt.App): |
| 1607 | """Test that the state proxy works. |
| 1608 | |
| 1609 | Args: |
| 1610 | grandchild_state: A grandchild state. |
| 1611 | mock_app: An app that will be returned by `get_app()` |
| 1612 | """ |
| 1613 | child_state = grandchild_state.parent_state |
| 1614 | assert child_state is not None |
| 1615 | parent_state = child_state.parent_state |
| 1616 | assert parent_state is not None |
| 1617 | if isinstance(mock_app.state_manager, StateManagerMemory): |
| 1618 | mock_app.state_manager.states[parent_state.get_token()] = parent_state |
| 1619 | |
| 1620 | sp = StateProxy(grandchild_state) |
| 1621 | assert sp.__wrapped__ == grandchild_state |
| 1622 | assert sp._self_substate_path == grandchild_state.get_full_name().split(".") |
| 1623 | assert sp._self_app is mock_app |
| 1624 | assert not sp._self_mutable |
| 1625 | assert sp._self_actx is None |
| 1626 | |
| 1627 | # cannot use normal contextmanager protocol |
| 1628 | with pytest.raises(TypeError), sp: |
| 1629 | pass |
| 1630 | |
| 1631 | with pytest.raises(ImmutableStateError): |
| 1632 | # cannot directly modify state proxy outside of async context |
| 1633 | sp.value2 = 16 |
| 1634 | |
| 1635 | async with sp: |
| 1636 | assert sp._self_actx is not None |
| 1637 | assert sp._self_mutable # proxy is mutable inside context |
| 1638 | if isinstance(mock_app.state_manager, StateManagerMemory): |
| 1639 | # For in-process store, only one instance of the state exists |
| 1640 | assert sp.__wrapped__ is grandchild_state |
| 1641 | else: |
| 1642 | # When redis is used, a new+updated instance is assigned to the proxy |
| 1643 | assert sp.__wrapped__ is not grandchild_state |
| 1644 | sp.value2 = 42 |
| 1645 | assert not sp._self_mutable # proxy is not mutable after exiting context |
| 1646 | assert sp._self_actx is None |
| 1647 | assert sp.value2 == 42 |
| 1648 | |
| 1649 | # Get the state from the state manager directly and check that the value is updated |
| 1650 | gotten_state = await mock_app.state_manager.get_state(grandchild_state.get_token()) |
| 1651 | if isinstance(mock_app.state_manager, StateManagerMemory): |
| 1652 | # For in-process store, only one instance of the state exists |
| 1653 | assert gotten_state is parent_state |
| 1654 | else: |
| 1655 | assert gotten_state is not parent_state |
| 1656 | gotten_grandchild_state = gotten_state.get_substate(sp._self_substate_path) |
| 1657 | assert gotten_grandchild_state is not None |
| 1658 | assert gotten_grandchild_state.value2 == 42 |
| 1659 | |
| 1660 | # ensure state update was emitted |
| 1661 | assert mock_app.event_namespace is not None |
| 1662 | mock_app.event_namespace.emit.assert_called_once() |
| 1663 | mcall = mock_app.event_namespace.emit.mock_calls[0] |
nothing calls this directly
no test coverage detected