Skip to content

Commit a8fda8f

Browse files
committed
✨(backend) add ancestors link reach and role to document API
On a document, we need to display the status of the link (reach and role) as inherited from its ancestors.
1 parent a01cb5a commit a8fda8f

9 files changed

+185
-2
lines changed

src/backend/core/api/serializers.py

+8
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ class Meta:
179179
fields = [
180180
"id",
181181
"abilities",
182+
"ancestors_link_reach",
183+
"ancestors_link_role",
182184
"created_at",
183185
"creator",
184186
"depth",
@@ -197,6 +199,8 @@ class Meta:
197199
read_only_fields = [
198200
"id",
199201
"abilities",
202+
"ancestors_link_reach",
203+
"ancestors_link_role",
200204
"created_at",
201205
"creator",
202206
"depth",
@@ -251,6 +255,8 @@ class Meta:
251255
fields = [
252256
"id",
253257
"abilities",
258+
"ancestors_link_reach",
259+
"ancestors_link_role",
254260
"content",
255261
"created_at",
256262
"creator",
@@ -270,6 +276,8 @@ class Meta:
270276
read_only_fields = [
271277
"id",
272278
"abilities",
279+
"ancestors_link_reach",
280+
"ancestors_link_role",
273281
"created_at",
274282
"creator",
275283
"depth",

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

+29
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ def test_api_documents_children_list_anonymous_public_standalone(
3535
"results": [
3636
{
3737
"abilities": child1.get_abilities(AnonymousUser()),
38+
"ancestors_link_reach": "public",
39+
"ancestors_link_role": document.link_role,
3840
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
3941
"creator": str(child1.creator.id),
4042
"depth": 2,
@@ -53,6 +55,8 @@ def test_api_documents_children_list_anonymous_public_standalone(
5355
},
5456
{
5557
"abilities": child2.get_abilities(AnonymousUser()),
58+
"ancestors_link_reach": "public",
59+
"ancestors_link_role": document.link_role,
5660
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
5761
"creator": str(child2.creator.id),
5862
"depth": 2,
@@ -101,6 +105,8 @@ def test_api_documents_children_list_anonymous_public_parent(django_assert_num_q
101105
"results": [
102106
{
103107
"abilities": child1.get_abilities(AnonymousUser()),
108+
"ancestors_link_reach": child1.ancestors_link_reach,
109+
"ancestors_link_role": child1.ancestors_link_role,
104110
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
105111
"creator": str(child1.creator.id),
106112
"depth": 4,
@@ -119,6 +125,8 @@ def test_api_documents_children_list_anonymous_public_parent(django_assert_num_q
119125
},
120126
{
121127
"abilities": child2.get_abilities(AnonymousUser()),
128+
"ancestors_link_reach": child2.ancestors_link_reach,
129+
"ancestors_link_role": child2.ancestors_link_role,
122130
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
123131
"creator": str(child2.creator.id),
124132
"depth": 4,
@@ -186,6 +194,8 @@ def test_api_documents_children_list_authenticated_unrelated_public_or_authentic
186194
"results": [
187195
{
188196
"abilities": child1.get_abilities(user),
197+
"ancestors_link_reach": reach,
198+
"ancestors_link_role": document.link_role,
189199
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
190200
"creator": str(child1.creator.id),
191201
"depth": 2,
@@ -204,6 +214,8 @@ def test_api_documents_children_list_authenticated_unrelated_public_or_authentic
204214
},
205215
{
206216
"abilities": child2.get_abilities(user),
217+
"ancestors_link_reach": reach,
218+
"ancestors_link_role": document.link_role,
207219
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
208220
"creator": str(child2.creator.id),
209221
"depth": 2,
@@ -257,6 +269,8 @@ def test_api_documents_children_list_authenticated_public_or_authenticated_paren
257269
"results": [
258270
{
259271
"abilities": child1.get_abilities(user),
272+
"ancestors_link_reach": child1.ancestors_link_reach,
273+
"ancestors_link_role": child1.ancestors_link_role,
260274
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
261275
"creator": str(child1.creator.id),
262276
"depth": 4,
@@ -275,6 +289,8 @@ def test_api_documents_children_list_authenticated_public_or_authenticated_paren
275289
},
276290
{
277291
"abilities": child2.get_abilities(user),
292+
"ancestors_link_reach": child2.ancestors_link_reach,
293+
"ancestors_link_role": child2.ancestors_link_role,
278294
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
279295
"creator": str(child2.creator.id),
280296
"depth": 4,
@@ -347,13 +363,16 @@ def test_api_documents_children_list_authenticated_related_direct(
347363
)
348364

349365
assert response.status_code == 200
366+
link_role = None if document.link_reach == "restricted" else document.link_role
350367
assert response.json() == {
351368
"count": 2,
352369
"next": None,
353370
"previous": None,
354371
"results": [
355372
{
356373
"abilities": child1.get_abilities(user),
374+
"ancestors_link_reach": document.link_reach,
375+
"ancestors_link_role": link_role,
357376
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
358377
"creator": str(child1.creator.id),
359378
"depth": 2,
@@ -372,6 +391,8 @@ def test_api_documents_children_list_authenticated_related_direct(
372391
},
373392
{
374393
"abilities": child2.get_abilities(user),
394+
"ancestors_link_reach": document.link_reach,
395+
"ancestors_link_role": link_role,
375396
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
376397
"creator": str(child2.creator.id),
377398
"depth": 2,
@@ -428,6 +449,8 @@ def test_api_documents_children_list_authenticated_related_parent(
428449
"results": [
429450
{
430451
"abilities": child1.get_abilities(user),
452+
"ancestors_link_reach": "restricted",
453+
"ancestors_link_role": None,
431454
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
432455
"creator": str(child1.creator.id),
433456
"depth": 4,
@@ -446,6 +469,8 @@ def test_api_documents_children_list_authenticated_related_parent(
446469
},
447470
{
448471
"abilities": child2.get_abilities(user),
472+
"ancestors_link_reach": "restricted",
473+
"ancestors_link_role": None,
449474
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
450475
"creator": str(child2.creator.id),
451476
"depth": 4,
@@ -554,6 +579,8 @@ def test_api_documents_children_list_authenticated_related_team_members(
554579
"results": [
555580
{
556581
"abilities": child1.get_abilities(user),
582+
"ancestors_link_reach": "restricted",
583+
"ancestors_link_role": None,
557584
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
558585
"creator": str(child1.creator.id),
559586
"depth": 2,
@@ -572,6 +599,8 @@ def test_api_documents_children_list_authenticated_related_team_members(
572599
},
573600
{
574601
"abilities": child2.get_abilities(user),
602+
"ancestors_link_reach": "restricted",
603+
"ancestors_link_role": None,
575604
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
576605
"creator": str(child2.creator.id),
577606
"depth": 2,

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

+50-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ def test_api_documents_descendants_list_anonymous_public_standalone():
3232
"results": [
3333
{
3434
"abilities": child1.get_abilities(AnonymousUser()),
35+
"ancestors_link_reach": "public",
36+
"ancestors_link_role": document.link_role,
3537
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
3638
"creator": str(child1.creator.id),
3739
"depth": 2,
@@ -50,6 +52,10 @@ def test_api_documents_descendants_list_anonymous_public_standalone():
5052
},
5153
{
5254
"abilities": grand_child.get_abilities(AnonymousUser()),
55+
"ancestors_link_reach": "public",
56+
"ancestors_link_role": "editor"
57+
if (child1.link_reach == "public" and child1.link_role == "editor")
58+
else document.link_role,
5359
"created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"),
5460
"creator": str(grand_child.creator.id),
5561
"depth": 3,
@@ -68,6 +74,8 @@ def test_api_documents_descendants_list_anonymous_public_standalone():
6874
},
6975
{
7076
"abilities": child2.get_abilities(AnonymousUser()),
77+
"ancestors_link_reach": "public",
78+
"ancestors_link_role": document.link_role,
7179
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
7280
"creator": str(child2.creator.id),
7381
"depth": 2,
@@ -115,6 +123,8 @@ def test_api_documents_descendants_list_anonymous_public_parent():
115123
"results": [
116124
{
117125
"abilities": child1.get_abilities(AnonymousUser()),
126+
"ancestors_link_reach": "public",
127+
"ancestors_link_role": grand_parent.link_role,
118128
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
119129
"creator": str(child1.creator.id),
120130
"depth": 4,
@@ -133,6 +143,8 @@ def test_api_documents_descendants_list_anonymous_public_parent():
133143
},
134144
{
135145
"abilities": grand_child.get_abilities(AnonymousUser()),
146+
"ancestors_link_reach": "public",
147+
"ancestors_link_role": grand_child.ancestors_link_role,
136148
"created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"),
137149
"creator": str(grand_child.creator.id),
138150
"depth": 5,
@@ -151,6 +163,8 @@ def test_api_documents_descendants_list_anonymous_public_parent():
151163
},
152164
{
153165
"abilities": child2.get_abilities(AnonymousUser()),
166+
"ancestors_link_reach": "public",
167+
"ancestors_link_role": grand_parent.link_role,
154168
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
155169
"creator": str(child2.creator.id),
156170
"depth": 4,
@@ -201,7 +215,9 @@ def test_api_documents_descendants_list_authenticated_unrelated_public_or_authen
201215
client.force_login(user)
202216

203217
document = factories.DocumentFactory(link_reach=reach)
204-
child1, child2 = factories.DocumentFactory.create_batch(2, parent=document)
218+
child1, child2 = factories.DocumentFactory.create_batch(
219+
2, parent=document, link_reach="restricted"
220+
)
205221
grand_child = factories.DocumentFactory(parent=child1)
206222

207223
factories.UserDocumentAccessFactory(document=child1)
@@ -217,6 +233,8 @@ def test_api_documents_descendants_list_authenticated_unrelated_public_or_authen
217233
"results": [
218234
{
219235
"abilities": child1.get_abilities(user),
236+
"ancestors_link_reach": reach,
237+
"ancestors_link_role": document.link_role,
220238
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
221239
"creator": str(child1.creator.id),
222240
"depth": 2,
@@ -235,6 +253,8 @@ def test_api_documents_descendants_list_authenticated_unrelated_public_or_authen
235253
},
236254
{
237255
"abilities": grand_child.get_abilities(user),
256+
"ancestors_link_reach": reach,
257+
"ancestors_link_role": document.link_role,
238258
"created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"),
239259
"creator": str(grand_child.creator.id),
240260
"depth": 3,
@@ -253,6 +273,8 @@ def test_api_documents_descendants_list_authenticated_unrelated_public_or_authen
253273
},
254274
{
255275
"abilities": child2.get_abilities(user),
276+
"ancestors_link_reach": reach,
277+
"ancestors_link_role": document.link_role,
256278
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
257279
"creator": str(child2.creator.id),
258280
"depth": 2,
@@ -289,7 +311,9 @@ def test_api_documents_descendants_list_authenticated_public_or_authenticated_pa
289311
grand_parent = factories.DocumentFactory(link_reach=reach)
290312
parent = factories.DocumentFactory(parent=grand_parent, link_reach="restricted")
291313
document = factories.DocumentFactory(link_reach="restricted", parent=parent)
292-
child1, child2 = factories.DocumentFactory.create_batch(2, parent=document)
314+
child1, child2 = factories.DocumentFactory.create_batch(
315+
2, parent=document, link_reach="restricted"
316+
)
293317
grand_child = factories.DocumentFactory(parent=child1)
294318

295319
factories.UserDocumentAccessFactory(document=child1)
@@ -304,6 +328,8 @@ def test_api_documents_descendants_list_authenticated_public_or_authenticated_pa
304328
"results": [
305329
{
306330
"abilities": child1.get_abilities(user),
331+
"ancestors_link_reach": reach,
332+
"ancestors_link_role": grand_parent.link_role,
307333
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
308334
"creator": str(child1.creator.id),
309335
"depth": 4,
@@ -322,6 +348,8 @@ def test_api_documents_descendants_list_authenticated_public_or_authenticated_pa
322348
},
323349
{
324350
"abilities": grand_child.get_abilities(user),
351+
"ancestors_link_reach": reach,
352+
"ancestors_link_role": grand_parent.link_role,
325353
"created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"),
326354
"creator": str(grand_child.creator.id),
327355
"depth": 5,
@@ -340,6 +368,8 @@ def test_api_documents_descendants_list_authenticated_public_or_authenticated_pa
340368
},
341369
{
342370
"abilities": child2.get_abilities(user),
371+
"ancestors_link_reach": reach,
372+
"ancestors_link_role": grand_parent.link_role,
343373
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
344374
"creator": str(child2.creator.id),
345375
"depth": 4,
@@ -414,6 +444,8 @@ def test_api_documents_descendants_list_authenticated_related_direct():
414444
"results": [
415445
{
416446
"abilities": child1.get_abilities(user),
447+
"ancestors_link_reach": child1.ancestors_link_reach,
448+
"ancestors_link_role": child1.ancestors_link_role,
417449
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
418450
"creator": str(child1.creator.id),
419451
"depth": 2,
@@ -432,6 +464,8 @@ def test_api_documents_descendants_list_authenticated_related_direct():
432464
},
433465
{
434466
"abilities": grand_child.get_abilities(user),
467+
"ancestors_link_reach": grand_child.ancestors_link_reach,
468+
"ancestors_link_role": grand_child.ancestors_link_role,
435469
"created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"),
436470
"creator": str(grand_child.creator.id),
437471
"depth": 3,
@@ -450,6 +484,8 @@ def test_api_documents_descendants_list_authenticated_related_direct():
450484
},
451485
{
452486
"abilities": child2.get_abilities(user),
487+
"ancestors_link_reach": child2.ancestors_link_reach,
488+
"ancestors_link_role": child2.ancestors_link_role,
453489
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
454490
"creator": str(child2.creator.id),
455491
"depth": 2,
@@ -504,6 +540,8 @@ def test_api_documents_descendants_list_authenticated_related_parent():
504540
"results": [
505541
{
506542
"abilities": child1.get_abilities(user),
543+
"ancestors_link_reach": child1.ancestors_link_reach,
544+
"ancestors_link_role": child1.ancestors_link_role,
507545
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
508546
"creator": str(child1.creator.id),
509547
"depth": 4,
@@ -522,6 +560,8 @@ def test_api_documents_descendants_list_authenticated_related_parent():
522560
},
523561
{
524562
"abilities": grand_child.get_abilities(user),
563+
"ancestors_link_reach": grand_child.ancestors_link_reach,
564+
"ancestors_link_role": grand_child.ancestors_link_role,
525565
"created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"),
526566
"creator": str(grand_child.creator.id),
527567
"depth": 5,
@@ -540,6 +580,8 @@ def test_api_documents_descendants_list_authenticated_related_parent():
540580
},
541581
{
542582
"abilities": child2.get_abilities(user),
583+
"ancestors_link_reach": child2.ancestors_link_reach,
584+
"ancestors_link_role": child2.ancestors_link_role,
543585
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
544586
"creator": str(child2.creator.id),
545587
"depth": 4,
@@ -640,6 +682,8 @@ def test_api_documents_descendants_list_authenticated_related_team_members(
640682
"results": [
641683
{
642684
"abilities": child1.get_abilities(user),
685+
"ancestors_link_reach": child1.ancestors_link_reach,
686+
"ancestors_link_role": child1.ancestors_link_role,
643687
"created_at": child1.created_at.isoformat().replace("+00:00", "Z"),
644688
"creator": str(child1.creator.id),
645689
"depth": 2,
@@ -658,6 +702,8 @@ def test_api_documents_descendants_list_authenticated_related_team_members(
658702
},
659703
{
660704
"abilities": grand_child.get_abilities(user),
705+
"ancestors_link_reach": grand_child.ancestors_link_reach,
706+
"ancestors_link_role": grand_child.ancestors_link_role,
661707
"created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"),
662708
"creator": str(grand_child.creator.id),
663709
"depth": 3,
@@ -676,6 +722,8 @@ def test_api_documents_descendants_list_authenticated_related_team_members(
676722
},
677723
{
678724
"abilities": child2.get_abilities(user),
725+
"ancestors_link_reach": child2.ancestors_link_reach,
726+
"ancestors_link_role": child2.ancestors_link_role,
679727
"created_at": child2.created_at.isoformat().replace("+00:00", "Z"),
680728
"creator": str(child2.creator.id),
681729
"depth": 2,

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

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def test_api_document_favorite_list_authenticated_with_favorite():
5959
"results": [
6060
{
6161
"abilities": document.get_abilities(user),
62+
"ancestors_link_reach": None,
63+
"ancestors_link_role": None,
6264
"created_at": document.created_at.isoformat().replace("+00:00", "Z"),
6365
"creator": str(document.creator.id),
6466
"content": document.content,

0 commit comments

Comments
 (0)