create_spec.rb 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. require 'system/examples/core_workflow_examples'
  4. require 'system/examples/text_modules_examples'
  5. RSpec.describe 'Ticket Create', type: :system do
  6. context 'when applying ticket templates' do
  7. let(:agent) { create(:agent, groups: [permitted_group]) }
  8. let(:permitted_group) { create(:group) }
  9. let(:unpermitted_group) { create(:group) }
  10. let!(:template) { create(:template, :dummy_data, group: unpermitted_group, owner: agent) }
  11. # Regression test for issue #2424 - Unavailable ticket template attributes get applied
  12. it 'unavailable attributes do not get applied', authenticated_as: :agent do
  13. visit 'ticket/create'
  14. use_template(template)
  15. expect(page).to have_no_selector 'select[name="group_id"]'
  16. end
  17. end
  18. context 'when using text modules' do
  19. include_examples 'text modules', path: 'ticket/create'
  20. end
  21. context 'S/MIME', authenticated_as: :authenticate do
  22. def authenticate
  23. Setting.set('smime_integration', true)
  24. Setting.set('smime_config', smime_config) if defined?(smime_config)
  25. current_user
  26. end
  27. context 'no certificate present' do
  28. let!(:template) { create(:template, :dummy_data) }
  29. let(:current_user) { true }
  30. it 'has no security selections' do
  31. visit 'ticket/create'
  32. within(:active_content) do
  33. use_template(template)
  34. expect(page).to have_no_css('div.js-securityEncrypt.btn--active')
  35. expect(page).to have_no_css('div.js-securitySign.btn--active')
  36. click '.js-submit'
  37. expect(page).to have_css('.ticket-article-item', count: 1)
  38. open_article_meta
  39. expect(page).to have_no_css('span', text: 'Signed')
  40. expect(page).to have_no_css('span', text: 'Encrypted')
  41. security_result = Ticket::Article.last.preferences['security']
  42. expect(security_result['encryption']['success']).to be nil
  43. expect(security_result['sign']['success']).to be nil
  44. end
  45. end
  46. end
  47. context 'private key configured' do
  48. let(:current_user) { agent }
  49. let!(:template) { create(:template, :dummy_data, group: group, owner: agent, customer: customer) }
  50. let(:system_email_address) { 'smime1@example.com' }
  51. let(:email_address) { create(:email_address, email: system_email_address) }
  52. let(:group) { create(:group, email_address: email_address) }
  53. let(:agent_groups) { [group] }
  54. let(:agent) { create(:agent, groups: agent_groups) }
  55. before do
  56. create(:smime_certificate, :with_private, fixture: system_email_address)
  57. end
  58. context 'recipient certificate present' do
  59. let(:recipient_email_address) { 'smime2@example.com' }
  60. let(:customer) { create(:customer, email: recipient_email_address) }
  61. before do
  62. create(:smime_certificate, fixture: recipient_email_address)
  63. end
  64. it 'plain' do
  65. visit 'ticket/create'
  66. within(:active_content) do
  67. use_template(template)
  68. # wait till S/MIME check AJAX call is ready
  69. expect(page).to have_css('div.js-securityEncrypt.btn--active')
  70. expect(page).to have_css('div.js-securitySign.btn--active')
  71. # deactivate encryption and signing
  72. click '.js-securityEncrypt'
  73. click '.js-securitySign'
  74. click '.js-submit'
  75. expect(page).to have_css('.ticket-article-item', count: 1)
  76. open_article_meta
  77. expect(page).to have_no_css('span', text: 'Signed')
  78. expect(page).to have_no_css('span', text: 'Encrypted')
  79. security_result = Ticket::Article.last.preferences['security']
  80. expect(security_result['encryption']['success']).to be nil
  81. expect(security_result['sign']['success']).to be nil
  82. end
  83. end
  84. it 'signed' do
  85. visit 'ticket/create'
  86. within(:active_content) do
  87. use_template(template)
  88. # wait till S/MIME check AJAX call is ready
  89. expect(page).to have_css('div.js-securityEncrypt.btn--active')
  90. expect(page).to have_css('div.js-securitySign.btn--active')
  91. # deactivate encryption
  92. click '.js-securityEncrypt'
  93. click '.js-submit'
  94. expect(page).to have_css('.ticket-article-item', count: 1)
  95. open_article_meta
  96. expect(page).to have_css('span', text: 'Signed')
  97. expect(page).to have_no_css('span', text: 'Encrypted')
  98. security_result = Ticket::Article.last.preferences['security']
  99. expect(security_result['encryption']['success']).to be nil
  100. expect(security_result['sign']['success']).to be true
  101. end
  102. end
  103. it 'encrypted' do
  104. visit 'ticket/create'
  105. within(:active_content) do
  106. use_template(template)
  107. # wait till S/MIME check AJAX call is ready
  108. expect(page).to have_css('div.js-securityEncrypt.btn--active')
  109. expect(page).to have_css('div.js-securitySign.btn--active')
  110. # deactivate signing
  111. click '.js-securitySign'
  112. click '.js-submit'
  113. expect(page).to have_css('.ticket-article-item', count: 1)
  114. open_article_meta
  115. expect(page).to have_no_css('span', text: 'Signed')
  116. expect(page).to have_css('span', text: 'Encrypted')
  117. security_result = Ticket::Article.last.preferences['security']
  118. expect(security_result['encryption']['success']).to be true
  119. expect(security_result['sign']['success']).to be nil
  120. end
  121. end
  122. it 'signed and encrypted' do
  123. visit 'ticket/create'
  124. within(:active_content) do
  125. use_template(template)
  126. # wait till S/MIME check AJAX call is ready
  127. expect(page).to have_css('div.js-securityEncrypt.btn--active')
  128. expect(page).to have_css('div.js-securitySign.btn--active')
  129. click '.js-submit'
  130. expect(page).to have_css('.ticket-article-item', count: 1)
  131. open_article_meta
  132. expect(page).to have_css('span', text: 'Signed')
  133. expect(page).to have_css('span', text: 'Encrypted')
  134. security_result = Ticket::Article.last.preferences['security']
  135. expect(security_result['encryption']['success']).to be true
  136. expect(security_result['sign']['success']).to be true
  137. end
  138. end
  139. context 'Group default behavior' do
  140. let(:smime_config) { {} }
  141. shared_examples 'security defaults example' do |sign:, encrypt:|
  142. it "security defaults sign: #{sign}, encrypt: #{encrypt}" do
  143. within(:active_content) do
  144. encrypt_button = find('.js-securityEncrypt')
  145. sign_button = find('.js-securitySign')
  146. active_button_class = '.btn--active'
  147. expect(encrypt_button.matches_css?(active_button_class)).to be(encrypt)
  148. expect(sign_button.matches_css?(active_button_class)).to be(sign)
  149. end
  150. end
  151. end
  152. shared_examples 'security defaults' do |sign:, encrypt:|
  153. before do
  154. visit 'ticket/create'
  155. within(:active_content) do
  156. use_template(template)
  157. end
  158. end
  159. include_examples 'security defaults example', sign: sign, encrypt: encrypt
  160. end
  161. shared_examples 'security defaults group change' do |sign:, encrypt:|
  162. before do
  163. visit 'ticket/create'
  164. within(:active_content) do
  165. use_template(template)
  166. select new_group.name, from: 'group_id'
  167. end
  168. end
  169. include_examples 'security defaults example', sign: sign, encrypt: encrypt
  170. end
  171. context 'not configured' do
  172. it_behaves_like 'security defaults', sign: true, encrypt: true
  173. end
  174. context 'configuration present' do
  175. let(:smime_config) do
  176. {
  177. 'group_id' => group_defaults
  178. }
  179. end
  180. let(:group_defaults) do
  181. {
  182. 'default_encryption' => {
  183. group.id.to_s => default_encryption,
  184. },
  185. 'default_sign' => {
  186. group.id.to_s => default_sign,
  187. }
  188. }
  189. end
  190. let(:default_sign) { true }
  191. let(:default_encryption) { true }
  192. shared_examples 'sign and encrypt variations' do |check_examples_name|
  193. it_behaves_like check_examples_name, sign: true, encrypt: true
  194. context 'no value' do
  195. let(:group_defaults) { {} }
  196. it_behaves_like check_examples_name, sign: true, encrypt: true
  197. end
  198. context 'signing disabled' do
  199. let(:default_sign) { false }
  200. it_behaves_like check_examples_name, sign: false, encrypt: true
  201. end
  202. context 'encryption disabled' do
  203. let(:default_encryption) { false }
  204. it_behaves_like check_examples_name, sign: true, encrypt: false
  205. end
  206. end
  207. context 'same Group' do
  208. it_behaves_like 'sign and encrypt variations', 'security defaults'
  209. end
  210. context 'Group change' do
  211. let(:new_group) { create(:group, email_address: email_address) }
  212. let(:agent_groups) { [group, new_group] }
  213. let(:group_defaults) do
  214. {
  215. 'default_encryption' => {
  216. new_group.id.to_s => default_encryption,
  217. },
  218. 'default_sign' => {
  219. new_group.id.to_s => default_sign,
  220. }
  221. }
  222. end
  223. it_behaves_like 'sign and encrypt variations', 'security defaults group change'
  224. end
  225. end
  226. end
  227. end
  228. end
  229. end
  230. describe 'object manager attributes maxlength', authenticated_as: :authenticate, db_strategy: :reset do
  231. def authenticate
  232. create :object_manager_attribute_text, name: 'maxtest', display: 'maxtest', screens: attributes_for(:required_screen), data_option: {
  233. 'type' => 'text',
  234. 'maxlength' => 3,
  235. 'null' => true,
  236. 'translate' => false,
  237. 'default' => '',
  238. 'options' => {},
  239. 'relation' => '',
  240. }
  241. ObjectManager::Attribute.migration_execute
  242. true
  243. end
  244. it 'checks ticket create' do
  245. visit 'ticket/create'
  246. within(:active_content) do
  247. fill_in 'maxtest', with: 'hellu'
  248. expect(page.find_field('maxtest').value).to eq('hel')
  249. end
  250. end
  251. end
  252. describe 'GitLab Integration', :integration, authenticated_as: :authenticate, required_envs: %w[GITLAB_ENDPOINT GITLAB_APITOKEN] do
  253. let(:customer) { create(:customer) }
  254. let(:agent) { create(:agent, groups: [Group.find_by(name: 'Users')]) }
  255. let!(:template) { create(:template, :dummy_data, group: Group.find_by(name: 'Users'), owner: agent, customer: customer) }
  256. def authenticate
  257. Setting.set('gitlab_integration', true)
  258. Setting.set('gitlab_config', {
  259. api_token: ENV['GITLAB_APITOKEN'],
  260. endpoint: ENV['GITLAB_ENDPOINT'],
  261. })
  262. true
  263. end
  264. it 'creates a ticket with links' do
  265. visit 'ticket/create'
  266. within(:active_content) do
  267. use_template(template)
  268. # switch to gitlab sidebar
  269. click('.tabsSidebar-tab[data-tab=gitlab]')
  270. click('.sidebar-header-headline.js-headline')
  271. # add issue
  272. click_on 'Link issue'
  273. fill_in 'link', with: ENV['GITLAB_ISSUE_LINK']
  274. click_on 'Submit'
  275. # verify issue
  276. content = find('.sidebar-git-issue-content')
  277. expect(content).to have_text('#1 Example issue')
  278. expect(content).to have_text('critical')
  279. expect(content).to have_text('special')
  280. expect(content).to have_text('important milestone')
  281. expect(content).to have_text('zammad-robot')
  282. # create Ticket
  283. click '.js-submit'
  284. # check stored data
  285. expect(Ticket.last.preferences[:gitlab][:issue_links][0]).to eq(ENV['GITLAB_ISSUE_LINK'])
  286. end
  287. end
  288. end
  289. describe 'GitHub Integration', :integration, authenticated_as: :authenticate, required_envs: %w[GITHUB_ENDPOINT GITHUB_APITOKEN] do
  290. let(:customer) { create(:customer) }
  291. let(:agent) { create(:agent, groups: [Group.find_by(name: 'Users')]) }
  292. let!(:template) { create(:template, :dummy_data, group: Group.find_by(name: 'Users'), owner: agent, customer: customer) }
  293. def authenticate
  294. Setting.set('github_integration', true)
  295. Setting.set('github_config', {
  296. api_token: ENV['GITHUB_APITOKEN'],
  297. endpoint: ENV['GITHUB_ENDPOINT'],
  298. })
  299. true
  300. end
  301. it 'creates a ticket with links' do
  302. visit 'ticket/create'
  303. within(:active_content) do
  304. use_template(template)
  305. # switch to github sidebar
  306. click('.tabsSidebar-tab[data-tab=github]')
  307. click('.sidebar-header-headline.js-headline')
  308. # add issue
  309. click_on 'Link issue'
  310. fill_in 'link', with: ENV['GITHUB_ISSUE_LINK']
  311. click_on 'Submit'
  312. # verify issue
  313. content = find('.sidebar-git-issue-content')
  314. expect(content).to have_text('#1575 GitHub integration')
  315. expect(content).to have_text('feature backlog')
  316. expect(content).to have_text('integration')
  317. expect(content).to have_text('4.0')
  318. expect(content).to have_text('Thorsten')
  319. # create Ticket
  320. click '.js-submit'
  321. # check stored data
  322. expect(Ticket.last.preferences[:github][:issue_links][0]).to eq(ENV['GITHUB_ISSUE_LINK'])
  323. end
  324. end
  325. end
  326. describe 'Core Workflow' do
  327. include_examples 'core workflow' do
  328. let(:object_name) { 'Ticket' }
  329. let(:before_it) do
  330. lambda {
  331. ensure_websocket(check_if_pinged: false) do
  332. visit 'ticket/create'
  333. end
  334. }
  335. end
  336. end
  337. end
  338. # https://github.com/zammad/zammad/issues/2669
  339. context 'when canceling new ticket creation' do
  340. it 'closes the dialog' do
  341. visit 'ticket/create'
  342. task_key = find(:task_active)['data-key']
  343. expect { click('.js-cancel') }.to change { has_selector?(:task_with, task_key, wait: 0) }.to(false)
  344. end
  345. it 'asks for confirmation if the dialog was modified' do
  346. visit 'ticket/create'
  347. task_key = find(:task_active)['data-key']
  348. find('[name=title]').fill_in with: 'Title'
  349. click '.js-cancel'
  350. in_modal do
  351. click '.js-submit'
  352. end
  353. expect(page).to have_no_selector(:task_with, task_key)
  354. end
  355. it 'asks for confirmation if attachment was added' do
  356. visit 'ticket/create'
  357. within :active_content do
  358. page.find('input#fileUpload_1', visible: :all).set(Rails.root.join('test/data/mail/mail001.box'))
  359. await_empty_ajax_queue
  360. find('.js-cancel').click
  361. end
  362. in_modal disappears: false do
  363. expect(page).to have_text 'Tab has changed'
  364. end
  365. end
  366. end
  367. context 'when uploading attachment' do
  368. it 'shows an error if server throws an error' do
  369. allow(Store).to receive(:add) { raise 'Error' }
  370. visit 'ticket/create'
  371. within :active_content do
  372. page.find('input#fileUpload_1', visible: :all).set(Rails.root.join('test/data/mail/mail001.box'))
  373. end
  374. in_modal disappears: false do
  375. expect(page).to have_text 'Error'
  376. end
  377. end
  378. end
  379. context 'when closing taskbar tab for new ticket creation' do
  380. it 'close task bar entry after some changes in ticket create form' do
  381. visit 'ticket/create'
  382. within(:active_content) do
  383. find('[name=title]').fill_in with: 'Title'
  384. end
  385. taskbar_tab_close(find(:task_active)['data-key'])
  386. end
  387. end
  388. describe 'customer selection to check the field search' do
  389. before do
  390. create(:customer, active: true)
  391. create(:customer, active: false)
  392. end
  393. it 'check for inactive customer in customer/organization selection' do
  394. visit 'ticket/create'
  395. within(:active_content) do
  396. find('[name=customer_id] ~ .user-select.token-input').fill_in with: '**'
  397. expect(page).to have_css('ul.recipientList > li.recipientList-entry', minimum: 2)
  398. expect(page).to have_css('ul.recipientList > li.recipientList-entry.is-inactive', count: 1)
  399. end
  400. end
  401. end
  402. context 'when agent and customer user login after another' do
  403. let(:agent) { create(:agent, password: 'test') }
  404. let(:customer) { create(:customer, password: 'test') }
  405. it 'customer user should not have agent object attributes', authenticated_as: :agent do
  406. # Log out again, so that we can execute the next login.
  407. logout
  408. # Re-create agent session and fetch object attributes.
  409. login(
  410. username: agent.login,
  411. password: 'test'
  412. )
  413. visit 'ticket/create'
  414. # Re-remove local object attributes bound to the session
  415. # there was an issue (#1856) where the old attribute values
  416. # persisted and were stored as the original attributes.
  417. logout
  418. # Create customer session and fetch object attributes.
  419. login(
  420. username: customer.login,
  421. password: 'test'
  422. )
  423. visit 'customer_ticket_new'
  424. expect(page).to have_no_css('.newTicket input[name="customer_id"]')
  425. end
  426. end
  427. context 'when state options have a special translation', authenticated_as: :authenticate do
  428. let(:admin_de) { create(:admin, preferences: { locale: 'de-de' }) }
  429. context 'when translated state option has a single quote' do
  430. def authenticate
  431. open_tranlation = Translation.where(locale: 'de-de', source: 'open')
  432. open_tranlation.update(target: "off'en")
  433. admin_de
  434. end
  435. it 'shows the translated state options correctly' do
  436. visit 'ticket/create'
  437. expect(page).to have_select('state_id', with_options: ["off'en"])
  438. end
  439. end
  440. end
  441. describe 'It should be possible to show attributes which are configured shown false #3726', authenticated_as: :authenticate, db_strategy: :reset do
  442. let(:field_name) { SecureRandom.uuid }
  443. let(:field) do
  444. create :object_manager_attribute_text, name: field_name, display: field_name, screens: {
  445. 'create_middle' => {
  446. 'ticket.agent' => {
  447. 'shown' => false,
  448. 'required' => false,
  449. }
  450. }
  451. }
  452. ObjectManager::Attribute.migration_execute
  453. end
  454. before do
  455. visit 'ticket/create'
  456. end
  457. context 'when field visible' do
  458. let(:workflow) do
  459. create(:core_workflow,
  460. object: 'Ticket',
  461. perform: { "ticket.#{field_name}" => { 'operator' => 'show', 'show' => 'true' } })
  462. end
  463. def authenticate
  464. field
  465. workflow
  466. true
  467. end
  468. it 'does show up the field' do
  469. expect(page).to have_css("div[data-attribute-name='#{field_name}']")
  470. end
  471. end
  472. context 'when field hidden' do
  473. def authenticate
  474. field
  475. true
  476. end
  477. it 'does not show the field' do
  478. expect(page).to have_css("div[data-attribute-name='#{field_name}'].is-hidden.is-removed", visible: :hidden)
  479. end
  480. end
  481. end
  482. describe 'Support workflow mechanism to do pending reminder state hide pending time use case #3790', authenticated_as: :authenticate do
  483. let(:template) { create(:template, :dummy_data) }
  484. def add_state
  485. Ticket::State.create_or_update(
  486. name: 'pending customer feedback',
  487. state_type: Ticket::StateType.find_by(name: 'pending reminder'),
  488. ignore_escalation: true,
  489. created_by_id: 1,
  490. updated_by_id: 1,
  491. )
  492. end
  493. def update_screens
  494. attribute = ObjectManager::Attribute.get(
  495. object: 'Ticket',
  496. name: 'state_id',
  497. )
  498. attribute.data_option[:filter] = Ticket::State.by_category(:viewable).pluck(:id)
  499. attribute.screens[:create_middle]['ticket.agent'][:filter] = Ticket::State.by_category(:viewable_agent_new).pluck(:id)
  500. attribute.screens[:create_middle]['ticket.customer'][:filter] = Ticket::State.by_category(:viewable_customer_new).pluck(:id)
  501. attribute.screens[:edit]['ticket.agent'][:filter] = Ticket::State.by_category(:viewable_agent_edit).pluck(:id)
  502. attribute.screens[:edit]['ticket.customer'][:filter] = Ticket::State.by_category(:viewable_customer_edit).pluck(:id)
  503. attribute.save!
  504. end
  505. def create_flow
  506. create(:core_workflow,
  507. object: 'Ticket',
  508. condition_selected: { 'ticket.state_id'=>{ 'operator' => 'is', 'value' => Ticket::State.find_by(name: 'pending customer feedback').id.to_s } },
  509. perform: { 'ticket.pending_time'=> { 'operator' => 'remove', 'remove' => 'true' } })
  510. end
  511. def authenticate
  512. add_state
  513. update_screens
  514. create_flow
  515. template
  516. true
  517. end
  518. before do
  519. visit 'ticket/create'
  520. use_template(template)
  521. end
  522. it 'does make it possible to create pending states where the pending time is optional and not visible' do
  523. select 'pending customer feedback', from: 'state_id'
  524. click '.js-submit'
  525. expect(current_url).to include('ticket/zoom')
  526. expect(Ticket.last.state_id).to eq(Ticket::State.find_by(name: 'pending customer feedback').id)
  527. expect(Ticket.last.pending_time).to be nil
  528. end
  529. end
  530. context 'default priority', authenticated_as: :authenticate do
  531. let(:template) { create(:template, :dummy_data) }
  532. let(:ticket_priority) { create(:ticket_priority, default_create: true) }
  533. let(:another_priority) { Ticket::Priority.find(1) }
  534. let(:priority_field) { find('[name=priority_id]') }
  535. def authenticate
  536. template
  537. ticket_priority
  538. true
  539. end
  540. it 'shows default priority on load' do
  541. visit 'ticket/create'
  542. expect(priority_field.value).to eq ticket_priority.id.to_s
  543. end
  544. it 'does not reset to default priority on reload' do
  545. visit 'ticket/create'
  546. taskbar_timestamp = Taskbar.last.updated_at
  547. priority_field.select another_priority.name
  548. wait.until { Taskbar.last.updated_at != taskbar_timestamp }
  549. refresh
  550. expect(priority_field.reload.value).to eq another_priority.id.to_s
  551. end
  552. it 'saves default priority' do
  553. visit 'ticket/create'
  554. use_template template
  555. click '.js-submit'
  556. expect(Ticket.last).to have_attributes(priority: ticket_priority)
  557. end
  558. it 'saves different priority if overriden' do
  559. visit 'ticket/create'
  560. use_template template
  561. priority_field.select another_priority.name
  562. click '.js-submit'
  563. expect(Ticket.last).to have_attributes(priority: another_priority)
  564. end
  565. end
  566. describe 'When looking for customers, it is no longer possible to change into organizations #3815' do
  567. before do
  568. visit 'ticket/create'
  569. # modal reaper ;)
  570. sleep 3
  571. end
  572. context 'when less than 10 customers' do
  573. let(:organization) { Organization.first }
  574. it 'has no show more option' do
  575. find('[name=customer_id_completion]').fill_in with: 'zam'
  576. expect(page).to have_selector("li.js-organization[data-organization-id='#{organization.id}']")
  577. page.find("li.js-organization[data-organization-id='#{organization.id}']").click
  578. expect(page).to have_selector("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li.js-showMoreMembers.hidden", visible: :all)
  579. end
  580. end
  581. context 'when more than 10 customers', authenticated_as: :authenticate do
  582. def authenticate
  583. customers
  584. true
  585. end
  586. let(:organization) { create(:organization, name: 'Zammed') }
  587. let(:customers) do
  588. create_list(:customer, 50, organization: organization)
  589. end
  590. it 'does paginate through organization' do
  591. find('[name=customer_id_completion]').fill_in with: 'zam'
  592. expect(page).to have_selector("li.js-organization[data-organization-id='#{organization.id}']")
  593. page.find("li.js-organization[data-organization-id='#{organization.id}']").click
  594. wait.until { page.all("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li", visible: :all).count == 12 } # 10 users + back + show more button
  595. expect(page).to have_selector("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li.js-showMoreMembers[organization-member-limit='10']")
  596. scroll_into_view('li.js-showMoreMembers')
  597. page.find("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li.js-showMoreMembers").click
  598. wait.until { page.all("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li", visible: :all).count == 27 } # 25 users + back + show more button
  599. expect(page).to have_selector("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li.js-showMoreMembers[organization-member-limit='25']")
  600. scroll_into_view('li.js-showMoreMembers')
  601. page.find("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li.js-showMoreMembers").click
  602. wait.until { page.all("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li", visible: :all).count == 52 } # 50 users + back + show more button
  603. scroll_into_view('li.js-showMoreMembers')
  604. expect(page).to have_selector("ul.recipientList-organizationMembers[organization-id='#{organization.id}'] li.js-showMoreMembers.hidden", visible: :all)
  605. end
  606. end
  607. end
  608. describe 'Ticket create screen will loose attachments by time #3827' do
  609. before do
  610. visit 'ticket/create'
  611. end
  612. it 'does not loose attachments on rerender of the ui' do
  613. # upload two files
  614. await_empty_ajax_queue
  615. page.find('input#fileUpload_1', visible: :all).set(Rails.root.join('test/data/mail/mail001.box'))
  616. await_empty_ajax_queue
  617. wait.until { page.all('div.attachment-delete.js-delete', visible: :all).count == 1 }
  618. expect(page).to have_text('mail001.box')
  619. page.find('input#fileUpload_1', visible: :all).set(Rails.root.join('test/data/mail/mail002.box'))
  620. await_empty_ajax_queue
  621. wait.until { page.all('div.attachment-delete.js-delete', visible: :all).count == 2 }
  622. expect(page).to have_text('mail002.box')
  623. # remove last file
  624. begin
  625. page.evaluate_script("$('div.attachment-delete.js-delete:last').trigger('click')") # not interactable
  626. rescue # Lint/SuppressedException
  627. # because its not interactable it also
  628. # returns this weird exception for the jquery
  629. # even tho it worked fine
  630. end
  631. await_empty_ajax_queue
  632. wait.until { page.all('div.attachment-delete.js-delete', visible: :all).count == 1 }
  633. expect(page).to have_text('mail001.box')
  634. expect(page).to have_no_text('mail002.box')
  635. # simulate rerender b
  636. page.evaluate_script("App.Event.trigger('ui:rerender')")
  637. expect(page).to have_text('mail001.box')
  638. expect(page).to have_no_text('mail002.box')
  639. end
  640. end
  641. describe 'Invalid group and owner list for tickets created via customer profile #3835' do
  642. let(:invalid_ticket) { create(:ticket) }
  643. before do
  644. visit "#ticket/create/id/#{invalid_ticket.id}/customer/#{User.find_by(firstname: 'Nicole').id}"
  645. end
  646. it 'does show an empty list of owners' do
  647. wait.until { page.all('select[name=owner_id] option').count == 1 }
  648. expect(page.all('select[name=owner_id] option').count).to eq(1)
  649. end
  650. end
  651. # https://github.com/zammad/zammad/issues/3825
  652. describe 'CC token field' do
  653. before do
  654. visit 'ticket/create'
  655. find('[data-type=email-out]').click
  656. end
  657. it 'can be cleared by cutting out text' do
  658. add_email 'asd@example.com'
  659. add_email 'def@example.com'
  660. find('.token', text: 'def@example.com').double_click
  661. meta_key = Gem::Platform.local.os == 'darwin' ? :command : :control
  662. send_keys([meta_key, 'x'])
  663. find('.token').click # trigger blur
  664. expect(find('[name="cc"]', visible: :all).value).to eq 'asd@example.com'
  665. end
  666. def add_email(input)
  667. fill_in 'CC', with: input
  668. send_keys(:enter) # trigger blur
  669. find '.token', text: input # wait for email to tokenize
  670. end
  671. end
  672. describe 'No signature on new ticket if email is default message type #3844', authenticated_as: :authenticate do
  673. def authenticate
  674. Setting.set('ui_ticket_create_default_type', 'email-out')
  675. Group.where.not(name: 'Users').each { |g| g.update(active: false) }
  676. true
  677. end
  678. before do
  679. visit 'ticket/create'
  680. end
  681. it 'does render the create screen with an initial core workflow state to set signatures and other defaults properly' do
  682. expect(page.find('.richtext-content')).to have_text('Support')
  683. end
  684. end
  685. describe 'Zammad 5 mail template double signature #3816', authenticated_as: :authenticate do
  686. let(:agent_template) { create(:agent) }
  687. let!(:template) do
  688. create(
  689. :template,
  690. :dummy_data,
  691. group: Group.first, owner: agent_template,
  692. body: 'Content dummy.<br><br><div data-signature="true" data-signature-id="1"> Test Other Agent<br><br>--<br> Super Support - Waterford Business Park<br> 5201 Blue Lagoon Drive - 8th Floor &amp; 9th Floor - Miami, 33126 USA<br> Email: hot@example.com - Web: <a href="http://www.example.com/" rel="nofollow noreferrer noopener" target="_blank">http://www.example.com/</a><br>--</div>'
  693. )
  694. end
  695. def authenticate
  696. Group.first.update(signature: Signature.first)
  697. true
  698. end
  699. before do
  700. visit 'ticket/create'
  701. find('[data-type=email-out]').click
  702. end
  703. it 'does not show double signature on template usage' do
  704. select Group.first.name, from: 'group_id'
  705. use_template(template)
  706. expect(page).to have_no_text('Test Other Agent')
  707. end
  708. end
  709. end