Commit cc4cc764 authored by Patrick Bajao's avatar Patrick Bajao

Merge branch '357229-return-sorted-labels-in-mutation-responses' into 'master'

Reset labels after issuables updates

See merge request gitlab-org/gitlab!83946
parents 8d34ff01 0128b699
...@@ -539,6 +539,9 @@ class IssuableBaseService < ::BaseProjectService ...@@ -539,6 +539,9 @@ class IssuableBaseService < ::BaseProjectService
def handle_label_changes(issuable, old_labels) def handle_label_changes(issuable, old_labels)
return unless has_label_changes?(issuable, old_labels) return unless has_label_changes?(issuable, old_labels)
# reset to preserve the label sort order (title ASC)
issuable.labels.reset
GraphqlTriggers.issuable_labels_updated(issuable) GraphqlTriggers.issuable_labels_updated(issuable)
end end
......
...@@ -8,9 +8,9 @@ RSpec.describe Mutations::Epics::Update do ...@@ -8,9 +8,9 @@ RSpec.describe Mutations::Epics::Update do
let_it_be(:current_user) { create(:user) } let_it_be(:current_user) { create(:user) }
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let(:label_1) { create(:group_label, group: group) } let(:label_1) { create(:group_label, title: "a", group: group) }
let(:label_2) { create(:group_label, group: group) } let(:label_2) { create(:group_label, title: "b", group: group) }
let(:label_3) { create(:group_label, group: group) } let(:label_3) { create(:group_label, title: "c", group: group) }
let(:epic) { create(:epic, group: group, title: 'original title', labels: [label_2]) } let(:epic) { create(:epic, group: group, title: 'original title', labels: [label_2]) }
let(:attributes) do let(:attributes) do
...@@ -25,9 +25,8 @@ RSpec.describe Mutations::Epics::Update do ...@@ -25,9 +25,8 @@ RSpec.describe Mutations::Epics::Update do
} }
end end
let(:params) { { group_path: group.full_path, iid: epic.iid.to_s }.merge(attributes) }
let(:mutation) do let(:mutation) do
params = { group_path: group.full_path, iid: epic.iid.to_s }.merge(attributes)
graphql_mutation(:update_epic, params) graphql_mutation(:update_epic, params)
end end
...@@ -106,12 +105,39 @@ RSpec.describe Mutations::Epics::Update do ...@@ -106,12 +105,39 @@ RSpec.describe Mutations::Epics::Update do
context 'when changing labels of the epic' do context 'when changing labels of the epic' do
let(:attributes) { { add_label_ids: [label_1.id, label_3.id], remove_label_ids: label_2.id } } let(:attributes) { { add_label_ids: [label_1.id, label_3.id], remove_label_ids: label_2.id } }
let(:mutation) do
graphql_mutation(:update_epic, params) do
<<~QL
epic {
labels {
nodes {
id
}
}
}
errors
QL
end
end
it 'adds and removes labels correctly' do it 'adds and removes labels correctly' do
post_graphql_mutation(mutation, current_user: current_user) post_graphql_mutation(mutation, current_user: current_user)
expect(epic.reload.labels).to match_array([label_1, label_3]) expect(epic.reload.labels).to match_array([label_1, label_3])
end end
context 'when labels are added' do
let(:attributes) { { add_label_ids: [label_1.id, label_3.id] } }
it 'adds labels correctly and keeps the title ordering' do
post_graphql_mutation(mutation, current_user: current_user)
labels_ids = mutation_response['epic']['labels']['nodes'].map { |l| l['id'] }
expected_label_ids = [label_1, label_2, label_3].map { |l| l.to_global_id.to_s }
expect(labels_ids).to eq(expected_label_ids)
end
end
end end
context 'when there are ActiveRecord validation errors' do context 'when there are ActiveRecord validation errors' do
......
...@@ -537,11 +537,14 @@ RSpec.describe Epics::UpdateService do ...@@ -537,11 +537,14 @@ RSpec.describe Epics::UpdateService do
let(:parent) { group } let(:parent) { group }
end end
it_behaves_like 'broadcasting issuable labels updates' do context 'labels are updated' do
let(:label_a) { create(:group_label, group: group) } let(:label_a) { create(:group_label, title: 'a', group: group) }
let(:label_b) { create(:group_label, group: group) } let(:label_b) { create(:group_label, title: 'b', group: group) }
let(:issuable) { epic } let(:issuable) { epic }
it_behaves_like 'keeps issuable labels sorted after update'
it_behaves_like 'broadcasting issuable labels updates'
def update_issuable(update_params) def update_issuable(update_params)
update_epic(update_params) update_epic(update_params)
end end
......
...@@ -8,8 +8,8 @@ RSpec.describe 'Update of an existing issue' do ...@@ -8,8 +8,8 @@ RSpec.describe 'Update of an existing issue' do
let_it_be(:current_user) { create(:user) } let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project, :public) } let_it_be(:project) { create(:project, :public) }
let_it_be(:issue) { create(:issue, project: project) } let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:label1) { create(:label, project: project) } let_it_be(:label1) { create(:label, title: "a", project: project) }
let_it_be(:label2) { create(:label, project: project) } let_it_be(:label2) { create(:label, title: "b", project: project) }
let(:input) do let(:input) do
{ {
...@@ -124,7 +124,7 @@ RSpec.describe 'Update of an existing issue' do ...@@ -124,7 +124,7 @@ RSpec.describe 'Update of an existing issue' do
context 'add and remove labels' do context 'add and remove labels' do
let(:input_params) { input.merge(extra_params).merge({ addLabelIds: [label1.id], removeLabelIds: [label2.id] }) } let(:input_params) { input.merge(extra_params).merge({ addLabelIds: [label1.id], removeLabelIds: [label2.id] }) }
it 'returns error for mutually exclusive arguments' do it 'returns correct labels' do
post_graphql_mutation(mutation, current_user: current_user) post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success) expect(response).to have_gitlab_http_status(:success)
...@@ -132,6 +132,22 @@ RSpec.describe 'Update of an existing issue' do ...@@ -132,6 +132,22 @@ RSpec.describe 'Update of an existing issue' do
expect(mutation_response['issue']['labels']).to include({ "nodes" => [{ "id" => label1.to_global_id.to_s }] }) expect(mutation_response['issue']['labels']).to include({ "nodes" => [{ "id" => label1.to_global_id.to_s }] })
end end
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 end
end end
...@@ -8,8 +8,8 @@ RSpec.describe 'Setting labels of a merge request' do ...@@ -8,8 +8,8 @@ RSpec.describe 'Setting labels of a merge request' do
let(:current_user) { create(:user) } let(:current_user) { create(:user) }
let(:merge_request) { create(:merge_request) } let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.project } let(:project) { merge_request.project }
let(:label) { create(:label, project: project) } let(:label) { create(:label, title: "a", project: project) }
let(:label2) { create(:label, project: project) } let(:label2) { create(:label, title: "b", project: project) }
let(:input) { { label_ids: [GitlabSchema.id_from_object(label).to_s] } } let(:input) { { label_ids: [GitlabSchema.id_from_object(label).to_s] } }
let(:mutation) do let(:mutation) do
...@@ -81,12 +81,12 @@ RSpec.describe 'Setting labels of a merge request' do ...@@ -81,12 +81,12 @@ RSpec.describe 'Setting labels of a merge request' do
merge_request.update!(labels: [label2]) merge_request.update!(labels: [label2])
end end
it 'sets the labels, without removing others' do it 'sets the labels and resets labels to keep the title ordering, without removing others' do
post_graphql_mutation(mutation, current_user: current_user) post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success) expect(response).to have_gitlab_http_status(:success)
expect(mutation_label_nodes.count).to eq(2) expect(mutation_label_nodes.count).to eq(2)
expect(mutation_label_nodes).to contain_exactly({ 'id' => label.to_global_id.to_s }, { 'id' => label2.to_global_id.to_s }) expect(mutation_label_nodes).to eq([{ 'id' => label.to_global_id.to_s }, { 'id' => label2.to_global_id.to_s }])
end end
end end
......
...@@ -9,8 +9,8 @@ RSpec.describe Issues::UpdateService, :mailer do ...@@ -9,8 +9,8 @@ RSpec.describe Issues::UpdateService, :mailer do
let_it_be(:guest) { create(:user) } let_it_be(:guest) { create(:user) }
let_it_be(:group) { create(:group, :public, :crm_enabled) } let_it_be(:group) { create(:group, :public, :crm_enabled) }
let_it_be(:project, reload: true) { create(:project, :repository, group: group) } let_it_be(:project, reload: true) { create(:project, :repository, group: group) }
let_it_be(:label) { create(:label, project: project) } let_it_be(:label) { create(:label, title: 'a', project: project) }
let_it_be(:label2) { create(:label, project: project) } let_it_be(:label2) { create(:label, title: 'b', project: project) }
let_it_be(:milestone) { create(:milestone, project: project) } let_it_be(:milestone) { create(:milestone, project: project) }
let(:issue) do let(:issue) do
...@@ -1361,11 +1361,14 @@ RSpec.describe Issues::UpdateService, :mailer do ...@@ -1361,11 +1361,14 @@ RSpec.describe Issues::UpdateService, :mailer do
end end
end end
it_behaves_like 'broadcasting issuable labels updates' do context 'labels are updated' do
let(:label_a) { label } let(:label_a) { label }
let(:label_b) { label2 } let(:label_b) { label2 }
let(:issuable) { issue } let(:issuable) { issue }
it_behaves_like 'keeps issuable labels sorted after update'
it_behaves_like 'broadcasting issuable labels updates'
def update_issuable(update_params) def update_issuable(update_params)
update_issue(update_params) update_issue(update_params)
end end
......
...@@ -10,7 +10,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer do ...@@ -10,7 +10,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:user2) { create(:user) } let(:user2) { create(:user) }
let(:user3) { create(:user) } let(:user3) { create(:user) }
let(:label) { create(:label, project: project) } let(:label) { create(:label, title: 'a', project: project) }
let(:label2) { create(:label) } let(:label2) { create(:label) }
let(:milestone) { create(:milestone, project: project) } let(:milestone) { create(:milestone, project: project) }
...@@ -1193,11 +1193,14 @@ RSpec.describe MergeRequests::UpdateService, :mailer do ...@@ -1193,11 +1193,14 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
let(:issuable) { described_class.new(project: project, current_user: user, params: params).execute(existing_merge_request) } let(:issuable) { described_class.new(project: project, current_user: user, params: params).execute(existing_merge_request) }
end end
it_behaves_like 'broadcasting issuable labels updates' do context 'labels are updated' do
let(:label_a) { label } let(:label_a) { label }
let(:label_b) { create(:label, project: project) } let(:label_b) { create(:label, title: 'b', project: project) }
let(:issuable) { merge_request } let(:issuable) { merge_request }
it_behaves_like 'keeps issuable labels sorted after update'
it_behaves_like 'broadcasting issuable labels updates'
def update_issuable(update_params) def update_issuable(update_params)
update_merge_request(update_params) update_merge_request(update_params)
end end
......
...@@ -24,6 +24,20 @@ RSpec.shared_examples 'issuable update service' do ...@@ -24,6 +24,20 @@ RSpec.shared_examples 'issuable update service' do
end end
end end
RSpec.shared_examples 'keeps issuable labels sorted after update' do
before do
update_issuable(label_ids: [label_b.id])
end
context 'when label is changed' do
it 'keeps the labels sorted by title ASC' do
update_issuable({ add_label_ids: [label_a.id] })
expect(issuable.labels).to eq([label_a, label_b])
end
end
end
RSpec.shared_examples 'broadcasting issuable labels updates' do RSpec.shared_examples 'broadcasting issuable labels updates' do
before do before do
update_issuable(label_ids: [label_a.id]) update_issuable(label_ids: [label_a.id])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment