1# frozen_string_literal: true
2
3require 'spec_helper'
4
5RSpec.describe PreviewMarkdownService do
6  let(:user) { create(:user) }
7  let(:project) { create(:project, :repository) }
8
9  before do
10    project.add_developer(user)
11  end
12
13  describe 'user references' do
14    let(:params) { { text: "Take a look #{user.to_reference}" } }
15    let(:service) { described_class.new(project, user, params) }
16
17    it 'returns users referenced in text' do
18      result = service.execute
19
20      expect(result[:users]).to eq [user.username]
21    end
22  end
23
24  describe 'suggestions' do
25    let(:merge_request) do
26      create(:merge_request, target_project: project, source_project: project)
27    end
28
29    let(:text) { "```suggestion\nfoo\n```" }
30    let(:params) do
31      suggestion_params.merge(text: text,
32                              target_type: 'MergeRequest',
33                              target_id: merge_request.iid)
34    end
35
36    let(:service) { described_class.new(project, user, params) }
37
38    context 'when preview markdown param is present' do
39      let(:path) { "files/ruby/popen.rb" }
40      let(:line) { 10 }
41      let(:diff_refs) { merge_request.diff_refs }
42
43      let(:suggestion_params) do
44        {
45          preview_suggestions: true,
46          file_path: path,
47          line: line,
48          base_sha: diff_refs.base_sha,
49          start_sha: diff_refs.start_sha,
50          head_sha: diff_refs.head_sha
51        }
52      end
53
54      it 'returns suggestions referenced in text' do
55        position = Gitlab::Diff::Position.new(new_path: path,
56                                              new_line: line,
57                                              diff_refs: diff_refs)
58
59        expect(Gitlab::Diff::SuggestionsParser)
60          .to receive(:parse)
61          .with(text, position: position,
62                      project: merge_request.project,
63                      supports_suggestion: true)
64          .and_call_original
65
66        result = service.execute
67
68        expect(result[:suggestions]).to all(be_a(Gitlab::Diff::Suggestion))
69      end
70
71      context 'when user is not authorized' do
72        let(:another_user) { create(:user) }
73        let(:service) { described_class.new(project, another_user, params) }
74
75        before do
76          project.add_guest(another_user)
77        end
78
79        it 'returns no suggestions' do
80          result = service.execute
81
82          expect(result[:suggestions]).to be_empty
83        end
84      end
85    end
86
87    context 'when preview markdown param is not present' do
88      let(:suggestion_params) do
89        {
90          preview_suggestions: false
91        }
92      end
93
94      it 'returns suggestions referenced in text' do
95        result = service.execute
96
97        expect(result[:suggestions]).to eq([])
98      end
99    end
100  end
101
102  context 'new note with quick actions' do
103    let(:issue) { create(:issue, project: project) }
104    let(:params) do
105      {
106        text: "Please do it\n/assign #{user.to_reference}",
107        target_type: 'Issue',
108        target_id: issue.id
109      }
110    end
111
112    let(:service) { described_class.new(project, user, params) }
113
114    it 'removes quick actions from text' do
115      result = service.execute
116
117      expect(result[:text]).to eq 'Please do it'
118    end
119
120    it 'explains quick actions effect' do
121      result = service.execute
122
123      expect(result[:commands]).to eq "Assigns #{user.to_reference}."
124    end
125  end
126
127  context 'merge request description' do
128    let(:params) do
129      {
130        text: "My work\n/estimate 2y",
131        target_type: 'MergeRequest'
132      }
133    end
134
135    let(:service) { described_class.new(project, user, params) }
136
137    it 'removes quick actions from text' do
138      result = service.execute
139
140      expect(result[:text]).to eq 'My work'
141    end
142
143    it 'explains quick actions effect' do
144      result = service.execute
145
146      expect(result[:commands]).to eq 'Sets time estimate to 2y.'
147    end
148  end
149
150  context 'commit description' do
151    let(:project) { create(:project, :repository) }
152    let(:commit) { project.commit }
153    let(:params) do
154      {
155        text: "My work\n/tag v1.2.3 Stable release",
156        target_type: 'Commit',
157        target_id: commit.id
158      }
159    end
160
161    let(:service) { described_class.new(project, user, params) }
162
163    it 'removes quick actions from text' do
164      result = service.execute
165
166      expect(result[:text]).to eq 'My work'
167    end
168
169    it 'explains quick actions effect' do
170      result = service.execute
171
172      expect(result[:commands]).to eq 'Tags this commit to v1.2.3 with "Stable release".'
173    end
174  end
175end
176