recent_view_spec.rb 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe RecentView, type: :model do
  4. let(:admin) { create(:admin) }
  5. let(:agent) { create(:agent) }
  6. let(:customer) { create(:customer) }
  7. let(:ticket) { create(:ticket, owner: owner, customer: customer) }
  8. let(:tickets) { create_list(:ticket, 15, owner: owner, customer: customer) }
  9. let(:owner) { admin }
  10. describe '::list' do
  11. it 'returns a sample of recently viewed objects (e.g., tickets/users/organizations)' do
  12. tickets.each { |t| described_class.log('Ticket', t.id, admin) }
  13. expect(described_class.list(admin).map(&:o_id)).to include(*tickets.last(10).map(&:id))
  14. end
  15. it 'returns up to 10 results by default' do
  16. tickets.each { |t| described_class.log('Ticket', t.id, admin) }
  17. expect(described_class.list(admin).length).to eq(10)
  18. end
  19. context 'with a `limit` argument (optional)' do
  20. it 'returns up to that number of results' do
  21. tickets.each { |t| described_class.log('Ticket', t.id, admin) }
  22. expect(described_class.list(admin, 12).length).to eq(12)
  23. end
  24. end
  25. context 'with an `object_name` argument (optional)' do
  26. it 'includes only the specified model class' do
  27. described_class.log('Ticket', ticket.id, admin)
  28. described_class.log('Organization', 1, admin)
  29. expect(described_class.list(admin, 10, 'Organization').length).to eq(1)
  30. end
  31. it 'does not include merged tickets in results' do
  32. described_class.log('Ticket', ticket.id, admin)
  33. ticket.update(state: Ticket::State.find_by(name: 'merged'))
  34. expect(described_class.list(admin, 10, 'Ticket').length).to eq(0)
  35. end
  36. it 'does not include removed tickets in results' do
  37. described_class.log('Ticket', ticket.id, admin)
  38. ticket.update(state: Ticket::State.find_by(name: 'removed'))
  39. expect(described_class.list(admin, 10, 'Ticket').length).to eq(0)
  40. end
  41. end
  42. it 'does not include duplicate results' do
  43. 5.times { described_class.log('Ticket', ticket.id, admin) }
  44. expect(described_class.list(admin).length).to eq(1)
  45. end
  46. it 'does not include deleted tickets in results' do
  47. described_class.log('Ticket', ticket.id, admin)
  48. ticket.destroy
  49. expect(described_class.list(admin).length).to eq(0)
  50. end
  51. describe 'access privileges' do
  52. context 'when given user is agent' do
  53. let(:owner) { agent }
  54. it 'includes own tickets in results' do
  55. described_class.log('Ticket', ticket.id, agent)
  56. expect(described_class.list(agent).length).to eq(1)
  57. end
  58. it 'does not include other agents’ tickets in results' do
  59. described_class.log('Ticket', ticket.id, agent)
  60. ticket.update(owner: User.first)
  61. expect(described_class.list(agent).length).to eq(0)
  62. end
  63. it 'includes any organizations in results' do
  64. agent.update(organization: nil)
  65. described_class.log('Organization', 1, agent)
  66. expect(described_class.list(agent).length).to eq(1)
  67. end
  68. end
  69. context 'when given user is customer' do
  70. it 'includes own tickets in results' do
  71. described_class.log('Ticket', ticket.id, customer)
  72. expect(described_class.list(customer).length).to eq(1)
  73. end
  74. it 'does not include other customers’ tickets in results' do
  75. described_class.log('Ticket', ticket.id, customer)
  76. ticket.update(customer: User.first)
  77. expect(described_class.list(customer).length).to eq(0)
  78. end
  79. it 'includes own organization in results' do
  80. customer.update(organization: Organization.first)
  81. described_class.log('Organization', 1, customer)
  82. expect(described_class.list(customer).length).to eq(1)
  83. end
  84. it 'does not include other organizations in results' do
  85. customer.update(organization: Organization.first)
  86. described_class.log('Organization', 1, customer)
  87. customer.update(organization: nil)
  88. expect(described_class.list(customer).length).to eq(0)
  89. end
  90. end
  91. end
  92. end
  93. describe '::user_log_destroy' do
  94. it 'deletes all RecentView records for a given user' do
  95. create_list(:recent_view, 10, created_by_id: admin.id)
  96. expect { described_class.user_log_destroy(admin) }
  97. .to change { described_class.exists?(created_by_id: admin.id) }.to(false)
  98. end
  99. end
  100. describe '::log' do
  101. let(:viewed_object) { ticket }
  102. let(:viewed_object_class_id) { ObjectLookup.by_name(viewed_object.class.name) }
  103. it 'wraps RecentView.create' do
  104. expect do
  105. described_class.log(viewed_object.class.name, viewed_object.id, admin)
  106. end.to change(described_class, :count).by(1)
  107. end
  108. describe 'access privileges' do
  109. let(:owner) { agent }
  110. it 'does not create RecentView for records the given user cannot read' do
  111. ticket.update(owner: User.first, # read access may come from ticket ownership,
  112. customer: User.first, # customer status,
  113. organization: nil) # organization's 'shared' status,
  114. agent.update(groups: []) # and membership in the Ticket's group
  115. expect do
  116. described_class.log(viewed_object.class.name, viewed_object.id, agent)
  117. end.not_to change(described_class, :count)
  118. end
  119. end
  120. context 'when given an invalid object' do
  121. it 'does not create RecentView for non-existent record' do
  122. expect do
  123. described_class.log('User', 99_999_999, admin)
  124. end.not_to change(described_class, :count)
  125. end
  126. it 'does not create RecentView for instance of non-ObjectLookup class' do
  127. expect do
  128. described_class.log('Overview', 1, admin)
  129. end.not_to change(described_class, :count)
  130. end
  131. it 'does not create RecentView for instance of non-existent class' do
  132. expect do
  133. described_class.log('NonExistentClass', 1, admin)
  134. end.not_to change(described_class, :count)
  135. end
  136. end
  137. end
  138. end