Fixes #3123: Merging Tickets/Users/... does not update ExternalSync references.
This commit is contained in:
parent
543b552298
commit
b49802a161
9 changed files with 147 additions and 0 deletions
|
@ -46,6 +46,15 @@ class ExternalSync < ApplicationModel
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def migrate(object, from_id, to_id)
|
||||||
|
where(
|
||||||
|
object: object,
|
||||||
|
o_id: from_id,
|
||||||
|
).update_all( # rubocop:disable Rails/SkipsModelValidations
|
||||||
|
o_id: to_id,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def extract(remote_key, structure)
|
def extract(remote_key, structure)
|
||||||
|
|
|
@ -356,6 +356,9 @@ returns
|
||||||
link_object_target_value: id
|
link_object_target_value: id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# external sync references
|
||||||
|
ExternalSync.migrate('Ticket', id, target_ticket.id)
|
||||||
|
|
||||||
# set state to 'merged'
|
# set state to 'merged'
|
||||||
self.state_id = Ticket::State.lookup(name: 'merged').id
|
self.state_id = Ticket::State.lookup(name: 'merged').id
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
class Issue3123ExternalSyncTicketMerge < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
|
||||||
|
# return if it's a new setup
|
||||||
|
return if !Setting.find_by(name: 'system_init_done')
|
||||||
|
|
||||||
|
merged_ticket_ids_with_external_sync.each do |id_from|
|
||||||
|
id_to = merged_ticket_ids_map[id_from]
|
||||||
|
ExternalSync.migrate('Ticket', id_from, id_to)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# reduce to the ones with an ExternalSync entry
|
||||||
|
def merged_ticket_ids_with_external_sync
|
||||||
|
@merged_ticket_ids_with_external_sync ||= ExternalSync.where(
|
||||||
|
object: 'Ticket',
|
||||||
|
o_id: merged_ticket_ids_map.keys,
|
||||||
|
).pluck(:o_id).uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
# get all merged tickets
|
||||||
|
def merged_ticket_ids_map
|
||||||
|
@merged_ticket_ids_map ||= History.where(
|
||||||
|
history_type_id: History.type_lookup('merged_into').id,
|
||||||
|
history_object_id: History.object_lookup('Ticket').id,
|
||||||
|
).pluck(:id_from, :id_to).to_h
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -266,6 +266,9 @@ returns
|
||||||
items_to_update.each_value(&:save!)
|
items_to_update.each_value(&:save!)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ExternalSync.migrate(object_name, object_id_primary, object_id_to_merge)
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
37
spec/db/migrate/issue3123_external_sync_ticket_merge_spec.rb
Normal file
37
spec/db/migrate/issue3123_external_sync_ticket_merge_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Issue3123ExternalSyncTicketMerge, type: :db_migration do
|
||||||
|
|
||||||
|
let(:user) { create(:agent) }
|
||||||
|
let(:source_ticket) { create(:ticket) }
|
||||||
|
let(:target_ticket) { create(:ticket) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
source_ticket.merge_to(
|
||||||
|
ticket_id: target_ticket.id,
|
||||||
|
user_id: user.id,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when no ExternalSync entries' do
|
||||||
|
|
||||||
|
it "doesn't send ExternalSync.migrate" do
|
||||||
|
allow(ExternalSync).to receive(:migrate)
|
||||||
|
migrate
|
||||||
|
expect(ExternalSync).not_to have_received(:migrate)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when ExternalSync entries present' do
|
||||||
|
|
||||||
|
before do
|
||||||
|
create(:external_sync, object: 'Ticket', o_id: source_ticket.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends ExternalSync.migrate' do
|
||||||
|
allow(ExternalSync).to receive(:migrate)
|
||||||
|
migrate
|
||||||
|
expect(ExternalSync).to have_received(:migrate).with('Ticket', source_ticket.id, target_ticket.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,14 @@
|
||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :external_sync do
|
factory :external_sync do
|
||||||
|
source { 'Some3rdPartyService' }
|
||||||
|
source_id { SecureRandom.uuid }
|
||||||
|
object { 'Ticket' }
|
||||||
|
o_id { 1 }
|
||||||
|
|
||||||
|
# https://github.com/thoughtbot/factory_bot/issues/1142
|
||||||
|
after :build do |record, options|
|
||||||
|
record.source_id = options.source_id
|
||||||
|
record.source = options.source
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -172,4 +172,25 @@ RSpec.describe ExternalSync do
|
||||||
expect(source.destroyed?).to be false
|
expect(source.destroyed?).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.migrate' do
|
||||||
|
|
||||||
|
let(:model) { 'Ticket' }
|
||||||
|
let(:factory_name) { model.downcase.to_sym }
|
||||||
|
let(:source) { create(factory_name) }
|
||||||
|
let(:target) { create(factory_name) }
|
||||||
|
let(:entries) do
|
||||||
|
create_list(:external_sync, 2,
|
||||||
|
object: model,
|
||||||
|
o_id: source.id,)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'migrates entries' do
|
||||||
|
expect do
|
||||||
|
described_class.migrate('Ticket', source.id, target.id)
|
||||||
|
end.to change {
|
||||||
|
entries.each(&:reload).map(&:o_id).uniq
|
||||||
|
}.from([source.id]).to([target.id])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
25
spec/lib/models_spec.rb
Normal file
25
spec/lib/models_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Models do
|
||||||
|
|
||||||
|
describe '.merge' do
|
||||||
|
|
||||||
|
context 'when ExternalSync references are present' do
|
||||||
|
|
||||||
|
shared_examples 'migrates entries' do |model|
|
||||||
|
|
||||||
|
let(:factory_name) { model.downcase.to_sym }
|
||||||
|
let(:source) { create(factory_name) }
|
||||||
|
let(:target) { create(factory_name) }
|
||||||
|
|
||||||
|
it 'sends ExternalSync.migrate' do
|
||||||
|
allow(ExternalSync).to receive(:migrate)
|
||||||
|
described_class.merge(model, source.id, target.id)
|
||||||
|
expect(ExternalSync).to have_received(:migrate).with(model, source.id, target.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'migrates entries', 'User'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -116,6 +116,14 @@ RSpec.describe Ticket, type: :model do
|
||||||
expect(origin_history['id_to']).to eq target_ticket.id
|
expect(origin_history['id_to']).to eq target_ticket.id
|
||||||
expect(origin_history['id_from']).to eq ticket.id
|
expect(origin_history['id_from']).to eq ticket.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'sends ExternalSync.migrate' do
|
||||||
|
allow(ExternalSync).to receive(:migrate)
|
||||||
|
|
||||||
|
ticket.merge_to(ticket_id: target_ticket.id, user_id: merge_user.id)
|
||||||
|
|
||||||
|
expect(ExternalSync).to have_received(:migrate).with('Ticket', ticket.id, target_ticket.id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue