has_history_examples.rb 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. RSpec.shared_examples 'HasHistory' do |history_relation_object: []|
  2. describe 'auto-creation of history records' do
  3. let(:histories) { History.where(history_object_id: History::Object.find_by(name: described_class.name)) }
  4. context 'on creation' do
  5. it 'creates a History record for it' do
  6. expect { subject }.to change(histories, :count).by(1)
  7. expect(histories.last.history_type.name).to eq('created')
  8. end
  9. end
  10. context 'on update' do
  11. let(:histories) do
  12. History.where(history_object_id: History::Object.lookup(name: described_class.name).id,
  13. history_type_id: History::Type.lookup(name: 'updated').id,
  14. history_attribute_id: History::Attribute.find_or_create_by(name: attribute).id)
  15. end
  16. let!(:old_value) { subject.send(attribute) }
  17. shared_examples 'attribute update' do
  18. it 'creates a History record for it' do
  19. expect { subject.update(attribute => new_value) }.to change(histories, :count).by(1)
  20. expect(histories.last.attributes).to include(attributes)
  21. end
  22. end
  23. describe 'of #active', if: described_class.attribute_names.include?('active') do
  24. let(:attribute) { 'active' }
  25. let(:new_value) { !subject.active }
  26. let(:attributes) { { 'value_from' => old_value.to_s, 'value_to' => new_value.to_s } }
  27. include_examples 'attribute update'
  28. end
  29. describe 'of #body', if: described_class.attribute_names.include?('body') do
  30. let(:attribute) { 'body' }
  31. let(:new_value) { 'Lorem ipsum dolor' }
  32. let(:attributes) { { 'value_from' => old_value, 'value_to' => new_value } }
  33. include_examples 'attribute update'
  34. end
  35. describe 'of #email', if: described_class.attribute_names.include?('email') do
  36. let(:attribute) { 'email' }
  37. let(:new_value) { Faker::Internet.email }
  38. let(:attributes) { { 'value_from' => old_value, 'value_to' => new_value } }
  39. include_examples 'attribute update'
  40. end
  41. describe 'of #lastname', if: described_class.attribute_names.include?('lastname') do
  42. let(:attribute) { 'lastname' }
  43. let(:new_value) { 'Foo' }
  44. let(:attributes) { { 'value_from' => old_value, 'value_to' => new_value } }
  45. include_examples 'attribute update'
  46. end
  47. describe 'of #name', if: described_class.attribute_names.include?('name') do
  48. let(:attribute) { 'name' }
  49. let(:new_value) { 'Foo' }
  50. let(:attributes) { { 'value_from' => old_value, 'value_to' => new_value } }
  51. include_examples 'attribute update'
  52. end
  53. describe 'of #state', if: described_class.attribute_names.include?('state_id') do
  54. let(:attribute) { 'state' }
  55. let(:new_value) { state_class.where.not(id: old_value.id).first }
  56. let(:state_class) { "#{described_class.name}::State".constantize }
  57. let(:attributes) { { 'value_from' => old_value.name, 'value_to' => new_value.name } }
  58. include_examples 'attribute update'
  59. end
  60. describe 'of #title', if: described_class.attribute_names.include?('title') do
  61. let(:attribute) { 'title' }
  62. let(:new_value) { 'foo' }
  63. let(:attributes) { { 'value_from' => old_value, 'value_to' => new_value } }
  64. include_examples 'attribute update'
  65. end
  66. context 'when validations or callbacks prevent update' do
  67. shared_examples 'failed attribute update' do
  68. it 'does not create a History record for it' do
  69. expect { subject.update(attribute => new_value) }.not_to change(histories, :count)
  70. end
  71. end
  72. describe 'of #owner', if: described_class.attribute_names.include?('owner_id') do
  73. let(:attribute) { 'owner' }
  74. let(:new_value) { create(:customer) } # Ticket#owner is restricted to active agents of the same group
  75. include_examples 'failed attribute update'
  76. end
  77. end
  78. end
  79. end
  80. describe '#history_get' do
  81. context 'without "full" flag' do
  82. it 'delegates to History.list for self' do
  83. expect(History).to receive(:list).with(described_class.name, subject.id, history_relation_object)
  84. subject.history_get
  85. end
  86. end
  87. context 'with "full" flag' do
  88. it 'returns a hash including History.list for self' do
  89. expect(subject.history_get(true))
  90. .to include(history: History.list(described_class.name, subject.id, history_relation_object))
  91. end
  92. it 'returns a hash including FE assets of self and related objects' do
  93. expect(subject.history_get(true))
  94. .to include(assets: hash_including(subject.assets({})))
  95. end
  96. end
  97. end
  98. end