checklist_spec.rb 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Gql::Queries::Ticket::Checklist, current_user_id: 1, type: :graphql do
  4. let(:group) { create(:group) }
  5. let(:agent) { create(:agent, groups: [group]) }
  6. let(:ticket) { create(:ticket, group: group) }
  7. let(:checklist) { create(:checklist, name: 'foobar', ticket: ticket) }
  8. let(:query) do
  9. <<~QUERY
  10. query ticketChecklist($ticketId: ID, $ticketInternalId: Int, $ticketNumber: String) {
  11. ticketChecklist(
  12. ticket: {
  13. ticketId: $ticketId
  14. ticketInternalId: $ticketInternalId
  15. ticketNumber: $ticketNumber
  16. }
  17. ) {
  18. id
  19. name
  20. completed
  21. incomplete
  22. complete
  23. total
  24. items {
  25. id
  26. text
  27. checked
  28. ticketReference {
  29. ticket {
  30. id
  31. }
  32. }
  33. }
  34. }
  35. }
  36. QUERY
  37. end
  38. let(:variables) { { ticketId: gql.id(ticket) } }
  39. let(:response) do
  40. {
  41. 'id' => gql.id(checklist),
  42. 'name' => checklist.name,
  43. 'completed' => false,
  44. 'incomplete' => 5,
  45. 'complete' => 0,
  46. 'total' => 5,
  47. 'items' => checklist.items.sort_by(&:id).map do |item|
  48. {
  49. 'id' => gql.id(item),
  50. 'text' => item.text,
  51. 'checked' => item.checked,
  52. 'ticketReference' => nil,
  53. }
  54. end,
  55. }
  56. end
  57. before do
  58. setup if defined?(setup)
  59. checklist
  60. gql.execute(query, variables: variables)
  61. end
  62. shared_examples 'returning checklist data' do
  63. it 'returns checklist data' do
  64. expect(gql.result.data).to eq(response)
  65. end
  66. end
  67. shared_examples 'raising an error' do |error_type|
  68. it 'raises an error' do
  69. expect(gql.result.error_type).to eq(error_type)
  70. end
  71. end
  72. context 'with authenticated session', authenticated_as: :agent do
  73. it_behaves_like 'returning checklist data'
  74. context 'with disabled checklist feature' do
  75. let(:setup) do
  76. Setting.set('checklist', false)
  77. end
  78. it_behaves_like 'raising an error', Exceptions::Forbidden
  79. end
  80. context 'without access to the ticket' do
  81. let(:agent) { create(:agent) }
  82. it_behaves_like 'raising an error', Exceptions::Forbidden
  83. end
  84. context 'with ticket read permission' do
  85. let(:agent) { create(:agent, groups: [group], group_names_access_map: { group.name => 'read' }) }
  86. it_behaves_like 'returning checklist data'
  87. end
  88. context 'when checklist does not exist' do
  89. let(:checklist) { nil }
  90. let(:response) { nil }
  91. it_behaves_like 'returning checklist data'
  92. end
  93. context 'with alternative input variables' do
  94. context 'with internal ticket ID' do
  95. let(:variables) { { ticketInternalId: ticket.id } }
  96. it_behaves_like 'returning checklist data'
  97. end
  98. context 'with ticket number' do
  99. let(:variables) { { ticketNumber: ticket.number } }
  100. it_behaves_like 'returning checklist data'
  101. end
  102. context 'without any of required variables' do
  103. let(:variables) { {} }
  104. it_behaves_like 'raising an error', GraphQL::Schema::Validator::ValidationFailedError
  105. end
  106. end
  107. context 'with ticket checklist item' do
  108. let(:checklist) do
  109. create(:checklist, name: 'foobar', ticket: ticket, item_count: 1).tap do |checklist|
  110. checklist.items.last.update!(text: "Ticket##{another_ticket.number}", ticket_id: another_ticket.id)
  111. checklist.reload
  112. end
  113. end
  114. context 'with an open ticket' do
  115. let(:another_ticket) { create(:ticket, group: group, state: Ticket::State.find_by(name: 'open')) }
  116. let(:response) do
  117. {
  118. 'id' => gql.id(checklist),
  119. 'name' => checklist.name,
  120. 'completed' => false,
  121. 'incomplete' => 1,
  122. 'complete' => 0,
  123. 'total' => 1,
  124. 'items' => [
  125. {
  126. 'id' => gql.id(checklist.items.last),
  127. 'text' => checklist.items.last.text,
  128. 'checked' => checklist.items.last.checked,
  129. 'ticketReference' => {
  130. 'ticket' => {
  131. 'id' => gql.id(another_ticket),
  132. },
  133. },
  134. },
  135. ],
  136. }
  137. end
  138. it_behaves_like 'returning checklist data'
  139. end
  140. context 'with a closed ticket' do
  141. let(:another_ticket) { create(:ticket, group: group, state: Ticket::State.find_by(name: 'closed')) }
  142. let(:response) do
  143. {
  144. 'id' => gql.id(checklist),
  145. 'name' => checklist.name,
  146. 'completed' => true,
  147. 'incomplete' => 0,
  148. 'complete' => 1,
  149. 'total' => 1,
  150. 'items' => [
  151. {
  152. 'id' => gql.id(checklist.items.last),
  153. 'text' => checklist.items.last.text,
  154. 'checked' => checklist.items.last.checked,
  155. 'ticketReference' => {
  156. 'ticket' => {
  157. 'id' => gql.id(another_ticket),
  158. },
  159. },
  160. },
  161. ],
  162. }
  163. end
  164. it_behaves_like 'returning checklist data'
  165. end
  166. context 'when the agent has no access to the linked ticket' do
  167. let(:another_ticket) do
  168. create(:ticket, state: Ticket::State.find_by(name: 'new')).tap do |t|
  169. create(:checklist, name: 'foobar', ticket: t, item_count: 1).tap do |checklist|
  170. checklist.items.last.update!(text: "Ticket##{ticket.number}", ticket_id: ticket.id)
  171. checklist.reload
  172. end
  173. end
  174. end
  175. let(:response) do
  176. {
  177. 'id' => gql.id(checklist),
  178. 'name' => checklist.name,
  179. 'completed' => false,
  180. 'incomplete' => 1,
  181. 'complete' => 0,
  182. 'total' => 1,
  183. 'items' => [
  184. {
  185. 'id' => gql.id(checklist.items.last),
  186. 'text' => checklist.items.last.text,
  187. 'checked' => checklist.items.last.checked,
  188. 'ticketReference' => {
  189. 'ticket' => nil,
  190. },
  191. },
  192. ],
  193. }
  194. end
  195. it_behaves_like 'returning checklist data'
  196. end
  197. end
  198. end
  199. it_behaves_like 'graphql responds with error if unauthenticated'
  200. end