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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
# frozen_string_literal: true
require "spec_helper"
RSpec.describe API::Markdown, feature_category: :team_planning do
describe "POST /markdown" do
let(:user) {} # No-op. It gets overwritten in the contexts below.
let(:token) {} # No-op. It gets overwritten in the contexts below.
let(:disable_authenticate_markdown_api) { false }
before do
stub_commonmark_sourcepos_disabled
stub_feature_flags(authenticate_markdown_api: false) if disable_authenticate_markdown_api
if token
post api("/markdown", personal_access_token: token), params: params
else
post api("/markdown", user), params: params
end
end
shared_examples "rendered markdown text without GFM" do
it "renders markdown text" do
expect(response).to have_gitlab_http_status(:created)
expect(response.headers["Content-Type"]).to eq("application/json")
expect(json_response).to be_a(Hash)
expect(json_response["html"]).to eq("<p>#{text}</p>")
end
end
shared_examples '404 Project Not Found' do
it 'responds with 404 Not Found' do
expect(response).to have_gitlab_http_status(:not_found)
expect(response.headers["Content-Type"]).to eq("application/json")
expect(json_response).to be_a(Hash)
expect(json_response['message']).to eq('404 Project Not Found')
end
end
shared_examples '400 Bad Request' do
it 'responds with 400 Bad Request' do
expect(response).to have_gitlab_http_status(:bad_request)
expect(response.headers['Content-Type']).to eq('application/json')
expect(json_response).to be_a(Hash)
expect(json_response['error']).to eq('text is missing')
end
end
context 'when not logged in' do
let(:user) {}
let(:params) { {} }
context 'and authenticate_markdown_api turned on' do
it 'responds with 401 Unathorized' do
expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.headers['Content-Type']).to eq('application/json')
expect(json_response).to be_a(Hash)
expect(json_response['message']).to eq('401 Unauthorized')
end
end
context 'and authenticate_markdown_api turned off' do
let(:disable_authenticate_markdown_api) { true }
it_behaves_like '400 Bad Request'
end
end
context 'when arguments are invalid' do
let(:user) { create(:user) }
context 'when text is missing' do
let(:params) { {} }
it_behaves_like '400 Bad Request'
end
context "when project is not found" do
let(:params) { { text: "Hello world!", gfm: true, project: "Dummy project" } }
it_behaves_like "404 Project Not Found"
end
end
context "when arguments are valid" do
let_it_be(:project) { create(:project) }
let_it_be(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
let(:issue_url) { "http://#{Gitlab.config.gitlab.host}/#{issue.project.namespace.path}/#{issue.project.path}/-/issues/#{issue.iid}" }
let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }
context "when personal access token has only read_api scope" do
let(:token) { create(:personal_access_token, user: user, scopes: [:read_api]) }
let(:params) { { text: text } }
it_behaves_like "rendered markdown text without GFM"
end
context "when not using gfm" do
context "without project" do
let(:params) { { text: text } }
it_behaves_like "rendered markdown text without GFM"
end
context "with project" do
let(:params) { { text: text, project: project.full_path } }
context "when not authorized" do
it_behaves_like "404 Project Not Found"
end
context "when authorized" do
let(:user) { project.first_owner }
it_behaves_like "rendered markdown text without GFM"
end
end
end
context "when using gfm" do
context "without project" do
let(:params) { { text: text, gfm: true } }
it "renders markdown text" do
expect(response).to have_gitlab_http_status(:created)
expect(response.headers["Content-Type"]).to eq("application/json")
expect(json_response).to be_a(Hash)
expect(json_response["html"]).to include("Hello world!")
.and include('data-name="tada"')
.and include('data-name="100"')
.and include("#1")
.and exclude("<a href=\"#{issue_url}\"")
.and exclude("#1</a>")
end
end
context "with project" do
let(:params) { { text: text, gfm: true, project: project.full_path } }
let(:user) { project.first_owner }
it "renders markdown text" do
expect(response).to have_gitlab_http_status(:created)
expect(response.headers["Content-Type"]).to eq("application/json")
expect(json_response).to be_a(Hash)
expect(json_response["html"]).to include("Hello world!")
.and include('data-name="tada"')
.and include('data-name="100"')
.and include("<a href=\"#{issue_url}\"")
.and include("#1</a>")
end
end
context 'with a public project and confidential issue' do
let(:public_project) { create(:project, :public) }
let(:issue) { create(:issue, :confidential, project: public_project, title: 'Confidential title') }
let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }
let(:params) { { text: text, gfm: true, project: public_project.full_path } }
shared_examples 'user without proper access' do
it 'does not render the title or link' do
expect(response).to have_gitlab_http_status(:created)
expect(json_response["html"]).not_to include('Confidential title')
expect(json_response["html"]).not_to include('<a href=')
expect(json_response["html"]).to include('Hello world!')
.and include('data-name="tada"')
.and include('data-name="100"')
.and include('#1</p>')
end
end
context 'when not logged in' do
let(:user) {}
let(:disable_authenticate_markdown_api) { true }
it_behaves_like 'user without proper access'
end
context 'when logged in as user without access' do
it_behaves_like 'user without proper access'
end
context 'when logged in as author' do
let(:user) { issue.author }
it 'renders the title or link' do
expect(response).to have_gitlab_http_status(:created)
expect(json_response["html"]).to include('Confidential title')
expect(json_response["html"]).to include('Hello world!')
.and include('data-name="tada"')
.and include('data-name="100"')
.and include("<a href=\"#{issue_url}\"")
.and include("#1</a>")
end
end
end
context 'with a public project and issues only for team members' do
let(:public_project) do
create(:project, :public).tap do |project|
project.project_feature.update_attribute(:issues_access_level, ProjectFeature::PRIVATE)
end
end
let(:issue) { create(:issue, project: public_project, title: 'Team only title') }
let(:text) { issue.to_reference.to_s }
let(:params) { { text: text, gfm: true, project: public_project.full_path } }
shared_examples 'user without proper access' do
it 'does not render the title' do
expect(response).to have_gitlab_http_status(:created)
expect(json_response["html"]).not_to include('Team only title')
end
end
context 'when not logged in and authenticate_markdown_api turned off' do
let(:user) {}
let(:disable_authenticate_markdown_api) { true }
it_behaves_like 'user without proper access'
end
context 'when logged in as user without access' do
let(:user) { create(:user) }
it_behaves_like 'user without proper access'
end
context 'when logged in as author' do
let(:user) { issue.author }
it 'renders the title or link' do
expect(response).to have_gitlab_http_status(:created)
expect(json_response["html"]).to include('Team only title')
end
end
end
end
end
end
end
|