summaryrefslogtreecommitdiff
path: root/spec/requests/api/markdown_spec.rb
blob: e369c1435f08f349de20b9b05e98de241e566c11 (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
require "spec_helper"

describe API::Markdown do
  RSpec::Matchers.define_negated_matcher :exclude, :include

  describe "POST /markdown" do
    let(:user) {} # No-op. It gets overwritten in the contexts below.

    before do
      post api("/markdown", user), params
    end

    shared_examples "rendered markdown text without GFM" do
      it "renders markdown text" do
        expect(response).to have_http_status(201)
        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 "responses with 404 Not Found" do
        expect(response).to have_http_status(404)
        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

    context "when arguments are invalid" do
      context "when text is missing" do
        let(:params) { {} }

        it "responses with 400 Bad Request" do
          expect(response).to have_http_status(400)
          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 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
      set(:project) { create(:project) }
      set(:issue) { create(:issue, project: project) }
      let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }

      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.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_http_status(201)
            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=\"#{IssuesHelper.url_for_issue(issue.iid, project)}\"")
                                        .and exclude("#1</a>")
          end
        end

        context "with project" do
          let(:params) { { text: text, gfm: true, project: project.full_path } }
          let(:user) { project.owner }

          it "renders markdown text" do
            expect(response).to have_http_status(201)
            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=\"#{IssuesHelper.url_for_issue(issue.iid, project)}\"")
                                        .and include("#1</a>")
          end
        end

        context 'with a public project and confidential issue' do
          let(:public_project)     { create(:project, :public) }
          let(:confidential_issue) { create(:issue, :confidential, project: public_project, title: 'Confidential title') }

          let(:text)   { ":tada: Hello world! :100: #{confidential_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_http_status(201)
              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) { }

            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) { confidential_issue.author }

            it 'renders the title or link' do
              expect(response).to have_http_status(201)
              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=\"#{IssuesHelper.url_for_issue(confidential_issue.iid, public_project)}\"")
                                          .and include("#1</a>")
            end
          end
        end
      end
    end
  end
end