mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-31 12:47:58 +00:00
✨(backend) apply user preferences on unconfigured room creation
Update the API so that, when a user creates a new meeting without passing an explicit configuration, the user's persisted preferences are applied as defaults. This allows a user to, for example, enable the waiting room by default on every meeting they create.
This commit is contained in:
@@ -308,8 +308,27 @@ class RoomViewSet(
|
|||||||
return drf_response.Response(serializer.data)
|
return drf_response.Response(serializer.data)
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
"""Set the current user as owner of the newly created room."""
|
"""Set the current user as owner of the newly created room.
|
||||||
room = serializer.save()
|
|
||||||
|
Apply the user's default room preferences (access level and configuration)
|
||||||
|
unless the request explicitly provides its own values.
|
||||||
|
"""
|
||||||
|
user = self.request.user
|
||||||
|
save_kwargs = {}
|
||||||
|
|
||||||
|
if (
|
||||||
|
"access_level" not in serializer.validated_data
|
||||||
|
and user.default_room_access_level not in (None, "")
|
||||||
|
):
|
||||||
|
save_kwargs["access_level"] = user.default_room_access_level
|
||||||
|
|
||||||
|
user_default_configuration = user.default_room_configuration
|
||||||
|
if not serializer.validated_data.get(
|
||||||
|
"configuration"
|
||||||
|
) and user_default_configuration not in (None, {}):
|
||||||
|
save_kwargs["configuration"] = user.default_room_configuration
|
||||||
|
|
||||||
|
room = serializer.save(**save_kwargs)
|
||||||
models.ResourceAccess.objects.create(
|
models.ResourceAccess.objects.create(
|
||||||
resource=room,
|
resource=room,
|
||||||
user=self.request.user,
|
user=self.request.user,
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ Test rooms API endpoints in the Meet core app: create.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=redefined-outer-name,unused-argument
|
# pylint: disable=redefined-outer-name,unused-argument
|
||||||
|
from django.conf import settings
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
from ...factories import RoomFactory, UserFactory
|
from ...factories import RoomFactory, UserFactory
|
||||||
from ...models import Room
|
from ...models import Room, RoomAccessLevel
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
@@ -109,3 +110,205 @@ def test_api_rooms_create_authenticated_existing_slug():
|
|||||||
|
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert response.json() == {"slug": ["Room with this Slug already exists."]}
|
assert response.json() == {"slug": ["Room with this Slug already exists."]}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_user_default_access_level():
|
||||||
|
"""
|
||||||
|
The user's default room access level should be applied to the new room
|
||||||
|
when the request does not provide one.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_access_level=RoomAccessLevel.RESTRICTED)
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.access_level == RoomAccessLevel.RESTRICTED
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_explicit_access_level_overrides_default():
|
||||||
|
"""
|
||||||
|
An access level explicitly provided in the request should take precedence
|
||||||
|
over the user's default room access level.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_access_level=RoomAccessLevel.RESTRICTED)
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
"access_level": RoomAccessLevel.TRUSTED,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.access_level == RoomAccessLevel.TRUSTED
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_no_user_default_access_level():
|
||||||
|
"""
|
||||||
|
When the user has no default room access level, the instance default
|
||||||
|
should be applied to the new room.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_access_level=None)
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.access_level == settings.RESOURCE_DEFAULT_ACCESS_LEVEL
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_user_default_configuration():
|
||||||
|
"""
|
||||||
|
The user's default room configuration should be applied to the new room
|
||||||
|
when the request does not provide one.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_configuration={"everyone_can_mute": False})
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.configuration == {"everyone_can_mute": False}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_explicit_configuration_overrides_default():
|
||||||
|
"""
|
||||||
|
A configuration explicitly provided in the request should take precedence
|
||||||
|
over the user's default room configuration.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_configuration={"everyone_can_mute": False})
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
"configuration": {"can_publish_sources": ["camera", "microphone"]},
|
||||||
|
},
|
||||||
|
format="json",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.configuration == {"can_publish_sources": ["camera", "microphone"]}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_empty_configuration_falls_back_to_default():
|
||||||
|
"""
|
||||||
|
An empty configuration in the request should not be considered an explicit
|
||||||
|
value: the user's default room configuration should still be applied.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_configuration={"everyone_can_mute": True})
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
"configuration": {},
|
||||||
|
},
|
||||||
|
format="json",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.configuration == {"everyone_can_mute": True}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_empty_user_default_configuration():
|
||||||
|
"""
|
||||||
|
When the user's default room configuration is empty, the new room should
|
||||||
|
keep its default empty configuration.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_configuration={})
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.configuration == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_request_precedence_over_user_empty():
|
||||||
|
"""
|
||||||
|
When the user's default room configuration is empty, the request should take precedence.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_configuration={})
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{"name": "my room", "configuration": {"everyone_can_mute": True}},
|
||||||
|
format="json",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.configuration == {"everyone_can_mute": True}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_rooms_create_authenticated_blank_user_default_access_level():
|
||||||
|
"""
|
||||||
|
A blank default room access level (stored as an empty string) should be
|
||||||
|
treated as unset: the instance default should be applied to the new room
|
||||||
|
instead of persisting an invalid empty access level.
|
||||||
|
"""
|
||||||
|
user = UserFactory(default_room_access_level="")
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/rooms/",
|
||||||
|
{
|
||||||
|
"name": "my room",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 201
|
||||||
|
room = Room.objects.get()
|
||||||
|
assert room.access_level == settings.RESOURCE_DEFAULT_ACCESS_LEVEL
|
||||||
|
|||||||
Reference in New Issue
Block a user