Coverage for tests/test_updates.py: 100%

211 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-01 22:07 +0000

1import peprs 

2import pytest 

3 

4from pepdbagent.const import PEPHUB_SAMPLE_ID_KEY 

5from pepdbagent.exceptions import ( 

6 ProjectDuplicatedSampleGUIDsError, 

7 SampleTableUpdateError, 

8) 

9 

10from .utils import PEPDBAgentContextManager 

11 

12 

13@pytest.mark.skipif( 

14 not PEPDBAgentContextManager().db_setup(), 

15 reason="DB is not setup", 

16) 

17class TestProjectUpdate: 

18 @pytest.mark.parametrize( 

19 "namespace, name,new_name", 

20 [ 

21 ["namespace1", "amendments1", "name1"], 

22 ["namespace1", "amendments2", "name2"], 

23 ], 

24 ) 

25 def test_update_project_name(self, namespace, name, new_name): 

26 with PEPDBAgentContextManager(add_data=True) as agent: 

27 agent.project.update( 

28 namespace=namespace, 

29 name=name, 

30 tag="default", 

31 update_dict={"name": new_name}, 

32 ) 

33 assert agent.project.exists( 

34 namespace=namespace, name=new_name, tag="default" 

35 ) 

36 

37 @pytest.mark.parametrize( 

38 "namespace, name,new_name", 

39 [ 

40 ["namespace1", "amendments1", "name1"], 

41 ["namespace1", "amendments2", "name2"], 

42 ], 

43 ) 

44 def test_update_project_name_in_config(self, namespace, name, new_name): 

45 with PEPDBAgentContextManager(add_data=True) as agent: 

46 prj = agent.project.get( 

47 namespace=namespace, name=name, raw=False, with_id=True 

48 ) 

49 prj.name = new_name 

50 agent.project.update( 

51 namespace=namespace, 

52 name=name, 

53 tag="default", 

54 update_dict={"project": prj}, 

55 ) 

56 assert agent.project.exists( 

57 namespace=namespace, name=new_name, tag="default" 

58 ) 

59 

60 @pytest.mark.parametrize( 

61 "namespace, name, new_tag", 

62 [ 

63 ["namespace1", "amendments1", "tag1"], 

64 ["namespace1", "amendments2", "tag2"], 

65 ], 

66 ) 

67 def test_update_project_tag(self, namespace, name, new_tag): 

68 with PEPDBAgentContextManager(add_data=True) as agent: 

69 agent.project.update( 

70 namespace=namespace, 

71 name=name, 

72 tag="default", 

73 update_dict={"tag": new_tag}, 

74 ) 

75 assert agent.project.exists(namespace=namespace, name=name, tag=new_tag) 

76 

77 @pytest.mark.parametrize( 

78 "namespace, name, new_description", 

79 [ 

80 ["namespace1", "amendments1", "desc1 f"], 

81 ["namespace2", "derive", "desc5 f"], 

82 ], 

83 ) 

84 def test_update_project_description(self, namespace, name, new_description): 

85 with PEPDBAgentContextManager(add_data=True) as agent: 

86 prj = agent.project.get(namespace=namespace, name=name, raw=False) 

87 prj.description = new_description 

88 agent.project.update( 

89 namespace=namespace, 

90 name=name, 

91 tag="default", 

92 update_dict={"description": new_description}, 

93 ) 

94 

95 assert ( 

96 agent.project.get(namespace=namespace, name=name, raw=False).description 

97 == new_description 

98 ) 

99 

100 @pytest.mark.parametrize( 

101 "namespace, name, new_schema", 

102 [ 

103 ["namespace1", "amendments1", "bedboss"], 

104 ["namespace2", "derive", "bedboss"], 

105 ], 

106 ) 

107 def test_update_project_schema(self, namespace, name, new_schema): 

108 with PEPDBAgentContextManager(add_data=True) as agent: 

109 prj_annot = agent.annotation.get(namespace=namespace, name=name) 

110 assert prj_annot.results[0].pep_schema == "namespace1/2.0.0:1.0.0" 

111 

112 agent.project.update( 

113 namespace=namespace, 

114 name=name, 

115 tag="default", 

116 update_dict={"pep_schema": "namespace2/bedboss:1.0.0"}, 

117 ) 

118 prj_annot = agent.annotation.get(namespace=namespace, name=name) 

119 assert prj_annot.results[0].pep_schema == "namespace2/bedboss:1.0.0" 

120 

121 @pytest.mark.parametrize( 

122 "namespace, name, new_description", 

123 [ 

124 ["namespace1", "amendments1", "desc1 f"], 

125 ], 

126 ) 

127 def test_update_project_description_in_config( 

128 self, namespace, name, new_description 

129 ): 

130 with PEPDBAgentContextManager(add_data=True) as agent: 

131 prj = agent.project.get( 

132 namespace=namespace, name=name, raw=False, with_id=True 

133 ) 

134 prj.description = new_description 

135 agent.project.update( 

136 namespace=namespace, 

137 name=name, 

138 tag="default", 

139 update_dict={"project": prj}, 

140 ) 

141 

142 assert ( 

143 agent.project.get(namespace=namespace, name=name, raw=False).description 

144 == new_description 

145 ) 

146 

147 @pytest.mark.parametrize( 

148 "namespace, name", 

149 [ 

150 ["namespace1", "amendments1"], 

151 ["namespace3", "subtable1"], 

152 ], 

153 ) 

154 def test_update_whole_project(self, namespace, name): 

155 with PEPDBAgentContextManager(add_data=True) as agent: 

156 new_prj = agent.project.get(namespace="namespace1", name="basic", raw=False) 

157 # update name. If name is different, it will update name too 

158 new_prj.name = name 

159 with pytest.raises(SampleTableUpdateError): 

160 agent.project.update( 

161 namespace=namespace, 

162 name=name, 

163 tag="default", 

164 update_dict={"project": new_prj}, 

165 ) 

166 

167 @pytest.mark.parametrize( 

168 "namespace, name, pep_schema", 

169 [ 

170 ["namespace1", "amendments1", "namespace2/bedmaker:1.0.0"], 

171 ["namespace2", "derive", "namespace2/bedbuncher:1.0.0"], 

172 ], 

173 ) 

174 def test_update_pep_schema(self, namespace, name, pep_schema): 

175 with PEPDBAgentContextManager(add_data=True) as agent: 

176 agent.project.update( 

177 namespace=namespace, 

178 name=name, 

179 tag="default", 

180 update_dict={"pep_schema": pep_schema}, 

181 ) 

182 res = agent.annotation.get(namespace, name, "default") 

183 assert res.results[0].pep_schema == pep_schema 

184 

185 @pytest.mark.parametrize( 

186 "namespace, name", 

187 [ 

188 ["namespace1", "amendments1"], 

189 ], 

190 ) 

191 def test_update_project_private(self, namespace, name): 

192 with PEPDBAgentContextManager(add_data=True) as agent: 

193 agent.project.update( 

194 namespace=namespace, 

195 name=name, 

196 tag="default", 

197 update_dict={"is_private": True}, 

198 ) 

199 

200 is_private = ( 

201 agent.annotation.get( 

202 namespace=namespace, name=name, tag="default", admin=[namespace] 

203 ) 

204 .results[0] 

205 .is_private 

206 ) 

207 assert is_private is True 

208 

209 @pytest.mark.parametrize( 

210 "namespace, name", 

211 [ 

212 ["namespace1", "amendments1"], 

213 ], 

214 ) 

215 def test_update_project_pop(self, namespace, name): 

216 with PEPDBAgentContextManager(add_data=True) as agent: 

217 agent.project.update( 

218 namespace=namespace, 

219 name=name, 

220 tag="default", 

221 update_dict={"pop": True}, 

222 ) 

223 

224 pop = ( 

225 agent.annotation.get( 

226 namespace=namespace, name=name, tag="default", admin=[namespace] 

227 ) 

228 .results[0] 

229 .pop 

230 ) 

231 assert pop is True 

232 

233 # Update to pop = False and check if it is updated 

234 agent.project.update( 

235 namespace=namespace, 

236 name=name, 

237 tag="default", 

238 update_dict={"pop": False}, 

239 ) 

240 

241 pop = ( 

242 agent.annotation.get( 

243 namespace=namespace, name=name, tag="default", admin=[namespace] 

244 ) 

245 .results[0] 

246 .pop 

247 ) 

248 assert pop is False 

249 

250 @pytest.mark.parametrize( 

251 "namespace, name", 

252 [ 

253 ["namespace1", "basic"], 

254 ], 

255 ) 

256 def test_project_can_have_2_sample_names(self, namespace, name): 

257 """ 

258 In PEP 2.1.0 project can have 2 rows with same sample name, 

259 ensure that update works correctly 

260 """ 

261 with PEPDBAgentContextManager(add_data=True) as agent: 

262 new_prj = agent.project.get( 

263 namespace=namespace, name=name, raw=False, with_id=True 

264 ) 

265 prj_dict = new_prj.to_dict(raw=True, by_sample=True) 

266 

267 prj_dict["samples"].append( 

268 { 

269 "file": "data/frog23_data.txt", 

270 "protocol": "anySample3Type", 

271 "sample_name": "frog_2", 

272 } 

273 ) 

274 prj_dict["samples"].append( 

275 { 

276 "file": "data/frog23_data.txt4", 

277 "protocol": "anySample3Type4", 

278 "sample_name": "frog_2", 

279 } 

280 ) 

281 

282 new_prj.description = "new_description" 

283 agent.project.update( 

284 namespace=namespace, 

285 name=name, 

286 tag="default", 

287 update_dict={"project": peprs.Project.from_dict(prj_dict)}, 

288 ) 

289 

290 prj = agent.project.get(namespace=namespace, name=name, raw=True) 

291 

292 assert len(prj["samples"]) == 4 

293 

294 

295@pytest.mark.skipif( 

296 not PEPDBAgentContextManager().db_setup(), 

297 reason="DB is not setup", 

298) 

299class TestUpdateProjectWithId: 

300 @pytest.mark.parametrize( 

301 "namespace, name", 

302 [ 

303 ["namespace1", "amendments1"], 

304 ["namespace3", "subtable1"], 

305 ], 

306 ) 

307 def test_update_whole_project_with_id(self, namespace, name): 

308 """ 

309 General test for updating whole project with id (inserting one project without id) 

310 """ 

311 with PEPDBAgentContextManager(add_data=True) as agent: 

312 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

313 prj = agent.project.get( 

314 namespace=namespace, name=name, raw=True, with_id=True 

315 ) 

316 

317 new_sample = { 

318 "sample_name": "new_sample", 

319 "protocol": "new_protocol", 

320 PEPHUB_SAMPLE_ID_KEY: None, 

321 } 

322 

323 prj["samples"].append(new_sample.copy()) 

324 prj["samples"][0]["sample_name"] = "new_sample_name2" 

325 del prj["samples"][1] 

326 

327 agent.project.update( 

328 namespace=namespace, 

329 name=name, 

330 tag="default", 

331 update_dict={"project": peprs.Project.from_dict(prj)}, 

332 ) 

333 

334 del new_sample[PEPHUB_SAMPLE_ID_KEY] 

335 peppy_prj["samples"].append(new_sample.copy()) # add sample without id 

336 peppy_prj["samples"][0]["sample_name"] = "new_sample_name2" # modify sample 

337 del peppy_prj["samples"][1] # delete sample 

338 

339 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

340 namespace=namespace, name=name, raw=False 

341 ) 

342 

343 @pytest.mark.parametrize( 

344 "namespace, name", 

345 [ 

346 ["namespace1", "amendments1"], 

347 ["namespace3", "subtable1"], 

348 ], 

349 ) 

350 def test_insert_new_row(self, namespace, name): 

351 with PEPDBAgentContextManager(add_data=True) as agent: 

352 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

353 prj = agent.project.get( 

354 namespace=namespace, name=name, raw=True, with_id=True 

355 ) 

356 

357 new_sample = { 

358 "sample_name": "new_sample", 

359 "protocol": "new_protocol", 

360 PEPHUB_SAMPLE_ID_KEY: None, 

361 } 

362 

363 prj["samples"].append(new_sample.copy()) 

364 

365 agent.project.update( 

366 namespace=namespace, 

367 name=name, 

368 tag="default", 

369 update_dict={"project": peprs.Project.from_dict(prj)}, 

370 ) 

371 

372 del new_sample[PEPHUB_SAMPLE_ID_KEY] 

373 peppy_prj["samples"].append(new_sample.copy()) # add sample without id 

374 

375 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

376 namespace=namespace, name=name, raw=False 

377 ) 

378 

379 @pytest.mark.parametrize( 

380 "namespace, name", 

381 [ 

382 ["namespace1", "amendments1"], 

383 ["namespace3", "subtable1"], 

384 ], 

385 ) 

386 def test_insert_new_multiple_rows(self, namespace, name): 

387 with PEPDBAgentContextManager(add_data=True) as agent: 

388 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

389 prj = agent.project.get( 

390 namespace=namespace, name=name, raw=True, with_id=True 

391 ) 

392 

393 new_sample1 = { 

394 "sample_name": "new_sample", 

395 "protocol": "new_protocol", 

396 PEPHUB_SAMPLE_ID_KEY: None, 

397 } 

398 new_sample2 = { 

399 "sample_name": "new_sample2", 

400 "protocol": "new_protocol2", 

401 PEPHUB_SAMPLE_ID_KEY: None, 

402 } 

403 

404 prj["samples"].append(new_sample1.copy()) 

405 prj["samples"].append(new_sample2.copy()) 

406 

407 agent.project.update( 

408 namespace=namespace, 

409 name=name, 

410 tag="default", 

411 update_dict={"project": peprs.Project.from_dict(prj)}, 

412 ) 

413 

414 del new_sample1[PEPHUB_SAMPLE_ID_KEY] 

415 del new_sample2[PEPHUB_SAMPLE_ID_KEY] 

416 peppy_prj["samples"].append(new_sample1.copy()) # add sample without id 

417 peppy_prj["samples"].append(new_sample2.copy()) # add sample without id 

418 

419 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

420 namespace=namespace, name=name, raw=False 

421 ) 

422 

423 @pytest.mark.parametrize( 

424 "namespace, name", 

425 [ 

426 ["namespace3", "subtable1"], 

427 ], 

428 ) 

429 def test_insert_new_multiple_rows_duplicated_samples(self, namespace, name): 

430 """PEP 2.1.0 allows duplicate sample names, so this should succeed.""" 

431 with PEPDBAgentContextManager(add_data=True) as agent: 

432 original_count = len( 

433 agent.project.get(namespace=namespace, name=name, raw=True)["samples"] 

434 ) 

435 prj = agent.project.get( 

436 namespace=namespace, name=name, raw=True, with_id=True 

437 ) 

438 

439 new_sample1 = { 

440 "sample_name": "new_sample", 

441 "protocol": "new_protocol", 

442 PEPHUB_SAMPLE_ID_KEY: None, 

443 } 

444 new_sample2 = { 

445 "sample_name": "new_sample", 

446 "protocol": "new_protocol", 

447 PEPHUB_SAMPLE_ID_KEY: None, 

448 } 

449 

450 prj["samples"].append(new_sample1.copy()) 

451 prj["samples"].append(new_sample2.copy()) 

452 

453 agent.project.update( 

454 namespace=namespace, 

455 name=name, 

456 tag="default", 

457 update_dict={"project": peprs.Project.from_dict(prj)}, 

458 ) 

459 updated = agent.project.get(namespace=namespace, name=name, raw=True) 

460 assert len(updated["samples"]) == original_count + 2 

461 

462 @pytest.mark.parametrize( 

463 "namespace, name", 

464 [ 

465 ["namespace3", "subtable2"], 

466 ["namespace1", "append"], 

467 ], 

468 ) 

469 def test_delete_multiple_rows(self, namespace, name): 

470 with PEPDBAgentContextManager(add_data=True) as agent: 

471 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

472 prj = agent.project.get( 

473 namespace=namespace, name=name, raw=True, with_id=True 

474 ) 

475 

476 del prj["samples"][1] 

477 del prj["samples"][2] 

478 

479 agent.project.update( 

480 namespace=namespace, 

481 name=name, 

482 tag="default", 

483 update_dict={"project": peprs.Project.from_dict(prj)}, 

484 ) 

485 

486 del peppy_prj["samples"][1] # delete sample 

487 del peppy_prj["samples"][2] # delete sample 

488 

489 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

490 namespace=namespace, name=name, raw=False 

491 ) 

492 

493 @pytest.mark.parametrize( 

494 "namespace, name", 

495 [ 

496 ["namespace1", "amendments1"], 

497 ["namespace3", "subtable1"], 

498 ], 

499 ) 

500 def test_modify_one_row(self, namespace, name): 

501 with PEPDBAgentContextManager(add_data=True) as agent: 

502 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

503 prj = agent.project.get( 

504 namespace=namespace, name=name, raw=True, with_id=True 

505 ) 

506 

507 prj["samples"][0]["sample_name"] = "new_sample_name2" 

508 

509 agent.project.update( 

510 namespace=namespace, 

511 name=name, 

512 tag="default", 

513 update_dict={"project": peprs.Project.from_dict(prj)}, 

514 ) 

515 

516 peppy_prj["samples"][0]["sample_name"] = "new_sample_name2" # modify sample 

517 

518 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

519 namespace=namespace, name=name, raw=False 

520 ) 

521 

522 @pytest.mark.parametrize( 

523 "namespace, name", 

524 [ 

525 ["namespace1", "amendments1"], 

526 ["namespace3", "subtable1"], 

527 ], 

528 ) 

529 def test_modify_multiple_rows(self, namespace, name): 

530 with PEPDBAgentContextManager(add_data=True) as agent: 

531 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

532 prj = agent.project.get( 

533 namespace=namespace, name=name, raw=True, with_id=True 

534 ) 

535 

536 prj["samples"][0]["sample_name"] = "new_sample_name2" 

537 prj["samples"][1]["sample_name"] = "new_sample_name3" 

538 

539 agent.project.update( 

540 namespace=namespace, 

541 name=name, 

542 tag="default", 

543 update_dict={"project": peprs.Project.from_dict(prj)}, 

544 ) 

545 

546 peppy_prj["samples"][0]["sample_name"] = "new_sample_name2" # modify sample 

547 peppy_prj["samples"][1]["sample_name"] = "new_sample_name3" # modify sample 

548 

549 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

550 namespace=namespace, name=name, raw=False 

551 ) 

552 

553 @pytest.mark.parametrize( 

554 "namespace, name", 

555 [ 

556 ["namespace1", "amendments1"], 

557 ["namespace3", "subtable1"], 

558 ], 

559 ) 

560 def test_add_new_first_sample(self, namespace, name): 

561 with PEPDBAgentContextManager(add_data=True) as agent: 

562 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

563 prj = agent.project.get( 

564 namespace=namespace, name=name, raw=True, with_id=True 

565 ) 

566 

567 new_sample = { 

568 "sample_name": "new_sample", 

569 "protocol": "new_protocol", 

570 PEPHUB_SAMPLE_ID_KEY: None, 

571 } 

572 

573 prj["samples"].insert(0, new_sample.copy()) 

574 

575 agent.project.update( 

576 namespace=namespace, 

577 name=name, 

578 tag="default", 

579 update_dict={"project": peprs.Project.from_dict(prj)}, 

580 ) 

581 

582 del new_sample[PEPHUB_SAMPLE_ID_KEY] 

583 peppy_prj["samples"].insert(0, new_sample.copy()) # add sample without id 

584 

585 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

586 namespace=namespace, name=name, raw=False 

587 ) 

588 

589 @pytest.mark.parametrize( 

590 "namespace, name", 

591 [ 

592 ["namespace1", "amendments1"], 

593 ["namespace3", "subtable1"], 

594 ], 

595 ) 

596 def test_change_sample_order(self, namespace, name): 

597 with PEPDBAgentContextManager(add_data=True) as agent: 

598 peppy_prj = agent.project.get(namespace=namespace, name=name, raw=True) 

599 prj = agent.project.get( 

600 namespace=namespace, name=name, raw=True, with_id=True 

601 ) 

602 

603 sample1 = prj["samples"][0].copy() 

604 sample2 = prj["samples"][1].copy() 

605 

606 prj["samples"][0] = sample2 

607 prj["samples"][1] = sample1 

608 

609 agent.project.update( 

610 namespace=namespace, 

611 name=name, 

612 tag="default", 

613 update_dict={"project": peprs.Project.from_dict(prj)}, 

614 ) 

615 

616 peppy_prj["samples"][0] = sample2 

617 peppy_prj["samples"][1] = sample1 

618 

619 del peppy_prj["samples"][0][PEPHUB_SAMPLE_ID_KEY] 

620 del peppy_prj["samples"][1][PEPHUB_SAMPLE_ID_KEY] 

621 

622 assert peprs.Project.from_dict(peppy_prj) == agent.project.get( 

623 namespace=namespace, name=name, raw=False 

624 ) 

625 

626 @pytest.mark.parametrize( 

627 "namespace, name", 

628 [ 

629 ["namespace1", "amendments1"], 

630 ["namespace3", "subtable1"], 

631 ], 

632 ) 

633 def test_update_porject_without_ids(self, namespace, name): 

634 with PEPDBAgentContextManager(add_data=True) as agent: 

635 prj = agent.project.get( 

636 namespace=namespace, name=name, raw=True, with_id=False 

637 ) 

638 

639 prj["samples"][0]["sample_name"] = "new_sample_name2" 

640 

641 with pytest.raises(SampleTableUpdateError): 

642 agent.project.update( 

643 namespace=namespace, 

644 name=name, 

645 tag="default", 

646 update_dict={"project": peprs.Project.from_dict(prj)}, 

647 ) 

648 

649 @pytest.mark.parametrize( 

650 "namespace, name", 

651 [ 

652 ["namespace1", "amendments1"], 

653 ], 

654 ) 

655 def test_update_project_with_duplicated_sample_guids(self, namespace, name): 

656 with PEPDBAgentContextManager(add_data=True) as agent: 

657 new_prj = agent.project.get( 

658 namespace=namespace, name=name, raw=True, with_id=True 

659 ) 

660 new_prj["samples"].append(new_prj["samples"][0]) 

661 

662 with pytest.raises(ProjectDuplicatedSampleGUIDsError): 

663 agent.project.update( 

664 namespace=namespace, 

665 name=name, 

666 tag="default", 

667 update_dict={"project": peprs.Project.from_dict(new_prj)}, 

668 )