Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mark_packages_for_destruction_service_spec.rb « packages « services « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: cd6426d39ad349f82e85f70fce0e86921d12190d (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
120
121
122
123
124
125
126
127
128
129
130
131
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Packages::MarkPackagesForDestructionService, :sidekiq_inline, feature_category: :package_registry do
  let_it_be(:project) { create(:project) }
  let_it_be_with_reload(:packages) { create_list(:nuget_package, 3, project: project) }

  let(:user) { project.owner }

  # The service only accepts ActiveRecord relationships and not arrays.
  let(:service) { described_class.new(packages: ::Packages::Package.id_in(package_ids), current_user: user) }
  let(:package_ids) { packages.map(&:id) }

  describe '#execute' do
    subject { service.execute }

    shared_examples 'returning service response' do |status:, message:, reason: nil|
      it 'returns service response' do
        subject

        expect(subject).to be_a(ServiceResponse)
        expect(subject.status).to eq(status)
        expect(subject.message).to eq(message)
        expect(subject.reason).to eq(reason) if reason
      end
    end

    context 'when the user is authorized' do
      before do
        project.add_maintainer(user)
      end

      context 'when it is successful' do
        it 'marks the packages as pending destruction' do
          expect(::Packages::Maven::Metadata::SyncService).not_to receive(:new)
          expect(::Packages::Npm::CreateMetadataCacheService).not_to receive(:new)

          expect { subject }.to change { ::Packages::Package.pending_destruction.count }.from(0).to(3)
                                  .and change { Packages::PackageFile.pending_destruction.count }.from(0).to(3)
          packages.each { |pkg| expect(pkg.reload).to be_pending_destruction }
        end

        it_behaves_like 'returning service response', status: :success,
          message: 'Packages were successfully marked as pending destruction'

        context 'with maven packages' do
          let_it_be_with_reload(:packages) { create_list(:maven_package, 3, project: project) }

          it 'marks the packages as pending destruction' do
            expect(::Packages::Maven::Metadata::SyncService).to receive(:new).once.and_call_original

            expect { subject }.to change { ::Packages::Package.pending_destruction.count }.from(0).to(3)
                                    .and change { Packages::PackageFile.pending_destruction.count }.from(0).to(9)
            packages.each { |pkg| expect(pkg.reload).to be_pending_destruction }
          end

          it_behaves_like 'returning service response', status: :success,
            message: 'Packages were successfully marked as pending destruction'

          context 'without version' do
            before do
              ::Packages::Package.id_in(package_ids).update_all(version: nil)
            end

            it 'marks the packages as pending destruction' do
              expect(::Packages::Maven::Metadata::SyncService).not_to receive(:new)

              expect { subject }.to change { ::Packages::Package.pending_destruction.count }.from(0).to(3)
                                      .and change { Packages::PackageFile.pending_destruction.count }.from(0).to(9)
              packages.each { |pkg| expect(pkg.reload).to be_pending_destruction }
            end

            it_behaves_like 'returning service response', status: :success,
              message: 'Packages were successfully marked as pending destruction'
          end
        end

        context 'with npm packages' do
          let_it_be_with_reload(:packages) { create_list(:npm_package, 3, project: project, name: 'test-package') }

          it 'marks the packages as pending destruction' do
            expect(::Packages::Npm::CreateMetadataCacheService).to receive(:new).once.and_call_original

            expect { subject }.to change { ::Packages::Package.pending_destruction.count }.from(0).to(3)
                                    .and change { Packages::PackageFile.pending_destruction.count }.from(0).to(3)
            packages.each { |package| expect(package.reload).to be_pending_destruction }
          end

          it_behaves_like 'returning service response', status: :success,
            message: 'Packages were successfully marked as pending destruction'
        end
      end

      context 'when it is not successful' do
        before do
          allow(service).to receive(:can_destroy_packages?).and_raise(StandardError, 'test')
        end

        it 'does not mark the packages as pending destruction' do
          expect(::Packages::Maven::Metadata::SyncService).not_to receive(:new)

          expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
            instance_of(StandardError),
            package_ids: package_ids
          )

          expect { subject }.to not_change { ::Packages::Package.pending_destruction.count }
                                  .and not_change { ::Packages::PackageFile.pending_destruction.count }
        end

        it_behaves_like 'returning service response', status: :error,
          message: 'Failed to mark the packages as pending destruction'
      end
    end

    context 'when the user is not authorized' do
      let(:user) { nil }

      it 'does not mark the packages as pending destruction' do
        expect(::Packages::Maven::Metadata::SyncService).not_to receive(:new)

        expect { subject }.to not_change { ::Packages::Package.pending_destruction.count }
                                .and not_change { ::Packages::PackageFile.pending_destruction.count }
      end

      it_behaves_like 'returning service response', status: :error, reason: :unauthorized,
        message: "You don't have the permission to perform this action"
    end
  end
end