rocketchat-API 3.3.0__tar.gz → 3.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/workflows/release.yml +8 -0
  2. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/workflows/test.yml +1 -1
  3. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/PKG-INFO +1 -1
  4. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/base.py +42 -18
  5. rocketchat_api-3.5.0/rocketchat_API/APISections/custom_sounds.py +12 -0
  6. rocketchat_api-3.5.0/rocketchat_API/APISections/custom_user_status.py +41 -0
  7. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/licenses.py +4 -0
  8. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/livechat.py +12 -0
  9. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/rocketchat.py +4 -0
  10. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API.egg-info/PKG-INFO +1 -1
  11. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API.egg-info/SOURCES.txt +4 -0
  12. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/conftest.py +12 -0
  13. rocketchat_api-3.5.0/tests/test_custom_sounds.py +79 -0
  14. rocketchat_api-3.5.0/tests/test_custom_user_status.py +69 -0
  15. rocketchat_api-3.5.0/tests/test_licenses.py +22 -0
  16. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_livechat.py +15 -0
  17. rocketchat_api-3.3.0/tests/test_licenses.py +0 -3
  18. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.coveragerc +0 -0
  19. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.deepsource.toml +0 -0
  20. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.editorconfig +0 -0
  21. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  22. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  23. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/actions/test_rocketchat/action.yml +0 -0
  24. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/dependabot.yml +0 -0
  25. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/workflows/lint.yml +0 -0
  26. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/workflows/test_latest.yml +0 -0
  27. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.github/workflows/test_manually.yml +0 -0
  28. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/.gitignore +0 -0
  29. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/CONTRIBUTING.md +0 -0
  30. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/LICENSE.txt +0 -0
  31. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/README.md +0 -0
  32. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/bandit.yml +0 -0
  33. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/docker-compose.yml +0 -0
  34. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/pyproject.toml +0 -0
  35. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/qodana.yaml +0 -0
  36. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APIExceptions/RocketExceptions.py +0 -0
  37. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APIExceptions/__init__.py +0 -0
  38. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/__init__.py +0 -0
  39. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/assets.py +0 -0
  40. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/banners.py +0 -0
  41. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/channels.py +0 -0
  42. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/chat.py +0 -0
  43. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/custom_emoji.py +0 -0
  44. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/dm.py +0 -0
  45. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/groups.py +0 -0
  46. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/integrations.py +0 -0
  47. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/invites.py +0 -0
  48. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/miscellaneous.py +0 -0
  49. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/moderation.py +0 -0
  50. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/permissions.py +0 -0
  51. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/roles.py +0 -0
  52. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/rooms.py +0 -0
  53. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/settings.py +0 -0
  54. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/statistics.py +0 -0
  55. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/subscriptions.py +0 -0
  56. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/teams.py +0 -0
  57. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/users.py +0 -0
  58. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/APISections/users_engagement.py +0 -0
  59. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API/__init__.py +0 -0
  60. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API.egg-info/dependency_links.txt +0 -0
  61. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API.egg-info/requires.txt +0 -0
  62. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/rocketchat_API.egg-info/top_level.txt +0 -0
  63. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/setup.cfg +0 -0
  64. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/__init__.py +0 -0
  65. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/assets/avatar.png +0 -0
  66. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/assets/avatar.svg +0 -0
  67. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/assets/logo.png +0 -0
  68. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_assets.py +0 -0
  69. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_banners.py +0 -0
  70. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_channels.py +0 -0
  71. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_chat.py +0 -0
  72. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_custom_emoji.py +0 -0
  73. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_dms.py +0 -0
  74. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_exceptions.py +0 -0
  75. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_groups.py +0 -0
  76. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_integrations.py +0 -0
  77. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_invites.py +0 -0
  78. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_moderation.py +0 -0
  79. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_paginated.py +0 -0
  80. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_permissions.py +0 -0
  81. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_roles.py +0 -0
  82. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_rooms.py +0 -0
  83. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_server.py +0 -0
  84. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_settings.py +0 -0
  85. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_subscriptions.py +0 -0
  86. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_teams.py +0 -0
  87. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_user.py +0 -0
  88. {rocketchat_api-3.3.0 → rocketchat_api-3.5.0}/tests/test_users_engagement.py +0 -0
@@ -28,3 +28,11 @@ jobs:
28
28
  python3 -m build
29
29
  - name: Publish package distributions to PyPI
30
30
  uses: pypa/gh-action-pypi-publish@release/v1
31
+ - name: Announce release
32
+ uses: jadolg/rocketchat-notification-action@v3.0.0
33
+ with:
34
+ server: https://open.rocket.chat
35
+ message: A new version (${{ github.event.release.tag_name }}) has been released! ${{ github.event.release.html_url }}
36
+ user-id: ${{ secrets.ROCKETCHAT_USER_ID }}
37
+ auth-token: ${{ secrets.ROCKETCHAT_AUTH_TOKEN }}
38
+ channel: "#python_rocketchat_api"
@@ -15,7 +15,7 @@ jobs:
15
15
  fail-fast: false
16
16
  matrix:
17
17
  python-version: [ '3.10', '3.11', '3.12', '3.13', '3.14' ]
18
- rocket-chat-version: [ '7.10.7', '7.11.3', '7.12.4', '7.13.3' , '8.0.1', '8.1.0']
18
+ rocket-chat-version: [ '7.11.6', '7.12.6', '7.13.5' , '8.0.3', '8.1.2', '8.2.1', '8.3.1']
19
19
  steps:
20
20
  - name: Checkout
21
21
  uses: actions/checkout@v6.0.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rocketchat_API
3
- Version: 3.3.0
3
+ Version: 3.5.0
4
4
  Summary: Python API wrapper for Rocket.Chat
5
5
  Author-email: "Jorge Alberto Díaz Orozco (Akiel)" <diazorozcoj@gmail.com>
6
6
  Maintainer-email: "Jorge Alberto Díaz Orozco (Akiel)" <diazorozcoj@gmail.com>
@@ -200,24 +200,37 @@ class RocketChatBase:
200
200
  )
201
201
  )
202
202
 
203
- def call_api_post(self, method, files=None, use_json=None, **kwargs):
204
- reduced_args = self.__reduce_kwargs(kwargs)
205
- # Since pass is a reserved word in Python it has to be injected on the request dict
206
- # Some methods use pass (users.register) and others password (users.create)
207
- if "password" in reduced_args and method != "users.create":
208
- reduced_args["pass"] = reduced_args["password"]
209
- del reduced_args["password"]
210
- if use_json is None:
211
- # see https://requests.readthedocs.io/en/master/user/quickstart/#more-complicated-post-requests
212
- # > The json parameter is ignored if either data or files is passed.
213
- # If files are sent, json should not be used
214
- use_json = files is None
215
- if use_json:
203
+ def call_api_post(self, method, body=None, files=None, use_json=None, **kwargs):
204
+ """Send a POST request to the API.
205
+
206
+ There are two modes of operation:
207
+
208
+ 1. **Raw body** — pass ``body`` directly. The value is serialized as-is
209
+ via ``json=body``, which supports any JSON-serializable structure
210
+ (lists, dicts, etc.). ``kwargs`` are ignored in this mode.
211
+
212
+ 2. **Keyword arguments** (default) — individual kwargs are collected
213
+ into a dict and sent as the request payload. By default the payload
214
+ is sent as JSON (``json=``), but when ``files`` are provided it
215
+ falls back to form-encoded ``data=`` because requests ignores the
216
+ ``json`` parameter when ``files`` is set. You can override this
217
+ with ``use_json=True/False``.
218
+
219
+ :param method: API method path, appended to ``self.api_path``.
220
+ :param body: A raw JSON-serializable payload (e.g. a list).
221
+ When provided, ``kwargs``, ``files``, and ``use_json``
222
+ are ignored.
223
+ :param files: Files to upload (passed to ``requests``).
224
+ :param use_json: Force JSON (True) or form-encoded (False) encoding.
225
+ Defaults to JSON when no files are attached.
226
+ """
227
+ url = self.server_url + self.api_path + method
228
+
229
+ if body is not None:
216
230
  return json_or_error(
217
231
  self.session.post(
218
- self.server_url + self.api_path + method,
219
- json=reduced_args,
220
- files=files,
232
+ url,
233
+ json=body,
221
234
  headers=self.headers,
222
235
  verify=self.ssl_verify,
223
236
  cert=self.cert,
@@ -226,10 +239,21 @@ class RocketChatBase:
226
239
  )
227
240
  )
228
241
 
242
+ reduced_args = self.__reduce_kwargs(kwargs)
243
+
244
+ # "pass" is a Python reserved word, but some endpoints (e.g.
245
+ # users.register) expect it instead of "password".
246
+ if "password" in reduced_args and method != "users.create":
247
+ reduced_args["pass"] = reduced_args.pop("password")
248
+
249
+ if use_json is None:
250
+ use_json = files is None
251
+
229
252
  return json_or_error(
230
253
  self.session.post(
231
- self.server_url + self.api_path + method,
232
- data=reduced_args,
254
+ url,
255
+ json=reduced_args if use_json else None,
256
+ data=None if use_json else reduced_args,
233
257
  files=files,
234
258
  headers=self.headers,
235
259
  verify=self.ssl_verify,
@@ -0,0 +1,12 @@
1
+ from rocketchat_API.APISections.base import RocketChatBase, paginated
2
+
3
+
4
+ class RocketChatCustomSounds(RocketChatBase):
5
+ @paginated("sounds")
6
+ def custom_sounds_list(self, **kwargs):
7
+ """Retrieves all custom sounds."""
8
+ return self.call_api_get("custom-sounds.list", kwargs=kwargs)
9
+
10
+ def custom_sounds_get_one(self, sound_id, **kwargs):
11
+ """Retrieves a single custom sound by its _id."""
12
+ return self.call_api_get("custom-sounds.getOne", _id=sound_id, kwargs=kwargs)
@@ -0,0 +1,41 @@
1
+ from rocketchat_API.APISections.base import RocketChatBase, paginated
2
+
3
+
4
+ class RocketChatCustomUserStatus(RocketChatBase):
5
+ @paginated("statuses")
6
+ def custom_user_status_list(self, **kwargs):
7
+ """Lists all available custom user's status."""
8
+ return self.call_api_get("custom-user-status.list", kwargs=kwargs)
9
+
10
+ def custom_user_status_create(self, name, status_type, **kwargs):
11
+ """Creates custom user status.
12
+
13
+ :param name: The name of the custom status.
14
+ :param status_type: The statusType of the custom status. Valid status type includes: Online, Busy, Away, Offline.
15
+ """
16
+ return self.call_api_post(
17
+ "custom-user-status.create",
18
+ name=name,
19
+ statusType=status_type,
20
+ kwargs=kwargs,
21
+ )
22
+
23
+ def custom_user_status_delete(self, custom_user_status_id, **kwargs):
24
+ """Deletes a custom user status."""
25
+ return self.call_api_post(
26
+ "custom-user-status.delete",
27
+ customUserStatusId=custom_user_status_id,
28
+ kwargs=kwargs,
29
+ )
30
+
31
+ def custom_user_status_update(
32
+ self, custom_user_status_id, name, status_type, **kwargs
33
+ ):
34
+ """Updates a custom user status."""
35
+ return self.call_api_post(
36
+ "custom-user-status.update",
37
+ _id=custom_user_status_id,
38
+ name=name,
39
+ statusType=status_type,
40
+ kwargs=kwargs,
41
+ )
@@ -6,3 +6,7 @@ class RocketChatLicenses(RocketChatBase):
6
6
  def licenses_info(self, **kwargs):
7
7
  """Retrieves a list of all registered licenses in the workspace."""
8
8
  return self.call_api_get("licenses.info", kwargs=kwargs)
9
+
10
+ def licenses_max_active_users(self, **kwargs):
11
+ """Retrieves a list of the maximum active users."""
12
+ return self.call_api_get("licenses.maxActiveUsers", kwargs=kwargs)
@@ -70,3 +70,15 @@ class RocketChatLivechat(RocketChatBase):
70
70
  return self.call_api_get(
71
71
  "livechat/inquiries.getOne", roomId=room_id, kwargs=kwargs
72
72
  )
73
+
74
+ def livechat_get_appearance(self, **kwargs):
75
+ """Get the settings about the widget appearance. Permission required: view-livechat-manager"""
76
+ return self.call_api_get("livechat/appearance", kwargs=kwargs)
77
+
78
+ def livechat_set_appearance(self, settings):
79
+ """Update the livechat widget appearance settings. Permission required: view-livechat-manager
80
+
81
+ :param settings: list of dicts with '_id' and 'value' keys,
82
+ e.g. [{"_id": "Livechat_title", "value": "Support"}]
83
+ """
84
+ return self.call_api_post("livechat/appearance", body=settings)
@@ -6,6 +6,8 @@ from rocketchat_API.APISections.channels import RocketChatChannels
6
6
  from rocketchat_API.APISections.chat import RocketChatChat
7
7
  from rocketchat_API.APISections.dm import RocketChatDM
8
8
  from rocketchat_API.APISections.custom_emoji import RocketChatCustomEmoji
9
+ from rocketchat_API.APISections.custom_sounds import RocketChatCustomSounds
10
+ from rocketchat_API.APISections.custom_user_status import RocketChatCustomUserStatus
9
11
  from rocketchat_API.APISections.groups import RocketChatGroups
10
12
  from rocketchat_API.APISections.integrations import RocketChatIntegrations
11
13
  from rocketchat_API.APISections.invites import RocketChatInvites
@@ -31,6 +33,8 @@ class RocketChat(
31
33
  RocketChatChat,
32
34
  RocketChatDM,
33
35
  RocketChatCustomEmoji,
36
+ RocketChatCustomSounds,
37
+ RocketChatCustomUserStatus,
34
38
  RocketChatGroups,
35
39
  RocketChatIntegrations,
36
40
  RocketChatInvites,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rocketchat_API
3
- Version: 3.3.0
3
+ Version: 3.5.0
4
4
  Summary: Python API wrapper for Rocket.Chat
5
5
  Author-email: "Jorge Alberto Díaz Orozco (Akiel)" <diazorozcoj@gmail.com>
6
6
  Maintainer-email: "Jorge Alberto Díaz Orozco (Akiel)" <diazorozcoj@gmail.com>
@@ -34,6 +34,8 @@ rocketchat_API/APISections/base.py
34
34
  rocketchat_API/APISections/channels.py
35
35
  rocketchat_API/APISections/chat.py
36
36
  rocketchat_API/APISections/custom_emoji.py
37
+ rocketchat_API/APISections/custom_sounds.py
38
+ rocketchat_API/APISections/custom_user_status.py
37
39
  rocketchat_API/APISections/dm.py
38
40
  rocketchat_API/APISections/groups.py
39
41
  rocketchat_API/APISections/integrations.py
@@ -58,6 +60,8 @@ tests/test_banners.py
58
60
  tests/test_channels.py
59
61
  tests/test_chat.py
60
62
  tests/test_custom_emoji.py
63
+ tests/test_custom_sounds.py
64
+ tests/test_custom_user_status.py
61
65
  tests/test_dms.py
62
66
  tests/test_exceptions.py
63
67
  tests/test_groups.py
@@ -78,6 +78,18 @@ def secondary_user(logged_rocket):
78
78
  logged_rocket.users_delete(_testuser_id)
79
79
 
80
80
 
81
+ @pytest.fixture
82
+ def skip_if_version_under(rocket):
83
+ import semver
84
+
85
+ def _skip_if_version_under(minimum_version):
86
+ parse = lambda v: semver.Version.parse(v, optional_minor_and_patch=True)
87
+ if parse(rocket.info()["version"]) < parse(minimum_version):
88
+ pytest.skip(f"Requires Rocket.Chat >= {minimum_version}")
89
+
90
+ return _skip_if_version_under
91
+
92
+
81
93
  @pytest.fixture
82
94
  def skip_if_no_license(logged_rocket):
83
95
  try:
@@ -0,0 +1,79 @@
1
+ import json
2
+ import uuid
3
+
4
+
5
+ def _sound_name():
6
+ return "test_sound_" + str(uuid.uuid1()).replace("-", "")[:12]
7
+
8
+
9
+ def _create_sound(logged_rocket, name):
10
+ """Create a custom sound entry via method.call and return its _id."""
11
+ result = logged_rocket.call_api_post(
12
+ "method.call/insertOrUpdateSound",
13
+ message=json.dumps(
14
+ {
15
+ "msg": "method",
16
+ "id": "1",
17
+ "method": "insertOrUpdateSound",
18
+ "params": [{"name": name, "extension": "mp3", "newFile": True}],
19
+ }
20
+ ),
21
+ )
22
+ return json.loads(result["message"])["result"]
23
+
24
+
25
+ def _delete_sound(logged_rocket, sound_id):
26
+ """Delete a custom sound entry via method.call."""
27
+ logged_rocket.call_api_post(
28
+ "method.call/deleteCustomSound",
29
+ message=json.dumps(
30
+ {
31
+ "msg": "method",
32
+ "id": "1",
33
+ "method": "deleteCustomSound",
34
+ "params": [sound_id],
35
+ }
36
+ ),
37
+ )
38
+
39
+
40
+ def test_custom_sounds_list(logged_rocket):
41
+ result = list(logged_rocket.custom_sounds_list())
42
+ assert isinstance(result, list)
43
+
44
+
45
+ def test_custom_sounds_list_structure(logged_rocket):
46
+ name = _sound_name()
47
+ sound_id = _create_sound(logged_rocket, name)
48
+ try:
49
+ sounds = list(logged_rocket.custom_sounds_list())
50
+ assert any(s["_id"] == sound_id for s in sounds)
51
+ sound = next(s for s in sounds if s["_id"] == sound_id)
52
+ assert "name" in sound
53
+ assert "extension" in sound
54
+ finally:
55
+ _delete_sound(logged_rocket, sound_id)
56
+
57
+
58
+ def test_custom_sounds_list_filter_by_name(logged_rocket):
59
+ name = _sound_name()
60
+ sound_id = _create_sound(logged_rocket, name)
61
+ try:
62
+ sounds = list(logged_rocket.custom_sounds_list(name=name))
63
+ assert len(sounds) >= 1
64
+ assert all(name.lower() in s["name"].lower() for s in sounds)
65
+ finally:
66
+ _delete_sound(logged_rocket, sound_id)
67
+
68
+
69
+ def test_custom_sounds_get_one(logged_rocket, skip_if_version_under):
70
+ skip_if_version_under("8.3.0")
71
+ name = _sound_name()
72
+ sound_id = _create_sound(logged_rocket, name)
73
+ try:
74
+ result = logged_rocket.custom_sounds_get_one(sound_id)
75
+ assert "sound" in result
76
+ assert result["sound"]["_id"] == sound_id
77
+ assert result["sound"]["name"] == name
78
+ finally:
79
+ _delete_sound(logged_rocket, sound_id)
@@ -0,0 +1,69 @@
1
+ import uuid
2
+
3
+ import pytest
4
+
5
+
6
+ @pytest.fixture
7
+ def status_name():
8
+ return "test_status_" + str(uuid.uuid1()).replace("-", "")[:12]
9
+
10
+
11
+ @pytest.fixture
12
+ def created_status(logged_rocket, status_name):
13
+ result = logged_rocket.custom_user_status_create(
14
+ name=status_name, status_type="online"
15
+ )
16
+ status = result.get("customUserStatus")
17
+ assert status is not None
18
+
19
+ yield status
20
+
21
+ logged_rocket.custom_user_status_delete(custom_user_status_id=status["_id"])
22
+
23
+
24
+ def test_custom_user_status_list(logged_rocket, created_status):
25
+ statuses = list(logged_rocket.custom_user_status_list())
26
+ assert any(s["_id"] == created_status["_id"] for s in statuses)
27
+
28
+
29
+ def test_custom_user_status_create_delete(logged_rocket):
30
+ name = "test_status_" + str(uuid.uuid1()).replace("-", "")[:12]
31
+ result = logged_rocket.custom_user_status_create(name=name, status_type="busy")
32
+ status = result.get("customUserStatus")
33
+ assert status is not None
34
+ assert status["name"] == name
35
+ assert status["statusType"] == "busy"
36
+
37
+ logged_rocket.custom_user_status_delete(custom_user_status_id=status["_id"])
38
+
39
+ statuses = list(logged_rocket.custom_user_status_list())
40
+ assert not any(s["_id"] == status["_id"] for s in statuses)
41
+
42
+
43
+ def test_custom_user_status_update(logged_rocket, created_status):
44
+ new_name = created_status["name"] + "_upd"
45
+ result = logged_rocket.custom_user_status_update(
46
+ custom_user_status_id=created_status["_id"],
47
+ name=new_name,
48
+ status_type="away",
49
+ )
50
+ updated = result.get("customUserStatus")
51
+ assert updated is not None
52
+ assert updated["name"] == new_name
53
+ assert updated["statusType"] == "away"
54
+
55
+
56
+ def test_custom_user_status_create_all_types(logged_rocket):
57
+ created_ids = []
58
+ for status_type in ("online", "busy", "away", "offline"):
59
+ name = "test_" + status_type + "_" + str(uuid.uuid1()).replace("-", "")[:8]
60
+ result = logged_rocket.custom_user_status_create(
61
+ name=name, status_type=status_type
62
+ )
63
+ status = result.get("customUserStatus")
64
+ assert status is not None
65
+ assert status["statusType"] == status_type
66
+ created_ids.append(status["_id"])
67
+
68
+ for sid in created_ids:
69
+ logged_rocket.custom_user_status_delete(custom_user_status_id=sid)
@@ -0,0 +1,22 @@
1
+ def test_licenses_info_works_without_license(logged_rocket):
2
+ licenses_info = logged_rocket.licenses_info()
3
+ assert "license" in licenses_info
4
+
5
+
6
+ def test_licenses_info(logged_rocket, skip_if_no_license, skip_if_version_under):
7
+ skip_if_version_under("8.1.0")
8
+ licenses_info = logged_rocket.licenses_info()
9
+ assert "license" in licenses_info
10
+ license_data = licenses_info["license"]
11
+ assert "activeModules" in license_data
12
+ assert "hasValidLicense" in license_data
13
+ assert "tags" in license_data
14
+ assert "limits" in license_data
15
+ assert isinstance(license_data["activeModules"], list)
16
+ assert isinstance(license_data["tags"], list)
17
+
18
+
19
+ def test_licenses_max_active_users(logged_rocket, skip_if_no_license):
20
+ result = logged_rocket.licenses_max_active_users()
21
+ assert "maxActiveUsers" in result
22
+ assert "activeUsers" in result
@@ -125,3 +125,18 @@ def test_livechat_get_inquiries(logged_rocket, livechat_inquiry):
125
125
  def test_livechat_get_inquiries_non_existent_room(logged_rocket):
126
126
  inquiry_not_found = logged_rocket.livechat_inquiries_get_one(room_id="nonexistent")
127
127
  assert inquiry_not_found.get("inquiry") is None or "success" in inquiry_not_found
128
+
129
+
130
+ def test_livechat_get_appearance(logged_rocket):
131
+ result = logged_rocket.livechat_get_appearance()
132
+ assert "appearance" in result
133
+
134
+
135
+ def test_livechat_set_appearance(logged_rocket):
136
+ appearance = logged_rocket.livechat_get_appearance().get("appearance", [])
137
+ assert len(appearance) > 0, "Expected at least one appearance setting"
138
+
139
+ setting = appearance[0]
140
+ logged_rocket.livechat_set_appearance(
141
+ [{"_id": setting["_id"], "value": setting["value"]}]
142
+ )
@@ -1,3 +0,0 @@
1
- def test_licenses_info(logged_rocket):
2
- licenses_info = logged_rocket.licenses_info()
3
- assert "license" in licenses_info
File without changes
File without changes