Просмотр исходного кода

Fixed issue #1568 - select attribute in trigger shows internal id (fixes #1568)
This alternative approach does not use the database_cleaner gem.

Billy Zhou 6 лет назад
Родитель
Сommit
bbabae7c2c

+ 22 - 0
lib/notification_factory/renderer.rb

@@ -77,16 +77,25 @@ examples how to use
       return "\#{#{key} / no such method}"
     end
 
+    previous_object_refs = ''
     object_methods_s = ''
     object_methods.each do |method_raw|
 
       method = method_raw.strip
 
+      if method == 'value'
+        temp = object_refs
+        object_refs = display_value(previous_object_refs, method, object_methods_s, object_refs)
+        previous_object_refs = temp
+      end
+
       if object_methods_s != ''
         object_methods_s += '.'
       end
       object_methods_s += method
 
+      next if method == 'value'
+
       if object_methods_s == ''
         value = "\#{#{object_name}.#{object_methods_s} / no such method}"
         break
@@ -115,6 +124,7 @@ examples how to use
         break
       end
       begin
+        previous_object_refs = object_refs
         object_refs = object_refs.send(method.to_sym, *arguments)
       rescue => e
         value = "\#{#{object_name}.#{object_methods_s} / #{e.message}}"
@@ -166,4 +176,16 @@ examples how to use
     true
   end
 
+  def display_value(object, method_name, previous_method_names, key)
+    return key if method_name != 'value' ||
+                  !key.instance_of?(String)
+
+    attributes = ObjectManager::Attribute
+                 .where(object_lookup_id: ObjectLookup.by_name(object.class.to_s))
+                 .where(name: previous_method_names.split('.').last)
+
+    return key if attributes.count.zero? || attributes.first.data_type != 'select'
+
+    attributes.first.data_option['options'][key] || key
+  end
 end

+ 10 - 0
spec/factories/notification_factory/renderer.rb

@@ -0,0 +1,10 @@
+FactoryBot.define do
+  factory :notification_factory_renderer, class: NotificationFactory::Renderer do
+    objects {}
+    locale 'en-en'
+    template ''
+    escape true
+
+    initialize_with { new(objects, locale, template, escape) }
+  end
+end

+ 26 - 0
spec/factories/object_manager_attribute.rb

@@ -53,6 +53,32 @@ FactoryBot.define do
     end
   end
 
+  factory :object_manager_attribute_date, parent: :object_manager_attribute do
+    name        'date_attribute'
+    data_type   'date'
+    data_option do
+      {
+        'future' => true,
+        'past' => true,
+        'diff' => 24,
+        'null' => true,
+      }
+    end
+  end
+
+  factory :object_manager_attribute_datetime, parent: :object_manager_attribute do
+    name        'datetime_attribute'
+    data_type   'datetime'
+    data_option do
+      {
+        'future' => true,
+        'past' => true,
+        'diff' => 24,
+        'null' => true,
+      }
+    end
+  end
+
   factory :object_manager_attribute_select, parent: :object_manager_attribute do
     data_type   'select'
     data_option do

+ 149 - 0
spec/lib/notification_factory/renderer_spec.rb

@@ -0,0 +1,149 @@
+require 'rails_helper'
+
+RSpec.describe NotificationFactory::Renderer do
+  # rubocop:disable Lint/InterpolationCheck
+  describe 'render' do
+    self.use_transactional_tests = false
+
+    before { @user = User.where(firstname: 'Nicole').first }
+
+    it 'correctly renders a blank template' do
+      renderer = build :notification_factory_renderer
+      expect(renderer.render).to eq ''
+    end
+
+    it 'correctly renders chained object references' do
+      user = User.where(firstname: 'Nicole').first
+      ticket = create :ticket, customer: user
+      renderer = build :notification_factory_renderer,
+                       objects: { ticket: ticket },
+                       template: '#{ticket.customer.firstname.downcase}'
+      expect(renderer.render).to eq 'nicole'
+      ticket.destroy
+    end
+
+    it 'correctly renders multiple value calls' do
+      ticket = create :ticket, customer: @user
+      renderer = build :notification_factory_renderer,
+                       objects: { ticket: ticket },
+                       template: '#{ticket.created_at.value.value.value.value.to_s.first}'
+      expect(renderer.render).to eq '2'
+      ticket.destroy
+    end
+
+    it 'correctly renders simple select attributes' do
+      attribute = create :object_manager_attribute_select, name: 'select'
+      ObjectManager::Attribute.migration_execute
+
+      ticket = create :ticket, customer: @user, select: 'key_1'
+
+      renderer = build :notification_factory_renderer,
+                       objects: { ticket: ticket },
+                       template: '#{ticket.select} _SEPERATOR_ #{ticket.select.value}'
+
+      expect(renderer.render).to eq 'key_1 _SEPERATOR_ value_1'
+      ticket.destroy
+
+      ObjectManager::Attribute.remove(
+        object: 'Ticket',
+        name: 'select',
+      )
+      ObjectManager::Attribute.migration_execute
+    end
+
+    it 'correctly renders select attributes on chained user object' do
+      attribute = create :object_manager_attribute_select,
+                         object_lookup_id: ObjectLookup.by_name('User'),
+                         name: 'select'
+      ObjectManager::Attribute.migration_execute
+
+      user = User.where(firstname: 'Nicole').first
+      user.select = 'key_2'
+      user.save
+      ticket = create :ticket, customer: user
+
+      renderer = build :notification_factory_renderer,
+                       objects: { ticket: ticket },
+                       template: '#{ticket.customer.select} _SEPERATOR_ #{ticket.customer.select.value}'
+
+      expect(renderer.render).to eq 'key_2 _SEPERATOR_ value_2'
+      ticket.destroy
+
+      ObjectManager::Attribute.remove(
+        object: 'User',
+        name: 'select',
+      )
+      ObjectManager::Attribute.migration_execute
+    end
+
+    it 'correctly renders select attributes on chained group object' do
+      attribute = create :object_manager_attribute_select,
+                         object_lookup_id: ObjectLookup.by_name('Group'),
+                         name: 'select'
+      ObjectManager::Attribute.migration_execute
+
+      ticket = create :ticket, customer: @user
+      group = ticket.group
+      group.select = 'key_3'
+      group.save
+
+      renderer = build :notification_factory_renderer,
+                       objects: { ticket: ticket },
+                       template: '#{ticket.group.select} _SEPERATOR_ #{ticket.group.select.value}'
+
+      expect(renderer.render).to eq 'key_3 _SEPERATOR_ value_3'
+      ticket.destroy
+
+      ObjectManager::Attribute.remove(
+        object: 'Group',
+        name: 'select',
+      )
+      ObjectManager::Attribute.migration_execute
+    end
+
+    it 'correctly renders select attributes on chained organization object' do
+      attribute = create :object_manager_attribute_select,
+                         object_lookup_id: ObjectLookup.by_name('Organization'),
+                         name: 'select'
+      ObjectManager::Attribute.migration_execute
+
+      @user.organization.select = 'key_2'
+      @user.organization.save
+      ticket = create :ticket, customer: @user
+
+      renderer = build :notification_factory_renderer,
+                       objects: { ticket: ticket },
+                       template: '#{ticket.customer.organization.select} _SEPERATOR_ #{ticket.customer.organization.select.value}'
+
+      expect(renderer.render).to eq 'key_2 _SEPERATOR_ value_2'
+      ticket.destroy
+
+      ObjectManager::Attribute.remove(
+        object: 'Organization',
+        name: 'select',
+      )
+      ObjectManager::Attribute.migration_execute
+    end
+
+    it 'correctly renders tree select attributes' do
+      attribute = create :object_manager_attribute_tree_select, name: 'tree_select'
+      ObjectManager::Attribute.migration_execute
+
+      ticket = create :ticket, customer: @user, tree_select: 'Incident::Hardware::Laptop'
+
+      renderer = build :notification_factory_renderer,
+                       objects: { ticket: ticket },
+                       template: '#{ticket.tree_select} _SEPERATOR_ #{ticket.tree_select.value}'
+
+      expect(renderer.render).to eq 'Incident::Hardware::Laptop _SEPERATOR_ Incident::Hardware::Laptop'
+      ticket.destroy
+
+      ObjectManager::Attribute.remove(
+        object: 'Ticket',
+        name: 'tree_select',
+      )
+      ObjectManager::Attribute.migration_execute
+    end
+  end
+  # rubocop:enable Lint/InterpolationCheck
+end