|
1 | | -import { call, put, select, take } from "redux-saga/effects"; |
| 1 | +import { actionChannel, call, flush, put, select, take } from "redux-saga/effects"; |
2 | 2 | import { setupWebknossosForTesting, type WebknossosTestContext } from "test/helpers/apiHelpers"; |
3 | 3 | import { getMappingInfo } from "viewer/model/accessors/dataset_accessor"; |
4 | 4 | import { |
@@ -682,5 +682,72 @@ describe("Proofreading (Multi User)", () => { |
682 | 682 | await task.toPromise(); |
683 | 683 | }); |
684 | 684 |
|
685 | | - // TODOM: Implement tests for proofreading tree interactions. |
| 685 | + it("should merge two agglomerates optimistically and not trigger rebasing due to no incoming backend actions", async (context: WebknossosTestContext) => { |
| 686 | + const { api } = context; |
| 687 | + const _backendMock = mockInitialBucketAndAgglomerateData(context); |
| 688 | + |
| 689 | + const { annotation } = Store.getState(); |
| 690 | + const { tracingId } = annotation.volumes[0]; |
| 691 | + |
| 692 | + const task = startSaga(function* task() { |
| 693 | + const rebaseActionChannel = yield actionChannel(["PREPARE_REBASING", "FINISHED_REBASING"]); |
| 694 | + |
| 695 | + yield call(initializeMappingAndTool, context, tracingId); |
| 696 | + // Set up the merge-related segment partners. Normally, this would happen |
| 697 | + // due to the user's interactions. |
| 698 | + yield put(updateSegmentAction(1, { somePosition: [1, 1, 1] }, tracingId)); |
| 699 | + yield put(setActiveCellAction(1)); |
| 700 | + |
| 701 | + yield call(createEditableMapping); |
| 702 | + yield put(setOthersMayEditForAnnotationAction(true)); |
| 703 | + // Execute the actual merge and wait for the finished mapping. |
| 704 | + yield put( |
| 705 | + proofreadMergeAction( |
| 706 | + [4, 4, 4], // unmappedId=4 / mappedId=4 at this position |
| 707 | + 1, // unmappedId=1 maps to 1 |
| 708 | + ), |
| 709 | + ); |
| 710 | + yield take("FINISH_MAPPING_INITIALIZATION"); |
| 711 | + yield call(() => api.tracing.save()); |
| 712 | + |
| 713 | + const mergeSaveActionBatch = context.receivedDataPerSaveRequest.at(-1)![0]?.actions; |
| 714 | + |
| 715 | + expect(mergeSaveActionBatch).toEqual([ |
| 716 | + { |
| 717 | + name: "mergeAgglomerate", |
| 718 | + value: { |
| 719 | + actionTracingId: "volumeTracingId", |
| 720 | + segmentId1: 1, |
| 721 | + segmentId2: 4, |
| 722 | + agglomerateId1: 1, |
| 723 | + agglomerateId2: 4, |
| 724 | + }, |
| 725 | + }, |
| 726 | + ]); |
| 727 | + const finalMapping = yield select( |
| 728 | + (state) => |
| 729 | + getMappingInfo(state.temporaryConfiguration.activeMappingByLayer, tracingId).mapping, |
| 730 | + ); |
| 731 | + |
| 732 | + expect(finalMapping).toEqual( |
| 733 | + new Map([ |
| 734 | + [1, 1], |
| 735 | + [2, 1], |
| 736 | + [3, 1], |
| 737 | + [4, 1], |
| 738 | + [5, 1], |
| 739 | + [6, 6], |
| 740 | + [7, 6], |
| 741 | + // [1337, 1337], not loaded |
| 742 | + // [1338, 1337], not loaded |
| 743 | + ]), |
| 744 | + ); |
| 745 | + |
| 746 | + // Asserting no rebasing relevant actions were triggered. |
| 747 | + const rebasingActions = yield flush(rebaseActionChannel); |
| 748 | + expect(rebasingActions.length).toBe(0); |
| 749 | + }); |
| 750 | + |
| 751 | + await task.toPromise(); |
| 752 | + }, 8000); |
686 | 753 | }); |
0 commit comments