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