From db52adaec156ff9b9beebea0f98277d564f3daee Mon Sep 17 00:00:00 2001 From: Mantas Date: Sun, 12 Dec 2021 17:45:33 +0200 Subject: [PATCH] Maintenance: Ticket view Capybara specs cleanup --- spec/factories/object_manager_attribute.rb | 16 +- spec/support/capybara/browser_test_helper.rb | 8 +- spec/system/ticket/view_spec.rb | 357 ++++++++----------- 3 files changed, 158 insertions(+), 223 deletions(-) diff --git a/spec/factories/object_manager_attribute.rb b/spec/factories/object_manager_attribute.rb index 807374d1b..b35172a61 100644 --- a/spec/factories/object_manager_attribute.rb +++ b/spec/factories/object_manager_attribute.rb @@ -129,17 +129,23 @@ FactoryBot.define do end factory :object_manager_attribute_select, parent: :object_manager_attribute do + transient do + data_option_options do + { + 'key_1' => 'value_1', + 'key_2' => 'value_2', + 'key_3' => 'value_3', + } + end + end + default { '' } data_type { 'select' } data_option do { 'default' => default, - 'options' => { - 'key_1' => 'value_1', - 'key_2' => 'value_2', - 'key_3' => 'value_3', - }, + 'options' => data_option_options, 'relation' => '', 'nulloption' => true, 'multiple' => false, diff --git a/spec/support/capybara/browser_test_helper.rb b/spec/support/capybara/browser_test_helper.rb index fa89d20dc..80d5d58dd 100644 --- a/spec/support/capybara/browser_test_helper.rb +++ b/spec/support/capybara/browser_test_helper.rb @@ -133,10 +133,12 @@ module BrowserTestHelper # overview section. # # @example - # display_macro_batches(ticket) - # display_macro_batches(tr[data-id='1']) + # display_macro_batches(Ticket.first) # - def display_macro_batches(element) + def display_macro_batches(ticket) + # get DOM element + element = page.find(:table_row, ticket.id).native + # get element moving click_and_hold(element) # move element to y -ticket.location.y move_mouse_by(0, -element.location.y + 5) diff --git a/spec/system/ticket/view_spec.rb b/spec/system/ticket/view_spec.rb index 164991da0..e5403a417 100644 --- a/spec/system/ticket/view_spec.rb +++ b/spec/system/ticket/view_spec.rb @@ -2,125 +2,81 @@ require 'rails_helper' -RSpec.describe 'Ticket views', type: :system do +RSpec.describe 'Ticket views', type: :system, authenticated_as: :authenticate do + def authenticate + true + end + context 'macros' do - let!(:group1) { create :group } - let!(:group2) { create :group } - let!(:macro_without_group) { create :macro } - let!(:macro_note) { create :macro, perform: { 'article.note'=>{ 'body' => 'macro body', 'internal' => 'true', 'subject' => 'macro note' } } } - let!(:macro_group1) { create :macro, groups: [group1] } - let!(:macro_group2) { create :macro, groups: [group2] } + let(:group1) { create :group } + let(:group2) { create :group } + let(:macro_without_group) { create :macro } + let(:macro_note) { create :macro, perform: { 'article.note'=>{ 'body' => 'macro body', 'internal' => 'true', 'subject' => 'macro note' } } } + let(:macro_group1) { create :macro, groups: [group1] } + let(:macro_group2) { create :macro, groups: [group2] } + let(:ticket1) { create :ticket, group: group1 } + let(:ticket2) { create :ticket, group: group2 } - it 'supports group-dependent macros' do + describe 'group-dependent macros' do + let(:agent) { create(:agent, groups: Group.all) } - ticket1 = create :ticket, group: group1 - ticket2 = create :ticket, group: group2 - - # give user access to all groups including those created - # by using FactoryBot outside of the example - group_names_access_map = Group.all.pluck(:name).index_with do |_group_name| - 'full'.freeze + def authenticate + ticket1 && ticket2 + macro_without_group && macro_group1 && macro_group2 + agent end - current_user do |user| - user.group_names_access_map = group_names_access_map - user.save! + it 'shows only non-group macro when ticket does not match any group macros' do + visit '#ticket/view/all_open' + + within(:active_content) do + display_macro_batches Ticket.first + + expect(page).to have_selector(:macro_batch, macro_without_group.id) + .and(have_no_selector(:macro_batch, macro_group1.id)) + .and(have_no_selector(:macro_batch, macro_group2.id)) + end end - # refresh browser to get macro accessable - refresh - visit '#ticket/view/all_open' + it 'shows non-group and matching group macros for matching ticket' do + visit '#ticket/view/all_open' - within(:active_content) do - - ticket = page.find(:table_row, 1).native - - # click and hold first ticket in table - click_and_hold(ticket) - - # move ticket to y -ticket.location.y - move_mouse_by(0, -ticket.location.y + 5) - - # move a bit to the left to display macro batches - move_mouse_by(-250, 0) - - expect(page).to have_selector(:macro_batch, macro_without_group.id, visible: :visible) - expect(page).to have_no_selector(:macro_batch, macro_group1.id) - expect(page).to have_no_selector(:macro_batch, macro_group2.id) - - release_mouse - - refresh - - ticket = page.find(:table_row, ticket1.id).native - - # click and hold first ticket in table - click_and_hold(ticket) - - # move ticket to y -ticket.location.y - move_mouse_by(0, -ticket.location.y + 5) - - # move a bit to the left to display macro batches - move_mouse_by(-250, 0) - - expect(page).to have_selector(:macro_batch, macro_without_group.id, visible: :visible) - expect(page).to have_selector(:macro_batch, macro_group1.id) - expect(page).to have_no_selector(:macro_batch, macro_group2.id) - - release_mouse - - refresh - - ticket = page.find(:table_row, ticket2.id).native - - # click and hold first ticket in table - click_and_hold(ticket) - - # move ticket to y -ticket.location.y - move_mouse_by(0, -ticket.location.y + 5) - - # move a bit to the left to display macro batches - move_mouse_by(-250, 0) - - expect(page).to have_selector(:macro_batch, macro_without_group.id, visible: :visible) - expect(page).to have_no_selector(:macro_batch, macro_group1.id) - expect(page).to have_selector(:macro_batch, macro_group2.id) + within(:active_content) do + display_macro_batches ticket1 + expect(page).to have_selector(:macro_batch, macro_without_group.id) + .and(have_selector(:macro_batch, macro_group1.id)) + .and(have_no_selector(:macro_batch, macro_group2.id)) + end end end - it 'can use macro to create article' do - refresh - visit '#ticket/view/all_open' + describe 'macro article creation' do + def authenticate + macro_note + true + end - within(:active_content) do - ticket = page.find(:table_row, Ticket.first.id).native + it 'can use macro to create article' do + visit '#ticket/view/all_open' - # click and hold first ticket in table - click_and_hold(ticket) + within(:active_content) do + display_macro_batches Ticket.first - # move ticket to y -ticket.location.y - move_mouse_by(0, -ticket.location.y + 5) + move_mouse_to find(:macro_batch, macro_note.id) + release_mouse - # move a bit to the left to display macro batches - move_mouse_by(-250, 0) - - expect(page).to have_selector(:macro_batch, macro_note.id, wait: 10) - - macro = find(:macro_batch, macro_note.id) - move_mouse_to(macro) - - release_mouse - - expect do - wait(10, interval: 0.1).until { Ticket.first.articles.last.subject == 'macro note' } - end.not_to raise_error + expect do + wait.until { Ticket.first.articles.last.subject == 'macro note' } + end.not_to raise_error + end end end - context 'when saving is blocked by one of selected tickets', authenticated_as: :pre_authentication do - let(:core_workflow_action) { { 'ticket.priority_id': { operator: 'remove_option', remove_option: '3' } } } - let(:core_workflow) { create(:core_workflow, :active_and_screen, :perform_action) } + context 'when saving is blocked by one of selected tickets' do + let(:ticket) { Ticket.first } + let(:core_workflow_action) { { 'ticket.priority_id': { operator: 'remove_option', remove_option: '3' } } } + let(:core_workflow) { create(:core_workflow, :active_and_screen, :perform_action) } let(:macro_perform) do { @@ -129,9 +85,8 @@ RSpec.describe 'Ticket views', type: :system do end let(:macro_priority) { create :macro, perform: macro_perform } - let(:ticket1) { create :ticket, group: Group.first } - def pre_authentication + def authenticate core_workflow && macro_priority && ticket1 true @@ -141,26 +96,13 @@ RSpec.describe 'Ticket views', type: :system do visit '#ticket/view/all_open' within(:active_content) do - ticket_dom = page.find(:table_row, ticket1.id).native - - # click and hold first ticket in table - click_and_hold(ticket_dom) - - # move ticket to y -ticket.location.y - move_mouse_by(0, -ticket_dom.location.y + 5) - - # move a bit to the left to display macro batches - move_mouse_by(-250, 0) - - expect(page).to have_selector(:macro_batch, macro_priority.id, wait: 10) - - macro_dom = find(:macro_batch, macro_priority.id) - move_mouse_to(macro_dom) + display_macro_batches ticket + move_mouse_to find(:macro_batch, macro_priority.id) release_mouse in_modal disappears: false do - expect(page).to have_text(ticket1.title) + expect(page).to have_text(ticket.title) end end end @@ -170,14 +112,9 @@ RSpec.describe 'Ticket views', type: :system do shared_examples "adding 'small' class to macro element" do it 'adds a "small" class to the macro element' do within(:active_content) do + display_macro_batches Ticket.first - ticket = page.find(:table_row, Ticket.first.id).native - - display_macro_batches(ticket) - - expect(page).to have_selector('.batch-overlay-macro-entry.small', wait: 10) - - release_mouse + expect(page).to have_selector('.batch-overlay-macro-entry.small') end end end @@ -185,14 +122,9 @@ RSpec.describe 'Ticket views', type: :system do shared_examples "not adding 'small' class to macro element" do it 'does not add a "small" class to the macro element' do within(:active_content) do + display_macro_batches Ticket.first - ticket = page.find(:table_row, Ticket.first.id).native - - display_macro_batches(ticket) - - expect(page).to have_no_selector('.batch-overlay-macro-entry.small', wait: 10) - - release_mouse + expect(page).to have_no_selector('.batch-overlay-macro-entry.small') end end end @@ -200,14 +132,9 @@ RSpec.describe 'Ticket views', type: :system do shared_examples 'showing all macros' do it 'shows all macros' do within(:active_content) do + display_macro_batches Ticket.first - ticket = page.find(:table_row, Ticket.first.id).native - - display_macro_batches(ticket) - - expect(page).to have_selector('.batch-overlay-macro-entry', count: all, wait: 10) - - release_mouse + expect(page).to have_selector('.batch-overlay-macro-entry', count: all) end end end @@ -215,22 +142,20 @@ RSpec.describe 'Ticket views', type: :system do shared_examples 'showing some macros' do |count| it 'shows all macros' do within(:active_content) do + display_macro_batches Ticket.first - ticket = page.find(:table_row, Ticket.first.id).native - - display_macro_batches(ticket) - - expect(page).to have_selector('.batch-overlay-macro-entry', count: count, wait: 10) - - release_mouse + expect(page).to have_selector('.batch-overlay-macro-entry', count: count) end end end shared_examples 'show macros batch overlay' do - before do + def authenticate Macro.destroy_all && (create_list :macro, all) - refresh + true + end + + before do page.current_window.resize_to(width, height) visit '#ticket/view/all_open' end @@ -284,11 +209,13 @@ RSpec.describe 'Ticket views', type: :system do context 'when creating a Note', authenticated_as: :user do let(:group) { create :group } let(:user) { create :admin, groups: [group] } - let!(:ticket1) { create(:ticket, state_name: 'open', owner: user, group: group) } - let!(:ticket2) { create(:ticket, state_name: 'open', owner: user, group: group) } - let(:note) { Faker::Lorem.sentence } + let(:ticket1) { create(:ticket, state_name: 'open', owner: user, group: group) } + let(:ticket2) { create(:ticket, state_name: 'open', owner: user, group: group) } + let(:note) { Faker::Lorem.sentence } it 'adds note to all selected tickets' do + ticket1 && ticket2 + visit 'ticket/view/my_assigned' within :active_content do @@ -299,7 +226,7 @@ RSpec.describe 'Ticket views', type: :system do end expect do - wait(10, interval: 0.1).until { [ ticket1.articles.last&.body, ticket2.articles.last&.body ] == [note, note] } + wait.until { [ ticket1.articles.last&.body, ticket2.articles.last&.body ] == [note, note] } end.not_to raise_error end end @@ -358,7 +285,7 @@ RSpec.describe 'Ticket views', type: :system do end it 'shows modal with blocking ticket title' do - visit '#ticket/view/all_open' + visit 'ticket/view/all_open' within(:active_content) do find("tr[data-id='#{ticket1.id}']").check('bulk', allow_label_click: true) @@ -375,29 +302,32 @@ RSpec.describe 'Ticket views', type: :system do end context 'Setting "ui_table_group_by_show_count"', authenticated_as: :authenticate, db_strategy: :reset do - let!(:ticket1) { create(:ticket, group: Group.find_by(name: 'Users')) } - let!(:ticket2) { create(:ticket, group: Group.find_by(name: 'Users')) } - let!(:ticket3) { create(:ticket, group: Group.find_by(name: 'Users')) } - let!(:ticket4) { create(:ticket, group: Group.find_by(name: 'Users')) } + let(:custom_attribute) { create :object_manager_attribute_select, name: 'grouptest' } + let(:tickets) do + [ + create(:ticket, group: Group.find_by(name: 'Users')), + create(:ticket, group: Group.find_by(name: 'Users'), grouptest: 'key_1'), + create(:ticket, group: Group.find_by(name: 'Users'), grouptest: 'key_2'), + create(:ticket, group: Group.find_by(name: 'Users'), grouptest: 'key_1') + ] + end def authenticate - create :object_manager_attribute_select, name: 'grouptest' + custom_attribute ObjectManager::Attribute.migration_execute - ticket1 - ticket2.update(grouptest: 'key_1') - ticket3.update(grouptest: 'key_2') - ticket4.update(grouptest: 'key_1') - Overview.find_by(name: 'Open').update(group_by: 'grouptest') + tickets + Overview.find_by(name: 'Open').update(group_by: custom_attribute.name) Setting.set('ui_table_group_by_show_count', true) true end it 'shows correct ticket counts' do visit 'ticket/view/all_open' + within(:active_content) do - page.find('.js-tableBody td b', text: '(1)') - page.find('.js-tableBody td b', text: 'value_1 (2)') - page.find('.js-tableBody td b', text: 'value_2 (1)') + expect(page).to have_css('.js-tableBody td b', text: '(1)') + .and(have_css('.js-tableBody td b', text: 'value_1 (2)')) + .and(have_css('.js-tableBody td b', text: 'value_2 (1)')) end end end @@ -411,76 +341,73 @@ RSpec.describe 'Ticket views', type: :system do customer end - it 'does basic view test of tickets' do + it 'shows ticket in my tickets' do + visit 'ticket/view/my_tickets' + expect(page).to have_text(ticket.title) + end + + it 'shows ticket in my organization tickets' do visit 'ticket/view/my_tickets' - expect(page).to have_text(ticket.title, wait: 10) click_on 'My Organization Tickets' - expect(page).to have_text(ticket.title, wait: 10) + expect(page).to have_text(ticket.title) end end - describe 'Grouping' do - context 'when sorted by custom object date', authenticated_as: :authenticate, db_strategy: :reset do - let(:ticket1) { create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2018-01-17') } - let(:ticket2) { create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2018-08-19') } - let(:ticket3) { create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2019-01-19') } - let(:ticket4) { create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2021-08-18') } + describe 'Grouping by custom attribute', authenticated_as: :authenticate, db_strategy: :reset do + def authenticate + custom_attribute + ObjectManager::Attribute.migration_execute + tickets + Overview.find_by(link: 'all_unassigned').update(group_by: custom_attribute.name) + true + end - def authenticate - create :object_manager_attribute_date, name: 'cdate' - ObjectManager::Attribute.migration_execute - ticket4 - ticket3 - ticket2 - ticket1 - Overview.find_by(link: 'all_unassigned').update(group_by: 'cdate') - true + context 'when sorted by custom object date' do + let(:custom_attribute) { create :object_manager_attribute_date, name: 'cdate' } + + let(:tickets) do + [ + create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2021-08-18'), + create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2019-01-19'), + create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2018-01-17'), + create(:ticket, group: Group.find_by(name: 'Users'), cdate: '2018-08-19') + ] end it 'does show the values grouped and sorted by date key value (yyy-mm-dd) instead of display value' do visit 'ticket/view/all_unassigned' - text = page.find('.js-tableBody').text(:all) - expect(text.index('01/17/2018') < text.index('08/19/2018')).to eq(true) - expect(text.index('08/19/2018') < text.index('01/19/2019')).to eq(true) - expect(text.index('01/19/2019') < text.index('08/18/2021')).to eq(true) + headers = all('.js-tableBody td[colspan="6"]').map(&:text) + + expect(headers).to eq ['01/17/2018', '08/19/2018', '01/19/2019', '08/18/2021', '-'] end end context 'when sorted by custom object select', authenticated_as: :authenticate, db_strategy: :reset do - let(:ticket1) { create(:ticket, group: Group.find_by(name: 'Users'), cselect: 'a') } - let(:ticket2) { create(:ticket, group: Group.find_by(name: 'Users'), cselect: 'b') } - let(:ticket3) { create(:ticket, group: Group.find_by(name: 'Users'), cselect: 'c') } + let(:custom_attribute) do + create :object_manager_attribute_select, + name: 'cselect', + data_option_options: { + 'a' => 'Zzz a', + 'b' => 'Yyy b', + 'c' => 'Xxx c', + } + end - def authenticate - create :object_manager_attribute_select, name: 'cselect', data_option: { - 'default' => '', - 'options' => { - 'a' => 'Zzz a', - 'b' => 'Yyy b', - 'c' => 'Xxx c', - }, - 'relation' => '', - 'nulloption' => true, - 'multiple' => false, - 'null' => true, - 'translate' => true, - 'maxlength' => 255 - } - ObjectManager::Attribute.migration_execute - ticket1 - ticket2 - ticket3 - Overview.find_by(link: 'all_unassigned').update(group_by: 'cselect') - true + let(:tickets) do + [ + create(:ticket, group: Group.find_by(name: 'Users'), cselect: 'a'), + create(:ticket, group: Group.find_by(name: 'Users'), cselect: 'b'), + create(:ticket, group: Group.find_by(name: 'Users'), cselect: 'c') + ] end it 'does show the values grouped and sorted by display value instead of key value' do visit 'ticket/view/all_unassigned' - text = page.find('.js-tableBody').text(:all) - expect(text.index('Xxx c') < text.index('Yyy b')).to eq(true) - expect(text.index('Yyy b') < text.index('Zzz a')).to eq(true) + headers = all('.js-tableBody td[colspan="6"]').map(&:text) + + expect(headers).to eq ['-', 'Xxx c', 'Yyy b', 'Zzz a'] end end end