Coverage for src/tests/test_pages.py: 100%

506 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-12-20 11:53 +0000

1import grpc 

2import pytest 

3from google.protobuf import wrappers_pb2 

4 

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.test_communities import create_community 

11from tests.test_fixtures import db, generate_user, pages_session, testconfig # noqa 

12 

13 

14@pytest.fixture(autouse=True) 

15def _(testconfig): 

16 pass 

17 

18 

19def test_create_place_errors(db): 

20 user, token = generate_user() 

21 with session_scope() as session: 

22 create_community(session, 0, 2, "Root node", [user], [], None) 

23 

24 with pages_session(token) as api: 

25 with pytest.raises(grpc.RpcError) as e: 

26 api.CreatePlace( 

27 pages_pb2.CreatePlaceReq( 

28 title=None, 

29 content="dummy content", 

30 address="dummy address", 

31 location=pages_pb2.Coordinate( 

32 lat=1, 

33 lng=1, 

34 ), 

35 ) 

36 ) 

37 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

38 assert e.value.details() == "Missing page title." 

39 

40 with pages_session(token) as api: 

41 with pytest.raises(grpc.RpcError) as e: 

42 api.CreatePlace( 

43 pages_pb2.CreatePlaceReq( 

44 title="dummy title", 

45 content=None, 

46 address="dummy address", 

47 location=pages_pb2.Coordinate( 

48 lat=1, 

49 lng=1, 

50 ), 

51 ) 

52 ) 

53 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

54 assert e.value.details() == "Missing page text." 

55 

56 with pages_session(token) as api: 

57 with pytest.raises(grpc.RpcError) as e: 

58 api.CreatePlace( 

59 pages_pb2.CreatePlaceReq( 

60 title="dummy title", 

61 content="dummy content", 

62 address=None, 

63 location=pages_pb2.Coordinate( 

64 lat=1, 

65 lng=1, 

66 ), 

67 ) 

68 ) 

69 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

70 assert e.value.details() == "Missing page address." 

71 

72 with pages_session(token) as api: 

73 with pytest.raises(grpc.RpcError) as e: 

74 api.CreatePlace( 

75 pages_pb2.CreatePlaceReq( 

76 title="dummy title", 

77 content="dummy content", 

78 address="dummy address", 

79 ) 

80 ) 

81 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

82 assert e.value.details() == "Missing page geo-location." 

83 

84 

85def test_create_guide_errors(db): 

86 user, token = generate_user() 

87 with session_scope() as session: 

88 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id 

89 

90 with pages_session(token) as api: 

91 with pytest.raises(grpc.RpcError) as e: 

92 api.CreateGuide( 

93 pages_pb2.CreateGuideReq( 

94 title=None, 

95 content="dummy content", 

96 parent_community_id=c_id, 

97 ) 

98 ) 

99 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

100 assert e.value.details() == "Missing page title." 

101 

102 with pages_session(token) as api: 

103 with pytest.raises(grpc.RpcError) as e: 

104 api.CreateGuide( 

105 pages_pb2.CreateGuideReq( 

106 title="dummy title", 

107 content=None, 

108 parent_community_id=c_id, 

109 ) 

110 ) 

111 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

112 assert e.value.details() == "Missing page text." 

113 

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="dummy content", 

120 ) 

121 ) 

122 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

123 assert e.value.details() == "Missing page parent." 

124 

125 with pages_session(token) as api: 

126 with pytest.raises(grpc.RpcError) as e: 

127 api.CreateGuide( 

128 pages_pb2.CreateGuideReq( 

129 title="dummy title", 

130 content="dummy content", 

131 parent_community_id=9999, 

132 ) 

133 ) 

134 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

135 assert e.value.details() == "Community not found." 

136 

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 address="dummy address", 

144 parent_community_id=c_id, 

145 ) 

146 ) 

147 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

148 assert e.value.details() == "You need to either supply an address and location or neither for a guide." 

149 

150 with pages_session(token) as api: 

151 with pytest.raises(grpc.RpcError) as e: 

152 api.CreateGuide( 

153 pages_pb2.CreateGuideReq( 

154 title="dummy title", 

155 content="dummy content", 

156 location=pages_pb2.Coordinate( 

157 lat=1, 

158 lng=1, 

159 ), 

160 parent_community_id=c_id, 

161 ) 

162 ) 

163 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

164 assert e.value.details() == "You need to either supply an address and location or neither for a guide." 

165 

166 

167def test_create_page_place(db): 

168 user, token = generate_user() 

169 with session_scope() as session: 

170 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id 

171 

172 with pages_session(token) as api: 

173 time_before = now() 

174 res = api.CreatePlace( 

175 pages_pb2.CreatePlaceReq( 

176 title="dummy !#¤%&/-*' title", 

177 content="dummy content", 

178 address="dummy address", 

179 location=pages_pb2.Coordinate( 

180 lat=1, 

181 lng=1, 

182 ), 

183 ) 

184 ) 

185 

186 assert res.title == "dummy !#¤%&/-*' title" 

187 assert res.type == pages_pb2.PAGE_TYPE_PLACE 

188 assert res.content == "dummy content" 

189 assert res.address == "dummy address" 

190 assert res.location.lat == 1 

191 assert res.location.lng == 1 

192 assert res.slug == "dummy-title" 

193 assert time_before <= to_aware_datetime(res.created) <= now() 

194 assert time_before <= to_aware_datetime(res.last_edited) <= now() 

195 assert res.last_editor_user_id == user.id 

196 assert res.creator_user_id == user.id 

197 assert res.owner_user_id == user.id 

198 assert not res.owner_community_id 

199 assert not res.owner_group_id 

200 assert res.editor_user_ids == [user.id] 

201 assert res.can_edit 

202 assert res.can_moderate 

203 

204 

205def test_create_page_guide(db): 

206 user, token = generate_user() 

207 with session_scope() as session: 

208 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id 

209 

210 with pages_session(token) as api: 

211 time_before = now() 

212 res = api.CreateGuide( 

213 pages_pb2.CreateGuideReq( 

214 title="dummy title", 

215 content="dummy content", 

216 address="dummy address", 

217 location=pages_pb2.Coordinate( 

218 lat=1, 

219 lng=1, 

220 ), 

221 parent_community_id=c_id, 

222 ) 

223 ) 

224 

225 assert res.title == "dummy title" 

226 assert res.type == pages_pb2.PAGE_TYPE_GUIDE 

227 assert res.content == "dummy content" 

228 assert res.address == "dummy address" 

229 assert res.location.lat == 1 

230 assert res.location.lng == 1 

231 assert res.slug == "dummy-title" 

232 assert time_before <= to_aware_datetime(res.created) <= now() 

233 assert time_before <= to_aware_datetime(res.last_edited) <= now() 

234 assert res.last_editor_user_id == user.id 

235 assert res.creator_user_id == user.id 

236 assert res.owner_user_id == user.id 

237 assert not res.owner_community_id 

238 assert not res.owner_group_id 

239 assert res.editor_user_ids == [user.id] 

240 assert res.can_edit 

241 assert res.can_moderate 

242 

243 with pages_session(token) as api: 

244 time_before = now() 

245 res = api.CreateGuide( 

246 pages_pb2.CreateGuideReq( 

247 title="dummy title", 

248 content="dummy content", 

249 parent_community_id=c_id, 

250 ) 

251 ) 

252 

253 assert res.title == "dummy title" 

254 assert res.type == pages_pb2.PAGE_TYPE_GUIDE 

255 assert res.content == "dummy content" 

256 assert not res.address 

257 assert not res.HasField("location") 

258 assert res.slug == "dummy-title" 

259 assert time_before <= to_aware_datetime(res.created) <= now() 

260 assert time_before <= to_aware_datetime(res.last_edited) <= now() 

261 assert res.last_editor_user_id == user.id 

262 assert res.creator_user_id == user.id 

263 assert res.owner_user_id == user.id 

264 assert not res.owner_community_id 

265 assert not res.owner_group_id 

266 assert res.editor_user_ids == [user.id] 

267 assert res.can_edit 

268 assert res.can_moderate 

269 

270 

271def test_get_page(db): 

272 user1, token1 = generate_user() 

273 user2, token2 = generate_user() 

274 with session_scope() as session: 

275 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id 

276 

277 with pages_session(token1) as api: 

278 time_before_create = now() 

279 page_id = api.CreatePlace( 

280 pages_pb2.CreatePlaceReq( 

281 title="dummy title", 

282 content="dummy content", 

283 address="dummy address", 

284 location=pages_pb2.Coordinate( 

285 lat=1, 

286 lng=1, 

287 ), 

288 ) 

289 ).page_id 

290 

291 with pages_session(token2) as api: 

292 time_before_get = now() 

293 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) 

294 assert res.title == "dummy title" 

295 assert res.content == "dummy content" 

296 assert res.address == "dummy address" 

297 assert res.location.lat == 1 

298 assert res.location.lng == 1 

299 assert res.slug == "dummy-title" 

300 assert time_before_create <= to_aware_datetime(res.created) <= time_before_get 

301 assert time_before_create <= to_aware_datetime(res.last_edited) <= time_before_get 

302 assert res.last_editor_user_id == user1.id 

303 assert res.creator_user_id == user1.id 

304 assert res.owner_user_id == user1.id 

305 assert not res.owner_community_id 

306 assert not res.owner_group_id 

307 assert res.editor_user_ids == [user1.id] 

308 assert not res.can_edit 

309 assert not res.can_moderate 

310 assert res.thread.thread_id > 0 

311 assert res.thread.num_responses == 0 

312 

313 

314def test_update_page(db): 

315 user, token = generate_user() 

316 with session_scope() as session: 

317 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id 

318 

319 with pages_session(token) as api: 

320 time_before_create = now() 

321 page_id = api.CreatePlace( 

322 pages_pb2.CreatePlaceReq( 

323 title="dummy title", 

324 content="dummy content", 

325 address="dummy address", 

326 location=pages_pb2.Coordinate( 

327 lat=1, 

328 lng=1, 

329 ), 

330 ) 

331 ).page_id 

332 

333 time_before_update = now() 

334 api.UpdatePage( 

335 pages_pb2.UpdatePageReq( 

336 page_id=page_id, 

337 title=wrappers_pb2.StringValue(value="test title"), 

338 ) 

339 ) 

340 

341 time_before_get = now() 

342 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) 

343 assert res.title == "test title" 

344 assert res.content == "dummy content" 

345 assert res.address == "dummy address" 

346 assert res.location.lat == 1 

347 assert res.location.lng == 1 

348 assert res.slug == "test-title" 

349 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update 

350 assert time_before_update <= to_aware_datetime(res.last_edited) <= time_before_get 

351 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited) 

352 assert res.last_editor_user_id == user.id 

353 assert res.creator_user_id == user.id 

354 assert res.owner_user_id == user.id 

355 assert not res.owner_community_id 

356 assert not res.owner_group_id 

357 assert res.editor_user_ids == [user.id] 

358 assert res.can_edit 

359 assert res.can_moderate 

360 

361 time_before_second_update = now() 

362 api.UpdatePage( 

363 pages_pb2.UpdatePageReq( 

364 page_id=page_id, 

365 content=wrappers_pb2.StringValue(value="test content"), 

366 ) 

367 ) 

368 

369 time_before_second_get = now() 

370 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) 

371 assert res.title == "test title" 

372 assert res.content == "test content" 

373 assert res.address == "dummy address" 

374 assert res.location.lat == 1 

375 assert res.location.lng == 1 

376 assert res.slug == "test-title" 

377 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update 

378 assert time_before_second_update <= to_aware_datetime(res.last_edited) <= time_before_second_get 

379 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited) 

380 assert res.last_editor_user_id == user.id 

381 assert res.creator_user_id == user.id 

382 assert res.owner_user_id == user.id 

383 assert not res.owner_community_id 

384 assert not res.owner_group_id 

385 assert res.editor_user_ids == [user.id] 

386 assert res.can_edit 

387 assert res.can_moderate 

388 assert res.thread.thread_id > 0 

389 assert res.thread.num_responses == 0 

390 

391 time_before_third_update = now() 

392 api.UpdatePage( 

393 pages_pb2.UpdatePageReq( 

394 page_id=page_id, 

395 address=wrappers_pb2.StringValue(value="test address"), 

396 ) 

397 ) 

398 

399 time_before_third_get = now() 

400 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) 

401 assert res.title == "test title" 

402 assert res.content == "test content" 

403 assert res.address == "test address" 

404 assert res.location.lat == 1 

405 assert res.location.lng == 1 

406 assert res.slug == "test-title" 

407 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update 

408 assert time_before_third_update <= to_aware_datetime(res.last_edited) <= time_before_third_get 

409 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited) 

410 assert res.last_editor_user_id == user.id 

411 assert res.creator_user_id == user.id 

412 assert res.owner_user_id == user.id 

413 assert not res.owner_community_id 

414 assert not res.owner_group_id 

415 assert res.editor_user_ids == [user.id] 

416 assert res.can_edit 

417 assert res.can_moderate 

418 assert res.thread.thread_id > 0 

419 assert res.thread.num_responses == 0 

420 

421 time_before_fourth_update = now() 

422 api.UpdatePage( 

423 pages_pb2.UpdatePageReq( 

424 page_id=page_id, 

425 location=pages_pb2.Coordinate( 

426 lat=3, 

427 lng=1.222, 

428 ), 

429 ) 

430 ) 

431 

432 time_before_fourth_get = now() 

433 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) 

434 assert res.title == "test title" 

435 assert res.content == "test content" 

436 assert res.address == "test address" 

437 assert res.location.lat == 3 

438 assert res.location.lng == 1.222 

439 assert res.slug == "test-title" 

440 assert time_before_create <= to_aware_datetime(res.created) <= time_before_update 

441 assert time_before_fourth_update <= to_aware_datetime(res.last_edited) <= time_before_fourth_get 

442 assert to_aware_datetime(res.created) <= to_aware_datetime(res.last_edited) 

443 assert res.last_editor_user_id == user.id 

444 assert res.creator_user_id == user.id 

445 assert res.owner_user_id == user.id 

446 assert not res.owner_community_id 

447 assert not res.owner_group_id 

448 assert res.editor_user_ids == [user.id] 

449 assert res.can_edit 

450 assert res.can_moderate 

451 assert res.thread.thread_id > 0 

452 assert res.thread.num_responses == 0 

453 

454 

455def test_owner_not_moderator(db): 

456 """ 

457 You can be the owner of content yet not have moderation rights 

458 """ 

459 user1, token1 = generate_user() 

460 user2, token2 = generate_user() 

461 with session_scope() as session: 

462 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id 

463 

464 # user2 makes page, is owner but not moderator, so can edit, not moderate 

465 with pages_session(token2) as api: 

466 res = api.CreatePlace( 

467 pages_pb2.CreatePlaceReq( 

468 title="dummy title", 

469 content="dummy content", 

470 address="dummy address", 

471 location=pages_pb2.Coordinate( 

472 lat=1, 

473 lng=1, 

474 ), 

475 ) 

476 ) 

477 assert res.title == "dummy title" 

478 assert res.content == "dummy content" 

479 assert res.address == "dummy address" 

480 assert res.location.lat == 1 

481 assert res.location.lng == 1 

482 assert res.slug == "dummy-title" 

483 assert res.last_editor_user_id == user2.id 

484 assert res.creator_user_id == user2.id 

485 assert res.owner_user_id == user2.id 

486 assert not res.owner_community_id 

487 assert not res.owner_group_id 

488 assert res.editor_user_ids == [user2.id] 

489 assert res.can_edit 

490 assert not res.can_moderate 

491 

492 page_id = res.page_id 

493 

494 # user1 is not owner so can't edit but can moderate 

495 with pages_session(token1) as api: 

496 res = api.GetPage(pages_pb2.GetPageReq(page_id=page_id)) 

497 assert res.title == "dummy title" 

498 assert res.content == "dummy content" 

499 assert res.address == "dummy address" 

500 assert res.location.lat == 1 

501 assert res.location.lng == 1 

502 assert res.slug == "dummy-title" 

503 assert res.last_editor_user_id == user2.id 

504 assert res.creator_user_id == user2.id 

505 assert res.owner_user_id == user2.id 

506 assert not res.owner_community_id 

507 assert not res.owner_group_id 

508 assert res.editor_user_ids == [user2.id] 

509 assert res.can_edit 

510 assert res.can_moderate 

511 assert res.thread.thread_id > 0 

512 assert res.thread.num_responses == 0 

513 

514 

515def test_update_page_errors(db): 

516 user, token = generate_user() 

517 with session_scope() as session: 

518 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id 

519 

520 with pages_session(token) as api: 

521 page_id = api.CreatePlace( 

522 pages_pb2.CreatePlaceReq( 

523 title="dummy title", 

524 content="dummy content", 

525 address="dummy address", 

526 location=pages_pb2.Coordinate( 

527 lat=1, 

528 lng=1, 

529 ), 

530 ) 

531 ).page_id 

532 

533 with pytest.raises(grpc.RpcError) as e: 

534 api.UpdatePage( 

535 pages_pb2.UpdatePageReq( 

536 page_id=page_id, 

537 title=wrappers_pb2.StringValue(value=""), 

538 ) 

539 ) 

540 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

541 assert e.value.details() == "Missing page title." 

542 

543 with pytest.raises(grpc.RpcError) as e: 

544 api.UpdatePage( 

545 pages_pb2.UpdatePageReq( 

546 page_id=page_id, 

547 content=wrappers_pb2.StringValue(value=""), 

548 ) 

549 ) 

550 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

551 assert e.value.details() == "Missing page text." 

552 

553 with pytest.raises(grpc.RpcError) as e: 

554 api.UpdatePage( 

555 pages_pb2.UpdatePageReq( 

556 page_id=page_id, 

557 address=wrappers_pb2.StringValue(value=""), 

558 ) 

559 ) 

560 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

561 assert e.value.details() == "Missing page address." 

562 

563 

564def test_page_transfer(db): 

565 # transfers the pages 

566 user1, token1 = generate_user() 

567 # admin of the community/group 

568 user2, token2 = generate_user() 

569 # member of the community/group, shouldn't ever have edit access to anything 

570 user3, token3 = generate_user() 

571 with session_scope() as session: 

572 # create a community 

573 node = Node(geom=to_multi(create_polygon_lat_lng([[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]))) 

574 session.add(node) 

575 community_cluster = Cluster( 

576 name="Testing Community", 

577 description="Description for testing community", 

578 parent_node=node, 

579 is_official_cluster=True, 

580 ) 

581 session.add(community_cluster) 

582 main_page = Page( 

583 parent_node=community_cluster.parent_node, 

584 creator_user_id=user2.id, 

585 owner_cluster=community_cluster, 

586 type=PageType.main_page, 

587 thread=Thread(), 

588 ) 

589 session.add(main_page) 

590 session.add( 

591 PageVersion( 

592 page=main_page, 

593 editor_user_id=user2.id, 

594 title="Main page for the testing community", 

595 content="Empty.", 

596 ) 

597 ) 

598 community_cluster.cluster_subscriptions.append( 

599 ClusterSubscription( 

600 user_id=user2.id, 

601 role=ClusterRole.admin, 

602 ) 

603 ) 

604 community_cluster.cluster_subscriptions.append( 

605 ClusterSubscription( 

606 user_id=user3.id, 

607 role=ClusterRole.member, 

608 ) 

609 ) 

610 

611 # create a group 

612 group_cluster = Cluster( 

613 name="Testing Group", 

614 description="Description for testing group", 

615 parent_node=node, 

616 ) 

617 session.add(group_cluster) 

618 main_page = Page( 

619 parent_node=group_cluster.parent_node, 

620 creator_user_id=user2.id, 

621 owner_cluster=group_cluster, 

622 type=PageType.main_page, 

623 thread=Thread(), 

624 ) 

625 session.add(main_page) 

626 session.add( 

627 PageVersion( 

628 page=main_page, 

629 editor_user_id=user2.id, 

630 title="Main page for the testing community", 

631 content="Empty.", 

632 ) 

633 ) 

634 group_cluster.cluster_subscriptions.append( 

635 ClusterSubscription( 

636 user_id=user2.id, 

637 role=ClusterRole.admin, 

638 ) 

639 ) 

640 group_cluster.cluster_subscriptions.append( 

641 ClusterSubscription( 

642 user_id=user3.id, 

643 role=ClusterRole.member, 

644 ) 

645 ) 

646 session.flush() 

647 

648 community_id = node.id 

649 community_cluster_id = community_cluster.id 

650 group_id = group_cluster.id 

651 

652 with pages_session(token1) as api: 

653 create_page_req = pages_pb2.CreatePlaceReq( 

654 title="title", 

655 content="content", 

656 address="address", 

657 location=pages_pb2.Coordinate( 

658 lat=1, 

659 lng=1, 

660 ), 

661 ) 

662 

663 # transfer should work fine to a community 

664 page1 = api.CreatePlace(create_page_req) 

665 assert page1.owner_user_id == user1.id 

666 assert page1.can_edit 

667 assert not page1.can_moderate 

668 

669 with pages_session(token2) as api: 

670 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit 

671 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate 

672 

673 with pages_session(token3) as api: 

674 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit 

675 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate 

676 

677 with pages_session(token1) as api: 

678 page1 = api.TransferPage( 

679 pages_pb2.TransferPageReq( 

680 page_id=page1.page_id, 

681 new_owner_community_id=community_id, 

682 ) 

683 ) 

684 assert page1.owner_community_id == community_id 

685 assert not page1.can_edit 

686 assert not page1.can_moderate 

687 

688 with pages_session(token2) as api: 

689 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit 

690 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate 

691 

692 with pages_session(token3) as api: 

693 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit 

694 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate 

695 

696 with pages_session(token1) as api: 

697 # now we're no longer the owner, can't transfer 

698 page1 = api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)) 

699 with pytest.raises(grpc.RpcError) as e: 

700 api.TransferPage( 

701 pages_pb2.TransferPageReq( 

702 page_id=page1.page_id, 

703 new_owner_group_id=group_id, 

704 ) 

705 ) 

706 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED 

707 assert e.value.details() == "You're not allowed to transfer that page." 

708 page1 = api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)) 

709 assert page1.owner_community_id == community_id 

710 assert not page1.can_edit 

711 assert not page1.can_moderate 

712 

713 with pages_session(token2) as api: 

714 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit 

715 assert api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate 

716 

717 with pages_session(token3) as api: 

718 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_edit 

719 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page1.page_id)).can_moderate 

720 

721 with pages_session(token1) as api: 

722 # try a new page, just for fun 

723 page2 = api.CreatePlace(create_page_req) 

724 assert page2.owner_user_id == user1.id 

725 

726 page2 = api.TransferPage( 

727 pages_pb2.TransferPageReq( 

728 page_id=page2.page_id, 

729 new_owner_community_id=community_id, 

730 ) 

731 ) 

732 assert page2.owner_community_id == community_id 

733 

734 with pages_session(token2) as api: 

735 assert api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_edit 

736 assert api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_moderate 

737 

738 with pages_session(token3) as api: 

739 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_edit 

740 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page2.page_id)).can_moderate 

741 

742 with pages_session(token1) as api: 

743 # can't transfer a page to an official cluster, only through community 

744 page3 = api.CreatePlace(create_page_req) 

745 assert page3.owner_user_id == user1.id 

746 

747 with pytest.raises(grpc.RpcError) as e: 

748 api.TransferPage( 

749 pages_pb2.TransferPageReq( 

750 page_id=page3.page_id, 

751 new_owner_community_id=community_cluster_id, 

752 ) 

753 ) 

754 assert e.value.code() == grpc.StatusCode.NOT_FOUND 

755 assert e.value.details() == "Group or community not found." 

756 page3 = api.GetPage(pages_pb2.GetPageReq(page_id=page3.page_id)) 

757 assert page3.owner_user_id == user1.id 

758 

759 # can transfer to group 

760 page4 = api.CreatePlace(create_page_req) 

761 assert page4.owner_user_id == user1.id 

762 assert page4.can_edit 

763 assert not page4.can_moderate 

764 

765 with pages_session(token2) as api: 

766 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit 

767 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate 

768 

769 with pages_session(token3) as api: 

770 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit 

771 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate 

772 

773 with pages_session(token1) as api: 

774 page4 = api.TransferPage( 

775 pages_pb2.TransferPageReq( 

776 page_id=page4.page_id, 

777 new_owner_group_id=group_id, 

778 ) 

779 ) 

780 assert page4.owner_group_id == group_id 

781 assert not page4.can_edit 

782 assert not page4.can_moderate 

783 

784 with pages_session(token2) as api: 

785 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit 

786 assert api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate 

787 

788 with pages_session(token3) as api: 

789 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_edit 

790 assert not api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)).can_moderate 

791 

792 with pages_session(token1) as api: 

793 # now we're no longer the owner, can't transfer 

794 with pytest.raises(grpc.RpcError) as e: 

795 api.TransferPage( 

796 pages_pb2.TransferPageReq( 

797 page_id=page4.page_id, 

798 new_owner_community_id=community_id, 

799 ) 

800 ) 

801 assert e.value.code() == grpc.StatusCode.PERMISSION_DENIED 

802 assert e.value.details() == "You're not allowed to transfer that page." 

803 page4 = api.GetPage(pages_pb2.GetPageReq(page_id=page4.page_id)) 

804 assert page4.owner_group_id == group_id 

805 

806 

807def test_page_photo(db): 

808 user, token = generate_user() 

809 with session_scope() as session: 

810 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id 

811 

812 with pages_session(token) as api: 

813 key1 = random_hex(32) 

814 filename1 = random_hex(32) 

815 

816 with session_scope() as session: 

817 session.add( 

818 Upload( 

819 key=key1, 

820 filename=filename1, 

821 creator_user_id=user.id, 

822 ) 

823 ) 

824 

825 res = api.CreatePlace( 

826 pages_pb2.CreatePlaceReq( 

827 title="dummy title", 

828 content="dummy content", 

829 photo_key=key1, 

830 address="dummy address", 

831 location=pages_pb2.Coordinate( 

832 lat=1, 

833 lng=1, 

834 ), 

835 ) 

836 ) 

837 

838 assert filename1 in res.photo_url 

839 

840 # can't create with non-existent photo 

841 with pytest.raises(grpc.RpcError) as e: 

842 api.CreatePlace( 

843 pages_pb2.CreatePlaceReq( 

844 title="dummy title", 

845 content="dummy content", 

846 photo_key="nonexisten", 

847 address="dummy address", 

848 location=pages_pb2.Coordinate( 

849 lat=1, 

850 lng=1, 

851 ), 

852 ) 

853 ) 

854 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

855 assert e.value.details() == "Photo not found." 

856 

857 # can create page with no photo 

858 res = api.CreatePlace( 

859 pages_pb2.CreatePlaceReq( 

860 title="dummy title", 

861 content="dummy content", 

862 address="dummy address", 

863 location=pages_pb2.Coordinate( 

864 lat=1, 

865 lng=1, 

866 ), 

867 ) 

868 ) 

869 

870 assert res.photo_url == "" 

871 

872 page_id = res.page_id 

873 

874 # can't set it to non-existent stuff 

875 with pytest.raises(grpc.RpcError) as e: 

876 api.UpdatePage( 

877 pages_pb2.UpdatePageReq( 

878 page_id=page_id, 

879 photo_key=wrappers_pb2.StringValue(value="non-existent id"), 

880 ) 

881 ) 

882 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT 

883 assert e.value.details() == "Photo not found." 

884 

885 key2 = random_hex(32) 

886 filename2 = random_hex(32) 

887 

888 with session_scope() as session: 

889 session.add( 

890 Upload( 

891 key=key2, 

892 filename=filename2, 

893 creator_user_id=user.id, 

894 ) 

895 ) 

896 

897 res = api.UpdatePage( 

898 pages_pb2.UpdatePageReq( 

899 page_id=page_id, 

900 photo_key=wrappers_pb2.StringValue(value=key2), 

901 ) 

902 ) 

903 

904 assert filename2 in res.photo_url 

905 

906 # can unset it 

907 

908 res = api.UpdatePage( 

909 pages_pb2.UpdatePageReq( 

910 page_id=page_id, 

911 photo_key=wrappers_pb2.StringValue(value=""), 

912 ) 

913 ) 

914 

915 assert res.photo_url == "" 

916 

917 

918def test_list_user_places(db): 

919 user1, token1 = generate_user() 

920 with session_scope() as session: 

921 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id 

922 

923 with pages_session(token1) as api: 

924 place1_id = api.CreatePlace( 

925 pages_pb2.CreatePlaceReq( 

926 title="dummy title", 

927 content="dummy content", 

928 address="dummy address", 

929 location=pages_pb2.Coordinate( 

930 lat=1, 

931 lng=1, 

932 ), 

933 ) 

934 ).page_id 

935 

936 place2_id = api.CreatePlace( 

937 pages_pb2.CreatePlaceReq( 

938 title="dummy title 2", 

939 content="dummy content 2", 

940 address="dummy address 2", 

941 location=pages_pb2.Coordinate( 

942 lat=1, 

943 lng=1, 

944 ), 

945 ) 

946 ).page_id 

947 

948 with pages_session(token1) as api: 

949 res = api.ListUserPlaces(pages_pb2.ListUserPlacesReq()) 

950 assert [p.page_id for p in res.places] == [place1_id, place2_id] 

951 

952 

953def test_list_other_user_places(db): 

954 user1, token1 = generate_user() 

955 user2, token2 = generate_user() 

956 with session_scope() as session: 

957 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id 

958 

959 with pages_session(token1) as api: 

960 place1_id = api.CreatePlace( 

961 pages_pb2.CreatePlaceReq( 

962 title="dummy title", 

963 content="dummy content", 

964 address="dummy address", 

965 location=pages_pb2.Coordinate( 

966 lat=1, 

967 lng=1, 

968 ), 

969 ) 

970 ).page_id 

971 

972 place2_id = api.CreatePlace( 

973 pages_pb2.CreatePlaceReq( 

974 title="dummy title 2", 

975 content="dummy content 2", 

976 address="dummy address 2", 

977 location=pages_pb2.Coordinate( 

978 lat=1, 

979 lng=1, 

980 ), 

981 ) 

982 ).page_id 

983 

984 with pages_session(token2) as api: 

985 res = api.ListUserPlaces(pages_pb2.ListUserPlacesReq(user_id=user1.id)) 

986 assert [p.page_id for p in res.places] == [place1_id, place2_id] 

987 

988 

989def test_list_user_guides(db): 

990 user1, token1 = generate_user() 

991 with session_scope() as session: 

992 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id 

993 

994 with pages_session(token1) as api: 

995 guide1_id = api.CreateGuide( 

996 pages_pb2.CreateGuideReq( 

997 title="dummy title", 

998 content="dummy content", 

999 address="dummy address", 

1000 location=pages_pb2.Coordinate( 

1001 lat=1, 

1002 lng=1, 

1003 ), 

1004 parent_community_id=c_id, 

1005 ) 

1006 ).page_id 

1007 

1008 guide2_id = api.CreateGuide( 

1009 pages_pb2.CreateGuideReq( 

1010 title="dummy title 2", 

1011 content="dummy content 2", 

1012 address="dummy address 2", 

1013 location=pages_pb2.Coordinate( 

1014 lat=1, 

1015 lng=1, 

1016 ), 

1017 parent_community_id=c_id, 

1018 ) 

1019 ).page_id 

1020 

1021 with pages_session(token1) as api: 

1022 res = api.ListUserGuides(pages_pb2.ListUserGuidesReq()) 

1023 assert [p.page_id for p in res.guides] == [guide1_id, guide2_id] 

1024 

1025 

1026def test_list_other_user_guides(db): 

1027 user1, token1 = generate_user() 

1028 user2, token2 = generate_user() 

1029 with session_scope() as session: 

1030 c_id = create_community(session, 0, 2, "Root node", [user1], [], None).id 

1031 

1032 with pages_session(token1) as api: 

1033 guide1_id = api.CreateGuide( 

1034 pages_pb2.CreateGuideReq( 

1035 title="dummy title", 

1036 content="dummy content", 

1037 address="dummy address", 

1038 location=pages_pb2.Coordinate( 

1039 lat=1, 

1040 lng=1, 

1041 ), 

1042 parent_community_id=c_id, 

1043 ) 

1044 ).page_id 

1045 

1046 guide2_id = api.CreateGuide( 

1047 pages_pb2.CreateGuideReq( 

1048 title="dummy title 2", 

1049 content="dummy content 2", 

1050 address="dummy address 2", 

1051 location=pages_pb2.Coordinate( 

1052 lat=1, 

1053 lng=1, 

1054 ), 

1055 parent_community_id=c_id, 

1056 ) 

1057 ).page_id 

1058 

1059 with pages_session(token2) as api: 

1060 res = api.ListUserGuides(pages_pb2.ListUserGuidesReq(user_id=user1.id)) 

1061 assert [p.page_id for p in res.guides] == [guide1_id, guide2_id]