summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/requests/snippet_shared_examples.rb
blob: a17163328f4b27250bc8897918a7aa12e9a395ec (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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# frozen_string_literal: true

RSpec.shared_examples 'update with repository actions' do
  context 'when the repository exists' do
    it 'commits the changes to the repository' do
      existing_blob = snippet.blobs.first
      new_file_name = existing_blob.path + '_new'
      new_content = 'New content'

      update_snippet(params: { content: new_content, file_name: new_file_name })

      aggregate_failures do
        expect(response).to have_gitlab_http_status(:ok)
        expect(snippet.repository.blob_at('master', existing_blob.path)).to be_nil

        blob = snippet.repository.blob_at('master', new_file_name)
        expect(blob).not_to be_nil
        expect(blob.data).to eq(new_content)
      end
    end
  end

  context 'when the repository does not exist' do
    let(:snippet) { snippet_without_repo }

    context 'when update attributes does not include file_name or content' do
      it 'does not create the repository' do
        update_snippet(snippet_id: snippet.id, params: { title: 'foo' })

        expect(snippet.repository).not_to exist
      end
    end

    context 'when update attributes include file_name or content' do
      it 'creates the repository' do
        update_snippet(snippet_id: snippet.id, params: { title: 'foo', file_name: 'foo' })

        expect(snippet.repository).to exist
      end

      it 'commits the file to the repository' do
        content = 'New Content'
        file_name = 'file_name.rb'

        update_snippet(snippet_id: snippet.id, params: { content: content, file_name: file_name })

        blob = snippet.repository.blob_at('master', file_name)
        expect(blob).not_to be_nil
        expect(blob.data).to eq content
      end

      context 'when save fails due to a repository creation error' do
        let(:content) { 'File content' }
        let(:file_name) { 'test.md' }

        before do
          allow_next_instance_of(Snippets::UpdateService) do |instance|
            allow(instance).to receive(:create_repository_for).with(snippet).and_raise(Snippets::UpdateService::CreateRepositoryError)
          end

          update_snippet(snippet_id: snippet.id, params: { content: content, file_name: file_name })
        end

        it 'returns 400' do
          expect(response).to have_gitlab_http_status(:bad_request)
        end

        it 'does not save the changes to the snippet object' do
          expect(snippet.content).not_to eq(content)
          expect(snippet.file_name).not_to eq(file_name)
        end
      end
    end
  end
end

RSpec.shared_examples 'snippet blob content' do
  it 'returns content from repository' do
    expect(Gitlab::Workhorse).to receive(:send_git_blob).and_call_original

    subject

    expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq 'true'
    expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
  end

  context 'when snippet repository is empty' do
    let(:snippet) { snippet_with_empty_repo }

    it 'returns content from database' do
      subject

      expect(response.body).to eq(snippet.content)
    end
  end
end

RSpec.shared_examples 'snippet_multiple_files feature disabled' do
  before do
    stub_feature_flags(snippet_multiple_files: false)

    subject
  end

  it 'does not return files attributes' do
    expect(json_response).not_to have_key('files')
  end
end

RSpec.shared_examples 'snippet creation with files parameter' do
  using RSpec::Parameterized::TableSyntax

  where(:path, :content, :status, :error) do
    '.gitattributes'      | 'file content' | :created     | nil
    'valid/path/file.rb'  | 'file content' | :created     | nil

    '.gitattributes'      | nil            | :bad_request | 'files[0][content] is empty'
    '.gitattributes'      | ''             | :bad_request | 'files[0][content] is empty'

    ''                    | 'file content' | :bad_request | 'files[0][file_path] is empty'
    nil                   | 'file content' | :bad_request | 'files[0][file_path] should be a valid file path, files[0][file_path] is empty'
    '../../etc/passwd'    | 'file content' | :bad_request | 'files[0][file_path] should be a valid file path'
  end

  with_them do
    let(:file_path)    { path }
    let(:file_content) { content }

    before do
      subject
    end

    it 'responds correctly' do
      expect(response).to have_gitlab_http_status(status)
      expect(json_response['error']).to eq(error)
    end
  end

  it 'returns 400 if both files and content are provided' do
    params[:file_name] = 'foo.rb'
    params[:content] = 'bar'

    subject

    expect(response).to have_gitlab_http_status(:bad_request)
    expect(json_response['error']).to eq 'files, content are mutually exclusive'
  end

  it 'returns 400 when neither files or content are provided' do
    params.delete(:files)

    subject

    expect(response).to have_gitlab_http_status(:bad_request)
    expect(json_response['error']).to eq 'files, content are missing, exactly one parameter must be provided'
  end
end

RSpec.shared_examples 'snippet creation without files parameter' do
  let(:file_params) { { file_name: 'testing.rb', content: 'snippet content' } }

  it 'allows file_name and content parameters' do
    subject

    expect(response).to have_gitlab_http_status(:created)
  end

  it 'returns 400 if file_name and content are not both provided' do
    params.delete(:file_name)

    subject

    expect(response).to have_gitlab_http_status(:bad_request)
    expect(json_response['error']).to eq 'file_name is missing'
  end

  it 'returns 400 if content is blank' do
    params[:content] = ''

    subject

    expect(response).to have_gitlab_http_status(:bad_request)
    expect(json_response['error']).to eq 'content is empty'
  end
end