import_job_spec.rb 5.7 KB

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