can_perform_changes_examples.rb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. RSpec.shared_examples 'CanPerformChanges', :aggregate_failures do |object_name:, data_privacy_deletion_task: true|
  3. describe '#perform_changes' do
  4. let(:object_name_downcase) { object_name.downcase }
  5. # a `performable` can be a Trigger or a Job
  6. # we use DuckTyping and expect that a performable
  7. # implements the following interface
  8. let(:performable) do
  9. PERFORMABLE_STRUCT.new(id: 1, perform: perform)
  10. end
  11. before do
  12. stub_const('PERFORMABLE_STRUCT', Struct.new(:id, :perform, keyword_init: true))
  13. end
  14. context 'when data privacy deletion task should be created', if: data_privacy_deletion_task do
  15. let(:perform) do
  16. {
  17. "#{object_name_downcase}.action" => {
  18. 'value' => 'data_privacy_deletion_task',
  19. }
  20. }
  21. end
  22. it 'does create deletion task' do
  23. object.perform_changes(performable, 'trigger', object, User.first)
  24. expect(DataPrivacyTask.last.deletable).to eq(object)
  25. end
  26. end
  27. describe 'Allow placeholders in trigger perform actions for string attributes #4216', db_strategy: :reset do
  28. let(:custom_attribute_text1) do
  29. create(:object_manager_attribute_text, name: 'custom_attribute_text1', object_name: object_name)
  30. end
  31. let(:custom_attribute_text2) do
  32. create(:object_manager_attribute_text, name: 'custom_attribute_text2', object_name: object_name)
  33. end
  34. let(:object) { create(object_name.downcase.to_sym, custom_attribute_text1: 'testing-example') }
  35. let(:perform) do
  36. {
  37. "#{object_name_downcase}.custom_attribute_text2" => {
  38. 'value' => "\#{#{object_name_downcase}.custom_attribute_text1}",
  39. }
  40. }
  41. end
  42. before do
  43. custom_attribute_text1
  44. custom_attribute_text2
  45. ObjectManager::Attribute.migration_execute
  46. object
  47. end
  48. it 'does replace custom fields in trigger' do
  49. object.perform_changes(performable, 'trigger', object, User.first)
  50. expect(object.reload.custom_attribute_text2).to eq('testing-example')
  51. end
  52. end
  53. # All fields (aside from richtext) are escaped in frontend. No need to escape in database.
  54. # https://github.com/zammad/zammad/issues/5108
  55. describe 'Allow special characters', db_strategy: :reset do
  56. let(:custom_attribute_text1) do
  57. create(:object_manager_attribute_text, name: 'custom_attribute_text1', object_name: object_name)
  58. end
  59. let(:custom_attribute_text2) do
  60. create(:object_manager_attribute_text, name: 'custom_attribute_text2', object_name: object_name)
  61. end
  62. let(:object) { create(object_name.downcase.to_sym, custom_attribute_text2: 'special &&& characters') }
  63. let(:perform) do
  64. {
  65. "#{object_name_downcase}.#{target_field}" => {
  66. 'value' => "\#{#{object_name_downcase}.custom_attribute_text2}",
  67. }
  68. }
  69. end
  70. before do
  71. custom_attribute_text1
  72. custom_attribute_text2
  73. ObjectManager::Attribute.migration_execute
  74. object
  75. end
  76. context 'when target field is a text field' do
  77. let(:target_field) { :custom_attribute_text1 }
  78. it 'does not escape special characters' do
  79. expect { object.perform_changes(performable, 'trigger') }
  80. .to change { object.reload.custom_attribute_text1 }
  81. .to 'special &&& characters'
  82. end
  83. end
  84. context 'when target field is a rich text field' do
  85. let(:target_field) { :note }
  86. it 'escapes special characters' do
  87. expect { object.perform_changes(performable, 'trigger') }
  88. .to change { object.reload.note }
  89. .to 'special &&& characters'
  90. end
  91. end
  92. end
  93. end
  94. end