def workflow_delete_column(workflow, column, cond_to_delete=None): """ Given a workflow and a column, removes it from the workflow (and the corresponding data frame :param workflow: Workflow object :param column: Column object to delete :param cond_to_delete: List of conditions to delete after removing the column :return: Nothing. Effect reflected in the database """ # Drop the column from the DB table storing the data frame pandas_db.df_drop_column(workflow.id, column.name) # Delete the column column.delete() # Update the information in the workflow workflow.ncols = workflow.ncols - 1 workflow.save() if not cond_to_delete: # The conditions to delete are not given, so calculate them # Get the conditions/actions attached to this workflow cond_to_delete = [ x for x in Condition.objects.filter(action__workflow=workflow) if formula_evaluation.has_variable(x.formula, column.name) ] # If a column disappears, the conditions that contain that variable # are removed.. for condition in cond_to_delete: # Formula has the name of the deleted column. # Solution 1: Nuke (Very easy) # Solution 2: Mark as invalid and enhance the edit condition form # to handle renaming the fields in a formula (Complex) # # Solution 1 chosen. condition.delete() # If a column disappears, the views that contain only that column need to # disappear as well as they are no longer relevant. for view in workflow.views.all(): if view.columns.all().count() == 0: view.delete() return
def test_action_01_rename_column_condition_attribute(self): # First get objects for future checks workflow = Workflow.objects.get(name=self.wflow_name) column = Column.objects.get(name='registered', workflow=workflow) attributes = workflow.attributes action_in = Action.objects.get(name='Check registration', workflow=workflow) action_out = Action.objects.get(name='Detecting age', workflow=workflow) condition = Condition.objects.get( name='Registered', action=action_out, ) filter_obj = action_out.get_filter() # pre-conditions # Column name is the correct one self.assertEqual(column.name, 'registered') # Condition name is the correct one self.assertEqual(condition.name, 'Registered') # Attribute name is the correct one self.assertEqual(attributes['attribute name'], 'attribute value') # Column name is present in condition formula self.assertTrue(has_variable(condition.formula, 'registered')) # Column name is present in action_out text self.assertTrue('{{ registered }}' in action_out.content) # Attribute name is present in action_out text self.assertTrue('{{ attribute name }}' in action_out.content) # Column name is present in action-in filter self.assertTrue(has_variable(filter_obj.formula, 'age')) # Login self.login('*****@*****.**') # Go to the details page self.access_workflow_from_home_page(self.wflow_name) # Click the button to rename the "registered" column self.open_column_edit('registered') # Introduce the new column name and submit self.selenium.find_element_by_id("id_name").click() self.selenium.find_element_by_id("id_name").clear() self.selenium.find_element_by_id("id_name").send_keys("registered new") self.selenium.find_element_by_xpath("//button[@type='submit']").click() self.wait_close_modal_refresh_table('column-table_previous') # Click the button to rename the "age" column self.open_column_edit('age') # Introduce the new column name and submit self.selenium.find_element_by_id("id_name").click() self.selenium.find_element_by_id("id_name").clear() self.selenium.find_element_by_id("id_name").send_keys("age new") self.selenium.find_element_by_xpath("//button[@type='submit']").click() self.wait_close_modal_refresh_table('column-table_previous') # Go to the attribute page self.go_to_attribute_page() # Change the name of the attribute and submit element = self.search_table_row_by_string('attribute-table', 1, 'attribute name') element.find_element_by_xpath("td[3]/button[1]").click() WebDriverWait(self.selenium, 10).until( EC.text_to_be_present_in_element((By.CLASS_NAME, 'modal-title'), 'Edit attribute')) self.selenium.find_element_by_id('id_key').clear() self.selenium.find_element_by_id('id_key').send_keys( 'attribute name new') self.selenium.find_element_by_id('id_value').clear() self.selenium.find_element_by_id('id_value').send_keys( 'attribute value') # Submit self.selenium.find_element_by_xpath( "//div[@class='modal-footer']/button[2]").click() # Go back to the attribute table page self.wait_close_modal_refresh_table('attribute-table_previous') # Go to the actions and select the edit button of the action out self.go_to_actions() self.open_action_edit('Detecting age') # Click the button to edit a condition and change its name self.selenium.find_element_by_xpath( "//button[contains(@class, 'js-condition-edit')]").click() WebDriverWait(self.selenium, 10).until( EC.presence_of_element_located( (By.XPATH, "//div[@id='modal-item']//form"))) self.selenium.find_element_by_id("id_name").click() self.selenium.find_element_by_id("id_name").clear() self.selenium.find_element_by_id("id_name").send_keys("Registered new") self.selenium.find_element_by_xpath( "//div[@id='modal-item']//button[@type='submit']").click() WebDriverWait(self.selenium, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-open'))) # Refresh variables workflow = Workflow.objects.get(pk=workflow.id) column = Column.objects.get(pk=column.id) attributes = workflow.attributes action_out = Action.objects.get(pk=action_out.id) condition = Condition.objects.get(pk=condition.id) filter_obj = action_out.get_filter() # Post conditions # Column name is the correct one self.assertEqual(column.name, 'registered new') # Condition name is the correct one self.assertEqual(condition.name, 'Registered new') # Attribute name is the correct one self.assertEqual(attributes['attribute name new'], 'attribute value') # Column name is present in condition formula self.assertFalse(has_variable(condition.formula, 'registered')) self.assertTrue(has_variable(condition.formula, 'registered new')) # Column name is present in action_out text self.assertTrue('{{ registered new }}' in action_out.content) # Attribute name is present in action_out text self.assertTrue('{{ attribute name new }}' in action_out.content) # Column age is present in action-in filter self.assertFalse(has_variable(filter_obj.formula, 'age')) self.assertTrue(has_variable(filter_obj.formula, 'age new')) # End of session self.logout()
def column_delete(request, pk): """ Delete a column in the table attached to a workflow :param request: HTTP request :param pk: ID of the column to delete. The workflow element is taken from the session. :return: Render the delete column form """ # JSON response, context and default values data = dict() # JSON response # Get the workflow element workflow = get_workflow(request) if not workflow: data['form_is_valid'] = True data['html_redirect'] = reverse('workflow:index') return JsonResponse(data) data['form_is_valid'] = False context = {'pk': pk} # For rendering # Get the column try: column = Column.objects.get(pk=pk, workflow=workflow) except ObjectDoesNotExist: # The column is not there. Redirect to workflow detail data['form_is_valid'] = True data['html_redirect'] = reverse('workflow:detail', kwargs={'pk': workflow.id}) return JsonResponse(data) # If the columns is unique and it is the only one, we cannot allow # the operation unique_column = workflow.get_column_unique() if column.is_key and len([x for x in unique_column if x]) == 1: # This is the only key column messages.error(request, _('You cannot delete the only key column')) data['form_is_valid'] = True data['html_redirect'] = reverse('workflow:detail', kwargs={'pk': workflow.id}) return JsonResponse(data) # Get the name of the column to delete context['cname'] = column.name # Get the conditions/actions attached to this workflow cond_to_delete = [x for x in Condition.objects.filter( action__workflow=workflow) if formula_evaluation.has_variable(x.formula, column.name)] # Put it in the context because it is shown to the user before confirming # the deletion context['cond_to_delete'] = cond_to_delete if request.method == 'POST': # Proceed deleting the column workflow_delete_column(workflow, column, cond_to_delete) # Log the event logs.ops.put(request.user, 'column_delete', workflow, {'id': workflow.id, 'name': workflow.name, 'column_name': column.name}) data['form_is_valid'] = True # There are various points of return from_url = request.META['HTTP_REFERER'] if from_url.endswith(reverse('table:display')): data['html_redirect'] = reverse('table:display') else: data['html_redirect'] = reverse('workflow:detail', kwargs={'pk': workflow.id}) return JsonResponse(data) data['html_form'] = render_to_string( 'workflow/includes/partial_column_delete.html', context, request=request) return JsonResponse(data)
def test_action_01_rename_column_condition_attribute(self): # First get objects for future checks workflow = Workflow.objects.get(name=self.wflow_name) column = Column.objects.get(name='registered', workflow=workflow) attributes = workflow.attributes action_in = Action.objects.get(name='Check registration', workflow=workflow) action_out = Action.objects.get(name='Detecting age', workflow=workflow) condition = Condition.objects.get( name='Registered', action=action_out, ) # pre-conditions # Column name is the correct one self.assertEqual(column.name, 'registered') # Condition name is the correct one self.assertEqual(condition.name, 'Registered') # Attribute name is the correct one self.assertEqual(attributes['attribute name'], 'attribute value') # Column name is present in condition formula self.assertTrue(has_variable(condition.formula, 'registered')) # Column name is present in action_out text self.assertTrue('{{ registered }}' in action_out.content) # Attribute name is present in action_out text self.assertTrue('{{ attribute name }}' in action_out.content) # Column name is present in action-in filter self.assertTrue(has_variable(action_in.filter, 'registered')) # Login self.login('*****@*****.**') self.open(reverse('workflow:index')) # Select the workflow self.selenium.find_element_by_link_text("wflow2").click() WebDriverWait(self.selenium, 10).until( EC.element_to_be_clickable((By.CLASS_NAME, 'success'))) # Click the button to rename the "registered" column self.selenium.find_element_by_xpath( "//table[@id='column-table']/tbody/tr[5]/td[4]/div/button").click( ) self.selenium.find_element_by_xpath( "//table[@id='column-table']/tbody/tr[5]/td[4]/div/ul/li[1]/button" ).click() WebDriverWait(self.selenium, 10).until( EC.text_to_be_present_in_element((By.CLASS_NAME, 'modal-title'), 'Edit column')) # Wait for the table to be refreshed WebDriverWait(self.selenium, 10).until( EC.presence_of_element_located((By.ID, 'column-table_previous'))) # Introduce the new column name and submit self.selenium.find_element_by_id("id_name").click() self.selenium.find_element_by_id("id_name").clear() self.selenium.find_element_by_id("id_name").send_keys("registered new") self.selenium.find_element_by_xpath("//button[@type='submit']").click() WebDriverWait(self.selenium, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-open'))) # Click in the more ops button and then attribute self.selenium.find_element_by_xpath( "(//button[@type='button'])[4]").click() self.selenium.find_element_by_link_text("Attributes").click() # Change the name of the attribute and submit self.selenium.find_element_by_xpath( "//table[@id='attribute-table']/tbody/tr[1]/td[3]/button[1]" ).click() WebDriverWait(self.selenium, 10).until( EC.text_to_be_present_in_element((By.CLASS_NAME, 'modal-title'), 'Edit attribute')) self.selenium.find_element_by_id('id_key').clear() self.selenium.find_element_by_id('id_key').send_keys( 'attribute name new') self.selenium.find_element_by_id('id_value').clear() self.selenium.find_element_by_id('id_value').send_keys( 'attribute value') # Submit self.selenium.find_element_by_xpath( "//div[@class='modal-footer']/button[2]").click() # MODAL WAITING WebDriverWait(self.selenium, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-open'))) # Go to the actions and select the edit button of the action out self.selenium.find_element_by_link_text("Actions").click() self.selenium.find_element_by_xpath( "//table[@id='action-table']/tbody/tr[2]/td[5]/div/a").click() # Click the button to edit a condition and change its name self.selenium.find_element_by_xpath( "(//button[@type='button'])[6]").click() self.selenium.find_element_by_id("id_name").click() self.selenium.find_element_by_id("id_name").clear() self.selenium.find_element_by_id("id_name").send_keys("Registered new") self.selenium.find_element_by_xpath( "(//button[@type='submit'])[3]").click() WebDriverWait(self.selenium, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-open'))) # Refresh variables workflow = Workflow.objects.get(pk=workflow.id) column = Column.objects.get(pk=column.id) attributes = workflow.attributes action_in = Action.objects.get(pk=action_in.id) action_out = Action.objects.get(pk=action_out.id) condition = Condition.objects.get(pk=condition.id) # Post conditions # Column name is the correct one self.assertEqual(column.name, 'registered new') # Condition name is the correct one self.assertEqual(condition.name, 'Registered new') # Attribute name is the correct one self.assertEqual(attributes['attribute name new'], 'attribute value') # Column name is present in condition formula self.assertFalse(has_variable(condition.formula, 'registered')) self.assertTrue(has_variable(condition.formula, 'registered new')) # Column name is present in action_out text self.assertTrue('{{ registered new }}' in action_out.content) # Attribute name is present in action_out text #self.assertTrue('{{ attribute name new }}' in action_out.content) # Column name is present in action-in filter self.assertFalse(has_variable(action_in.filter, 'registered')) self.assertTrue(has_variable(action_in.filter, 'registered new')) # End of session self.logout()
def test_action_01_rename_column_condition_attribute(self): # First get objects for future checks workflow = Workflow.objects.get(name=self.wflow_name) column = Column.objects.get(name='registered', workflow=workflow) attributes = workflow.attributes Action.objects.get(name='Check registration', workflow=workflow) action_out = Action.objects.get(name='Detecting age', workflow=workflow) condition = Condition.objects.get( name='Registered', action=action_out, ) filter_obj = action_out.get_filter() # pre-conditions # Column name is the correct one self.assertEqual(column.name, 'registered') # Condition name is the correct one self.assertEqual(condition.name, 'Registered') # Attribute name is the correct one self.assertEqual(attributes['attribute name'], 'attribute value') # Column name is present in condition formula self.assertTrue(has_variable(condition.formula, 'registered')) # Column name is present in action_out text self.assertTrue('{{ registered }}' in action_out.content) # Attribute name is present in action_out text self.assertTrue('{{ attribute name }}' in action_out.content) # Column name is present in action-in filter self.assertTrue(has_variable(filter_obj.formula, 'age')) # Login self.login('*****@*****.**') # Go to the details page self.access_workflow_from_home_page(self.wflow_name) # Click the button to rename the "registered" column self.go_to_details() self.open_column_edit('registered') # Introduce the new column name and submit self.selenium.find_element_by_id("id_name").click() self.selenium.find_element_by_id("id_name").clear() self.selenium.find_element_by_id("id_name").send_keys("registered new") self.selenium.find_element_by_xpath("//button[@type='submit']").click() self.wait_close_modal_refresh_table('column-table_previous') # Click the button to rename the "age" column self.open_column_edit('age') # Introduce the new column name and submit self.selenium.find_element_by_id("id_name").click() self.selenium.find_element_by_id("id_name").clear() self.selenium.find_element_by_id("id_name").send_keys("age new") self.selenium.find_element_by_xpath("//button[@type='submit']").click() self.wait_close_modal_refresh_table('column-table_previous') # Go to the attribute page self.go_to_attribute_page() # Change the name of the attribute and submit self.edit_attribute('attribute name', 'attribute name new', 'attribute value') # Go to the actions and select the edit button of the action out self.go_to_actions() self.open_action_edit('Detecting age') # Click the button to edit a condition and change its name self.edit_condition('Registered', 'Registered new', None, []) # Refresh variables workflow = Workflow.objects.get(pk=workflow.id) column = Column.objects.get(pk=column.id) attributes = workflow.attributes action_out = Action.objects.get(pk=action_out.id) condition = Condition.objects.get(pk=condition.id) filter_obj = action_out.get_filter() # Post conditions # Column name is the correct one self.assertEqual(column.name, 'registered new') # Condition name is the correct one self.assertEqual(condition.name, 'Registered new') # Attribute name is the correct one self.assertEqual(attributes['attribute name new'], 'attribute value') # Column name is present in condition formula self.assertFalse(has_variable(condition.formula, 'registered')) self.assertTrue(has_variable(condition.formula, 'registered new')) # Column name is present in action_out text self.assertTrue('{{ registered new }}' in action_out.content) # Attribute name is present in action_out text self.assertTrue('{{ attribute name new }}' in action_out.content) # Column age is present in action-in filter self.assertFalse(has_variable(filter_obj.formula, 'age')) self.assertTrue(has_variable(filter_obj.formula, 'age new')) # End of session self.logout()