Skip to content

Commit 247ce1e

Browse files
committed
🚩(back) use existing no websocket feature flag
An already existing feature flag COLLABORATION_WS_NOT_CONNECTED_READY_ONLY was used bu the frontend application to disable or not the edition for a user not connected to the websocket. We want to reuse it in the backend application to disable or not the no websocket feature.
1 parent a3fd723 commit 247ce1e

File tree

3 files changed

+85
-9
lines changed

3 files changed

+85
-9
lines changed

src/backend/core/api/viewsets.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from rest_framework import response as drf_response
3333
from rest_framework.permissions import AllowAny
3434
from rest_framework.throttling import UserRateThrottle
35-
from sentry_sdk import capture_exception
3635

3736
from core import authentication, enums, models
3837
from core.services.ai_services import AIService
@@ -682,7 +681,10 @@ def _can_user_edit_document(self, document_id, set_cache=False):
682681

683682
def perform_update(self, serializer):
684683
"""Check rules about collaboration."""
685-
if serializer.validated_data.get("websocket", False):
684+
if (
685+
serializer.validated_data.get("websocket", False)
686+
or not settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY
687+
):
686688
return super().perform_update(serializer)
687689

688690
if self._can_user_edit_document(serializer.instance.id, set_cache=True):
@@ -701,10 +703,14 @@ def can_edit(self, request, *args, **kwargs):
701703
"""Check if the current user can edit the document."""
702704
document = self.get_object()
703705

704-
return drf.response.Response(
705-
{"can_edit": self._can_user_edit_document(document.id)}
706+
can_edit = (
707+
True
708+
if not settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY
709+
else self._can_user_edit_document(document.id)
706710
)
707711

712+
return drf.response.Response({"can_edit": can_edit})
713+
708714
@drf.decorators.action(
709715
detail=False,
710716
methods=["get"],

src/backend/core/tests/documents/test_api_documents_can_edit.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,36 @@
1111
pytestmark = pytest.mark.django_db
1212

1313

14-
def test_api_documents_can_edit_anonymous():
14+
@responses.activate
15+
@pytest.mark.parametrize("ws_not_connected_ready_only", [True, False])
16+
@pytest.mark.parametrize("role", ["editor", "reader"])
17+
def test_api_documents_can_edit_anonymous(settings, ws_not_connected_ready_only, role):
1518
"""Anonymous users can not edit documents."""
16-
document = factories.DocumentFactory()
19+
document = factories.DocumentFactory(link_reach="public", link_role=role)
1720
client = APIClient()
21+
session_key = client.session.session_key
22+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = ws_not_connected_ready_only
23+
endpoint_url = (
24+
f"{settings.COLLABORATION_API_URL}get-connections/"
25+
f"?room={document.id}&sessionKey={session_key}"
26+
)
27+
ws_resp = responses.get(endpoint_url, json={"count": 0, "exists": False})
28+
1829
response = client.get(f"/api/v1.0/documents/{document.id!s}/can-edit/")
19-
assert response.status_code == 401
30+
31+
if role == "reader":
32+
assert response.status_code == 401
33+
else:
34+
assert response.status_code == 200
35+
assert response.json() == {"can_edit": True}
36+
assert ws_resp.call_count == (1 if ws_not_connected_ready_only else 0)
2037

2138

2239
@responses.activate
23-
def test_api_documents_can_edit_authenticated_no_websocket(settings):
40+
@pytest.mark.parametrize("ws_not_connected_ready_only", [True, False])
41+
def test_api_documents_can_edit_authenticated_no_websocket(
42+
settings, ws_not_connected_ready_only
43+
):
2444
"""
2545
A user not connected to the websocket and no other user have already updated the document,
2646
the document can be updated.
@@ -34,6 +54,7 @@ def test_api_documents_can_edit_authenticated_no_websocket(settings):
3454

3555
settings.COLLABORATION_API_URL = "http://example.com/"
3656
settings.COLLABORATION_SERVER_SECRET = "secret-token"
57+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = ws_not_connected_ready_only
3758
endpoint_url = (
3859
f"{settings.COLLABORATION_API_URL}get-connections/"
3960
f"?room={document.id}&sessionKey={session_key}"
@@ -49,7 +70,7 @@ def test_api_documents_can_edit_authenticated_no_websocket(settings):
4970
assert response.status_code == 200
5071

5172
assert response.json() == {"can_edit": True}
52-
assert ws_resp.call_count == 1
73+
assert ws_resp.call_count == (1 if ws_not_connected_ready_only else 0)
5374

5475

5576
@responses.activate
@@ -69,6 +90,7 @@ def test_api_documents_can_edit_authenticated_no_websocket_user_already_editing(
6990

7091
settings.COLLABORATION_API_URL = "http://example.com/"
7192
settings.COLLABORATION_SERVER_SECRET = "secret-token"
93+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
7294
endpoint_url = (
7395
f"{settings.COLLABORATION_API_URL}get-connections/"
7496
f"?room={document.id}&sessionKey={session_key}"
@@ -103,6 +125,7 @@ def test_api_documents_can_edit_no_websocket_other_user_connected_to_websocket(
103125

104126
settings.COLLABORATION_API_URL = "http://example.com/"
105127
settings.COLLABORATION_SERVER_SECRET = "secret-token"
128+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
106129
endpoint_url = (
107130
f"{settings.COLLABORATION_API_URL}get-connections/"
108131
f"?room={document.id}&sessionKey={session_key}"
@@ -134,6 +157,7 @@ def test_api_documents_can_edit_user_connected_to_websocket(settings):
134157

135158
settings.COLLABORATION_API_URL = "http://example.com/"
136159
settings.COLLABORATION_SERVER_SECRET = "secret-token"
160+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
137161
endpoint_url = (
138162
f"{settings.COLLABORATION_API_URL}get-connections/"
139163
f"?room={document.id}&sessionKey={session_key}"
@@ -168,6 +192,7 @@ def test_api_documents_can_edit_websocket_server_unreachable_fallback_to_no_webs
168192

169193
settings.COLLABORATION_API_URL = "http://example.com/"
170194
settings.COLLABORATION_SERVER_SECRET = "secret-token"
195+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
171196
endpoint_url = (
172197
f"{settings.COLLABORATION_API_URL}get-connections/"
173198
f"?room={document.id}&sessionKey={session_key}"
@@ -202,6 +227,7 @@ def test_api_documents_can_edit_websocket_server_unreachable_fallback_to_no_webs
202227

203228
settings.COLLABORATION_API_URL = "http://example.com/"
204229
settings.COLLABORATION_SERVER_SECRET = "secret-token"
230+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
205231
endpoint_url = (
206232
f"{settings.COLLABORATION_API_URL}get-connections/"
207233
f"?room={document.id}&sessionKey={session_key}"

src/backend/core/tests/documents/test_api_documents_update.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ def test_api_documents_update_authenticated_no_websocket(settings):
313313
new_document_values["websocket"] = False
314314
settings.COLLABORATION_API_URL = "http://example.com/"
315315
settings.COLLABORATION_SERVER_SECRET = "secret-token"
316+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
316317
endpoint_url = (
317318
f"{settings.COLLABORATION_API_URL}get-connections/"
318319
f"?room={document.id}&sessionKey={session_key}"
@@ -352,6 +353,7 @@ def test_api_documents_update_authenticated_no_websocket_user_already_editing(se
352353
new_document_values["websocket"] = False
353354
settings.COLLABORATION_API_URL = "http://example.com/"
354355
settings.COLLABORATION_SERVER_SECRET = "secret-token"
356+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
355357
endpoint_url = (
356358
f"{settings.COLLABORATION_API_URL}get-connections/"
357359
f"?room={document.id}&sessionKey={session_key}"
@@ -390,6 +392,7 @@ def test_api_documents_update_no_websocket_other_user_connected_to_websocket(set
390392
new_document_values["websocket"] = False
391393
settings.COLLABORATION_API_URL = "http://example.com/"
392394
settings.COLLABORATION_SERVER_SECRET = "secret-token"
395+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
393396
endpoint_url = (
394397
f"{settings.COLLABORATION_API_URL}get-connections/"
395398
f"?room={document.id}&sessionKey={session_key}"
@@ -427,6 +430,7 @@ def test_api_documents_update_user_connected_to_websocket(settings):
427430
new_document_values["websocket"] = False
428431
settings.COLLABORATION_API_URL = "http://example.com/"
429432
settings.COLLABORATION_SERVER_SECRET = "secret-token"
433+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
430434
endpoint_url = (
431435
f"{settings.COLLABORATION_API_URL}get-connections/"
432436
f"?room={document.id}&sessionKey={session_key}"
@@ -466,6 +470,7 @@ def test_api_documents_update_websocket_server_unreachable_fallback_to_no_websoc
466470
new_document_values["websocket"] = False
467471
settings.COLLABORATION_API_URL = "http://example.com/"
468472
settings.COLLABORATION_SERVER_SECRET = "secret-token"
473+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
469474
endpoint_url = (
470475
f"{settings.COLLABORATION_API_URL}get-connections/"
471476
f"?room={document.id}&sessionKey={session_key}"
@@ -506,6 +511,7 @@ def test_api_documents_update_websocket_server_unreachable_fallback_to_no_websoc
506511
new_document_values["websocket"] = False
507512
settings.COLLABORATION_API_URL = "http://example.com/"
508513
settings.COLLABORATION_SERVER_SECRET = "secret-token"
514+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
509515
endpoint_url = (
510516
f"{settings.COLLABORATION_API_URL}get-connections/"
511517
f"?room={document.id}&sessionKey={session_key}"
@@ -562,6 +568,44 @@ def test_api_documents_update_force_websocket_param_to_true(settings):
562568
assert ws_resp.call_count == 0
563569

564570

571+
@responses.activate
572+
def test_api_documents_update_feature_flag_disabled(settings):
573+
"""
574+
When the feature flag is disabled, the document should be updated without any check.
575+
"""
576+
user = factories.UserFactory(with_owned_document=True)
577+
client = APIClient()
578+
client.force_login(user)
579+
session_key = client.session.session_key
580+
581+
document = factories.DocumentFactory(users=[(user, "editor")])
582+
583+
new_document_values = serializers.DocumentSerializer(
584+
instance=factories.DocumentFactory()
585+
).data
586+
new_document_values["websocket"] = False
587+
settings.COLLABORATION_API_URL = "http://example.com/"
588+
settings.COLLABORATION_SERVER_SECRET = "secret-token"
589+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = False
590+
endpoint_url = (
591+
f"{settings.COLLABORATION_API_URL}get-connections/"
592+
f"?room={document.id}&sessionKey={session_key}"
593+
)
594+
ws_resp = responses.get(endpoint_url, status=500)
595+
596+
assert cache.get(f"docs:no-websocket:{document.id}") is None
597+
598+
response = client.put(
599+
f"/api/v1.0/documents/{document.id!s}/",
600+
new_document_values,
601+
format="json",
602+
)
603+
assert response.status_code == 200
604+
605+
assert cache.get(f"docs:no-websocket:{document.id}") is None
606+
assert ws_resp.call_count == 0
607+
608+
565609
@pytest.mark.parametrize("via", VIA)
566610
def test_api_documents_update_administrator_or_owner_of_another(via, mock_user_teams):
567611
"""

0 commit comments

Comments
 (0)