summaryrefslogtreecommitdiff
path: root/spec/services/ci/create_web_ide_terminal_service_spec.rb
blob: 3462b48cfe7492b45115a8c2e19381b9dea9213c (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Ci::CreateWebIdeTerminalService do
  let_it_be(:project) { create(:project, :repository) }
  let_it_be(:user) { create(:user) }

  let(:ref) { 'master' }

  describe '#execute' do
    subject { described_class.new(project, user, ref: ref).execute }

    context 'for maintainer' do
      shared_examples 'be successful' do
        it 'returns a success with pipeline object' do
          is_expected.to include(status: :success)

          expect(subject[:pipeline]).to be_a(Ci::Pipeline)
          expect(subject[:pipeline]).to be_persisted
          expect(subject[:pipeline].stages.count).to eq(1)
          expect(subject[:pipeline].builds.count).to eq(1)
        end

        it 'calls ensure_project_iid explicitly' do
          expect_next_instance_of(Ci::Pipeline) do |instance|
            expect(instance).to receive(:ensure_project_iid!).twice
          end
          subject
        end
      end

      before do
        project.add_maintainer(user)
      end

      context 'when web-ide has valid configuration' do
        before do
          stub_webide_config_file(config_content)
        end

        context 'for empty configuration' do
          let(:config_content) do
            'terminal: {}'
          end

          it_behaves_like 'be successful'
        end

        context 'for configuration with container image' do
          let(:config_content) do
            'terminal: { image: ruby }'
          end

          it_behaves_like 'be successful'
        end

        context 'for configuration with ports' do
          let(:config_content) do
            <<-EOS
              terminal:
                image:
                  name: image:1.0
                  ports:
                    - 80
                script: rspec
                services:
                  - name: test
                    alias: test
                    ports:
                      - 8080
            EOS
          end

          it_behaves_like 'be successful'
        end

        context 'for configuration with variables' do
          let(:config_content) do
            <<-EOS
              terminal:
                script: rspec
                variables:
                  KEY1: VAL1
            EOS
          end

          it_behaves_like 'be successful'

          it 'saves the variables' do
            expect(subject[:pipeline].builds[0].variables).to include(
              key: 'KEY1', value: 'VAL1', public: true, masked: false
            )
          end
        end
      end
    end

    context 'error handling' do
      shared_examples 'having an error' do |message|
        it 'returns an error' do
          is_expected.to eq(
            status: :error,
            message: message
          )
        end
      end

      shared_examples 'having insufficient permissions' do
        it_behaves_like 'having an error', 'Insufficient permissions to create a terminal'
      end

      context 'when user is developer' do
        before do
          project.add_developer(user)
        end

        it_behaves_like 'having insufficient permissions'
      end

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

        context 'when terminal is already running' do
          let!(:webide_pipeline) { create(:ci_pipeline, :webide, :running, project: project, user: user) }

          it_behaves_like 'having an error', 'There is already a terminal running'
        end

        context 'when ref is non-existing' do
          let(:ref) { 'non-existing-ref' }

          it_behaves_like 'having an error', 'Ref does not exist'
        end

        context 'when ref is a tag' do
          let(:ref) { 'v1.0.0' }

          it_behaves_like 'having an error', 'Ref needs to be a branch'
        end

        context 'when terminal config is missing' do
          let(:ref) { 'v1.0.0' }

          it_behaves_like 'having an error', 'Ref needs to be a branch'
        end

        context 'when webide config is present' do
          before do
            stub_webide_config_file(config_content)
          end

          context 'config has invalid content' do
            let(:config_content) { 'invalid' }

            it_behaves_like 'having an error', 'Invalid configuration format'
          end

          context 'config is valid, but does not have terminal' do
            let(:config_content) { '{}' }

            it_behaves_like 'having an error', 'Terminal is not configured'
          end
        end
      end
    end
  end
end