summaryrefslogtreecommitdiff
path: root/spec/serializers/suggestion_entity_spec.rb
blob: b133c3fb82e3160138f75e3f0f6a26e3aab9f008 (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
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe SuggestionEntity do
  include RepoHelpers

  let(:user) { create(:user) }
  let(:request) { double('request', current_user: user) }
  let(:suggestion) { create(:suggestion) }
  let(:entity) { described_class.new(suggestion, request: request) }

  subject { entity.as_json }

  it 'exposes correct attributes' do
    expect(subject.keys).to match_array([:id, :appliable, :applied, :diff_lines, :current_user, :inapplicable_reason])
  end

  it 'exposes current user abilities' do
    expect(subject[:current_user]).to include(:can_apply)
  end

  describe 'inapplicable_reason' do
    let(:inapplicable_reason) { subject[:inapplicable_reason] }

    before do
      allow(Ability).to receive(:allowed?).and_call_original

      allow(Ability)
        .to receive(:allowed?)
        .with(user, :apply_suggestion, suggestion)
        .and_return(can_apply_suggestion)
    end

    context 'when user can apply suggestion' do
      let(:can_apply_suggestion) { true }

      before do
        allow(suggestion).to receive(:appliable?).and_return(appliable)
      end

      context 'and suggestion is appliable' do
        let(:appliable) { true }

        it 'returns nil' do
          expect(inapplicable_reason).to be_nil
        end
      end

      context 'but suggestion is not applicable' do
        let(:appliable) { false }

        before do
          allow(suggestion).to receive(:inapplicable_reason).and_return(reason)
        end

        context 'and merge request was merged' do
          let(:reason) { :merge_request_merged }

          it 'returns appropriate message' do
            expect(inapplicable_reason).to eq("This merge request was merged. To apply this suggestion, edit this file directly.")
          end
        end

        context 'and source branch was deleted' do
          let(:reason) { :source_branch_deleted }

          it 'returns appropriate message' do
            expect(inapplicable_reason).to eq("Can't apply as the source branch was deleted.")
          end
        end

        context 'and merge request is closed' do
          let(:reason) { :merge_request_closed }

          it 'returns appropriate message' do
            expect(inapplicable_reason).to eq("This merge request is closed. To apply this suggestion, edit this file directly.")
          end
        end

        context 'and suggestion is outdated' do
          let(:reason) { :outdated }

          before do
            allow(suggestion).to receive(:single_line?).and_return(single_line)
          end

          context 'and suggestion is for a single line' do
            let(:single_line) { true }

            it 'returns appropriate message' do
              expect(inapplicable_reason).to eq("Can't apply as this line was changed in a more recent version.")
            end
          end

          context 'and suggestion is for multiple lines' do
            let(:single_line) { false }

            it 'returns appropriate message' do
              expect(inapplicable_reason).to eq("Can't apply as these lines were changed in a more recent version.")
            end
          end
        end

        context 'and suggestion has the same content' do
          let(:reason) { :same_content }

          it 'returns appropriate message' do
            expect(inapplicable_reason).to eq("This suggestion already matches its content.")
          end
        end

        context 'and suggestion is inapplicable for other reasons' do
          let(:reason) { :some_other_reason }

          it 'returns default message' do
            expect(inapplicable_reason).to eq("Can't apply this suggestion.")
          end
        end
      end
    end

    context 'when user cannot apply suggestion' do
      let(:can_apply_suggestion) { false }

      it 'returns appropriate message' do
        expect(inapplicable_reason).to eq("You don't have write access to the source branch.")
      end
    end
  end
end