summaryrefslogtreecommitdiff
path: root/spec/support_specs/helpers/packages/npm_spec.rb
blob: e1316a10fb1f5dd76c959ff282f4426a0926722e (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
132
133
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe ::API::Helpers::Packages::Npm, feature_category: :package_registry do  # rubocop: disable RSpec/FilePath
  let(:object) { klass.new(params) }
  let(:klass) do
    Struct.new(:params) do
      include ::API::Helpers
      include ::API::Helpers::Packages::Npm
    end
  end

  let_it_be(:user) { create(:user) }
  let_it_be(:group) { create(:group) }
  let_it_be(:namespace) { group }
  let_it_be(:project) { create(:project, :public, namespace: namespace) }
  let_it_be(:package) { create(:npm_package, project: project) }

  describe '#endpoint_scope' do
    subject { object.endpoint_scope }

    context 'when params includes an id' do
      let(:params) { { id: 42, package_name: 'foo' } }

      it { is_expected.to eq(:project) }
    end

    context 'when params does not include an id' do
      let(:params) { { package_name: 'foo' } }

      it { is_expected.to eq(:instance) }
    end
  end

  describe '#finder_for_endpoint_scope' do
    subject { object.finder_for_endpoint_scope(package_name) }

    let(:package_name) { package.name }

    context 'when called with project scope' do
      let(:params) { { id: project.id } }

      it 'returns a PackageFinder for project scope' do
        expect(::Packages::Npm::PackageFinder).to receive(:new).with(package_name, project: project)

        subject
      end
    end

    context 'when called with instance scope' do
      let(:params) { { package_name: package_name } }

      it 'returns a PackageFinder for namespace scope' do
        expect(::Packages::Npm::PackageFinder).to receive(:new).with(package_name, namespace: group)

        subject
      end
    end
  end

  describe '#project_id_or_nil' do
    subject { object.project_id_or_nil }

    context 'when called with project scope' do
      let(:params) { { id: project.id } }

      it { is_expected.to eq(project.id) }
    end

    context 'when called with namespace scope' do
      context 'when given an unscoped name' do
        let(:params) { { package_name: 'foo' } }

        it { is_expected.to eq(nil) }
      end

      context 'when given a scope that does not match a group name' do
        let(:params) { { package_name: '@nonexistent-group/foo' } }

        it { is_expected.to eq(nil) }
      end

      context 'when given a scope that matches a group name' do
        let(:params) { { package_name: package.name } }

        it { is_expected.to eq(project.id) }

        context 'with another package with the same name, in another project in the namespace' do
          let_it_be(:project2) { create(:project, :public, namespace: namespace) }
          let_it_be(:package2) { create(:npm_package, name: package.name, project: project2) }

          it 'returns the project id for the newest matching package within the scope' do
            expect(subject).to eq(project2.id)
          end
        end
      end

      context 'with npm_allow_packages_in_multiple_projects disabled' do
        before do
          stub_feature_flags(npm_allow_packages_in_multiple_projects: false)
        end

        context 'when given an unscoped name' do
          let(:params) { { package_name: 'foo' } }

          it { is_expected.to eq(nil) }
        end

        context 'when given a scope that does not match a group name' do
          let(:params) { { package_name: '@nonexistent-group/foo' } }

          it { is_expected.to eq(nil) }
        end

        context 'when given a scope that matches a group name' do
          let(:params) { { package_name: package.name } }

          it { is_expected.to eq(project.id) }

          context 'with another package with the same name, in another project in the namespace' do
            let_it_be(:project2) { create(:project, :public, namespace: namespace) }
            let_it_be(:package2) { create(:npm_package, name: package.name, project: project2) }

            it 'returns the project id for the newest matching package within the scope' do
              expect(subject).to eq(project2.id)
            end
          end
        end
      end
    end
  end
end