summaryrefslogtreecommitdiff
path: root/spec/graphql/mutations/release_asset_links/create_spec.rb
blob: cc6c155486630fc0f2bc1b9314557960c9b345e2 (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
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Mutations::ReleaseAssetLinks::Create, feature_category: :release_orchestration do
  include GraphqlHelpers

  let_it_be(:project) { create(:project, :private, :repository) }
  let_it_be(:release) { create(:release, project: project, tag: 'v13.10') }
  let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } }
  let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }

  let(:current_user) { developer }
  let(:context) { { current_user: current_user } }
  let(:project_path) { project.full_path }
  let(:tag) { release.tag }
  let(:name) { 'awesome-app.dmg' }
  let(:url) { 'https://example.com/download/awesome-app.dmg' }
  let(:filepath) { '/binaries/awesome-app.dmg' }

  let(:args) do
    {
      project_path: project_path,
      tag_name: tag,
      name: name,
      direct_asset_path: filepath,
      url: url
    }
  end

  let(:last_release_link) { release.links.last }

  describe '#resolve' do
    subject do
      resolve(described_class, obj: project, args: args, ctx: context)
    end

    context 'when the user has access and no validation errors occur' do
      it 'creates a new release asset link', :aggregate_failures do
        expect(subject).to include({
          link: release.reload.links.first,
          errors: []
        })

        expect(release.links.length).to be(1)

        expect(last_release_link.name).to eq(name)
        expect(last_release_link.url).to eq(url)
        expect(last_release_link.filepath).to eq(filepath)
      end
    end

    context 'with protected tag' do
      context 'when user has access to the protected tag' do
        let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }

        it 'does not have errors' do
          expect(subject).to include(errors: [])
        end
      end

      context 'when user does not have access to the protected tag' do
        let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }

        it 'has an access error' do
          expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
            subject
          end
        end
      end
    end

    context "when the user doesn't have access to the project" do
      let(:current_user) { reporter }

      it 'generates an error' do
        expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
          subject
        end
      end
    end

    context "when the project doesn't exist" do
      let(:project_path) { 'project/that/does/not/exist' }

      it 'generates an error' do
        expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
          subject
        end
      end
    end

    context "when a validation errors occur" do
      shared_examples 'returns errors-as-data' do |expected_messages|
        it { expect(subject[:errors]).to eq(expected_messages) }
      end

      context "when the release doesn't exist" do
        let(:tag) { "nonexistent-tag" }

        it_behaves_like 'returns errors-as-data', ['Release with tag "nonexistent-tag" was not found']
      end

      context 'when the URL is badly formatted' do
        let(:url) { 'badly-formatted-url' }

        it_behaves_like 'returns errors-as-data', ["Url is blocked: Only allowed schemes are http, https, ftp"]
      end

      context 'when the name is not provided' do
        let(:name) { '' }

        it_behaves_like 'returns errors-as-data', ["Name can't be blank"]
      end

      context 'when the link already exists' do
        let!(:existing_release_link) do
          create(:release_link, release: release, name: name, url: url, filepath: filepath)
        end

        it_behaves_like 'returns errors-as-data', [
          "Url has already been taken",
          "Name has already been taken",
          "Filepath has already been taken"
        ]
      end
    end
  end
end