def test_reorder_blocks_on_automatically_generated_report( self, send_update): future_none = asyncio.Future() future_none.set_result(None) send_update.return_value = future_none create_module_zipfile("chart", spec_kwargs={"html_output": True}) workflow = Workflow.create_and_init(has_custom_report=False) tab = workflow.tabs.first() tab.steps.create(order=0, slug="step-1", module_id_name="nochart") step2 = tab.steps.create(order=1, slug="step-2", module_id_name="chart") step3 = tab.steps.create(order=2, slug="step-3", module_id_name="chart") self.run_with_async_db( commands.do( ReorderBlocks, workflow_id=workflow.id, slugs=["block-auto-step-3", "block-auto-step-2"], )) self.assertEqual( list( workflow.blocks.values_list("position", "slug", "block_type", "text_markdown", "step_id")), [ (0, "block-auto-step-3", "Chart", "", step3.id), (1, "block-auto-step-2", "Chart", "", step2.id), ], ) delta1 = send_update.call_args[0][1] self.assertEqual(delta1.workflow.has_custom_report, True) self.assertEqual( delta1.workflow.block_slugs, ["block-auto-step-3", "block-auto-step-2"], ) self.assertEqual( delta1.blocks, { "block-auto-step-2": clientside.ChartBlock("step-2"), "block-auto-step-3": clientside.ChartBlock("step-3"), }, ) self.run_with_async_db(commands.undo(workflow.id)) self.assertEqual(list(workflow.blocks.values_list("slug", "position")), []) delta2 = send_update.call_args[0][1] self.assertEqual(delta2.workflow.has_custom_report, False) self.assertEqual(delta2.workflow.block_slugs, []) self.assertEqual( delta2.clear_block_slugs, frozenset(["block-auto-step-2", "block-auto-step-3"]), ) self.assertEqual(delta2.blocks, {})
def load_clientside_update(self, delta): ret = ( super() .load_clientside_update(delta) .update_tab( delta.step.tab_slug, step_ids=list(delta.step.tab.live_steps.values_list("id", flat=True)), ) ) blocks = delta.values_for_backward.get("blocks", []) if blocks: ret = ret.update_workflow( block_slugs=list(delta.workflow.blocks.values_list("slug", flat=True)) ) if delta.step.is_deleted: # Clear the blocks we deleted ret = ret.clear_blocks(block["slug"] for block in blocks) else: # Undoing, we need to re-add slugs ret = ret.replace_blocks( { block["slug"]: clientside.ChartBlock(delta.step.slug) for block in blocks } ) return ret
def load_clientside_update(self, delta): data = (super().load_clientside_update(delta).update_workflow( tab_slugs=list( delta.workflow.live_tabs.values_list("slug", flat=True)))) if delta.tab.is_deleted: data = data.clear_tab(delta.tab.slug) else: data = data.replace_tab(delta.tab.slug, delta.tab.to_clientside()) blocks = delta.values_for_backward.get("blocks", []) if blocks: data = data.update_workflow(block_slugs=list( delta.workflow.blocks.values_list("slug", flat=True))) if delta.tab.is_deleted: data = data.clear_blocks(block["slug"] for block in blocks) else: clientside_blocks = {} for block in blocks: if block["block_type"] == "Chart": clientside_block = clientside.ChartBlock( block["step_slug"]) else: clientside_block = clientside.TableBlock( delta.tab.slug) clientside_blocks[block["slug"]] = clientside_block data = data.replace_blocks(clientside_blocks) return data
def test_delete_custom_report_chart(self, send_update): future_none = asyncio.Future() future_none.set_result(None) send_update.return_value = future_none workflow = Workflow.create_and_init(selected_tab_position=0, has_custom_report=True) # tab-1 tab2 = workflow.tabs.create(position=1, slug="tab-2") step = tab2.steps.create( order=0, slug="step-x", last_relevant_delta_id=workflow.last_delta_id, params={}, ) block1 = workflow.blocks.create(position=0, slug="block-1", block_type="Text", text_markdown="1") block2 = workflow.blocks.create(position=1, slug="block-2", block_type="Chart", step_id=step.id) block3 = workflow.blocks.create(position=2, slug="block-3", block_type="Text", text_markdown="3") self.run_with_async_db( commands.do(DeleteTab, workflow_id=workflow.id, tab=tab2)) delta1 = send_update.call_args[0][1] self.assertEqual(delta1.workflow.block_slugs, ["block-1", "block-3"]) self.assertEqual(delta1.blocks, {}) self.assertEqual(delta1.clear_block_slugs, frozenset(["block-2"])) with self.assertRaises(Block.DoesNotExist): block2.refresh_from_db() block3.refresh_from_db() self.assertEqual(block3.position, 1) self.run_with_async_db(commands.undo(workflow.id)) delta2 = send_update.call_args[0][1] self.assertEqual(delta2.workflow.block_slugs, ["block-1", "block-2", "block-3"]) self.assertEqual(delta2.blocks, {"block-2": clientside.ChartBlock("step-x")}) self.assertEqual(delta2.clear_block_slugs, frozenset())
def test_delete_custom_report_blocks(self, send_update): future_none = asyncio.Future() future_none.set_result(None) send_update.return_value = future_none workflow = Workflow.create_and_init(has_custom_report=True) # tab-1 tab1 = workflow.tabs.first() step1 = tab1.steps.create( order=0, slug="step-1", last_relevant_delta_id=workflow.last_delta_id, params={"url": ""}, ) step2 = tab1.steps.create( order=0, slug="step-2", last_relevant_delta_id=workflow.last_delta_id, params={"url": ""}, ) # Report will include the step twice, and have another step elsewhere # that should not be touched block1 = workflow.blocks.create(position=0, slug="block-step-1-1", block_type="Chart", step=step1) block2 = workflow.blocks.create(position=1, slug="block-step-2", block_type="Chart", step=step2) block3 = workflow.blocks.create(position=2, slug="block-step-1-2", block_type="Chart", step=step1) self.run_with_async_db( commands.do(DeleteStep, workflow_id=workflow.id, step=step1)) with self.assertRaises(Block.DoesNotExist): block1.refresh_from_db() with self.assertRaises(Block.DoesNotExist): block3.refresh_from_db() block2.refresh_from_db() self.assertEqual(block2.position, 0) send_update.assert_called() update = send_update.call_args[0][1] self.assertEqual(update.workflow.block_slugs, ["block-step-2"]) self.assertEqual(update.tabs, {"tab-1": clientside.TabUpdate(step_ids=[step2.id])}) self.assertEqual(update.clear_step_ids, frozenset([step1.id])) self.assertEqual(update.blocks, {}) self.run_with_async_db(commands.undo(workflow.id)) # The old blocks are deleted. We expect new blocks with new IDs. with self.assertRaises(Block.DoesNotExist): block1.refresh_from_db() with self.assertRaises(Block.DoesNotExist): block3.refresh_from_db() new_block1 = workflow.blocks.get(slug=block1.slug) new_block3 = workflow.blocks.get(slug=block3.slug) self.assertEqual(new_block1.step_id, step1.id) self.assertEqual(new_block3.step_id, step1.id) block2.refresh_from_db() self.assertEqual(new_block1.position, 0) self.assertEqual(block2.position, 1) self.assertEqual(new_block3.position, 2) send_update.assert_called() update = send_update.call_args[0][1] self.assertEqual( update.workflow.block_slugs, ["block-step-1-1", "block-step-2", "block-step-1-2"], ) self.assertEqual( update.tabs, {"tab-1": clientside.TabUpdate(step_ids=[step1.id, step2.id])}) self.assertEqual( update.blocks, { "block-step-1-1": clientside.ChartBlock("step-1"), "block-step-1-2": clientside.ChartBlock("step-1"), }, ) self.run_with_async_db(commands.redo(workflow.id)) block2.refresh_from_db() self.assertEqual(block2.position, 0)