Skip to content

Commit

Permalink
feat: lock() accepts an optional userId (#142)
Browse files Browse the repository at this point in the history
  • Loading branch information
palazzem authored Feb 2, 2024
1 parent c694e31 commit ad9de56
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
7 changes: 5 additions & 2 deletions src/elmo/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,15 @@ def poll(self, ids):

@contextmanager
@require_session
def lock(self, code):
def lock(self, code, user_id=1):
"""Context manager to obtain a system lock. The alerting system allows
only one user at a time and obtaining the lock is mandatory. When the
context manager is closed, the lock is automatically released.
Args:
code: the alarm code used to obtain the lock.
user_id: the `userId` used by some main units. This value is optional and
should be used only if the main unit requires it. The default value is 1.
Raises:
CodeError: if used `code` is not valid.
LockError: if the server is refusing to assign the lock. It could mean
Expand All @@ -169,7 +171,8 @@ def lock(self, code):
Returns:
A client instance with an acquired lock.
"""
payload = {"userId": 1, "password": code, "sessionId": self._session_id}
# Main units that do not require a userId param, expects userId to be "1"
payload = {"userId": user_id, "password": code, "sessionId": self._session_id}
response = self._session.post(self._router.lock, data=payload)

try:
Expand Down
23 changes: 22 additions & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ def test_statusadv_missing(self, server):


def test_client_lock(server, mocker):
"""Should acquire a lock if credentials are properly provided."""
"""Should acquire the lock, sending `userId=1` as a default."""
html = """[
{
"Poller": {"Poller": 1, "Panel": 1},
Expand All @@ -618,6 +618,27 @@ def test_client_lock(server, mocker):
with client.lock("test"):
assert not client._lock.acquire(False)
assert len(server.calls) == 1
assert server.calls[0].request.body == "userId=1&password=test&sessionId=test"


def test_client_lock_with_user_id(server, mocker):
"""Should acquire the lock sending a user-defined `userId`."""
html = """[
{
"Poller": {"Poller": 1, "Panel": 1},
"CommandId": 5,
"Successful": true
}
]"""
server.add(responses.POST, "https://example.com/api/panel/syncLogin", body=html, status=200)
client = ElmoClient(base_url="https://example.com", domain="domain")
client._session_id = "test"
mocker.patch.object(client, "unlock")
# Test
with client.lock("test", user_id="001"):
assert not client._lock.acquire(False)
assert len(server.calls) == 1
assert server.calls[0].request.body == "userId=001&password=test&sessionId=test"


def test_client_lock_wrong_code(server, mocker):
Expand Down

0 comments on commit ad9de56

Please sign in to comment.