Coverage for app / backend / src / tests / test_pages.py: 100%
518 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 06:18 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 06:18 +0000
1import grpc
2import pytest
3from google.protobuf import wrappers_pb2
5from couchers.crypto import random_hex
6from couchers.db import session_scope
7from couchers.models import Cluster, ClusterRole, ClusterSubscription, Node, Page, PageType, PageVersion, Thread, Upload
8from couchers.proto import pages_pb2
9from couchers.utils import create_polygon_lat_lng, now, to_aware_datetime, to_multi
10from tests.fixtures.db import generate_user
11from tests.fixtures.sessions import pages_session
12from tests.test_communities import create_community
15@pytest.fixture(autouse=True)
16def _(testconfig):
17 pass
20def test_create_place_errors(db):
21 user, token = generate_user()
22 with session_scope() as session:
23 create_community(session, 0, 2, "Root node", [user], [], None)
25 with pages_session(token) as api:
26 with pytest.raises(grpc.RpcError) as e:
27 api.CreatePlace(
28 pages_pb2.CreatePlaceReq(
29 title=None,
30 content="dummy content",
31 address="dummy address",
32 location=pages_pb2.Coordinate(
33 lat=1,
34 lng=1,
35 ),
36 )
37 )
38 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
39 assert e.value.details() == "Missing page title."
41 with pages_session(token) as api:
42 with pytest.raises(grpc.RpcError) as e:
43 api.CreatePlace(
44 pages_pb2.CreatePlaceReq(
45 title="dummy title",
46 content=None,
47 address="dummy address",
48 location=pages_pb2.Coordinate(
49 lat=1,
50 lng=1,
51 ),
52 )
53 )
54 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
55 assert e.value.details() == "Missing page text."
57 with pages_session(token) as api:
58 with pytest.raises(grpc.RpcError) as e:
59 api.CreatePlace(
60 pages_pb2.CreatePlaceReq(
61 title="dummy title",
62 content="dummy content",
63 address=None,
64 location=pages_pb2.Coordinate(
65 lat=1,
66 lng=1,
67 ),
68 )
69 )
70 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
71 assert e.value.details() == "Missing page address."
73 with pages_session(token) as api:
74 with pytest.raises(grpc.RpcError) as e:
75 api.CreatePlace(
76 pages_pb2.CreatePlaceReq(
77 title="dummy title",
78 content="dummy content",
79 address="dummy address",
80 )
81 )
82 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
83 assert e.value.details() == "Missing page geo-location."
86def test_create_guide_errors(db):
87 user, token = generate_user()
88 with session_scope() as session:
89 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id
91 with pages_session(token) as api:
92 with pytest.raises(grpc.RpcError) as e:
93 api.CreateGuide(
94 pages_pb2.CreateGuideReq(
95 title=None,
96 content="dummy content",
97 parent_community_id=c_id,
98 )
99 )
100 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
101 assert e.value.details() == "Missing page title."
103 with pages_session(token) as api:
104 with pytest.raises(grpc.RpcError) as e:
105 api.CreateGuide(
106 pages_pb2.CreateGuideReq(
107 title="dummy title",
108 content=None,
109 parent_community_id=c_id,
110 )
111 )
112 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
113 assert e.value.details() == "Missing page text."
115 with pages_session(token) as api:
116 with pytest.raises(grpc.RpcError) as e:
117 api.CreateGuide(
118 pages_pb2.CreateGuideReq(
119 title="dummy title",
120 content="dummy content",
121 )
122 )
123 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
124 assert e.value.details() == "Missing page parent."
126 with pages_session(token) as api:
127 with pytest.raises(grpc.RpcError) as e:
128 api.CreateGuide(
129 pages_pb2.CreateGuideReq(
130 title="dummy title",
131 content="dummy content",
132 parent_community_id=9999,
133 )
134 )
135 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
136 assert e.value.details() == "Community not found."
138 with pages_session(token) as api:
139 with pytest.raises(grpc.RpcError) as e:
140 api.CreateGuide(
141 pages_pb2.CreateGuideReq(
142 title="dummy title",
143 content="dummy content",
144 address="dummy address",
145 parent_community_id=c_id,
146 )
147 )
148 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
149 assert e.value.details() == "You need to either supply an address and location or neither for a guide."
151 with pages_session(token) as api:
152 with pytest.raises(grpc.RpcError) as e:
153 api.CreateGuide(
154 pages_pb2.CreateGuideReq(
155 title="dummy title",
156 content="dummy content",
157 location=pages_pb2.Coordinate(
158 lat=1,
159 lng=1,
160 ),
161 parent_community_id=c_id,
162 )
163 )
164 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
165 assert e.value.details() == "You need to either supply an address and location or neither for a guide."
168def test_create_page_place(db):
169 user, token = generate_user()
170 with session_scope() as session:
171 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id
173 with pages_session(token) as api:
174 time_before = now()
175 res = api.CreatePlace(
176 pages_pb2.CreatePlaceReq(
177 title="dummy !#¤%&/-*' title",
178 content="dummy content",
179 address="dummy address",
180 location=pages_pb2.Coordinate(
181 lat=1,
182 lng=1,
183 ),
184 )
185 )
187 assert res.title == "dummy !#¤%&/-*' title"
188 assert res.type == pages_pb2.PAGE_TYPE_PLACE
189 assert res.content == "dummy content"
190 assert res.address == "dummy address"
191 assert res.location.lat == 1
192 assert res.location.lng == 1
193 assert res.slug == "dummy-title"
194 assert time_before <= to_aware_datetime(res.created) <= now()
195 assert time_before <= to_aware_datetime(res.last_edited) <= now()
196 assert res.last_editor_user_id == user.id
197 assert res.creator_user_id == user.id
198 assert res.owner_user_id == user.id
199 assert not res.owner_community_id
200 assert not res.owner_group_id
201 assert res.editor_user_ids == [user.id]
202 assert res.can_edit
203 assert res.can_moderate
206def test_create_page_guide(db):
207 user, token = generate_user()
208 with session_scope() as session:
209 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id
211 with pages_session(token) as api:
212 time_before = now()
213 res = api.CreateGuide(
214 pages_pb2.CreateGuideReq(
215 title="dummy title",
216 content="dummy content",
217 address="dummy address",
218 location=pages_pb2.Coordinate(
219 lat=1,
220 lng=1,
221 ),
222 parent_community_id=c_id,
223 )
224 )
226 assert res.title == "dummy title"
227 assert res.type == pages_pb2.PAGE_TYPE_GUIDE
228 assert res.content == "dummy content"
229 assert res.address == "dummy address"
230 assert res.location.lat == 1
231 assert res.location.lng == 1
232 assert res.slug == "dummy-title"
233 assert time_before <= to_aware_datetime(res.created) <= now()
234 assert time_before <= to_aware_datetime(res.last_edited) <= now()
235 assert res.last_editor_user_id == user.id
236 assert res.creator_user_id == user.id
237 assert res.owner_user_id == user.id
238 assert not res.owner_community_id
239 assert not res.owner_group_id
240 assert res.editor_user_ids == [user.id]
241 assert res.can_edit
242 assert res.can_moderate
244 with pages_session(token) as api:
245 time_before = now()
246 res = api.CreateGuide(
247 pages_pb2.CreateGuideReq(
248 title="dummy title",
249 content="dummy content",
250 parent_community_id=c_id,
251 )
252 )
254 assert res.title == "dummy title"
255 assert res.type == pages_pb2.PAGE_TYPE_GUIDE
256 assert res.content == "dummy content"
257 assert not res.address
258 assert not res.HasField("location")
259 assert res.slug == "dummy-title"
260 assert time_before <= to_aware_datetime(res.created) <= now()
261 assert time_before <= to_aware_datetime(res.last_edited) <= now()
262 assert res.last_editor_user_id == user.id
263 assert res.creator_user_id == user.id
264 assert res.owner_user_id == user.id
265 assert not res.owner_community_id
266 assert not res.owner_group_id
267 assert res.editor_user_ids == [user.id]
268 assert res.can_edit
269 assert res.can_moderate
272def test_get_page(db):
273 user1, token1 = generate_user()
274 user2, token2 = generate_user()
275 with session_scope() as session:
276 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id
278 with pages_session(token1) as api:
279 time_before_create = now()
280 page_id = api.CreatePlace(
281 pages_pb2.CreatePlaceReq(
282 title="dummy title",
283 content="dummy content",
284 address="dummy address",
285 location=pages_pb2.Coordinate(
286 lat=1,
287 lng=1,
288 ),
289 )
290 ).page_id
292 with pages_session(token2) as api:
293 time_before_get = now()
294 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id))
295 assert res.title == "dummy title"
296 assert res.content == "dummy content"
297 assert res.address == "dummy address"
298 assert res.location.lat == 1
299 assert res.location.lng == 1
300 assert res.slug == "dummy-title"
301 assert time_before_create <= to_aware_datetime(res.created) <= time_before_get
302 assert time_before_create <= to_aware_datetime(res.last_edited) <= time_before_get
303 assert res.last_editor_user_id == user1.id
304 assert res.creator_user_id == user1.id
305 assert res.owner_user_id == user1.id
306 assert not res.owner_community_id
307 assert not res.owner_group_id
308 assert res.editor_user_ids == [user1.id]
309 assert not res.can_edit
310 assert not res.can_moderate
311 assert res.thread.thread_id > 0
312 assert res.thread.num_responses == 0
315def test_update_page(db):
316 user, token = generate_user()
317 with session_scope() as session:
318 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id
320 with pages_session(token) as api:
321 time_before_create = now()
322 page_id = api.CreatePlace(
323 pages_pb2.CreatePlaceReq(
324 title="dummy title",
325 content="dummy content",
326 address="dummy address",
327 location=pages_pb2.Coordinate(
328 lat=1,
329 lng=1,
330 ),
331 )
332 ).page_id
334 time_before_update = now()
335 api.UpdatePage(
336 pages_pb2.UpdatePageReq(
337 page_id=page_id,
338 title=wrappers_pb2.StringValue(value="test title"),
339 )
340 )
342 time_before_get = now()
343 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id))
344 assert res.title == "test title"
345 assert res.content == "dummy content"
346 assert res.address == "dummy address"
347 assert res.location.lat == 1
348 assert res.location.lng == 1
349 assert res.slug == "test-title"
350 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update
351 assert time_before_update <= to_aware_datetime(res.last_edited) <= time_before_get
352 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited)
353 assert res.last_editor_user_id == user.id
354 assert res.creator_user_id == user.id
355 assert res.owner_user_id == user.id
356 assert not res.owner_community_id
357 assert not res.owner_group_id
358 assert res.editor_user_ids == [user.id]
359 assert res.can_edit
360 assert res.can_moderate
362 time_before_second_update = now()
363 api.UpdatePage(
364 pages_pb2.UpdatePageReq(
365 page_id=page_id,
366 content=wrappers_pb2.StringValue(value="test content"),
367 )
368 )
370 time_before_second_get = now()
371 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id))
372 assert res.title == "test title"
373 assert res.content == "test content"
374 assert res.address == "dummy address"
375 assert res.location.lat == 1
376 assert res.location.lng == 1
377 assert res.slug == "test-title"
378 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update
379 assert time_before_second_update <= to_aware_datetime(res.last_edited) <= time_before_second_get
380 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited)
381 assert res.last_editor_user_id == user.id
382 assert res.creator_user_id == user.id
383 assert res.owner_user_id == user.id
384 assert not res.owner_community_id
385 assert not res.owner_group_id
386 assert res.editor_user_ids == [user.id]
387 assert res.can_edit
388 assert res.can_moderate
389 assert res.thread.thread_id > 0
390 assert res.thread.num_responses == 0
392 time_before_third_update = now()
393 api.UpdatePage(
394 pages_pb2.UpdatePageReq(
395 page_id=page_id,
396 address=wrappers_pb2.StringValue(value="test address"),
397 )
398 )
400 time_before_third_get = now()
401 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id))
402 assert res.title == "test title"
403 assert res.content == "test content"
404 assert res.address == "test address"
405 assert res.location.lat == 1
406 assert res.location.lng == 1
407 assert res.slug == "test-title"
408 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update
409 assert time_before_third_update <= to_aware_datetime(res.last_edited) <= time_before_third_get
410 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited)
411 assert res.last_editor_user_id == user.id
412 assert res.creator_user_id == user.id
413 assert res.owner_user_id == user.id
414 assert not res.owner_community_id
415 assert not res.owner_group_id
416 assert res.editor_user_ids == [user.id]
417 assert res.can_edit
418 assert res.can_moderate
419 assert res.thread.thread_id > 0
420 assert res.thread.num_responses == 0
422 time_before_fourth_update = now()
423 api.UpdatePage(
424 pages_pb2.UpdatePageReq(
425 page_id=page_id,
426 location=pages_pb2.Coordinate(
427 lat=3,
428 lng=1.222,
429 ),
430 )
431 )
433 time_before_fourth_get = now()
434 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id))
435 assert res.title == "test title"
436 assert res.content == "test content"
437 assert res.address == "test address"
438 assert res.location.lat == 3
439 assert res.location.lng == 1.222
440 assert res.slug == "test-title"
441 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update
442 assert time_before_fourth_update <= to_aware_datetime(res.last_edited) <= time_before_fourth_get
443 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited)
444 assert res.last_editor_user_id == user.id
445 assert res.creator_user_id == user.id
446 assert res.owner_user_id == user.id
447 assert not res.owner_community_id
448 assert not res.owner_group_id
449 assert res.editor_user_ids == [user.id]
450 assert res.can_edit
451 assert res.can_moderate
452 assert res.thread.thread_id > 0
453 assert res.thread.num_responses == 0
456def test_owner_not_moderator(db):
457 """
458 You can be the owner of content yet not have moderation rights
459 """
460 user1, token1 = generate_user()
461 user2, token2 = generate_user()
462 with session_scope() as session:
463 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id
465 # user2 makes page, is owner but not moderator, so can edit, not moderate
466 with pages_session(token2) as api:
467 res = api.CreatePlace(
468 pages_pb2.CreatePlaceReq(
469 title="dummy title",
470 content="dummy content",
471 address="dummy address",
472 location=pages_pb2.Coordinate(
473 lat=1,
474 lng=1,
475 ),
476 )
477 )
478 assert res.title == "dummy title"
479 assert res.content == "dummy content"
480 assert res.address == "dummy address"
481 assert res.location.lat == 1
482 assert res.location.lng == 1
483 assert res.slug == "dummy-title"
484 assert res.last_editor_user_id == user2.id
485 assert res.creator_user_id == user2.id
486 assert res.owner_user_id == user2.id
487 assert not res.owner_community_id
488 assert not res.owner_group_id
489 assert res.editor_user_ids == [user2.id]
490 assert res.can_edit
491 assert not res.can_moderate
493 page_id = res.page_id
495 # user1 is not owner so can't edit but can moderate
496 with pages_session(token1) as api:
497 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id))
498 assert res.title == "dummy title"
499 assert res.content == "dummy content"
500 assert res.address == "dummy address"
501 assert res.location.lat == 1
502 assert res.location.lng == 1
503 assert res.slug == "dummy-title"
504 assert res.last_editor_user_id == user2.id
505 assert res.creator_user_id == user2.id
506 assert res.owner_user_id == user2.id
507 assert not res.owner_community_id
508 assert not res.owner_group_id
509 assert res.editor_user_ids == [user2.id]
510 assert res.can_edit
511 assert res.can_moderate
512 assert res.thread.thread_id > 0
513 assert res.thread.num_responses == 0
516def test_update_page_errors(db):
517 user, token = generate_user()
518 with session_scope() as session:
519 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id
521 with pages_session(token) as api:
522 page_id = api.CreatePlace(
523 pages_pb2.CreatePlaceReq(
524 title="dummy title",
525 content="dummy content",
526 address="dummy address",
527 location=pages_pb2.Coordinate(
528 lat=1,
529 lng=1,
530 ),
531 )
532 ).page_id
534 with pytest.raises(grpc.RpcError) as e:
535 api.UpdatePage(
536 pages_pb2.UpdatePageReq(
537 page_id=page_id,
538 title=wrappers_pb2.StringValue(value=""),
539 )
540 )
541 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
542 assert e.value.details() == "Missing page title."
544 with pytest.raises(grpc.RpcError) as e:
545 api.UpdatePage(
546 pages_pb2.UpdatePageReq(
547 page_id=page_id,
548 content=wrappers_pb2.StringValue(value=""),
549 )
550 )
551 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
552 assert e.value.details() == "Missing page text."
554 with pytest.raises(grpc.RpcError) as e:
555 api.UpdatePage(
556 pages_pb2.UpdatePageReq(
557 page_id=page_id,
558 address=wrappers_pb2.StringValue(value=""),
559 )
560 )
561 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
562 assert e.value.details() == "Missing page address."
565def test_page_transfer(db):
566 # transfers the pages
567 user1, token1 = generate_user()
568 # admin of the community/group
569 user2, token2 = generate_user()
570 # member of the community/group, shouldn't ever have edit access to anything
571 user3, token3 = generate_user()
572 with session_scope() as session:
573 # create a community
574 node = Node(geom=to_multi(create_polygon_lat_lng([[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]])))
575 session.add(node)
576 session.flush()
577 community_cluster = Cluster(
578 name="Testing Community",
579 description="Description for testing community",
580 parent_node_id=node.id,
581 is_official_cluster=True,
582 )
583 session.add(community_cluster)
584 session.flush()
585 thread = Thread()
586 session.add(thread)
587 session.flush()
588 main_page = Page(
589 parent_node_id=community_cluster.parent_node_id,
590 creator_user_id=user2.id,
591 owner_cluster_id=community_cluster.id,
592 type=PageType.main_page,
593 thread_id=thread.id,
594 )
595 session.add(main_page)
596 session.flush()
597 session.add(
598 PageVersion(
599 page_id=main_page.id,
600 editor_user_id=user2.id,
601 title="Main page for the testing community",
602 content="Empty.",
603 )
604 )
605 community_cluster.cluster_subscriptions.append(
606 ClusterSubscription(
607 user_id=user2.id,
608 cluster_id=community_cluster.id,
609 role=ClusterRole.admin,
610 )
611 )
612 community_cluster.cluster_subscriptions.append(
613 ClusterSubscription(
614 user_id=user3.id,
615 cluster_id=community_cluster.id,
616 role=ClusterRole.member,
617 )
618 )
620 # create a group
621 group_cluster = Cluster(
622 name="Testing Group",
623 description="Description for testing group",
624 parent_node_id=node.id,
625 )
626 session.add(group_cluster)
627 session.flush()
628 thread = Thread()
629 session.add(thread)
630 session.flush()
631 main_page = Page(
632 parent_node_id=group_cluster.parent_node_id,
633 creator_user_id=user2.id,
634 owner_cluster_id=group_cluster.id,
635 type=PageType.main_page,
636 thread_id=thread.id,
637 )
638 session.add(main_page)
639 session.flush()
640 session.add(
641 PageVersion(
642 page_id=main_page.id,
643 editor_user_id=user2.id,
644 title="Main page for the testing community",
645 content="Empty.",
646 )
647 )
648 group_cluster.cluster_subscriptions.append(
649 ClusterSubscription(
650 user_id=user2.id,
651 cluster_id=group_cluster.id,
652 role=ClusterRole.admin,
653 )
654 )
655 group_cluster.cluster_subscriptions.append(
656 ClusterSubscription(
657 user_id=user3.id,
658 cluster_id=group_cluster.id,
659 role=ClusterRole.member,
660 )
661 )
662 session.flush()
664 community_id = node.id
665 community_cluster_id = community_cluster.id
666 group_id = group_cluster.id
668 with pages_session(token1) as api:
669 create_page_req = pages_pb2.CreatePlaceReq(
670 title="title",
671 content="content",
672 address="address",
673 location=pages_pb2.Coordinate(
674 lat=1,
675 lng=1,
676 ),
677 )
679 # transfer should work fine to a community
680 page1 = api.CreatePlace(create_page_req)
681 assert page1.owner_user_id == user1.id
682 assert page1.can_edit
683 assert not page1.can_moderate
685 with pages_session(token2) as api:
686 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
687 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate
689 with pages_session(token3) as api:
690 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
691 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate
693 with pages_session(token1) as api:
694 page1 = api.TransferPage(
695 pages_pb2.TransferPageReq(
696 page_id=page1.page_id,
697 new_owner_community_id=community_id,
698 )
699 )
700 assert page1.owner_community_id == community_id
701 assert not page1.can_edit
702 assert not page1.can_moderate
704 with pages_session(token2) as api:
705 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
706 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate
708 with pages_session(token3) as api:
709 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
710 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate
712 with pages_session(token1) as api:
713 # now we're no longer the owner, can't transfer
714 page1 = api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id))
715 with pytest.raises(grpc.RpcError) as e:
716 api.TransferPage(
717 pages_pb2.TransferPageReq(
718 page_id=page1.page_id,
719 new_owner_group_id=group_id,
720 )
721 )
722 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
723 assert e.value.details() == "You're not allowed to transfer that page."
724 page1 = api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id))
725 assert page1.owner_community_id == community_id
726 assert not page1.can_edit
727 assert not page1.can_moderate
729 with pages_session(token2) as api:
730 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
731 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate
733 with pages_session(token3) as api:
734 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit
735 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate
737 with pages_session(token1) as api:
738 # try a new page, just for fun
739 page2 = api.CreatePlace(create_page_req)
740 assert page2.owner_user_id == user1.id
742 page2 = api.TransferPage(
743 pages_pb2.TransferPageReq(
744 page_id=page2.page_id,
745 new_owner_community_id=community_id,
746 )
747 )
748 assert page2.owner_community_id == community_id
750 with pages_session(token2) as api:
751 assert api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_edit
752 assert api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_moderate
754 with pages_session(token3) as api:
755 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_edit
756 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_moderate
758 with pages_session(token1) as api:
759 # can't transfer a page to an official cluster, only through community
760 page3 = api.CreatePlace(create_page_req)
761 assert page3.owner_user_id == user1.id
763 with pytest.raises(grpc.RpcError) as e:
764 api.TransferPage(
765 pages_pb2.TransferPageReq(
766 page_id=page3.page_id,
767 new_owner_community_id=community_cluster_id,
768 )
769 )
770 assert e.value.code() == grpc.StatusCode.NOT_FOUND
771 assert e.value.details() == "Group or community not found."
772 page3 = api.GetPage(pages_pb2.GetPageReq(page_id=page3.page_id))
773 assert page3.owner_user_id == user1.id
775 # can transfer to group
776 page4 = api.CreatePlace(create_page_req)
777 assert page4.owner_user_id == user1.id
778 assert page4.can_edit
779 assert not page4.can_moderate
781 with pages_session(token2) as api:
782 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
783 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate
785 with pages_session(token3) as api:
786 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
787 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate
789 with pages_session(token1) as api:
790 page4 = api.TransferPage(
791 pages_pb2.TransferPageReq(
792 page_id=page4.page_id,
793 new_owner_group_id=group_id,
794 )
795 )
796 assert page4.owner_group_id == group_id
797 assert not page4.can_edit
798 assert not page4.can_moderate
800 with pages_session(token2) as api:
801 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
802 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate
804 with pages_session(token3) as api:
805 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit
806 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate
808 with pages_session(token1) as api:
809 # now we're no longer the owner, can't transfer
810 with pytest.raises(grpc.RpcError) as e:
811 api.TransferPage(
812 pages_pb2.TransferPageReq(
813 page_id=page4.page_id,
814 new_owner_community_id=community_id,
815 )
816 )
817 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED
818 assert e.value.details() == "You're not allowed to transfer that page."
819 page4 = api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id))
820 assert page4.owner_group_id == group_id
823def test_page_photo(db):
824 user, token = generate_user()
825 with session_scope() as session:
826 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id
828 with pages_session(token) as api:
829 key1 = random_hex(32)
830 filename1 = random_hex(32)
832 with session_scope() as session:
833 session.add(
834 Upload(
835 key=key1,
836 filename=filename1,
837 creator_user_id=user.id,
838 )
839 )
841 res = api.CreatePlace(
842 pages_pb2.CreatePlaceReq(
843 title="dummy title",
844 content="dummy content",
845 photo_key=key1,
846 address="dummy address",
847 location=pages_pb2.Coordinate(
848 lat=1,
849 lng=1,
850 ),
851 )
852 )
854 assert filename1 in res.photo_url
856 # can't create with non-existent photo
857 with pytest.raises(grpc.RpcError) as e:
858 api.CreatePlace(
859 pages_pb2.CreatePlaceReq(
860 title="dummy title",
861 content="dummy content",
862 photo_key="nonexisten",
863 address="dummy address",
864 location=pages_pb2.Coordinate(
865 lat=1,
866 lng=1,
867 ),
868 )
869 )
870 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
871 assert e.value.details() == "Photo not found."
873 # can create page with no photo
874 res = api.CreatePlace(
875 pages_pb2.CreatePlaceReq(
876 title="dummy title",
877 content="dummy content",
878 address="dummy address",
879 location=pages_pb2.Coordinate(
880 lat=1,
881 lng=1,
882 ),
883 )
884 )
886 assert res.photo_url == ""
888 page_id = res.page_id
890 # can't set it to non-existent stuff
891 with pytest.raises(grpc.RpcError) as e:
892 api.UpdatePage(
893 pages_pb2.UpdatePageReq(
894 page_id=page_id,
895 photo_key=wrappers_pb2.StringValue(value="non-existent id"),
896 )
897 )
898 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
899 assert e.value.details() == "Photo not found."
901 key2 = random_hex(32)
902 filename2 = random_hex(32)
904 with session_scope() as session:
905 session.add(
906 Upload(
907 key=key2,
908 filename=filename2,
909 creator_user_id=user.id,
910 )
911 )
913 res = api.UpdatePage(
914 pages_pb2.UpdatePageReq(
915 page_id=page_id,
916 photo_key=wrappers_pb2.StringValue(value=key2),
917 )
918 )
920 assert filename2 in res.photo_url
922 # can unset it
924 res = api.UpdatePage(
925 pages_pb2.UpdatePageReq(
926 page_id=page_id,
927 photo_key=wrappers_pb2.StringValue(value=""),
928 )
929 )
931 assert res.photo_url == ""
934def test_list_user_places(db):
935 user1, token1 = generate_user()
936 with session_scope() as session:
937 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id
939 with pages_session(token1) as api:
940 place1_id = api.CreatePlace(
941 pages_pb2.CreatePlaceReq(
942 title="dummy title",
943 content="dummy content",
944 address="dummy address",
945 location=pages_pb2.Coordinate(
946 lat=1,
947 lng=1,
948 ),
949 )
950 ).page_id
952 place2_id = api.CreatePlace(
953 pages_pb2.CreatePlaceReq(
954 title="dummy title 2",
955 content="dummy content 2",
956 address="dummy address 2",
957 location=pages_pb2.Coordinate(
958 lat=1,
959 lng=1,
960 ),
961 )
962 ).page_id
964 with pages_session(token1) as api:
965 res = api.ListUserPlaces(pages_pb2.ListUserPlacesReq())
966 assert [p.page_id for p in res.places] == [place1_id, place2_id]
969def test_list_other_user_places(db):
970 user1, token1 = generate_user()
971 user2, token2 = generate_user()
972 with session_scope() as session:
973 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id
975 with pages_session(token1) as api:
976 place1_id = api.CreatePlace(
977 pages_pb2.CreatePlaceReq(
978 title="dummy title",
979 content="dummy content",
980 address="dummy address",
981 location=pages_pb2.Coordinate(
982 lat=1,
983 lng=1,
984 ),
985 )
986 ).page_id
988 place2_id = api.CreatePlace(
989 pages_pb2.CreatePlaceReq(
990 title="dummy title 2",
991 content="dummy content 2",
992 address="dummy address 2",
993 location=pages_pb2.Coordinate(
994 lat=1,
995 lng=1,
996 ),
997 )
998 ).page_id
1000 with pages_session(token2) as api:
1001 res = api.ListUserPlaces(pages_pb2.ListUserPlacesReq(user_id=user1.id))
1002 assert [p.page_id for p in res.places] == [place1_id, place2_id]
1005def test_list_user_guides(db):
1006 user1, token1 = generate_user()
1007 with session_scope() as session:
1008 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id
1010 with pages_session(token1) as api:
1011 guide1_id = api.CreateGuide(
1012 pages_pb2.CreateGuideReq(
1013 title="dummy title",
1014 content="dummy content",
1015 address="dummy address",
1016 location=pages_pb2.Coordinate(
1017 lat=1,
1018 lng=1,
1019 ),
1020 parent_community_id=c_id,
1021 )
1022 ).page_id
1024 guide2_id = api.CreateGuide(
1025 pages_pb2.CreateGuideReq(
1026 title="dummy title 2",
1027 content="dummy content 2",
1028 address="dummy address 2",
1029 location=pages_pb2.Coordinate(
1030 lat=1,
1031 lng=1,
1032 ),
1033 parent_community_id=c_id,
1034 )
1035 ).page_id
1037 with pages_session(token1) as api:
1038 res = api.ListUserGuides(pages_pb2.ListUserGuidesReq())
1039 assert [p.page_id for p in res.guides] == [guide1_id, guide2_id]
1042def test_list_other_user_guides(db):
1043 user1, token1 = generate_user()
1044 user2, token2 = generate_user()
1045 with session_scope() as session:
1046 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id
1048 with pages_session(token1) as api:
1049 guide1_id = api.CreateGuide(
1050 pages_pb2.CreateGuideReq(
1051 title="dummy title",
1052 content="dummy content",
1053 address="dummy address",
1054 location=pages_pb2.Coordinate(
1055 lat=1,
1056 lng=1,
1057 ),
1058 parent_community_id=c_id,
1059 )
1060 ).page_id
1062 guide2_id = api.CreateGuide(
1063 pages_pb2.CreateGuideReq(
1064 title="dummy title 2",
1065 content="dummy content 2",
1066 address="dummy address 2",
1067 location=pages_pb2.Coordinate(
1068 lat=1,
1069 lng=1,
1070 ),
1071 parent_community_id=c_id,
1072 )
1073 ).page_id
1075 with pages_session(token2) as api:
1076 res = api.ListUserGuides(pages_pb2.ListUserGuidesReq(user_id=user1.id))
1077 assert [p.page_id for p in res.guides] == [guide1_id, guide2_id]