BigW Consortium Gitlab

snippets_controller_spec.rb 17.2 KB
Newer Older
1 2 3
require 'spec_helper'

describe SnippetsController do
4
  let(:user) { create(:user) }
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
  describe 'GET #index' do
    let(:user) { create(:user) }

    context 'when username parameter is present' do
      it 'renders snippets of a user when username is present' do
        get :index, username: user.username

        expect(response).to render_template(:index)
      end
    end

    context 'when username parameter is not present' do
      it 'redirects to explore snippets page when user is not logged in' do
        get :index

        expect(response).to redirect_to(explore_snippets_path)
      end

      it 'redirects to snippets dashboard page when user is logged in' do
        sign_in(user)

        get :index

        expect(response).to redirect_to(dashboard_snippets_path)
      end
    end
  end

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
  describe 'GET #new' do
    context 'when signed in' do
      before do
        sign_in(user)
      end

      it 'responds with status 200' do
        get :new

        expect(response).to have_http_status(200)
      end
    end

    context 'when not signed in' do
      it 'redirects to the sign in page' do
        get :new

        expect(response).to redirect_to(new_user_session_path)
      end
    end
  end

56
  describe 'GET #show' do
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    context 'when the personal snippet is private' do
      let(:personal_snippet) { create(:personal_snippet, :private, author: user) }

      context 'when signed in' do
        before do
          sign_in(user)
        end

        context 'when signed in user is not the author' do
          let(:other_author) { create(:author) }
          let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) }

          it 'responds with status 404' do
            get :show, id: other_personal_snippet.to_param

72
            expect(response).to have_http_status(404)
73 74 75 76 77 78 79 80
          end
        end

        context 'when signed in user is the author' do
          it 'renders the snippet' do
            get :show, id: personal_snippet.to_param

            expect(assigns(:snippet)).to eq(personal_snippet)
81
            expect(response).to have_http_status(200)
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
          end
        end
      end

      context 'when not signed in' do
        it 'redirects to the sign in page' do
          get :show, id: personal_snippet.to_param

          expect(response).to redirect_to(new_user_session_path)
        end
      end
    end

    context 'when the personal snippet is internal' do
      let(:personal_snippet) { create(:personal_snippet, :internal, author: user) }

      context 'when signed in' do
        before do
          sign_in(user)
        end

        it 'renders the snippet' do
          get :show, id: personal_snippet.to_param

          expect(assigns(:snippet)).to eq(personal_snippet)
107
          expect(response).to have_http_status(200)
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
        end
      end

      context 'when not signed in' do
        it 'redirects to the sign in page' do
          get :show, id: personal_snippet.to_param

          expect(response).to redirect_to(new_user_session_path)
        end
      end
    end

    context 'when the personal snippet is public' do
      let(:personal_snippet) { create(:personal_snippet, :public, author: user) }

      context 'when signed in' do
        before do
          sign_in(user)
        end

        it 'renders the snippet' do
          get :show, id: personal_snippet.to_param

          expect(assigns(:snippet)).to eq(personal_snippet)
132
          expect(response).to have_http_status(200)
133 134 135 136 137 138 139 140
        end
      end

      context 'when not signed in' do
        it 'renders the snippet' do
          get :show, id: personal_snippet.to_param

          expect(assigns(:snippet)).to eq(personal_snippet)
141
          expect(response).to have_http_status(200)
142 143 144 145 146 147 148 149 150 151 152 153 154
        end
      end
    end

    context 'when the personal snippet does not exist' do
      context 'when signed in' do
        before do
          sign_in(user)
        end

        it 'responds with status 404' do
          get :show, id: 'doesntexist'

155
          expect(response).to have_http_status(404)
156 157 158 159 160 161 162
        end
      end

      context 'when not signed in' do
        it 'responds with status 404' do
          get :show, id: 'doesntexist'

163
          expect(response).to redirect_to(new_user_session_path)
164 165 166 167
        end
      end
    end
  end
168

169
  describe 'POST #create' do
170
    def create_snippet(snippet_params = {}, additional_params = {})
171 172 173
      sign_in(user)

      post :create, {
174
        personal_snippet: { title: 'Title', content: 'Content', description: 'Description' }.merge(snippet_params)
175 176 177
      }.merge(additional_params)

      Snippet.last
178 179
    end

180 181 182 183 184 185 186 187 188
    it 'creates the snippet correctly' do
      snippet = create_snippet(visibility_level: Snippet::PRIVATE)

      expect(snippet.title).to eq('Title')
      expect(snippet.content).to eq('Content')
      expect(snippet.description).to eq('Description')
    end

    context 'when the snippet description contains a file' do
189 190
      let(:picture_file) { '/-/system/temp/secret56/picture.jpg' }
      let(:text_file) { '/-/system/temp/secret78/text.txt' }
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
      let(:description) do
        "Description with picture: ![picture](/uploads#{picture_file}) and "\
        "text: [text.txt](/uploads#{text_file})"
      end

      before do
        allow(FileUtils).to receive(:mkdir_p)
        allow(FileUtils).to receive(:move)
      end

      subject { create_snippet({ description: description }, { files: [picture_file, text_file] }) }

      it 'creates the snippet' do
        expect { subject }.to change { Snippet.count }.by(1)
      end

      it 'stores the snippet description correctly' do
        snippet = subject

        expected_description = "Description with picture: "\
211 212
          "![picture](/uploads/-/system/personal_snippet/#{snippet.id}/secret56/picture.jpg) and "\
          "text: [text.txt](/uploads/-/system/personal_snippet/#{snippet.id}/secret78/text.txt)"
213 214 215 216 217

        expect(snippet.description).to eq(expected_description)
      end
    end

218 219 220 221 222 223 224
    context 'when the snippet is spam' do
      before do
        allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true)
      end

      context 'when the snippet is private' do
        it 'creates the snippet' do
225 226
          expect { create_snippet(visibility_level: Snippet::PRIVATE) }
            .to change { Snippet.count }.by(1)
227 228 229 230 231
        end
      end

      context 'when the snippet is public' do
        it 'rejects the shippet' do
232 233
          expect { create_snippet(visibility_level: Snippet::PUBLIC) }
            .not_to change { Snippet.count }
234 235 236
        end

        it 'creates a spam log' do
237 238
          expect { create_snippet(visibility_level: Snippet::PUBLIC) }
            .to change { SpamLog.count }.by(1)
239
        end
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275

        it 'renders :new with recaptcha disabled' do
          stub_application_setting(recaptcha_enabled: false)

          create_snippet(visibility_level: Snippet::PUBLIC)

          expect(response).to render_template(:new)
        end

        context 'recaptcha enabled' do
          before do
            stub_application_setting(recaptcha_enabled: true)
          end

          it 'renders :verify with recaptcha enabled' do
            create_snippet(visibility_level: Snippet::PUBLIC)

            expect(response).to render_template(:verify)
          end

          it 'renders snippet page when recaptcha verified' do
            spammy_title = 'Whatever'

            spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title)
            snippet = create_snippet({ title: spammy_title },
                                     { spam_log_id: spam_logs.last.id,
                                       recaptcha_verification: true })

            expect(response).to redirect_to(snippet_path(snippet))
          end
        end
      end
    end
  end

  describe 'PUT #update' do
276
    let(:project) { create :project }
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
    let(:snippet) { create :personal_snippet, author: user, project: project, visibility_level: visibility_level }

    def update_snippet(snippet_params = {}, additional_params = {})
      sign_in(user)

      put :update, {
        id: snippet.id,
        personal_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params)
      }.merge(additional_params)

      snippet.reload
    end

    context 'when the snippet is spam' do
      before do
        allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true)
      end

      context 'when the snippet is private' do
        let(:visibility_level) { Snippet::PRIVATE }

        it 'updates the snippet' do
299 300
          expect { update_snippet(title: 'Foo') }
            .to change { snippet.reload.title }.to('Foo')
301 302 303 304 305 306 307
        end
      end

      context 'when a private snippet is made public' do
        let(:visibility_level) { Snippet::PRIVATE }

        it 'rejects the snippet' do
308 309
          expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
            .not_to change { snippet.reload.title }
310 311 312
        end

        it 'creates a spam log' do
313 314
          expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
            .to change { SpamLog.count }.by(1)
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
        end

        it 'renders :edit with recaptcha disabled' do
          stub_application_setting(recaptcha_enabled: false)

          update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC)

          expect(response).to render_template(:edit)
        end

        context 'recaptcha enabled' do
          before do
            stub_application_setting(recaptcha_enabled: true)
          end

          it 'renders :verify with recaptcha enabled' do
            update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC)

            expect(response).to render_template(:verify)
          end

          it 'renders snippet page when recaptcha verified' do
            spammy_title = 'Whatever'

            spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title)
            snippet = update_snippet({ title: spammy_title, visibility_level: Snippet::PUBLIC },
                                     { spam_log_id: spam_logs.last.id,
                                       recaptcha_verification: true })

344
            expect(response).to redirect_to(snippet_path(snippet))
345 346 347 348 349 350 351 352
          end
        end
      end

      context 'when the snippet is public' do
        let(:visibility_level) { Snippet::PUBLIC }

        it 'rejects the shippet' do
353 354
          expect { update_snippet(title: 'Foo') }
            .not_to change { snippet.reload.title }
355 356 357
        end

        it 'creates a spam log' do
358 359
          expect { update_snippet(title: 'Foo') }
            .to change { SpamLog.count }.by(1)
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
        end

        it 'renders :edit with recaptcha disabled' do
          stub_application_setting(recaptcha_enabled: false)

          update_snippet(title: 'Foo')

          expect(response).to render_template(:edit)
        end

        context 'recaptcha enabled' do
          before do
            stub_application_setting(recaptcha_enabled: true)
          end

          it 'renders :verify with recaptcha enabled' do
            update_snippet(title: 'Foo')

            expect(response).to render_template(:verify)
          end

          it 'renders snippet page when recaptcha verified' do
            spammy_title = 'Whatever'

            spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title)
            snippet = update_snippet({ title: spammy_title },
                                     { spam_log_id: spam_logs.last.id,
                                       recaptcha_verification: true })

            expect(response).to redirect_to(snippet_path(snippet))
          end
        end
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
      end
    end
  end

  describe 'POST #mark_as_spam' do
    let(:snippet) { create(:personal_snippet, :public, author: user) }

    before do
      allow_any_instance_of(AkismetService).to receive_messages(submit_spam: true)
      stub_application_setting(akismet_enabled: true)
    end

    def mark_as_spam
      admin = create(:admin)
      create(:user_agent_detail, subject: snippet)
      sign_in(admin)

      post :mark_as_spam, id: snippet.id
    end

    it 'updates the snippet' do
      mark_as_spam

      expect(snippet.reload).not_to be_submittable_as_spam
    end
  end

419 420 421
  describe "GET #raw" do
    context 'when the personal snippet is private' do
      let(:personal_snippet) { create(:personal_snippet, :private, author: user) }
422

423 424 425 426
      context 'when signed in' do
        before do
          sign_in(user)
        end
427

428 429 430
        context 'when signed in user is not the author' do
          let(:other_author) { create(:author) }
          let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) }
431

432 433
          it 'responds with status 404' do
            get :raw, id: other_personal_snippet.to_param
434

435
            expect(response).to have_http_status(404)
436
          end
437
        end
438

439
        context 'when signed in user is the author' do
440 441 442
          before do
            get :raw, id: personal_snippet.to_param
          end
443

444 445 446 447
          it 'responds with status 200' do
            expect(assigns(:snippet)).to eq(personal_snippet)
            expect(response).to have_http_status(200)
          end
448

449 450
          it 'has expected headers' do
            expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
451

452
            expect(response.header['Content-Disposition']).to match(/inline/)
453 454
          end
        end
455
      end
456

457 458 459
      context 'when not signed in' do
        it 'redirects to the sign in page' do
          get :raw, id: personal_snippet.to_param
460

461
          expect(response).to redirect_to(new_user_session_path)
462 463
        end
      end
464
    end
465

466 467
    context 'when the personal snippet is internal' do
      let(:personal_snippet) { create(:personal_snippet, :internal, author: user) }
468

469 470 471 472
      context 'when signed in' do
        before do
          sign_in(user)
        end
473

474 475
        it 'responds with status 200' do
          get :raw, id: personal_snippet.to_param
476

477 478
          expect(assigns(:snippet)).to eq(personal_snippet)
          expect(response).to have_http_status(200)
479
        end
480
      end
481

482 483 484
      context 'when not signed in' do
        it 'redirects to the sign in page' do
          get :raw, id: personal_snippet.to_param
485

486
          expect(response).to redirect_to(new_user_session_path)
487 488
        end
      end
489
    end
490

491 492
    context 'when the personal snippet is public' do
      let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
493

494 495 496 497
      context 'when signed in' do
        before do
          sign_in(user)
        end
498

499 500
        it 'responds with status 200' do
          get :raw, id: personal_snippet.to_param
501

502 503 504
          expect(assigns(:snippet)).to eq(personal_snippet)
          expect(response).to have_http_status(200)
        end
505

506 507 508 509
        context 'CRLF line ending' do
          let(:personal_snippet) do
            create(:personal_snippet, :public, author: user, content: "first line\r\nsecond line\r\nthird line")
          end
510

511 512
          it 'returns LF line endings by default' do
            get :raw, id: personal_snippet.to_param
513

514 515
            expect(response.body).to eq("first line\nsecond line\nthird line")
          end
516

517 518
          it 'does not convert line endings when parameter present' do
            get :raw, id: personal_snippet.to_param, line_ending: :raw
519

520
            expect(response.body).to eq("first line\r\nsecond line\r\nthird line")
521
          end
522
        end
523
      end
524

525 526 527
      context 'when not signed in' do
        it 'responds with status 200' do
          get :raw, id: personal_snippet.to_param
528

529 530
          expect(assigns(:snippet)).to eq(personal_snippet)
          expect(response).to have_http_status(200)
531 532
        end
      end
533
    end
534

535 536 537 538 539
    context 'when the personal snippet does not exist' do
      context 'when signed in' do
        before do
          sign_in(user)
        end
540

541 542
        it 'responds with status 404' do
          get :raw, id: 'doesntexist'
543

544
          expect(response).to have_http_status(404)
545
        end
546
      end
547

548
      context 'when not signed in' do
549
        it 'redirects to the sign in path' do
550
          get :raw, id: 'doesntexist'
551

552
          expect(response).to redirect_to(new_user_session_path)
553 554 555 556
        end
      end
    end
  end
557 558

  context 'award emoji on snippets' do
559 560
    let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
    let(:another_user) { create(:user) }
561 562

    before do
563
      sign_in(another_user)
564 565 566 567 568 569
    end

    describe 'POST #toggle_award_emoji' do
      it "toggles the award emoji" do
        expect do
          post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup")
570
        end.to change { personal_snippet.award_emoji.count }.from(0).to(1)
571 572 573 574 575 576

        expect(response.status).to eq(200)
      end

      it "removes the already awarded emoji" do
        post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup")
577

578 579
        expect do
          post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup")
580
        end.to change { personal_snippet.award_emoji.count }.from(1).to(0)
581 582 583 584 585

        expect(response.status).to eq(200)
      end
    end
  end
586 587 588 589 590 591 592 593 594 595 596 597

  describe 'POST #preview_markdown' do
    let(:snippet) { create(:personal_snippet, :public) }

    it 'renders json in a correct format' do
      sign_in(user)

      post :preview_markdown, id: snippet, text: '*Markdown* text'

      expect(JSON.parse(response.body).keys).to match_array(%w(body references))
    end
  end
598
end