applies_ticket_template_examples.rb 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. RSpec.shared_examples 'FormUpdater::AppliesTicketTemplate' do
  3. context 'when applying a ticket template' do
  4. let(:object_name) { 'ticket' }
  5. let(:field_name) { 'title' }
  6. let(:field_template_config) { { 'value' => 'test' } }
  7. let(:field_result) { { value: 'test' } }
  8. let(:template) { create(:template, options: { "#{object_name}.#{field_name}" => field_template_config }) }
  9. let(:dirty_fields) { [] }
  10. let(:additional_data) { { 'templateId' => Gql::ZammadSchema.id_from_object(template) } }
  11. let(:meta) { { additional_data:, dirty_fields: } }
  12. shared_examples 'skips the field' do
  13. it 'skips the field' do
  14. expect(resolved_result.resolve[:fields][field_name]).not_to have_key(:value)
  15. end
  16. end
  17. shared_examples 'sets the template value for the field' do
  18. it 'sets the template value for the field' do
  19. expect(resolved_result.resolve[:fields][field_name]).to include(field_result)
  20. end
  21. end
  22. context 'without a template to be applied' do
  23. let(:additional_data) { {} }
  24. include_examples 'skips the field'
  25. end
  26. context 'with a template to be applied' do
  27. context 'when the field is dirty and has a value' do
  28. let(:data) { { field_name => 'previous value' } }
  29. let(:dirty_fields) { [field_name] }
  30. include_examples 'skips the field'
  31. end
  32. context 'when a value is present, but the field is not marked as dirty' do
  33. let(:data) { { field_name: 'already present' } }
  34. include_examples 'sets the template value for the field'
  35. end
  36. context 'with simple fields' do
  37. include_examples 'sets the template value for the field'
  38. end
  39. context 'with tags field' do
  40. let(:data) { { 'tags' => %w[tag2 tag3] } }
  41. let(:field_name) { 'tags' }
  42. let(:field_template_config) { { 'value' => 'tag1, tag2', 'operator' => operator } }
  43. context 'when adding tags' do
  44. let(:operator) { 'add' }
  45. context 'when tags field is not dirty' do
  46. # replace field content
  47. let(:field_result) { { value: %w[tag1 tag2] } }
  48. include_examples 'sets the template value for the field'
  49. end
  50. context 'when tags field is dirty' do
  51. let(:dirty_fields) { ['tags'] }
  52. # merge field content
  53. let(:field_result) { { value: %w[tag2 tag3 tag1] } }
  54. include_examples 'sets the template value for the field'
  55. end
  56. end
  57. context 'when removing tags' do
  58. let(:operator) { 'remove' }
  59. let(:field_result) { { value: ['tag3'] } }
  60. include_examples 'sets the template value for the field'
  61. end
  62. end
  63. context 'with user autocomplete fields' do
  64. let(:search_user) { create(:user, organization: create(:organization)) }
  65. let(:object_attribute) { create(:object_manager_attribute_user_autocompletion) }
  66. let(:field_name) { object_attribute.name }
  67. let(:field_template_config) { { 'value' => search_user.id, 'value_completion' => search_user.fullname } }
  68. let(:field_result) do
  69. {
  70. value: search_user.id,
  71. options: [{
  72. value: search_user.id,
  73. label: search_user.fullname,
  74. heading: search_user.organization.name,
  75. object: search_user.attributes
  76. .slice('active', 'email', 'firstname', 'fullname', 'image', 'lastname', 'mobile', 'out_of_office', 'out_of_office_end_at', 'out_of_office_start_at', 'phone', 'source', 'vip')
  77. .merge({
  78. '__typename' => 'User',
  79. 'id' => Gql::ZammadSchema.id_from_internal_id('User', search_user.id),
  80. })
  81. }]
  82. }
  83. end
  84. include_examples 'sets the template value for the field'
  85. end
  86. context 'with recipient autocomplete fields' do
  87. let(:search_user) { create(:user) }
  88. let(:object_name) { 'article' }
  89. let(:field_name) { 'cc' }
  90. let(:field_template_config) { { 'value' => search_user.email } }
  91. let(:field_result) do
  92. {
  93. value: [search_user.email],
  94. options: [{ value: search_user.email, label: search_user.email, heading: search_user.fullname }]
  95. }
  96. end
  97. include_examples 'sets the template value for the field'
  98. context 'with unknown email' do
  99. let(:search_user) { 'dummy@non-existing.com' }
  100. let(:field_template_config) { { 'value' => search_user } }
  101. let(:field_result) do
  102. {
  103. value: [search_user],
  104. options: [{ value: search_user, label: search_user }]
  105. }
  106. end
  107. include_examples 'sets the template value for the field'
  108. end
  109. context 'with multiple recipients' do
  110. let(:recipient_user) { create(:user) }
  111. let(:recipient_email) { 'dummy@non-existing.com' }
  112. let(:field_template_config) { { 'value' => "#{recipient_user.email}, #{recipient_email}" } }
  113. let(:field_result) do
  114. {
  115. value: [recipient_user.email, recipient_email],
  116. options: [
  117. { value: recipient_user.email, label: recipient_user.email, heading: recipient_user.fullname },
  118. { value: recipient_email, label: recipient_email },
  119. ],
  120. }
  121. end
  122. include_examples 'sets the template value for the field'
  123. end
  124. end
  125. context 'with organization autocomplete fields' do
  126. let(:search_organization) { create(:organization) }
  127. let(:object_attribute) { create(:object_manager_attribute_organization_autocompletion) }
  128. let(:field_name) { object_attribute.name }
  129. let(:field_template_config) { { 'value' => search_organization.id.to_s, 'value_completion' => search_organization.name } }
  130. let(:field_result) do
  131. {
  132. value: search_organization.id,
  133. options: [{ value: search_organization.id, label: search_organization.name }]
  134. }
  135. end
  136. include_examples 'sets the template value for the field'
  137. end
  138. context 'with date fields' do
  139. let(:object_attribute) { create(:object_manager_attribute_date) }
  140. let(:field_name) { object_attribute.name }
  141. context 'with fixed value' do
  142. let(:field_template_config) { { 'value' => '2024-01-01', 'operator' => 'static' } }
  143. let(:field_result) { { value: '2024-01-01' } }
  144. include_examples 'sets the template value for the field'
  145. end
  146. context 'with relative value' do
  147. before do
  148. travel_to(DateTime.parse('2024-01-01 00:00:00 UTC'))
  149. end
  150. let(:field_template_config) { { 'value' => '1', 'operator' => 'relative', 'range' => 'month' } }
  151. let(:field_result) { { value: '2024-02-01' } }
  152. include_examples 'sets the template value for the field'
  153. end
  154. end
  155. context 'with datetime fields' do
  156. let(:object_attribute) { create(:object_manager_attribute_datetime) }
  157. let(:field_name) { object_attribute.name }
  158. context 'with fixed value' do
  159. let(:field_template_config) { { 'value' => '2024-01-01T00:00:00Z', 'operator' => 'static' } }
  160. let(:field_result) { { value: '2024-01-01T00:00:00Z' } }
  161. include_examples 'sets the template value for the field'
  162. end
  163. context 'with relative value' do
  164. before do
  165. travel_to(DateTime.parse('2024-01-01 00:00:00 UTC'))
  166. end
  167. let(:field_template_config) { { 'value' => '1', 'operator' => 'relative', 'range' => 'month' } }
  168. let(:field_result) { { value: '2024-02-01T00:00:00Z' } }
  169. include_examples 'sets the template value for the field'
  170. end
  171. end
  172. context 'with group and owner fields' do
  173. let(:group) { create(:group, name: 'Example 1') }
  174. let(:user) { create(:agent, groups: [group]) }
  175. let(:context) { { current_user: user } }
  176. let(:template) { create(:template, options: { 'ticket.group_id' => { 'value' => group.id.to_s }, 'ticket.owner_id' => { 'value' => user.id.to_s } }) }
  177. it 'sets the template value for both fields', :aggregate_failures do
  178. expect(resolved_result.resolve[:fields]['group_id']).to include(value: group.id)
  179. expect(resolved_result.resolve[:fields]['owner_id']).to include(value: user.id)
  180. end
  181. end
  182. end
  183. end
  184. end