summaryrefslogtreecommitdiff
path: root/spec/requests/api/graphql/mutations/issues/update_spec.rb
blob: f38deb426b1e472a456b200c35da2be95e44ebc7 (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
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Update of an existing issue' do
  include GraphqlHelpers

  let_it_be(:current_user) { create(:user) }
  let_it_be(:project) { create(:project, :public) }
  let_it_be(:issue) { create(:issue, project: project) }
  let_it_be(:label1) { create(:label, title: "a", project: project) }
  let_it_be(:label2) { create(:label, title: "b", project: project) }

  let(:input) do
    {
      'iid' => issue.iid.to_s,
      'title' => 'new title',
      'description' => 'new description',
      'confidential' => true,
      'dueDate' => Date.tomorrow.strftime('%Y-%m-%d'),
      'type' => 'ISSUE'
    }
  end

  let(:extra_params) { { project_path: project.full_path, locked: true } }
  let(:input_params) { input.merge(extra_params) }
  let(:mutation) { graphql_mutation(:update_issue, input_params) }
  let(:mutation_response) { graphql_mutation_response(:update_issue) }

  context 'the user is not allowed to update issue' do
    it_behaves_like 'a mutation that returns a top-level access error'
  end

  context 'when user has permissions to update issue' do
    before do
      project.add_developer(current_user)
    end

    it 'updates the issue' do
      post_graphql_mutation(mutation, current_user: current_user)

      expect(response).to have_gitlab_http_status(:success)
      expect(mutation_response['issue']).to include(input)
      expect(mutation_response['issue']).to include('discussionLocked' => true)
    end

    context 'when issue_type is updated' do
      let(:input) { { 'iid' => issue.iid.to_s, 'type' => 'INCIDENT' } }

      it 'updates issue_type and work_item_type' do
        expect do
          post_graphql_mutation(mutation, current_user: current_user)
          issue.reload
        end.to change { issue.work_item_type.base_type }.from('issue').to('incident').and(
          change(issue, :issue_type).from('issue').to('incident')
        )
      end
    end

    context 'setting labels' do
      let(:mutation) do
        graphql_mutation(:update_issue, input_params) do
          <<~QL
              issue {
                 labels {
                   nodes {
                     id
                   }
                 }
              }
              errors
          QL
        end
      end

      context 'reset labels' do
        let(:input_params) { input.merge(extra_params).merge({ labelIds: [label1.id, label2.id] }) }

        it 'resets labels' do
          post_graphql_mutation(mutation, current_user: current_user)

          expect(response).to have_gitlab_http_status(:success)
          expect(json_response['errors']).to be_nil
          expect(mutation_response['issue']['labels']).to include({ "nodes" => [{ "id" => label1.to_global_id.to_s }, { "id" => label2.to_global_id.to_s }] })
        end

        context 'reset labels and add labels' do
          let(:input_params) { input.merge(extra_params).merge({ labelIds: [label1.id], addLabelIds: [label2.id] }) }

          it 'returns error for mutually exclusive arguments' do
            post_graphql_mutation(mutation, current_user: current_user)

            expect(response).to have_gitlab_http_status(:success)
            expect(json_response['errors'].first['message']).to eq('labelIds is mutually exclusive with any of addLabelIds or removeLabelIds')
            expect(mutation_response).to be_nil
          end
        end

        context 'reset labels and remove labels' do
          let(:input_params) { input.merge(extra_params).merge({ labelIds: [label1.id], removeLabelIds: [label2.id] }) }

          it 'returns error for mutually exclusive arguments' do
            post_graphql_mutation(mutation, current_user: current_user)

            expect(response).to have_gitlab_http_status(:success)
            expect(json_response['errors'].first['message']).to eq('labelIds is mutually exclusive with any of addLabelIds or removeLabelIds')
            expect(mutation_response).to be_nil
          end
        end

        context 'with global label ids' do
          let(:input_params) { input.merge(extra_params).merge({ labelIds: [label1.to_global_id.to_s, label2.to_global_id.to_s] }) }

          it 'resets labels' do
            post_graphql_mutation(mutation, current_user: current_user)

            expect(response).to have_gitlab_http_status(:success)
            expect(json_response['errors']).to be_nil
            expect(mutation_response['issue']['labels']).to include({ "nodes" => [{ "id" => label1.to_global_id.to_s }, { "id" => label2.to_global_id.to_s }] })
          end
        end
      end

      context 'add and remove labels' do
        let(:input_params) { input.merge(extra_params).merge({ addLabelIds: [label1.id], removeLabelIds: [label2.id] }) }

        it 'returns correct labels' do
          post_graphql_mutation(mutation, current_user: current_user)

          expect(response).to have_gitlab_http_status(:success)
          expect(json_response['errors']).to be_nil
          expect(mutation_response['issue']['labels']).to include({ "nodes" => [{ "id" => label1.to_global_id.to_s }] })
        end
      end

      context 'add labels' do
        let(:input_params) { input.merge(extra_params).merge({ addLabelIds: [label1.id] }) }

        before do
          issue.update!({ labels: [label2] })
        end

        it 'adds labels and keeps the title ordering' do
          post_graphql_mutation(mutation, current_user: current_user)

          expect(response).to have_gitlab_http_status(:success)
          expect(json_response['errors']).to be_nil
          expect(mutation_response['issue']['labels']['nodes']).to eq([{ "id" => label1.to_global_id.to_s }, { "id" => label2.to_global_id.to_s }])
        end
      end
    end
  end
end