time_accounting_spec.rb 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Manage > Time Accounting', authenticated_as: :authenticate, type: :system do
  4. let(:time_accounting) { true }
  5. def authenticate
  6. Setting.set('time_accounting', time_accounting)
  7. true
  8. end
  9. before do
  10. visit '/#manage/time_accounting'
  11. end
  12. context 'when toggling the switch' do
  13. before do
  14. within :active_content do
  15. click '.js-header-switch'
  16. end
  17. end
  18. context 'with the feature disabled' do
  19. let(:time_accounting) { false }
  20. it 'turns the feature on' do
  21. expect(Setting.get('time_accounting')).to be(true)
  22. end
  23. end
  24. it 'turns the feature off' do
  25. expect(Setting.get('time_accounting')).to be(false)
  26. end
  27. end
  28. context 'when configuring settings' do
  29. context 'with ticket selector setting' do
  30. before do
  31. within :active_content do
  32. find('.js-filterElement .js-attributeSelector select')
  33. .find('option', text: 'Priority')
  34. .select_option
  35. find('.js-filterElement .js-value select')
  36. .find('option', text: '3 high')
  37. .select_option
  38. click_on 'Save'
  39. end
  40. end
  41. it 'updates time_accounting_selector setting' do
  42. expect(Setting.get('time_accounting_selector'))
  43. .to eq({
  44. 'condition' => {
  45. 'ticket.priority_id' => {
  46. 'operator' => 'is',
  47. 'value' => ['3'],
  48. },
  49. },
  50. })
  51. end
  52. it 'does not have expert mode' do
  53. within :active_content do
  54. expect(page).to have_no_css('.ticket_selector .js-switch')
  55. end
  56. end
  57. end
  58. context 'with time unit setting' do
  59. before do
  60. within :active_content do
  61. find('#timeAccountingUnit')
  62. .find('option', text: unit)
  63. .select_option
  64. if custom_unit.present?
  65. find('#timeAccountingCustomUnit').fill_in with: custom_unit
  66. end
  67. click_on 'Save'
  68. end
  69. end
  70. shared_examples 'updating time_accounting_unit* settings' do
  71. it 'updates time_accounting_unit* settings' do
  72. if custom_unit.empty?
  73. expect(page).to have_no_css('#timeAccountingCustomUnit')
  74. end
  75. expect(Setting.get('time_accounting_unit')).to eq(unit)
  76. expect(Setting.get('time_accounting_unit_custom')).to eq(custom_unit)
  77. end
  78. end
  79. context 'with a pre-defined unit' do
  80. let(:unit) { 'minute' }
  81. let(:custom_unit) { '' }
  82. it_behaves_like 'updating time_accounting_unit* settings'
  83. end
  84. context 'with a custom unit' do
  85. let(:unit) { 'custom' }
  86. let(:custom_unit) { 'person day(s)' }
  87. it_behaves_like 'updating time_accounting_unit* settings'
  88. end
  89. end
  90. end
  91. context 'with activity types' do
  92. before do
  93. within :active_content do
  94. click_on 'Activity Types'
  95. end
  96. end
  97. context 'with feature setting' do
  98. before do
  99. within :active_content do
  100. find('#timeAccountingTypes')
  101. .find('option', text: setting_option)
  102. .select_option
  103. click_on 'Save'
  104. end
  105. end
  106. shared_examples 'updating time_accounting_types setting' do
  107. it 'updates time_accounting_types setting' do
  108. expect(Setting.get('time_accounting_types')).to be(setting_state)
  109. end
  110. end
  111. context 'when enabling the type selection' do
  112. let(:setting_option) { 'yes' }
  113. let(:setting_state) { true }
  114. it_behaves_like 'updating time_accounting_types setting'
  115. end
  116. context 'when disabling the type selection' do
  117. let(:setting_option) { 'no' }
  118. let(:setting_state) { false }
  119. def authenticate
  120. Setting.set('time_accounting_types', true)
  121. true
  122. end
  123. it_behaves_like 'updating time_accounting_types setting'
  124. end
  125. end
  126. context 'with new activity type form' do
  127. let(:name) { Faker::Name.unique.name }
  128. before do
  129. within :active_content do
  130. click_on 'New Activity Type'
  131. end
  132. in_modal do
  133. fill_in 'Name', with: name
  134. click_on 'Submit'
  135. end
  136. end
  137. it 'supports adding new activity types' do
  138. expect(page).to have_css('.js-tableBody tr.item td', exact_text: name)
  139. end
  140. end
  141. context 'with edit activity type form' do
  142. let(:activity_type) { create(:ticket_time_accounting_type) }
  143. let(:new_name) { Faker::Name.unique.name }
  144. def authenticate
  145. activity_type
  146. true
  147. end
  148. before do
  149. within :active_content do
  150. find('tr', text: activity_type.name).click
  151. end
  152. in_modal do
  153. fill_in 'Name', with: new_name
  154. click_on 'Submit'
  155. end
  156. end
  157. it 'supports editing existing activity types' do
  158. expect(page).to have_css(".js-tableBody tr.item[data-id='#{activity_type.id}'] td", exact_text: new_name)
  159. end
  160. end
  161. context 'with actions' do
  162. let(:activity_type) { create(:ticket_time_accounting_type) }
  163. def authenticate
  164. activity_type
  165. true
  166. end
  167. before do
  168. within :active_content do
  169. row = find('tr', text: activity_type.name)
  170. row.find('.js-action').click
  171. end
  172. end
  173. context 'with set as default action' do
  174. before do
  175. within :active_content do
  176. row = find('tr', text: activity_type.name)
  177. row.find('.js-set-as-default').click
  178. end
  179. in_modal do
  180. click_on 'Yes'
  181. end
  182. end
  183. it 'supports setting activity type as default' do
  184. expect(page).to have_css(".js-tableBody tr.item[data-id='#{activity_type.id}'] td", text: 'Default')
  185. end
  186. end
  187. context 'with unset default action' do
  188. def authenticate
  189. Setting.set('time_accounting_type_default', activity_type.id)
  190. true
  191. end
  192. before do
  193. within :active_content do
  194. row = find('tr', text: activity_type.name)
  195. row.find('.js-unset-default').click
  196. end
  197. in_modal do
  198. click_on 'Yes'
  199. end
  200. end
  201. it 'supports unsetting activity type as default' do
  202. expect(page).to have_no_css(".js-tableBody tr.item[data-id='#{activity_type.id}'] td", text: 'Default')
  203. end
  204. end
  205. end
  206. end
  207. context 'with accounted time' do
  208. def authenticate
  209. create_list(:ticket_time_accounting, count)
  210. true
  211. end
  212. before do
  213. within :active_content do
  214. click_on 'Accounted Time'
  215. end
  216. end
  217. context 'with less than 20 entries' do
  218. let(:count) { 10 }
  219. it 'shows all entries' do
  220. expect(find_all('.js-tableActivity tbody tr').count).to eq(count)
  221. expect(page).to have_no_text('Only the 20 most recent records are displayed. Download to view the full list.')
  222. end
  223. end
  224. context 'with more than 21 entries' do
  225. let(:count) { 21 }
  226. it 'shows the first 20 entries' do
  227. expect(find_all('.js-tableActivity tbody tr').count).to eq(20)
  228. expect(page).to have_text('Only the 20 most recent records are displayed. Download to view the full list.')
  229. end
  230. end
  231. end
  232. end