require 'rails_helper' RSpec.describe Tag::Item do subject(:item) { create(:'tag/item') } describe '.rename' do context 'when given a unique item name' do it 'updates the name on the Tag::Item' do expect { described_class.rename(id: item.id, name: 'foo') } .to change { item.reload.name }.to('foo') end it 'strips trailing/leading whitespace' do expect { described_class.rename(id: item.id, name: ' foo ') } .to change { item.reload.name }.to('foo') end end context 'when given a conflicting/existing item name' do let!(:item_2) { create(:'tag/item', name: 'foo') } context 'with no redundant tags' do let!(:tag) { create(:tag, o: Ticket.first, tag_item: item) } it 'reassigns all tags from old-name item to new-name item' do expect { described_class.rename(id: item.id, name: item_2.name) } .to change { tag.reload.tag_item }.to(item_2) .and change { Ticket.first.tag_list }.to([item_2.name]) end it 'strips trailing/leading whitespace' do expect { described_class.rename(id: item.id, name: " #{item_2.name} ") } .to change { tag.reload.tag_item }.to(item_2) .and change { Ticket.first.tag_list }.to([item_2.name]) end end context 'with redundant tags' do let!(:tags) do [create(:tag, o: Ticket.first, tag_item: item), create(:tag, o: Ticket.first, tag_item: item_2)] end it 'removes the tag assigned to old-name item' do expect { described_class.rename(id: item.id, name: item_2.name) } .to change { Tag.exists?(id: tags.first.id) }.to(false) .and change { Ticket.first.tag_list }.to([item_2.name]) end it 'strips trailing/leading whitespace' do expect { described_class.rename(id: item.id, name: " #{item_2.name} ") } .to change { Tag.exists?(id: tags.first.id) }.to(false) .and change { Ticket.first.tag_list }.to([item_2.name]) end end it 'deletes the original item' do expect { described_class.rename(id: item.id, name: item_2.name) } .to change { described_class.exists?(name: item.name) }.to(false) end end shared_examples 'updating references to tag names' do |object_klass:, method:, label: 'ticket.tags'| subject(:item) { create(:'tag/item', name: 'test1') } context "with reference to renamed tag in its #{method} hash (contains-one)" do let(:object) { create(object_klass.name.underscore, method => { label => tag_matcher }) } let(:tag_matcher) { { operator: 'contains one', value: 'test1' } } it 'updates reference with new tag name' do expect { described_class.rename(id: item.id, name: 'test1_renamed') } .to change { object.reload.send(method)[label][:value] } .from('test1').to('test1_renamed') end end context "with reference to renamed tag in its #{method} hash (contains-all)" do let(:object) { create(object_klass.name.underscore, method => { label => tag_matcher }) } let(:tag_matcher) { { operator: 'contains all', value: 'test1, test2, test3' } } it 'updates reference with new tag name' do expect { described_class.rename(id: item.id, name: 'test1_renamed') } .to change { object.reload.send(method)[label][:value] } .from('test1, test2, test3').to('test1_renamed, test2, test3') end end end context 'for Overview object' do include_examples 'updating references to tag names', object_klass: Overview, method: :condition end context 'for Trigger object' do include_examples 'updating references to tag names', object_klass: Trigger, method: :condition include_examples 'updating references to tag names', object_klass: Trigger, method: :perform end context 'for scheduler (Job) object' do include_examples 'updating references to tag names', object_klass: Job, method: :condition include_examples 'updating references to tag names', object_klass: Job, method: :perform end context 'for PostmasterFilter object' do include_examples 'updating references to tag names', object_klass: PostmasterFilter, method: :perform, label: 'x-zammad-ticket-tags' end end describe '.remove' do let!(:tags) do [create(:tag, tag_item: item, o: User.first), create(:tag, tag_item: item, o: Ticket.first)] end it 'removes the specified Tag::Item' do expect { described_class.remove(item.id) } .to change { described_class.exists?(id: item.id) }.to(false) end it 'removes all associated Tags' do expect { described_class.remove(item.id) } .to change { Tag.exists?(id: tags.first.id) }.to(false) .and change { Tag.exists?(id: tags.second.id) }.to(false) end end end