summaryrefslogtreecommitdiff
path: root/spec/uploaders/workers/object_storage/migrate_uploads_worker_spec.rb
blob: 7a7dcb716804b1304456e2ea25905fce171e73c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
require 'spec_helper'

describe ObjectStorage::MigrateUploadsWorker, :sidekiq do
  shared_context 'sanity_check! fails' do
    before do
      expect(described_class).to receive(:sanity_check!).and_raise(described_class::SanityCheckError)
    end
  end

  let!(:projects) { create_list(:project, 10, :with_avatar) }
  let(:uploads) { Upload.all }
  let(:model_class) { Project }
  let(:mounted_as) { :avatar }
  let(:to_store) { ObjectStorage::Store::REMOTE }

  before do
    stub_uploads_object_storage(AvatarUploader)
  end

  describe '.enqueue!' do
    def enqueue!
      described_class.enqueue!(uploads, Project, mounted_as, to_store)
    end

    it 'is guarded by .sanity_check!' do
      expect(described_class).to receive(:perform_async)
      expect(described_class).to receive(:sanity_check!)

      enqueue!
    end

    context 'sanity_check! fails' do
      include_context 'sanity_check! fails'

      it 'does not enqueue a job' do
        expect(described_class).not_to receive(:perform_async)

        expect { enqueue! }.to raise_error(described_class::SanityCheckError)
      end
    end
  end

  describe '.sanity_check!' do
    shared_examples 'raises a SanityCheckError' do
      let(:mount_point) { nil }

      it do
        expect { described_class.sanity_check!(uploads, model_class, mount_point) }
          .to raise_error(described_class::SanityCheckError)
      end
    end

    context 'uploader types mismatch' do
      let!(:outlier) { create(:upload, uploader: 'FileUploader') }

      include_examples 'raises a SanityCheckError'
    end

    context 'model types mismatch' do
      let!(:outlier) { create(:upload, model_type: 'Potato') }

      include_examples 'raises a SanityCheckError'
    end

    context 'mount point not found' do
      include_examples 'raises a SanityCheckError' do
        let(:mount_point) { :potato }
      end
    end
  end

  describe '#perform' do
    def perform
      described_class.new.perform(uploads.ids, model_class.to_s, mounted_as, to_store)
    rescue ObjectStorage::MigrateUploadsWorker::Report::MigrationFailures
      # swallow
    end

    shared_examples 'outputs correctly' do |success: 0, failures: 0|
      total = success + failures

      if success > 0
        it 'outputs the reports' do
          expect(Rails.logger).to receive(:info).with(%r{Migrated #{success}/#{total} files})

          perform
        end
      end

      if failures > 0
        it 'outputs upload failures' do
          expect(Rails.logger).to receive(:warn).with(/Error .* I am a teapot/)

          perform
        end
      end
    end

    it_behaves_like 'outputs correctly', success: 10

    it 'migrates files' do
      perform

      aggregate_failures do
        projects.each do |project|
          expect(project.reload.avatar.upload.local?).to be_falsey
        end
      end
    end

    context 'migration is unsuccessful' do
      before do
        allow_any_instance_of(ObjectStorage::Concern).to receive(:migrate!).and_raise(CarrierWave::UploadError, "I am a teapot.")
      end

      it_behaves_like 'outputs correctly', failures: 10
    end
  end
end