summaryrefslogtreecommitdiff
path: root/spec/services/packages/npm/create_package_service_spec.rb
blob: 10fce6c1651daf16bcb44897f5b65ad3175d5c77 (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
# frozen_string_literal: true
require 'spec_helper'

RSpec.describe Packages::Npm::CreatePackageService do
  let(:namespace) {create(:namespace)}
  let(:project) { create(:project, namespace: namespace) }
  let(:user) { create(:user) }
  let(:version) { '1.0.1' }

  let(:params) do
    Gitlab::Json.parse(fixture_file('packages/npm/payload.json')
        .gsub('@root/npm-test', package_name)
        .gsub('1.0.1', version)).with_indifferent_access
      .merge!(override)
  end

  let(:override) { {} }
  let(:package_name) { "@#{namespace.path}/my-app".freeze }

  subject { described_class.new(project, user, params).execute }

  shared_examples 'valid package' do
    it 'creates a package' do
      expect { subject }
        .to change { Packages::Package.count }.by(1)
        .and change { Packages::Package.npm.count }.by(1)
        .and change { Packages::Tag.count }.by(1)
    end

    it_behaves_like 'assigns the package creator' do
      let(:package) { subject }
    end

    it { is_expected.to be_valid }

    it 'creates a package with name and version' do
      package = subject

      expect(package.name).to eq(package_name)
      expect(package.version).to eq(version)
    end

    it { expect(subject.name).to eq(package_name) }
    it { expect(subject.version).to eq(version) }
  end

  describe '#execute' do
    context 'scoped package' do
      it_behaves_like 'valid package'

      context 'with build info' do
        let(:job) { create(:ci_build, user: user) }
        let(:params) { super().merge(build: job) }

        it_behaves_like 'assigns build to package'
        it_behaves_like 'assigns status to package'

        it 'creates a package file build info' do
          expect { subject }.to change { Packages::PackageFileBuildInfo.count }.by(1)
        end
      end
    end

    context 'invalid package name' do
      let(:package_name) { "@#{namespace.path}/my-group/my-app".freeze }

      it { expect { subject }.to raise_error(ActiveRecord::RecordInvalid) }
    end

    context 'package already exists' do
      let(:package_name) { "@#{namespace.path}/my_package" }
      let!(:existing_package) { create(:npm_package, project: project, name: package_name, version: '1.0.1') }

      it { expect(subject[:http_status]).to eq 403 }
      it { expect(subject[:message]).to be 'Package already exists.' }
    end

    context 'file size above maximum limit' do
      before do
        params['_attachments']["#{package_name}-#{version}.tgz"]['length'] = project.actual_limits.npm_max_file_size + 1
      end

      it { expect(subject[:http_status]).to eq 400 }
      it { expect(subject[:message]).to be 'File is too large.' }
    end

    context 'with incorrect namespace' do
      let(:package_name) { '@my_other_namespace/my-app' }

      it 'raises a RecordInvalid error' do
        expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
      end
    end

    context 'with empty versions' do
      let(:override) { { versions: {} } }

      it { expect(subject[:http_status]).to eq 400 }
      it { expect(subject[:message]).to eq 'Version is empty.' }
    end

    context 'with invalid versions' do
      using RSpec::Parameterized::TableSyntax

      where(:version) do
        [
          '1',
          '1.2',
          '1./2.3',
          '../../../../../1.2.3',
          '%2e%2e%2f1.2.3'
        ]
      end

      with_them do
        it { expect { subject }.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Version is invalid') }
      end
    end
  end
end