123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- require 'rails_helper'
- require 'system/apps/mobile_old/examples/core_workflow_examples'
- RSpec.describe 'Mobile > Ticket > Create', app: :mobile, authenticated_as: :user, type: :system do
- let(:group) { Group.find_by(name: 'Users') }
- let(:user) { create(:agent, groups: [group]) }
- let!(:customer) { create(:customer) }
- def next_step
- find_button('Continue').click
- end
- def check_is_step(step)
- expect(find("button[order=\"#{step}\"]").disabled?).to be(true)
- end
- def go_to_step(step)
- find("button[order=\"#{step}\"]").click
- end
- def submit_form
- find_button('Create').click
- wait_for_gql('shared/entities/ticket/graphql/mutations/create.graphql')
- end
- def check_is_focused(element)
- wait.until do
- page.driver.browser.switch_to.active_element == element.native
- end
- end
- before do
- visit '/tickets/create'
- wait_for_form_to_settle('ticket-create')
- end
- shared_examples 'creating a ticket' do |article_type:, direction: nil, redirect: nil|
- it 'can complete all steps' do
- expect(find_button('Create', disabled: true).disabled?).to be(true)
- within_form(form_updater_gql_number: 1) do
- # Step 1.
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- # Step 2.
- case article_type
- when 'email'
- find_radio('articleSenderType').select_choice('Send Email')
- when 'phone'
- if direction == 'out'
- find_radio('articleSenderType').select_choice('Outbound Call')
- end
- end
- find_select('Group').select_option('Users') if article_type == 'web'
- next_step
- if article_type != 'web'
- # Step 3.
- find_autocomplete('Customer').search_for_option(customer.email, label: customer.fullname)
- find_autocomplete('CC') if article_type == 'email'
- next_step
- end
- # Step 4.
- find_editor('Text').type(Faker::Hacker.say_something_smart)
- end
- submit_form
- find('[role=alert]', text: 'Ticket has been created successfully.')
- expect(page).to have_current_path(redirect || "/mobile/tickets/#{Ticket.last.id}")
- expect(Ticket.last.create_article_type_id).to eq(Ticket::Article::Type.find_by(name: article_type).id)
- end
- end
- context 'with different article types' do
- it_behaves_like 'creating a ticket', article_type: 'phone'
- it_behaves_like 'creating a ticket', article_type: 'phone', direction: 'out'
- it_behaves_like 'creating a ticket', article_type: 'email'
- context 'when dont have a "read" permission, but have "create" permission' do
- it_behaves_like 'creating a ticket', article_type: 'email', redirect: '/mobile/' do
- before do
- user.group_names_access_map = {
- group.name => ['create']
- }
- end
- end
- end
- context 'when a customer', authenticated_as: :customer do
- it_behaves_like 'creating a ticket', article_type: 'web'
- end
- end
- context 'with signatures' do
- let(:signature1) { create(:signature, body: '<strong>custom signature</strong>') }
- let(:group1) { create(:group, signature: signature1) }
- let(:group2) { Group.find_by(name: 'Users') }
- let(:group3) { create(:group) }
- let(:user) { create(:agent, groups: [group1, group2, group3]) }
- it 'adds signature' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- find_radio('articleSenderType').select_choice('Send Email')
- next_step
- next_step
- # only label is rendered as text
- expect(find_editor('Text')).to have_text_value('', exact: true)
- go_to_step(3)
- find_select('Group').select_option('Users')
- go_to_step(4)
- expect(find_editor('Text')).to have_text_value(user.fullname) # default signature is added
- end
- end
- it 'changes signature, when group is changed' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- find_radio('articleSenderType').select_choice('Send Email')
- next_step
- find_select('Group').select_option('Users')
- next_step
- expect(find_editor('Text')).to have_text_value(user.fullname)
- go_to_step(3)
- find_select('Group').select_option(group1.name)
- next_step
- expect(find_editor('Text')).to have_text_value('custom signature')
- end
- end
- it 'removes signature, when another group without signature is selected' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- find_radio('articleSenderType').select_choice('Send Email')
- next_step
- find_select('Group').select_option('Users')
- next_step
- expect(find_editor('Text')).to have_text_value(user.fullname)
- go_to_step(3)
- find_select('Group').select_option(group3.name)
- next_step
- expect(find_editor('Text')).to have_text_value('', exact: true)
- end
- end
- it 'removes signature when type is not email' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- find_radio('articleSenderType').select_choice('Send Email')
- next_step
- find_select('Group').select_option('Users')
- next_step
- expect(find_editor('Text')).to have_text_value(user.fullname)
- go_to_step(2)
- find_radio('articleSenderType').select_choice('Outbound Call')
- go_to_step(4)
- # only label is rendered as text
- expect(find_editor('Text')).to have_text_value('', exact: true)
- end
- end
- it 'removes signature when group is deselected' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- find_radio('articleSenderType').select_choice('Send Email')
- next_step
- find_select('Group').select_option('Users')
- next_step
- expect(find_editor('Text')).to have_text_value(user.fullname)
- go_to_step(3)
- find_select('Group').clear_selection
- go_to_step(4)
- # only label is rendered as text
- expect(find_editor('Text')).to have_text_value('', exact: true)
- end
- end
- end
- # TODO: Frontend tests!?
- context 'with entered form fields' do
- it 'remembers the data when switching between steps' do
- within_form(form_updater_gql_number: 1) do
- # Step 1.
- title = Faker::Name.unique.name_with_middle
- find_input('Title').type(title)
- next_step
- # Step 2.
- type = 'Outbound Call'
- find_radio('articleSenderType').select_choice(type)
- next_step
- # Step 3.
- find_autocomplete('Customer').search_for_option(customer.email, label: customer.fullname)
- next_step
- # Step 4.
- body = Faker::Hacker.say_something_smart
- find_editor('Text').type(body)
- # Step 1.
- go_to_step(1)
- expect(find_input('Title')).to have_value(title)
- # Step 3.
- go_to_step(3)
- expect(find_autocomplete('Customer')).to have_selected_option(customer.fullname)
- # Step 2.
- go_to_step(2)
- expect(find_radio('articleSenderType')).to have_selected_choice(type)
- # Step 4.
- go_to_step(4)
- expect(find_editor('Text')).to have_text_value(body)
- end
- end
- it 'shows a confirmation dialog when leaving the screen' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- end
- find_button('Go home').click
- within '[role=alert]' do
- expect(page).to have_text('Are you sure? You have unsaved changes that will get lost.')
- end
- end
- it 'fills out new customer when it\'s created in place' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- next_step
- find_autocomplete('Customer').element.click
- find_button('Create new customer').click
- find_input('First name').type('John')
- find_input('Last name').type('Doe')
- click_on('Save')
- expect(find_autocomplete('Customer')).to have_selected_option('John Doe')
- end
- end
- end
- context 'with accessibility support' do
- it 'focuses first visible field when switching between steps' do
- wait_for_form_autofocus('ticket-create')
- # Step 1.
- check_is_focused find_input('Title').input_element
- next_step
- # Step 2.
- check_is_focused find_radio('articleSenderType').find('label', text: 'Received Call').find('input')
- next_step
- # Step 3.
- check_is_focused find_autocomplete('Customer').input_element
- next_step
- # Step 4.
- check_is_focused find_editor('Text').input_element
- # Step 1.
- go_to_step(1)
- check_is_focused find_input('Title').input_element
- # Step 3.
- go_to_step(3)
- check_is_focused find_autocomplete('Customer').input_element
- # Step 2.
- go_to_step(2)
- check_is_focused find_radio('articleSenderType').find('label', text: 'Received Call').find('input')
- # Step 4.
- go_to_step(4)
- check_is_focused find_editor('Text').input_element
- end
- it 'advances to the next step on submit' do
- find_input('Title').input_element.send_keys :enter
- check_is_step(2)
- find_radio('articleSenderType').find('label', text: 'Received Call').find('input').send_keys :enter
- check_is_step(3)
- end
- context 'with many object attributes', authenticated_as: :authenticate, db_strategy: :reset do
- let(:screens) do
- {
- create_middle: {
- '-all-' => {
- shown: true,
- required: false,
- },
- },
- }
- end
- def authenticate
- create(:object_manager_attribute_select, screens: screens)
- create(:object_manager_attribute_text, screens: screens)
- create(:object_manager_attribute_tree_select, screens: screens)
- create(:object_manager_attribute_select, screens: screens)
- ObjectManager::Attribute.migration_execute
- true
- end
- it 'can interact with the fields at the bottom of the form without any obstructions' do
- # Step 3.
- next_step
- next_step
- # Tags is the last field in the form.
- # In case the field is obscured, the following action would fail.
- find_autocomplete('Tags').search_for_option('tag 1')
- end
- end
- end
- context 'when using ticket create as customer' do
- let(:group1) { Group.find_by(name: 'Users') }
- let(:user) { create(:customer, :with_org, groups: [group1]) }
- shared_examples 'can complete all steps as customer' do
- it 'can complete all steps' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- find_select('Group').select_option('Users')
- if organizations
- find_select('Organization').select_option(organizations.last.name)
- else
- expect(page).to have_no_select('Organization')
- end
- next_step
- find_editor('Text').type(Faker::Hacker.say_something_smart)
- end
- submit_form
- find('[role=alert]', text: 'Ticket has been created successfully.')
- expect(page).to have_current_path("/mobile/tickets/#{Ticket.last.id}")
- end
- end
- context 'with secondary organizations' do
- include_examples 'can complete all steps as customer' do
- let(:user) { create(:customer, :with_org, organizations: organizations, groups: [group1]) }
- let(:organizations) { create_list(:organization, 3) }
- end
- end
- context 'without secondary organizations' do
- include_examples 'can complete all steps as customer' do
- let(:organizations) { nil }
- end
- end
- end
- context 'when using suggestions' do
- let(:text_option) { create(:text_module, name: 'test', content: "Hello, \#{ticket.customer.firstname}!") }
- it 'text suggestion parses correctly' do
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- next_step
- next_step
- find_autocomplete('Customer').search_for_option(customer.email, label: customer.fullname)
- next_step
- editor = find_editor('Text')
- # only label is rendered as text
- expect(editor).to have_text_value('', exact: true)
- editor.type('::test')
- find('[role="option"]', text: text_option.name).click
- expect(editor).to have_text_value("Hello, #{customer.firstname}!")
- end
- end
- end
- describe 'Core Workflow' do
- include_examples 'mobile app: core workflow' do
- let(:object_name) { 'Ticket' }
- let(:form_updater_gql_number) { 2 }
- let(:before_it) do
- lambda {
- visit '/tickets/create'
- wait_for_form_to_settle('ticket-create')
- within_form(form_updater_gql_number: 1) do
- find_input('Title').type(Faker::Name.unique.name_with_middle)
- end
- next_step
- next_step
- }
- end
- end
- end
- end
|