checklist_spec.rb 6.7 KB

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