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

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.fixtures.db import generate_user 

11from tests.fixtures.sessions import pages_session 

12from tests.test_communities import create_community 

13 

14 

15@pytest.fixture(autouse=True) 

16def _(testconfig): 

17 pass 

18 

19 

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) 

24 

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." 

40 

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." 

56 

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." 

72 

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." 

84 

85 

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 

90 

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." 

102 

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." 

114 

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." 

125 

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." 

137 

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." 

150 

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." 

166 

167 

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 

172 

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 ) 

186 

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 

204 

205 

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 

210 

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 ) 

225 

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 

243 

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 ) 

253 

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 

270 

271 

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 

277 

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 

291 

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 

313 

314 

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 

319 

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 

333 

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 ) 

341 

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 

361 

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 ) 

369 

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 

391 

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 ) 

399 

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 

421 

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 ) 

432 

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 

454 

455 

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 

464 

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 

492 

493 page_id = res.page_id 

494 

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 

514 

515 

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 

520 

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 

533 

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." 

543 

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." 

553 

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." 

563 

564 

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 ) 

619 

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() 

663 

664 community_id = node.id 

665 community_cluster_id = community_cluster.id 

666 group_id = group_cluster.id 

667 

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 ) 

678 

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 

684 

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 

688 

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 

692 

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 

703 

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 

707 

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 

711 

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 

728 

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 

732 

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 

736 

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 

741 

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 

749 

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 

753 

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 

757 

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 

762 

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 

774 

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 

780 

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 

784 

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 

788 

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 

799 

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 

803 

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 

807 

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 

821 

822 

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 

827 

828 with pages_session(token) as api: 

829 key1 = random_hex(32) 

830 filename1 = random_hex(32) 

831 

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 ) 

840 

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 ) 

853 

854 assert filename1 in res.photo_url 

855 

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." 

872 

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 ) 

885 

886 assert res.photo_url == "" 

887 

888 page_id = res.page_id 

889 

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." 

900 

901 key2 = random_hex(32) 

902 filename2 = random_hex(32) 

903 

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 ) 

912 

913 res = api.UpdatePage( 

914 pages_pb2.UpdatePageReq( 

915 page_id=page_id, 

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

917 ) 

918 ) 

919 

920 assert filename2 in res.photo_url 

921 

922 # can unset it 

923 

924 res = api.UpdatePage( 

925 pages_pb2.UpdatePageReq( 

926 page_id=page_id, 

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

928 ) 

929 ) 

930 

931 assert res.photo_url == "" 

932 

933 

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 

938 

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 

951 

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 

963 

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] 

967 

968 

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 

974 

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 

987 

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 

999 

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] 

1003 

1004 

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 

1009 

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 

1023 

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 

1036 

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] 

1040 

1041 

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 

1047 

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 

1061 

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 

1074 

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]