summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/services/issuable/discussions_list_shared_examples.rb
blob: c38ca6a3bf029dc6f82174ce03332a65fef128cb (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
# frozen_string_literal: true

RSpec.shared_examples 'listing issuable discussions' do |user_role, internal_discussion_count, total_discussions_count|
  before_all do
    create_notes(issuable, "some user comment")
  end

  context 'when user cannot read issue' do
    it "returns no notes" do
      expect(discussions_service.execute).to be_empty
    end
  end

  context 'when user can read issuable' do
    before do
      group.add_developer(current_user)
    end

    context 'with paginated results' do
      let(:finder_params_for_issuable) { { per_page: 2 } }
      let(:next_page_cursor) { { cursor: discussions_service.paginator.cursor_for_next_page } }

      it "returns next page notes" do
        next_page_discussions_service = described_class.new(current_user, issuable,
          finder_params_for_issuable.merge(next_page_cursor))
        discussions = next_page_discussions_service.execute

        expect(discussions.count).to eq(2)
        expect(discussions.first.notes.map(&:note)).to match_array(["added #{label.to_reference} label"])
        expect(discussions.second.notes.map(&:note)).to match_array(["removed #{label.to_reference} label"])
      end
    end

    # confidential notes are currently available only on issues and epics
    context 'and cannot read confidential notes' do
      before do
        group.add_member(current_user, user_role)
      end

      it "returns non confidential notes" do
        discussions = discussions_service.execute

        non_conf_discussion_count = total_discussions_count - internal_discussion_count
        expect(discussions.count).to eq(non_conf_discussion_count)
        expect(discussions.count { |disc| disc.notes.any?(&:confidential) }).to eq(0)
        expect(discussions.count { |disc| !disc.notes.any?(&:confidential) }).to eq(non_conf_discussion_count)
      end
    end

    # confidential notes are currently available only on issues and epics
    context 'and can read confidential notes' do
      it "returns all notes" do
        discussions = discussions_service.execute

        expect(discussions.count).to eq(total_discussions_count)
        expect(discussions.count { |disc| disc.notes.any?(&:confidential) }).to eq(internal_discussion_count)
        non_conf_discussion_count = total_discussions_count - internal_discussion_count
        expect(discussions.count { |disc| !disc.notes.any?(&:confidential) }).to eq(non_conf_discussion_count)
      end
    end

    context 'and system notes only' do
      let(:finder_params_for_issuable) { { notes_filter: UserPreference::NOTES_FILTERS[:only_activity] } }

      it "returns system notes" do
        discussions = discussions_service.execute

        expect(discussions.count { |disc| disc.notes.any?(&:system) }).to be > 0
        expect(discussions.count { |disc| !disc.notes.any?(&:system) }).to eq(0)
      end
    end

    context 'and user comments only' do
      let(:finder_params_for_issuable) { { notes_filter: UserPreference::NOTES_FILTERS[:only_comments] } }

      it "returns user comments" do
        discussions = discussions_service.execute

        expect(discussions.count { |disc| disc.notes.any?(&:system) }).to eq(0)
        expect(discussions.count { |disc| !disc.notes.any?(&:system) }).to be > 0
      end
    end
  end
end

def create_notes(issuable, note_body)
  assoc_name = issuable.to_ability_name

  create(:note, system: true, project: issuable.project, noteable: issuable)

  first_discussion = create(:discussion_note_on_issue, noteable: issuable, project: issuable.project, note: note_body)
  create(:note,
    discussion_id: first_discussion.discussion_id, noteable: issuable,
    project: issuable.project, note: "reply on #{note_body}")

  create(:resource_label_event, user: current_user, "#{assoc_name}": issuable, label: label, action: 'add')
  create(:resource_label_event, user: current_user, "#{assoc_name}": issuable, label: label, action: 'remove')

  unless issuable.is_a?(Epic)
    create(:resource_milestone_event, "#{assoc_name}": issuable, milestone: milestone, action: 'add')
    create(:resource_milestone_event, "#{assoc_name}": issuable, milestone: milestone, action: 'remove')
  end

  # confidential notes are currently available only on issues and epics
  return unless issuable.is_a?(Issue) || issuable.is_a?(Epic)

  first_internal_discussion = create(:discussion_note_on_issue, :confidential,
    noteable: issuable, project: issuable.project, note: "confidential #{note_body}")
  create(:note, :confidential,
    discussion_id: first_internal_discussion.discussion_id, noteable: issuable,
    project: issuable.project, note: "reply on confidential #{note_body}")
end