import_job_spec.rb 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. require 'rails_helper'
  2. RSpec.describe ImportJob do
  3. before do
  4. stub_const test_backend_name, test_backend_class
  5. stub_const test_backend_noreschedule_name, test_backend_noreschedule_class
  6. end
  7. let(:test_backend_name) { 'Import::Test' }
  8. let(:test_backend_class) do
  9. Class.new(Import::Base) do
  10. def start
  11. @import_job.result = { state: 'Done' }
  12. end
  13. end
  14. end
  15. let(:test_backend_noreschedule_name) { 'Import::NoRescheduleMethod' }
  16. let(:test_backend_noreschedule_class) do
  17. Class.new do
  18. def initialize(import_job)
  19. @import_job = import_job
  20. end
  21. def start
  22. @import_job.result = { state: 'Done' }
  23. end
  24. def reschedule?(_delayed_job)
  25. 'invalid_but_checkable_result'
  26. end
  27. end
  28. end
  29. describe '#dry_run' do
  30. it 'starts delayed dry run import job' do
  31. expect do
  32. described_class.dry_run(
  33. name: test_backend_name,
  34. payload: {}
  35. )
  36. end.to change {
  37. Delayed::Job.count
  38. }.by(1)
  39. end
  40. it 'starts dry run import job immediately' do
  41. expect do
  42. described_class.dry_run(
  43. name: test_backend_name,
  44. payload: {},
  45. delay: false
  46. )
  47. end.not_to change {
  48. Delayed::Job.count
  49. }
  50. end
  51. it "doesn't start job if one exists" do
  52. create(:import_job, dry_run: true)
  53. expect do
  54. described_class.dry_run(
  55. name: test_backend_name,
  56. payload: {},
  57. )
  58. end.not_to change {
  59. Delayed::Job.count
  60. }
  61. end
  62. end
  63. describe '#queue_registered' do
  64. it 'queues registered import jobs' do
  65. allow(Setting).to receive(:get)
  66. allow(Setting).to receive(:get).with('import_backends').and_return([test_backend_name])
  67. expect do
  68. described_class.queue_registered
  69. end.to change {
  70. described_class.exists?(name: test_backend_name)
  71. }
  72. end
  73. it "doesn't queue if backend isn't #queueable?" do
  74. allow(Setting).to receive(:get)
  75. allow(Setting).to receive(:get).with('import_backends').and_return([test_backend_name])
  76. allow(test_backend_class).to receive(:queueable?).and_return(false)
  77. expect do
  78. described_class.queue_registered
  79. end.not_to change {
  80. described_class.exists?(name: test_backend_name)
  81. }
  82. end
  83. it "doesn't queue if unfinished job entries exist" do
  84. create(:import_job)
  85. allow(Setting).to receive(:get)
  86. allow(Setting).to receive(:get).with('import_backends').and_return([test_backend_name])
  87. expect do
  88. described_class.queue_registered
  89. end.not_to change {
  90. described_class.exists?(name: test_backend_name)
  91. }
  92. end
  93. it 'logs errors for invalid registered backends' do
  94. allow(Setting).to receive(:get)
  95. allow(Setting).to receive(:get).with('import_backends').and_return(['InvalidBackend'])
  96. allow(described_class.logger).to receive(:error)
  97. described_class.queue_registered
  98. expect(described_class.logger).to have_received(:error)
  99. end
  100. end
  101. describe '#start' do
  102. it 'starts queued import jobs' do
  103. create_list(:import_job, 2)
  104. expect do
  105. described_class.start
  106. end.to change {
  107. described_class.where(started_at: nil).count
  108. }.by(-2)
  109. end
  110. it "doesn't start queued dry run import jobs" do
  111. create_list(:import_job, 2)
  112. create(:import_job, dry_run: true)
  113. expect do
  114. described_class.start
  115. end.to change {
  116. described_class.where(started_at: nil).count
  117. }.by(-2)
  118. end
  119. end
  120. describe '#start_registered' do
  121. it 'queues and starts registered import backends' do
  122. allow(Setting).to receive(:get)
  123. allow(Setting).to receive(:get).with('import_backends').and_return([test_backend_name])
  124. expect do
  125. described_class.start_registered
  126. end.to change {
  127. described_class.where.not(started_at: nil, finished_at: nil).count
  128. }.by(1)
  129. end
  130. end
  131. describe '#backend_valid?' do
  132. it 'detects existing backends' do
  133. expect(described_class.backend_valid?(test_backend_name)).to be true
  134. end
  135. it 'detects not existing backends' do
  136. expect(described_class.backend_valid?('InvalidBackend')).to be false
  137. end
  138. end
  139. describe '#backends' do
  140. it 'returns list of backend namespaces' do
  141. allow(Setting).to receive(:get).with('import_backends').and_return(['Import::Ldap'])
  142. allow(Import::Ldap).to receive(:active?).and_return(true)
  143. backends = described_class.backends
  144. expect(backends).to be_a(Array)
  145. expect(backends).not_to be_blank
  146. end
  147. it 'returns blank array if none are found' do
  148. allow(Setting).to receive(:get).with('import_backends')
  149. expect(described_class.backends).to eq([])
  150. end
  151. it "doesn't return invalid backends" do
  152. allow(Setting).to receive(:get).with('import_backends').and_return(['Import::InvalidBackend'])
  153. expect(described_class.backends).to eq([])
  154. end
  155. it "doesn't return inactive backends" do
  156. allow(Setting).to receive(:get).with('import_backends').and_return(['Import::Ldap'])
  157. allow(Import::Ldap).to receive(:active?).and_return(false)
  158. expect(described_class.backends).to eq([])
  159. end
  160. end
  161. describe '.start' do
  162. it 'runs import backend and updates started_at and finished_at' do
  163. instance = create(:import_job)
  164. expect do
  165. instance.start
  166. end.to change {
  167. instance.started_at
  168. }.and change {
  169. instance.finished_at
  170. }.and change {
  171. instance.result
  172. }
  173. end
  174. it 'handles exceptions as errors' do
  175. instance = create(:import_job)
  176. error_message = 'Some horrible error'
  177. allow_any_instance_of(test_backend_class).to receive(:start).and_raise(error_message)
  178. expect do
  179. instance.start
  180. instance.reload
  181. end.to change {
  182. instance.started_at
  183. }.and change {
  184. instance.finished_at
  185. }.and change {
  186. instance.result
  187. }
  188. expect(instance.result[:error]).to eq(error_message)
  189. end
  190. end
  191. describe '.reschedule?' do
  192. it 'returns false for already finished jobs' do
  193. instance = create(:import_job)
  194. delayed_job = double()
  195. instance.update!(finished_at: Time.zone.now)
  196. expect(instance.reschedule?(delayed_job)).to be false
  197. end
  198. it 'returns false for backends not responding to reschedule?' do
  199. instance = create(:import_job)
  200. delayed_job = double()
  201. expect(instance.reschedule?(delayed_job)).to be false
  202. end
  203. it 'returns the backend reschedule? value' do
  204. instance = create(:import_job, name: 'Import::NoRescheduleMethod')
  205. delayed_job = double()
  206. expect(instance.reschedule?(delayed_job)).to eq 'invalid_but_checkable_result'
  207. end
  208. end
  209. end