def test_add_many_modules(self): self.workflow.refresh_from_db() v1 = self.workflow.revision() # beginning state: one WfModule all_modules = self.workflow.wf_modules self.assertEqual(all_modules.count(), 1) existing_module = WfModule.objects.first() self.assertEqual(existing_module.order, 0) self.assertWfModuleVersions([v1]) # Insert at beginning cmd1 = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=0) self.assertEqual(all_modules.count(), 2) self.assertEqual(cmd1.wf_module.order, 0) self.assertNotEqual(cmd1.wf_module, existing_module) v2 = self.workflow.revision() self.assertWfModuleVersions([v2, v2]) # Insert at end cmd2 = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=2) self.assertEqual(all_modules.count(), 3) self.assertEqual(cmd2.wf_module.order, 2) v3 = self.workflow.revision() self.assertWfModuleVersions([v2, v2, v3]) # Insert in between two modules cmd3 = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=2) self.assertEqual(all_modules.count(), 4) self.assertEqual(cmd3.wf_module.order, 2) v4 = self.workflow.revision() self.assertWfModuleVersions([v2, v2, v4, v4]) # Check the delta chain, should be 1 <-> 2 <-> 3 self.workflow.refresh_from_db() cmd1.refresh_from_db() cmd2.refresh_from_db() cmd3.refresh_from_db() self.assertEqual(self.workflow.last_delta, cmd3) self.assertIsNone(cmd3.next_delta) self.assertEqual(cmd3.prev_delta, cmd2) self.assertEqual(cmd2.next_delta, cmd3) self.assertEqual(cmd2.prev_delta, cmd1) self.assertEqual(cmd1.next_delta, cmd2) self.assertIsNone(cmd1.prev_delta) # We should be able to go all the way back cmd3.backward() self.assertWfModuleVersions([v2, v2, v3]) cmd2.backward() self.assertWfModuleVersions([v2, v2]) cmd1.backward() self.assertWfModuleVersions([v1]) self.assertEqual(all_modules.count(), 1)
def test_add_many_modules(self): # beginning state: one WfModule all_modules = WfModule.objects.filter(workflow=self.workflow) self.assertEqual(all_modules.count(), 1) existing_module = WfModule.objects.first() self.assertEqual(existing_module.order, 0) # Insert at beginning cmd1 = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=0) self.assertEqual(all_modules.count(), 2) self.assertEqual(cmd1.wf_module.order, 0) self.assertNotEqual(cmd1.wf_module, existing_module) # Insert at end cmd2 = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=2) self.assertEqual(all_modules.count(), 3) self.assertEqual(cmd2.wf_module.order, 2) # Insert in between two modules cmd3 = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=2) self.assertEqual(all_modules.count(), 4) self.assertEqual(cmd3.wf_module.order, 2) # We should be able to go all the way back cmd3.backward() cmd2.backward() cmd1.backward() self.assertEqual(all_modules.count(), 1)
def workflow_addmodule(request, pk, format=None): workflow = get_object_or_404(Workflow, pk=pk) if not workflow.request_authorized_write(request): return HttpResponseForbidden() module_id = int(request.data['moduleId']) index = int(request.data['index']) try: module = Module.objects.get(pk=module_id) except Module.DoesNotExist: return Response(status=status.HTTP_400_BAD_REQUEST) # don't allow python code module in anonymous workflow if module.id_name == 'pythoncode' and workflow.is_anonymous: return HttpResponseForbidden() # always add the latest version of a module (do we need ordering on the # objects to ensure last is always latest?) module_version = ModuleVersion.objects.filter(module=module).last() server.utils.log_user_event(request, 'Add Module ' + module.name, { 'name': module.name, 'id_name': module.id_name }) delta = AddModuleCommand.create(workflow, module_version, index) serializer = WfModuleSerializer(delta.wf_module) wfmodule_data = serializer.data return Response({ 'wfModule': wfmodule_data, 'index': index, }, status.HTTP_201_CREATED)
def workflow_addmodule(request, pk, format=None): workflow = get_object_or_404(Workflow, pk=pk) if not workflow.user_authorized_write(request.user): return HttpResponseForbidden() module_id = request.data['moduleId'] insert_before = int(request.data['insertBefore']) try: module = Module.objects.get(pk=module_id) except Module.DoesNotExist: return Response(status=status.HTTP_400_BAD_REQUEST) # always add the latest version of a module (do we need ordering on the objects to ensure last is always latest?) module_version = ModuleVersion.objects.filter(module=module).last() log_user_event(request.user, 'Add Module', {'name': module.name, 'id_name':module.id_name}) watch_list = ['columnchart', 'linechart', 'loadurl', 'twitter', 'googlesheets'] if module.id_name in watch_list: log_user_event(request.user, 'Add ' + module.name, {'name': module.name, 'id_name':module.id_name}) with workflow.cooperative_lock(): delta = AddModuleCommand.create(workflow, module_version, insert_before) serializer = WfModuleSerializer(delta.wf_module) wfmodule_data = serializer.data wfmodule_data['insert_before'] = request.data['insertBefore'] return Response(wfmodule_data, status.HTTP_201_CREATED)
def test_add_delete(self): cmda = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=0) DeleteModuleCommand.create(cmda.wf_module) self.workflow.delete() self.assertTrue(True) # we didn't crash! Yay, we pass
def test_add_module(self): # beginning state: one WfModule all_modules = WfModule.objects.filter(workflow=self.workflow) self.assertEqual(all_modules.count(), 1) existing_module = WfModule.objects.first() start_rev = self.workflow.revision() # Add a module, insert before the existing one, check to make sure it went there and old one is after cmd = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=0) self.assertEqual(all_modules.count(), 2) added_module = WfModule.objects.get(workflow=self.workflow, order=0) self.assertNotEqual(added_module, existing_module) bumped_module = WfModule.objects.get(workflow=self.workflow, order=1) self.assertEqual(bumped_module, existing_module) # workflow revision should have been incremented self.workflow.refresh_from_db() self.assertGreater(self.workflow.revision(), start_rev) # undo! undo! ahhhhh everything is on fire! undo! cmd.backward() self.assertEqual(all_modules.count(), 1) self.assertEqual(WfModule.objects.first(), existing_module) # wait no, we wanted that module cmd.forward() self.assertEqual(all_modules.count(), 2) added_module = WfModule.objects.get(workflow=self.workflow, order=0) self.assertNotEqual(added_module, existing_module) bumped_module = WfModule.objects.get(workflow=self.workflow, order=1) self.assertEqual(bumped_module, existing_module)
def test_add_module(self): # beginning state: one WfModule all_modules = WfModule.objects.filter(workflow=self.workflow) self.assertEqual(all_modules.count(), 1) existing_module = WfModule.objects.first() self.workflow.refresh_from_db() v1 = self.workflow.revision() # Add a module, insert before the existing one, check to make sure it # went there and old one is after cmd = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=0) self.assertEqual(all_modules.count(), 2) added_module = WfModule.objects.get(workflow=self.workflow, order=0) self.assertNotEqual(added_module, existing_module) bumped_module = WfModule.objects.get(workflow=self.workflow, order=1) self.assertEqual(bumped_module, existing_module) # workflow revision should have been incremented self.workflow.refresh_from_db() self.assertGreater(self.workflow.revision(), v1) # Check the delta chain (short, but should be sweet) self.workflow.refresh_from_db() self.assertEqual(self.workflow.last_delta, cmd) self.assertIsNone(cmd.prev_delta) self.assertIsNone(cmd.next_delta) # undo! undo! ahhhhh everything is on fire! undo! cmd.backward() self.assertEqual(all_modules.count(), 1) self.assertEqual(self.workflow.wf_modules.first(), existing_module) # wait no, we wanted that module cmd.forward() self.assertEqual(all_modules.count(), 2) added_module = WfModule.objects.get(workflow=self.workflow, order=0) self.assertNotEqual(added_module, existing_module) bumped_module = WfModule.objects.get(workflow=self.workflow, order=1) self.assertEqual(bumped_module, existing_module) # Undo and test deleting the un-applied command. Should delete dangling # WfModule too cmd.backward() self.assertEqual(all_modules.count(), 1) self.assertEqual(self.workflow.wf_modules.first(), existing_module) cmd.delete() with self.assertRaises(WfModule.DoesNotExist): WfModule.objects.get(pk=added_module.id) # should be gone
def workflow_addmodule(request, pk, format=None): try: workflow = Workflow.objects.get(pk=pk) except Workflow.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if not workflow.user_authorized(request.user): return HttpResponseForbidden() try: module_id = request.data['moduleID'] insert_before = int(request.data['insertBefore']) module = Module.objects.get(pk=module_id) # always add the latest version of a module (hence [0]) module_version = ModuleVersion.objects.filter(module=module)[0] except Module.DoesNotExist: return Response(status=status.HTTP_400_BAD_REQUEST) AddModuleCommand.create(workflow, module_version, insert_before) return Response(status=status.HTTP_204_NO_CONTENT)
def test_add_undo_selected(self): # beginning state: one WfModule all_modules = WfModule.objects.filter(workflow=self.workflow) self.assertEqual(all_modules.count(), 1) cmd = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=1) self.workflow.selected_wf_module = cmd.wf_module.order self.workflow.save() cmd.backward() self.workflow.refresh_from_db() self.assertIsNone(self.workflow.selected_wf_module)
def workflow_addmodule(request, pk, format=None): try: workflow = Workflow.objects.get(pk=pk) except Workflow.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if not workflow.user_authorized_write(request.user): return HttpResponseForbidden() try: module_id = request.data['moduleId'] insert_before = int(request.data['insertBefore']) module = Module.objects.get(pk=module_id) # always add the latest version of a module module_versions = ModuleVersion.objects.filter(module=module) module_version = module_versions[len(module_versions) - 1] except Module.DoesNotExist: return Response(status=status.HTTP_400_BAD_REQUEST) delta = AddModuleCommand.create(workflow, module_version, insert_before) return Response({"id": delta.wf_module.id}, status.HTTP_201_CREATED)
def test_undo_redo(self): # beginning state: nothing all_modules = WfModule.objects.filter( workflow=self.workflow ) # filter so we pick up only "attached" modules self.assertEqual(all_modules.count(), 0) self.assertEqual(self.workflow.last_delta, None) start_rev = self.workflow.revision() # Test undoing nothing at all. Should NOP WorkflowUndo(self.workflow) self.assertEqual(self.workflow.revision(), start_rev) self.assertEqual(all_modules.count(), 0) self.assertEqual(self.workflow.last_delta, None) # Add a module cmd1 = AddModuleCommand.create(self.workflow, self.csv, 0) self.assertEqual(all_modules.count(), 1) wfm = WfModule.objects.first() self.assertNotEqual(self.workflow.last_delta, None) rev1 = self.workflow.revision() self.assertGreater(rev1, start_rev) # Undo, ensure we are back at start WorkflowUndo(self.workflow) self.assertEqual(self.workflow.revision(), start_rev) self.assertEqual(all_modules.count(), 0) self.assertEqual(self.workflow.last_delta, None) # Redo, ensure we are back at rev1 WorkflowRedo(self.workflow) self.assertEqual(all_modules.count(), 1) self.assertNotEqual(self.workflow.last_delta, None) self.assertEqual(self.workflow.revision(), rev1) # Change a parameter pval = get_param_by_id_name('csv') cmd2 = ChangeParameterCommand.create(pval, 'some value') self.assertEqual(pval.value, 'some value') self.workflow.refresh_from_db() rev2 = self.workflow.revision() self.assertGreater(rev2, rev1) # Undo parameter change WorkflowUndo(self.workflow) self.assertEqual(self.workflow.revision(), rev1) pval.refresh_from_db() self.assertEqual(pval.value, '') # Redo WorkflowRedo(self.workflow) self.assertEqual(self.workflow.revision(), rev2) pval.refresh_from_db() self.assertEqual(pval.value, 'some value') # Redo again should do nothing WorkflowRedo(self.workflow) self.assertEqual(self.workflow.revision(), rev2) self.assertEqual(pval.value, 'some value') # Add one more command so the stack is 3 deep cmd3 = ChangeWorkflowTitleCommand.create(self.workflow, "Hot New Title") # self.workflow.refresh_from_db() rev3 = self.workflow.revision() self.assertGreater(rev3, rev2) # Undo twice WorkflowUndo(self.workflow) self.assertEqual(self.workflow.last_delta, cmd2) WorkflowUndo(self.workflow) self.assertEqual(self.workflow.last_delta, cmd1) # Redo twice WorkflowRedo(self.workflow) self.assertEqual(self.workflow.last_delta, cmd2) WorkflowRedo(self.workflow) self.assertEqual(self.workflow.last_delta, cmd3) # Undo again to get to a place where we have two commands to redo WorkflowUndo(self.workflow) WorkflowUndo(self.workflow) self.assertEqual(self.workflow.last_delta, cmd1) # Now add a new command. It should remove cmd2, cmd3 from the redo stack and delete them from the db cmd4 = ChangeWfModuleNotesCommand.create(wfm, "Note of no note") self.workflow.refresh_from_db() self.assertEqual(self.workflow.last_delta, cmd4) self.assertFalse(Delta.objects.filter(pk=cmd2.id).exists()) self.assertFalse(Delta.objects.filter(pk=cmd3.id).exists()) # Undo back to start, then add a command, ensure it deletes dangling commands # (tests an edge case in Delta.save) self.assertEqual(Delta.objects.count(), 2) WorkflowUndo(self.workflow) WorkflowUndo(self.workflow) self.assertIsNone(self.workflow.last_delta) cmd5 = ChangeWfModuleNotesCommand.create(wfm, "Note of some note") self.workflow.refresh_from_db() self.assertEqual(self.workflow.last_delta, cmd5) self.assertFalse(Delta.objects.filter(pk=cmd1.id).exists()) self.assertFalse(Delta.objects.filter(pk=cmd4.id).exists())
def test_add_delete(self): cmda = AddModuleCommand.create(self.workflow, module_version=self.module_version, insert_before=0) cmdd = DeleteModuleCommand.create(cmda.wf_module) self.workflow.delete()