Refactoring: Migrate tag_test to RSpec
This commit is contained in:
parent
7dce5315e1
commit
52f5b33484
7 changed files with 335 additions and 468 deletions
|
@ -145,20 +145,10 @@ returns
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.tag_list(data)
|
def self.tag_list(data)
|
||||||
tag_object_id_requested = Tag::Object.lookup(name: data[:object])
|
Tag.joins(:tag_item, :tag_object)
|
||||||
return [] if !tag_object_id_requested
|
.where(o_id: data[:o_id], tag_objects: { name: data[:object] })
|
||||||
|
.order(:id)
|
||||||
tag_search = Tag.where(
|
.pluck('tag_items.name')
|
||||||
tag_object_id: tag_object_id_requested,
|
|
||||||
o_id: data[:o_id],
|
|
||||||
).order(:id)
|
|
||||||
|
|
||||||
tag_search.each_with_object([]) do |tag, result|
|
|
||||||
tag_item = Tag::Item.lookup(id: tag.tag_item_id)
|
|
||||||
next if !tag_item
|
|
||||||
|
|
||||||
result.push tag_item.name
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Object < ApplicationModel
|
class Object < ApplicationModel
|
||||||
|
|
5
spec/factories/tag/item.rb
Normal file
5
spec/factories/tag/item.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :'tag/item', aliases: %i[tag_item] do
|
||||||
|
sequence(:name) { |n| "Item #{n}" }
|
||||||
|
end
|
||||||
|
end
|
66
spec/models/concerns/has_tags_examples.rb
Normal file
66
spec/models/concerns/has_tags_examples.rb
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
RSpec.shared_examples 'HasTags' do
|
||||||
|
subject { create(described_class.name.underscore) }
|
||||||
|
|
||||||
|
describe '#tag_add' do
|
||||||
|
let(:item_name) { 'foo' }
|
||||||
|
|
||||||
|
it 'delegates to Tag.tag_add' do
|
||||||
|
expect(Tag)
|
||||||
|
.to receive(:tag_add)
|
||||||
|
.with(object: described_class.name,
|
||||||
|
o_id: subject.id,
|
||||||
|
item: item_name,
|
||||||
|
created_by_id: nil)
|
||||||
|
|
||||||
|
subject.tag_add(item_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'optionally accepts a current_user_id argument' do
|
||||||
|
expect(Tag)
|
||||||
|
.to receive(:tag_add)
|
||||||
|
.with(object: described_class.name,
|
||||||
|
o_id: subject.id,
|
||||||
|
item: item_name,
|
||||||
|
created_by_id: 1)
|
||||||
|
|
||||||
|
subject.tag_add(item_name, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#tag_remove' do
|
||||||
|
let(:item_name) { 'foo' }
|
||||||
|
|
||||||
|
it 'delegates to Tag.tag_remove' do
|
||||||
|
expect(Tag)
|
||||||
|
.to receive(:tag_remove)
|
||||||
|
.with(object: described_class.name,
|
||||||
|
o_id: subject.id,
|
||||||
|
item: item_name,
|
||||||
|
created_by_id: nil)
|
||||||
|
|
||||||
|
subject.tag_remove(item_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'optionally accepts a current_user_id argument' do
|
||||||
|
expect(Tag)
|
||||||
|
.to receive(:tag_remove)
|
||||||
|
.with(object: described_class.name,
|
||||||
|
o_id: subject.id,
|
||||||
|
item: item_name,
|
||||||
|
created_by_id: 1)
|
||||||
|
|
||||||
|
subject.tag_remove(item_name, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#tag_list' do
|
||||||
|
it 'delegates to Tag.tag_list' do
|
||||||
|
expect(Tag)
|
||||||
|
.to receive(:tag_list)
|
||||||
|
.with(object: described_class.name,
|
||||||
|
o_id: subject.id)
|
||||||
|
|
||||||
|
subject.tag_list
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
125
spec/models/tag/item_spec.rb
Normal file
125
spec/models/tag/item_spec.rb
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
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
|
|
@ -1,90 +1,157 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe Tag do
|
RSpec.describe Tag, type: :model do
|
||||||
|
subject(:tag) { create(:tag) }
|
||||||
|
|
||||||
context 'rename' do
|
describe '.tag_add' do
|
||||||
before do
|
it 'touches the target object' do
|
||||||
Tag::Item.lookup_by_name_and_create('test1')
|
expect { described_class.tag_add(object: 'Ticket', item: 'foo', o_id: Ticket.first.id, created_by_id: 1) }
|
||||||
|
.to change { Ticket.first.updated_at }
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_rename
|
context 'when a Tag::Object does not exist for the given class' do
|
||||||
Tag::Item.rename(
|
it 'creates it and assigns it to a new Tag' do
|
||||||
id: Tag::Item.lookup(name: 'test1').id,
|
expect { described_class.tag_add(object: 'Foo', item: 'bar', o_id: 1, created_by_id: 1) }
|
||||||
name: 'test1_renamed',
|
.to change(Tag, :count).by(1)
|
||||||
updated_by_id: 1,
|
.and change { Tag::Object.exists?(name: 'Foo') }.to(true)
|
||||||
)
|
.and change { Tag.last&.tag_object&.name }.to('Foo')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'overview conditions with a single tag' do
|
context 'when a Tag::Object already exists for the given class' do
|
||||||
object = create :overview, condition: { 'ticket.tags' => { operator: 'contains one', value: 'test1' } }
|
let!(:tag_object) { Tag::Object.find_or_create_by(name: 'Ticket') }
|
||||||
tag_rename
|
|
||||||
expect(Overview.find(object.id).condition['ticket.tags'][:value]).to eq('test1_renamed')
|
it 'assigns it to a new Tag' do
|
||||||
|
expect { described_class.tag_add(object: 'Ticket', item: 'foo', o_id: 1, created_by_id: 1) }
|
||||||
|
.to change(Tag, :count).by(1)
|
||||||
|
.and not_change(Tag::Object, :count)
|
||||||
|
.and change { Tag.last&.tag_object&.name }.to('Ticket')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'overview conditions with a tag list ' do
|
context 'when a Tag::Item does not exist with the given name' do
|
||||||
object = create :overview, condition: { 'ticket.tags' => { operator: 'contains all', value: 'test1, test2, test3' } }
|
it 'creates it and assigns it to a new Tag' do
|
||||||
tag_rename
|
expect { described_class.tag_add(object: 'Ticket', item: 'foo', o_id: 1, created_by_id: 1) }
|
||||||
expect(Overview.find(object.id).condition['ticket.tags'][:value]).to eq('test1_renamed, test2, test3')
|
.to change(Tag, :count).by(1)
|
||||||
|
.and change { Tag::Item.exists?(name: 'foo') }.to(true)
|
||||||
|
.and change { Tag.last&.tag_item&.name }.to('foo')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'strips trailing/leading whitespace' do
|
||||||
|
expect { described_class.tag_add(object: 'Ticket', item: ' foo ', o_id: 1, created_by_id: 1) }
|
||||||
|
.to change(Tag, :count).by(1)
|
||||||
|
.and change { Tag::Item.exists?(name: 'foo') }.to(true)
|
||||||
|
.and change { Tag.last&.tag_item&.name }.to('foo')
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the name contains 8-bit Unicode characters' do
|
||||||
|
it 'creates it and assigns it to a new Tag' do
|
||||||
|
expect { described_class.tag_add(object: 'Ticket', item: 'fooöäüß', o_id: 1, created_by_id: 1) }
|
||||||
|
.to change(Tag, :count).by(1)
|
||||||
|
.and change { Tag::Item.exists?(name: 'fooöäüß') }.to(true)
|
||||||
|
.and change { Tag.last&.tag_item&.name }.to('fooöäüß')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'but the name is a case-sensitive variant of an existing Tag::Item' do
|
||||||
|
let!(:tag_item) { create(:'tag/item', name: 'foo') }
|
||||||
|
|
||||||
|
it 'creates it and assigns it to a new Tag' do
|
||||||
|
expect { described_class.tag_add(object: 'Ticket', item: 'FOO', o_id: 1, created_by_id: 1) }
|
||||||
|
.to change(Tag, :count).by(1)
|
||||||
|
.and change { Tag::Item.pluck(:name).include?('FOO') }.to(true) # .exists?(name: 'FOO') fails on MySQL
|
||||||
|
.and change { Tag.last&.tag_item&.name }.to('FOO')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'trigger conditions with a single tag' do
|
context 'when a Tag::Item already exists with the given name' do
|
||||||
object = create :trigger, condition: { 'ticket.tags' => { operator: 'contains one', value: 'test1' } }
|
let!(:tag_item) { create(:'tag/item', name: 'foo') }
|
||||||
tag_rename
|
|
||||||
expect(Trigger.find(object.id).condition['ticket.tags'][:value]).to eq('test1_renamed')
|
it 'assigns it to a new Tag' do
|
||||||
|
expect { described_class.tag_add(object: 'Ticket', item: 'foo', o_id: 1, created_by_id: 1) }
|
||||||
|
.to change(Tag, :count).by(1)
|
||||||
|
.and not_change(Tag::Item, :count)
|
||||||
|
.and change { Tag.last&.tag_item&.name }.to('foo')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'strips leading/trailing whitespace' do
|
||||||
|
expect { described_class.tag_add(object: 'Ticket', item: ' foo ', o_id: 1, created_by_id: 1) }
|
||||||
|
.to change(Tag, :count).by(1)
|
||||||
|
.and not_change(Tag::Item, :count)
|
||||||
|
.and change { Tag.last&.tag_item&.name }.to('foo')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'trigger conditions with a tag list ' do
|
context 'when a Tag already exists for the specified record with the given name' do
|
||||||
object = create :trigger, condition: { 'ticket.tags' => { operator: 'contains all', value: 'test1, test2, test3' } }
|
let!(:tag) { create(:tag, o: Ticket.first, tag_item: tag_item) }
|
||||||
tag_rename
|
let(:tag_item) { create(:'tag/item', name: 'foo') }
|
||||||
expect(Trigger.find(object.id).condition['ticket.tags'][:value]).to eq('test1_renamed, test2, test3')
|
|
||||||
|
it 'does not create any records' do
|
||||||
|
expect { described_class.tag_add(object: 'Ticket', item: 'foo', o_id: Ticket.first.id, created_by_id: 1) }
|
||||||
|
.to not_change(Tag, :count)
|
||||||
|
.and not_change(Tag::Item, :count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.tag_remove' do
|
||||||
|
it 'touches the target object' do
|
||||||
|
expect { described_class.tag_remove(object: 'Ticket', item: 'foo', o_id: Ticket.first.id, created_by_id: 1) }
|
||||||
|
.to change { Ticket.first.updated_at }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'trigger performs with a single tag' do
|
context 'when a matching Tag exists' do
|
||||||
object = create :trigger, perform: { 'ticket.tags' => { operator: 'contains one', value: 'test1' } }
|
let!(:tag) { create(:tag, o: Ticket.first, tag_item: tag_item) }
|
||||||
tag_rename
|
let(:tag_item) { create(:'tag/item', name: 'foo') }
|
||||||
expect(Trigger.find(object.id).perform['ticket.tags'][:value]).to eq('test1_renamed')
|
|
||||||
|
it 'destroys the Tag' do
|
||||||
|
expect { described_class.tag_remove(object: 'Ticket', o_id: Ticket.first.id, item: 'foo') }
|
||||||
|
.to change(Tag, :count).by(-1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'trigger performs with a tag list ' do
|
context 'when no matching Tag exists' do
|
||||||
object = create :trigger, perform: { 'ticket.tags' => { operator: 'contains all', value: 'test1, test2, test3' } }
|
it 'makes no changes' do
|
||||||
tag_rename
|
expect { described_class.tag_remove(object: 'Ticket', o_id: Ticket.first.id, item: 'foo') }
|
||||||
expect(Trigger.find(object.id).perform['ticket.tags'][:value]).to eq('test1_renamed, test2, test3')
|
.not_to change(Tag, :count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.tag_list' do
|
||||||
|
context 'with ASCII item names' do
|
||||||
|
before { items.map { |i| create(:tag, tag_item: i, o: Ticket.first) } }
|
||||||
|
|
||||||
|
let(:items) do
|
||||||
|
[
|
||||||
|
create(:'tag/item', name: 'foo'),
|
||||||
|
create(:'tag/item', name: 'bar'),
|
||||||
|
create(:'tag/item', name: 'BAR'),
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns all tag names (case-sensitive) for a given record' do
|
||||||
|
expect(described_class.tag_list(object: 'Ticket', o_id: Ticket.first.id))
|
||||||
|
.to match_array(%w[foo bar BAR])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'scheduler conditions with a single tag' do
|
context 'with Unicode (8-bit) item names' do
|
||||||
object = create :job, condition: { 'ticket.tags' => { operator: 'contains one', value: 'test1' } }
|
before { items.map { |i| create(:tag, tag_item: i, o: Ticket.first) } }
|
||||||
tag_rename
|
|
||||||
expect(Job.find(object.id).condition['ticket.tags'][:value]).to eq('test1_renamed')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'scheduler conditions with a tag list ' do
|
let(:items) do
|
||||||
object = create :job, condition: { 'ticket.tags' => { operator: 'contains all', value: 'test1, test2, test3' } }
|
[
|
||||||
tag_rename
|
create(:'tag/item', name: 'fooöäüß'),
|
||||||
expect(Job.find(object.id).condition['ticket.tags'][:value]).to eq('test1_renamed, test2, test3')
|
create(:'tag/item', name: 'baröäüß'),
|
||||||
end
|
create(:'tag/item', name: 'BARöäüß'),
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
it 'scheduler performs with a single tag' do
|
it 'returns all tag names (case-sensitive) for a given record' do
|
||||||
object = create :job, perform: { 'ticket.tags' => { operator: 'contains one', value: 'test1' } }
|
expect(described_class.tag_list(object: 'Ticket', o_id: Ticket.first.id))
|
||||||
tag_rename
|
.to match_array(%w[fooöäüß baröäüß BARöäüß])
|
||||||
expect(Job.find(object.id).perform['ticket.tags'][:value]).to eq('test1_renamed')
|
end
|
||||||
end
|
|
||||||
|
|
||||||
it 'scheduler performs with a tag list ' do
|
|
||||||
object = create :job, perform: { 'ticket.tags' => { operator: 'contains all', value: 'test1, test2, test3' } }
|
|
||||||
tag_rename
|
|
||||||
expect(Job.find(object.id).perform['ticket.tags'][:value]).to eq('test1_renamed, test2, test3')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'PostmasterFilter performs with a single tag' do
|
|
||||||
object = create :postmaster_filter, perform: { 'x-zammad-ticket-tags' => { operator: 'contains one', value: 'test1' } }
|
|
||||||
tag_rename
|
|
||||||
expect(PostmasterFilter.find(object.id).perform['x-zammad-ticket-tags'][:value]).to eq('test1_renamed')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'PostmasterFilter performs with a tag list ' do
|
|
||||||
object = create :postmaster_filter, perform: { 'x-zammad-ticket-tags' => { operator: 'contains all', value: 'test1, test2, test3' } }
|
|
||||||
tag_rename
|
|
||||||
expect(PostmasterFilter.find(object.id).perform['x-zammad-ticket-tags'][:value]).to eq('test1_renamed, test2, test3')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@ require 'models/application_model_examples'
|
||||||
require 'models/concerns/can_be_imported_examples'
|
require 'models/concerns/can_be_imported_examples'
|
||||||
require 'models/concerns/can_lookup_examples'
|
require 'models/concerns/can_lookup_examples'
|
||||||
require 'models/concerns/has_history_examples'
|
require 'models/concerns/has_history_examples'
|
||||||
|
require 'models/concerns/has_tags_examples'
|
||||||
require 'models/concerns/has_xss_sanitized_note_examples'
|
require 'models/concerns/has_xss_sanitized_note_examples'
|
||||||
require 'models/concerns/has_object_manager_attributes_validation_examples'
|
require 'models/concerns/has_object_manager_attributes_validation_examples'
|
||||||
|
|
||||||
|
@ -11,6 +12,7 @@ RSpec.describe Ticket, type: :model do
|
||||||
it_behaves_like 'CanBeImported'
|
it_behaves_like 'CanBeImported'
|
||||||
it_behaves_like 'CanLookup'
|
it_behaves_like 'CanLookup'
|
||||||
it_behaves_like 'HasHistory', history_relation_object: 'Ticket::Article'
|
it_behaves_like 'HasHistory', history_relation_object: 'Ticket::Article'
|
||||||
|
it_behaves_like 'HasTags'
|
||||||
it_behaves_like 'HasXssSanitizedNote', model_factory: :ticket
|
it_behaves_like 'HasXssSanitizedNote', model_factory: :ticket
|
||||||
it_behaves_like 'HasObjectManagerAttributesValidation'
|
it_behaves_like 'HasObjectManagerAttributesValidation'
|
||||||
|
|
||||||
|
|
|
@ -1,388 +0,0 @@
|
||||||
require 'test_helper'
|
|
||||||
|
|
||||||
class TagTest < ActiveSupport::TestCase
|
|
||||||
test 'tags' do
|
|
||||||
tests = [
|
|
||||||
|
|
||||||
# test 1
|
|
||||||
{
|
|
||||||
tag_add: {
|
|
||||||
item: 'tag1',
|
|
||||||
object: 'Object1',
|
|
||||||
o_id: 123,
|
|
||||||
created_by_id: 1
|
|
||||||
},
|
|
||||||
verify: {
|
|
||||||
object: 'Object1',
|
|
||||||
items: {
|
|
||||||
'tag1' => true,
|
|
||||||
'tag2' => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 2
|
|
||||||
{
|
|
||||||
tag_add: {
|
|
||||||
item: 'tag2',
|
|
||||||
object: 'Object1',
|
|
||||||
o_id: 123,
|
|
||||||
created_by_id: 1
|
|
||||||
},
|
|
||||||
verify: {
|
|
||||||
object: 'Object1',
|
|
||||||
items: {
|
|
||||||
'tag1' => true,
|
|
||||||
'tag2' => true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
tag_add: {
|
|
||||||
item: 'TAG2',
|
|
||||||
object: 'Object1',
|
|
||||||
o_id: 123,
|
|
||||||
created_by_id: 1
|
|
||||||
},
|
|
||||||
verify: {
|
|
||||||
object: 'Object1',
|
|
||||||
items: {
|
|
||||||
'tag1' => true,
|
|
||||||
'tag2' => true,
|
|
||||||
'TAG2' => true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 2
|
|
||||||
{
|
|
||||||
tag_add: {
|
|
||||||
item: 'tagöäüß1',
|
|
||||||
object: 'Object2',
|
|
||||||
o_id: 123,
|
|
||||||
created_by_id: 1
|
|
||||||
},
|
|
||||||
verify: {
|
|
||||||
object: 'Object2',
|
|
||||||
items: {
|
|
||||||
'tagöäüß1' => true,
|
|
||||||
'tag2' => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 4
|
|
||||||
{
|
|
||||||
tag_add: {
|
|
||||||
item: 'Tagöäüß2',
|
|
||||||
object: 'Object2',
|
|
||||||
o_id: 123,
|
|
||||||
created_by_id: 1
|
|
||||||
},
|
|
||||||
verify: {
|
|
||||||
object: 'Object2',
|
|
||||||
items: {
|
|
||||||
'tagöäüß1' => true,
|
|
||||||
'Tagöäüß2' => true,
|
|
||||||
'tagöäüß3' => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 5
|
|
||||||
{
|
|
||||||
tag_remove: {
|
|
||||||
item: 'tag1',
|
|
||||||
object: 'Object1',
|
|
||||||
o_id: 123,
|
|
||||||
created_by_id: 1
|
|
||||||
},
|
|
||||||
verify: {
|
|
||||||
object: 'Object1',
|
|
||||||
items: {
|
|
||||||
'tag1' => false,
|
|
||||||
'tag2' => true,
|
|
||||||
'TAG2' => true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 5
|
|
||||||
{
|
|
||||||
tag_remove: {
|
|
||||||
item: 'TAG2',
|
|
||||||
object: 'Object1',
|
|
||||||
o_id: 123,
|
|
||||||
created_by_id: 1
|
|
||||||
},
|
|
||||||
verify: {
|
|
||||||
object: 'Object1',
|
|
||||||
items: {
|
|
||||||
'tag1' => false,
|
|
||||||
'tag2' => true,
|
|
||||||
'TAG2' => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
]
|
|
||||||
tests.each do |test|
|
|
||||||
tags = nil
|
|
||||||
if test[:tag_add]
|
|
||||||
tags = test[:tag_add]
|
|
||||||
success = Tag.tag_add(tags)
|
|
||||||
assert(success, 'Tag.tag_add successful')
|
|
||||||
else
|
|
||||||
tags = test[:tag_remove]
|
|
||||||
success = Tag.tag_remove(tags)
|
|
||||||
assert(success, 'Tag.tag_remove successful')
|
|
||||||
end
|
|
||||||
list = Tag.tag_list(tags)
|
|
||||||
test[:verify][:items].each do |key, value|
|
|
||||||
if value == true
|
|
||||||
assert(list.include?(key), "Tag verify - should exists but exists #{key}")
|
|
||||||
else
|
|
||||||
assert_not(list.include?(key), "Tag verify - exists but should not #{key}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# delete tags
|
|
||||||
tests.each do |test|
|
|
||||||
tags = test[:tag_add] || test[:tag_remove]
|
|
||||||
success = Tag.tag_remove(tags)
|
|
||||||
assert(success, 'Tag.tag_remove successful')
|
|
||||||
list = Tag.tag_list(tags)
|
|
||||||
assert_not(list.include?(tags[:item]), 'Tag entry destroyed')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
test 'tags - real live' do
|
|
||||||
|
|
||||||
ticket1 = Ticket.create(
|
|
||||||
title: 'some title tag1',
|
|
||||||
group: Group.lookup(name: 'Users'),
|
|
||||||
customer_id: 2,
|
|
||||||
state: Ticket::State.lookup(name: 'new'),
|
|
||||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
|
||||||
updated_by_id: 1,
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
ticket2 = Ticket.create(
|
|
||||||
title: 'some title tag2',
|
|
||||||
group: Group.lookup(name: 'Users'),
|
|
||||||
customer_id: 2,
|
|
||||||
state: Ticket::State.lookup(name: 'new'),
|
|
||||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
|
||||||
updated_by_id: 1,
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
travel 2.seconds
|
|
||||||
|
|
||||||
ticket1.tag_add('some tag1', 1)
|
|
||||||
ticket1.tag_add('some tag2 ', 1)
|
|
||||||
ticket1.tag_add(' some tag3', 1)
|
|
||||||
ticket1.tag_add('some TAG4', 1)
|
|
||||||
ticket1.tag_add(' some tag4', 1)
|
|
||||||
|
|
||||||
ticket2.tag_add('some tag3', 1)
|
|
||||||
ticket2.tag_add('some TAG4', 1)
|
|
||||||
ticket2.tag_add('some tag4 ', 1)
|
|
||||||
|
|
||||||
ticket1.tag_remove('some tag1', 1)
|
|
||||||
|
|
||||||
ticket1_lookup1 = Ticket.lookup(id: ticket1.id)
|
|
||||||
assert_not_equal(ticket1.updated_at.to_s, ticket1_lookup1.updated_at.to_s)
|
|
||||||
ticket2_lookup1 = Ticket.lookup(id: ticket2.id)
|
|
||||||
assert_not_equal(ticket2.updated_at.to_s, ticket2_lookup1.updated_at.to_s)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(4, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('some tag2'))
|
|
||||||
assert(tags_ticket1.include?('some tag3'))
|
|
||||||
assert(tags_ticket1.include?('some TAG4'))
|
|
||||||
assert(tags_ticket1.include?('some tag4'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(3, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('some tag3'))
|
|
||||||
assert(tags_ticket2.include?('some TAG4'))
|
|
||||||
assert(tags_ticket2.include?('some tag4'))
|
|
||||||
|
|
||||||
# rename tag
|
|
||||||
travel 2.seconds
|
|
||||||
tag_item3 = Tag::Item.find_by(name: 'some tag3')
|
|
||||||
Tag::Item.rename(
|
|
||||||
id: tag_item3.id,
|
|
||||||
name: ' some tag33',
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
ticket1_lookup2 = Ticket.lookup(id: ticket1.id)
|
|
||||||
assert_not_equal(ticket1_lookup2.updated_at.to_s, ticket1_lookup1.updated_at.to_s)
|
|
||||||
ticket2_lookup2 = Ticket.lookup(id: ticket2.id)
|
|
||||||
assert_not_equal(ticket2_lookup2.updated_at.to_s, ticket2_lookup1.updated_at.to_s)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(4, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('some tag2'))
|
|
||||||
assert(tags_ticket1.include?('some tag33'))
|
|
||||||
assert(tags_ticket1.include?('some TAG4'))
|
|
||||||
assert(tags_ticket1.include?('some tag4'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(3, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('some tag33'))
|
|
||||||
assert(tags_ticket2.include?('some TAG4'))
|
|
||||||
assert(tags_ticket2.include?('some tag4'))
|
|
||||||
|
|
||||||
# merge tags
|
|
||||||
travel 2.seconds
|
|
||||||
Tag::Item.rename(
|
|
||||||
id: tag_item3.id,
|
|
||||||
name: 'some tag2',
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
ticket1_lookup3 = Ticket.lookup(id: ticket1.id)
|
|
||||||
assert_not_equal(ticket1_lookup3.updated_at.to_s, ticket1_lookup2.updated_at.to_s)
|
|
||||||
ticket2_lookup3 = Ticket.lookup(id: ticket2.id)
|
|
||||||
assert_not_equal(ticket2_lookup3.updated_at.to_s, ticket2_lookup2.updated_at.to_s)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(3, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('some tag2'))
|
|
||||||
assert(tags_ticket1.include?('some TAG4'))
|
|
||||||
assert(tags_ticket1.include?('some tag4'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(3, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('some tag2'))
|
|
||||||
assert(tags_ticket2.include?('some TAG4'))
|
|
||||||
assert(tags_ticket2.include?('some tag4'))
|
|
||||||
|
|
||||||
assert_not(Tag::Item.find_by(id: tag_item3.id))
|
|
||||||
|
|
||||||
# remove tag item
|
|
||||||
travel 2.seconds
|
|
||||||
tag_item4 = Tag::Item.find_by(name: 'some TAG4')
|
|
||||||
Tag::Item.remove(tag_item4.id)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(2, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('some tag2'))
|
|
||||||
assert(tags_ticket1.include?('some tag4'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(2, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('some tag2'))
|
|
||||||
assert(tags_ticket2.include?('some tag4'))
|
|
||||||
|
|
||||||
assert_not(Tag::Item.find_by(id: tag_item4.id))
|
|
||||||
|
|
||||||
ticket1_lookup4 = Ticket.lookup(id: ticket1.id)
|
|
||||||
assert_not_equal(ticket1_lookup4.updated_at.to_s, ticket1_lookup3.updated_at.to_s)
|
|
||||||
ticket2_lookup4 = Ticket.lookup(id: ticket2.id)
|
|
||||||
assert_not_equal(ticket2_lookup4.updated_at.to_s, ticket2_lookup3.updated_at.to_s)
|
|
||||||
travel_back
|
|
||||||
end
|
|
||||||
|
|
||||||
test 'tags - rename tag with same name' do
|
|
||||||
|
|
||||||
ticket1 = Ticket.create(
|
|
||||||
title: 'rename tag1',
|
|
||||||
group: Group.lookup(name: 'Users'),
|
|
||||||
customer_id: 2,
|
|
||||||
updated_by_id: 1,
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
ticket2 = Ticket.create(
|
|
||||||
title: 'rename tag2',
|
|
||||||
group: Group.lookup(name: 'Users'),
|
|
||||||
customer_id: 2,
|
|
||||||
updated_by_id: 1,
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
ticket1.tag_add('some rename tag1', 1)
|
|
||||||
ticket1.tag_add('some rename tag2 ', 1)
|
|
||||||
|
|
||||||
ticket2.tag_add('some rename tag2', 1)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(2, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('some rename tag1'))
|
|
||||||
assert(tags_ticket1.include?('some rename tag2'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(1, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('some rename tag2'))
|
|
||||||
|
|
||||||
tag_item1 = Tag::Item.find_by(name: 'some rename tag1')
|
|
||||||
Tag::Item.rename(
|
|
||||||
id: tag_item1.id,
|
|
||||||
name: ' some rename tag1',
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(2, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('some rename tag1'))
|
|
||||||
assert(tags_ticket1.include?('some rename tag2'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(1, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('some rename tag2'))
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
test 'tags - rename and merge tag with existing tag' do
|
|
||||||
|
|
||||||
ticket1 = Ticket.create(
|
|
||||||
title: 'rename tag1',
|
|
||||||
group: Group.lookup(name: 'Users'),
|
|
||||||
customer_id: 2,
|
|
||||||
updated_by_id: 1,
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
ticket2 = Ticket.create(
|
|
||||||
title: 'rename tag2',
|
|
||||||
group: Group.lookup(name: 'Users'),
|
|
||||||
customer_id: 2,
|
|
||||||
updated_by_id: 1,
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
ticket1.tag_add('tagname1', 1)
|
|
||||||
ticket1.tag_add('tagname2', 1)
|
|
||||||
|
|
||||||
ticket2.tag_add('Tagname2', 1)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(2, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('tagname1'))
|
|
||||||
assert(tags_ticket1.include?('tagname2'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(1, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('Tagname2'))
|
|
||||||
|
|
||||||
tag_item1 = Tag::Item.lookup(name: 'Tagname2')
|
|
||||||
Tag::Item.rename(
|
|
||||||
id: tag_item1.id,
|
|
||||||
name: 'tagname2',
|
|
||||||
created_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
tags_ticket1 = ticket1.tag_list
|
|
||||||
assert_equal(2, tags_ticket1.count)
|
|
||||||
assert(tags_ticket1.include?('tagname1'))
|
|
||||||
assert(tags_ticket1.include?('tagname2'))
|
|
||||||
|
|
||||||
tags_ticket2 = ticket2.tag_list
|
|
||||||
assert_equal(1, tags_ticket2.count)
|
|
||||||
assert(tags_ticket2.include?('tagname2'))
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in a new issue