Browse Source

Refactoring: Applied factory best practices (only required attributes and values, proc based attribute assignment, sequence attribute).

Martin Edenhofer 6 years ago
parent
commit
ace7cea315

+ 9 - 6
app/assets/javascripts/app/controllers/ticket_zoom.coffee

@@ -807,12 +807,15 @@ class App.TicketZoom extends App.Controller
     # stop autosave
     @autosaveStop()
 
-    # validate ticket form using HTML5 validity check
-    element = @$('.edit').parent().get(0)
-    if element && element.reportValidity && !element.reportValidity()
-      @submitEnable(e)
-      @autosaveStart()
-      return
+    # no form validation if macro is performed
+    if !macro.perform
+
+      # validate ticket form using HTML5 validity check
+      element = @$('.edit').parent().get(0)
+      if element && element.reportValidity && !element.reportValidity()
+        @submitEnable(e)
+        @autosaveStart()
+        return
 
     # validate ticket by model
     errors = ticket.validate(

+ 13 - 0
spec/factories/macro.rb

@@ -0,0 +1,13 @@
+FactoryBot.define do
+  factory :macro do
+    sequence(:name) { |n| "Macro #{n}" }
+    perform do
+      {}
+    end
+    ux_flow_next_up { 'next_task' }
+    note            { '' }
+    active          { true }
+    created_by_id   { 1 }
+    updated_by_id   { 1 }
+  end
+end

+ 102 - 15
spec/system/ticket/update_spec.rb

@@ -9,17 +9,98 @@ RSpec.describe 'Ticket Update', type: :system do
     scenario 'frontend checks reject the update', db_strategy: :reset do
       # setup and migrate a required select attribute
       attribute = create_attribute :object_manager_attribute_select,
-                                   screens: attributes_for(:required_screen)
+                                   screens:     attributes_for(:required_screen),
+                                   data_option: {
+                                     options:    {
+                                       'name 1': 'name 1',
+                                       'name 2': 'name 2',
+                                     },
+                                     default:    '',
+                                     null:       false,
+                                     relation:   '',
+                                     maxlength:  255,
+                                     nulloption: true,
+                                   }
 
       # create a new ticket and attempt to update its state without the required select attribute
       ticket = create :ticket, group: group
       visit "#ticket/zoom/#{ticket.id}"
-      select 'closed', from: 'state_id'
-      click('.content.active .js-attributeBar .js-submit')
-      expect(page).to have_css('.content.active')
+      within(:active_content) do
+        expect(page).to have_css('.js-objectNumber', wait: 2)
+
+        select 'closed', from: 'state_id'
+        click('.js-attributeBar .js-submit')
+        expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
+      end
 
       # the update should have failed and thus the ticket is still in the new state
       expect(ticket.reload.state.name).to eq('new')
+
+      within(:active_content) do
+        # update should work now
+        find('.edit [name=internal_name1]').select('name 2')
+        click('.js-attributeBar .js-submit')
+        expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
+      end
+
+      ticket.reload
+      expect(ticket[attribute.name]).to eq('name 2')
+      expect(ticket.state.name).to eq('closed')
+    end
+
+    scenario 'with macro and required tree_select field', db_strategy: :reset do
+      # setup and migrate a required select attribute
+      attribute = create_attribute :object_manager_attribute_tree_select,
+                                   screens:     attributes_for(:required_screen),
+                                   data_option: {
+                                     options:    [
+                                       {
+                                         name:  'name 1',
+                                         value: 'name 1',
+                                       },
+                                       {
+                                         name:  'name 2',
+                                         value: 'name 2',
+                                       },
+                                     ],
+                                     default:    '',
+                                     null:       false,
+                                     relation:   '',
+                                     maxlength:  255,
+                                     nulloption: true,
+                                   }
+
+      attribute_value = 'name 2'
+      state           = Ticket::State.by_category(:closed).first
+      macro           = create(:macro,
+                               perform: {
+                                 'ticket.state_id'          => {
+                                   value: state.id,
+                                 },
+                                 "ticket.#{attribute.name}" => {
+                                   value: attribute_value,
+                                 },
+                               })
+
+      # refresh browser to get macro accessable
+      page.driver.browser.navigate.refresh
+
+      # create a new ticket and attempt to update its state without the required select attribute
+      ticket = create(:ticket, group: group)
+      visit "#ticket/zoom/#{ticket.id}"
+
+      within(:active_content) do
+        expect(page).to have_css('.js-objectNumber', wait: 2)
+
+        click('.js-openDropdownMacro')
+        click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]")
+        expect(page).not_to have_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
+      end
+
+      # the update should not have failed and thus the ticket is in closed state
+      ticket.reload
+      expect(ticket[attribute.name]).to eq(attribute_value)
+      expect(ticket.state.name).to eq(state.name)
     end
   end
 
@@ -32,20 +113,26 @@ RSpec.describe 'Ticket Update', type: :system do
       origin_ticket.merge_to(ticket_id: target_ticket.id, user_id: user.id)
 
       visit "#ticket/zoom/#{origin_ticket.id}"
-      click '.content.active .js-actions .dropdown-toggle'
-      click '.content.active .js-actions .dropdown-menu [data-type="ticket-history"]'
+      within(:active_content) do
+        expect(page).to have_css('.js-actions .dropdown-toggle', wait: 3)
+        click '.js-actions .dropdown-toggle'
+        click '.js-actions .dropdown-menu [data-type="ticket-history"]'
 
-      modal = find('.content.active .modal')
-      expect(modal).to have_content "This ticket was merged into ticket ##{target_ticket.number}"
-      expect(modal).to have_link "##{target_ticket.number}", href: "#ticket/zoom/#{target_ticket.id}"
+        expect(page).to have_css('.modal', wait: 3)
+        modal = find('.modal')
+        expect(modal).to have_content "This ticket was merged into ticket ##{target_ticket.number}"
+        expect(modal).to have_link "##{target_ticket.number}", href: "#ticket/zoom/#{target_ticket.id}"
 
-      visit "#ticket/zoom/#{target_ticket.id}"
-      click '.content.active .js-actions .dropdown-toggle'
-      click '.content.active .js-actions .dropdown-menu [data-type="ticket-history"]'
+        visit "#ticket/zoom/#{target_ticket.id}"
+        expect(page).to have_css('.js-actions .dropdown-toggle', wait: 3)
+        click '.js-actions .dropdown-toggle'
+        click '.js-actions .dropdown-menu [data-type="ticket-history"]'
 
-      modal = find('.content.active .modal')
-      expect(modal).to have_content("Ticket ##{origin_ticket.number} was merged into this ticket")
-      expect(modal).to have_link "##{origin_ticket.number}", href: "#ticket/zoom/#{origin_ticket.id}"
+        expect(page).to have_css('.modal', wait: 3)
+        modal = find('.modal')
+        expect(modal).to have_content("Ticket ##{origin_ticket.number} was merged into this ticket")
+        expect(modal).to have_link "##{origin_ticket.number}", href: "#ticket/zoom/#{origin_ticket.id}"
+      end
     end
   end
 end