Skip to content

Commit 45f18db

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 0acab47 commit 45f18db

File tree

5 files changed

+89
-10
lines changed

5 files changed

+89
-10
lines changed

env.d/development/common.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ COLLABORATION_API_URL=http://y-provider-development:4444/collaboration/api/
6060
COLLABORATION_BACKEND_BASE_URL=http://app-dev:8000
6161
COLLABORATION_SERVER_ORIGIN=http://localhost:3000
6262
COLLABORATION_SERVER_SECRET=my-secret
63+
COLLABORATION_WS_NOT_CONNECTED_READY_ONLY=true
6364
COLLABORATION_WS_URL=ws://localhost:4444/collaboration/ws/
6465

6566
DJANGO_SERVER_TO_SERVER_API_TOKENS=server-api-token

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: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,38 @@
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_API_URL = "http://example.com/"
23+
settings.COLLABORATION_SERVER_SECRET = "secret-token"
24+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = ws_not_connected_ready_only
25+
endpoint_url = (
26+
f"{settings.COLLABORATION_API_URL}get-connections/"
27+
f"?room={document.id}&sessionKey={session_key}"
28+
)
29+
ws_resp = responses.get(endpoint_url, json={"count": 0, "exists": False})
30+
1831
response = client.get(f"/api/v1.0/documents/{document.id!s}/can-edit/")
19-
assert response.status_code == 401
32+
33+
if role == "reader":
34+
assert response.status_code == 401
35+
else:
36+
assert response.status_code == 200
37+
assert response.json() == {"can_edit": True}
38+
assert ws_resp.call_count == (1 if ws_not_connected_ready_only else 0)
2039

2140

2241
@responses.activate
23-
def test_api_documents_can_edit_authenticated_no_websocket(settings):
42+
@pytest.mark.parametrize("ws_not_connected_ready_only", [True, False])
43+
def test_api_documents_can_edit_authenticated_no_websocket(
44+
settings, ws_not_connected_ready_only
45+
):
2446
"""
2547
A user not connected to the websocket and no other user have already updated the document,
2648
the document can be updated.
@@ -34,6 +56,7 @@ def test_api_documents_can_edit_authenticated_no_websocket(settings):
3456

3557
settings.COLLABORATION_API_URL = "http://example.com/"
3658
settings.COLLABORATION_SERVER_SECRET = "secret-token"
59+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = ws_not_connected_ready_only
3760
endpoint_url = (
3861
f"{settings.COLLABORATION_API_URL}get-connections/"
3962
f"?room={document.id}&sessionKey={session_key}"
@@ -49,7 +72,7 @@ def test_api_documents_can_edit_authenticated_no_websocket(settings):
4972
assert response.status_code == 200
5073

5174
assert response.json() == {"can_edit": True}
52-
assert ws_resp.call_count == 1
75+
assert ws_resp.call_count == (1 if ws_not_connected_ready_only else 0)
5376

5477

5578
@responses.activate
@@ -69,6 +92,7 @@ def test_api_documents_can_edit_authenticated_no_websocket_user_already_editing(
6992

7093
settings.COLLABORATION_API_URL = "http://example.com/"
7194
settings.COLLABORATION_SERVER_SECRET = "secret-token"
95+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
7296
endpoint_url = (
7397
f"{settings.COLLABORATION_API_URL}get-connections/"
7498
f"?room={document.id}&sessionKey={session_key}"
@@ -103,6 +127,7 @@ def test_api_documents_can_edit_no_websocket_other_user_connected_to_websocket(
103127

104128
settings.COLLABORATION_API_URL = "http://example.com/"
105129
settings.COLLABORATION_SERVER_SECRET = "secret-token"
130+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
106131
endpoint_url = (
107132
f"{settings.COLLABORATION_API_URL}get-connections/"
108133
f"?room={document.id}&sessionKey={session_key}"
@@ -134,6 +159,7 @@ def test_api_documents_can_edit_user_connected_to_websocket(settings):
134159

135160
settings.COLLABORATION_API_URL = "http://example.com/"
136161
settings.COLLABORATION_SERVER_SECRET = "secret-token"
162+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
137163
endpoint_url = (
138164
f"{settings.COLLABORATION_API_URL}get-connections/"
139165
f"?room={document.id}&sessionKey={session_key}"
@@ -168,6 +194,7 @@ def test_api_documents_can_edit_websocket_server_unreachable_fallback_to_no_webs
168194

169195
settings.COLLABORATION_API_URL = "http://example.com/"
170196
settings.COLLABORATION_SERVER_SECRET = "secret-token"
197+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
171198
endpoint_url = (
172199
f"{settings.COLLABORATION_API_URL}get-connections/"
173200
f"?room={document.id}&sessionKey={session_key}"
@@ -202,6 +229,7 @@ def test_api_documents_can_edit_websocket_server_unreachable_fallback_to_no_webs
202229

203230
settings.COLLABORATION_API_URL = "http://example.com/"
204231
settings.COLLABORATION_SERVER_SECRET = "secret-token"
232+
settings.COLLABORATION_WS_NOT_CONNECTED_READY_ONLY = True
205233
endpoint_url = (
206234
f"{settings.COLLABORATION_API_URL}get-connections/"
207235
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
"""

src/frontend/apps/e2e/__tests__/app-impress/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const CONFIG = {
66
AI_FEATURE_ENABLED: true,
77
CRISP_WEBSITE_ID: null,
88
COLLABORATION_WS_URL: 'ws://localhost:4444/collaboration/ws/',
9-
COLLABORATION_WS_NOT_CONNECTED_READY_ONLY: false,
9+
COLLABORATION_WS_NOT_CONNECTED_READY_ONLY: true,
1010
ENVIRONMENT: 'development',
1111
FRONTEND_CSS_URL: null,
1212
FRONTEND_HOMEPAGE_FEATURE_ENABLED: true,

0 commit comments

Comments
 (0)