diff --git a/lib/notification_factory/renderer.rb b/lib/notification_factory/renderer.rb index f95bd26a9..440734a39 100644 --- a/lib/notification_factory/renderer.rb +++ b/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 diff --git a/spec/factories/notification_factory/renderer.rb b/spec/factories/notification_factory/renderer.rb new file mode 100644 index 000000000..abc251d92 --- /dev/null +++ b/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 diff --git a/spec/factories/object_manager_attribute.rb b/spec/factories/object_manager_attribute.rb index 6e98a3454..9f833edbf 100644 --- a/spec/factories/object_manager_attribute.rb +++ b/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 diff --git a/spec/lib/notification_factory/renderer_spec.rb b/spec/lib/notification_factory/renderer_spec.rb new file mode 100644 index 000000000..0d8eb3256 --- /dev/null +++ b/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