checklist_spec.rb 6.8 KB

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