Browse Source

Improved notification lib.

Martin Edenhofer 10 years ago
parent
commit
cb7b79eb2d
2 changed files with 211 additions and 20 deletions
  1. 45 10
      lib/notification_factory.rb
  2. 166 10
      test/unit/notification_factory_test.rb

+ 45 - 10
lib/notification_factory.rb

@@ -1,4 +1,18 @@
 module NotificationFactory
+
+=begin
+
+  result_string = NotificationFactory.build(
+    :string  => 'Hi #{recipient.firstname},',
+    :objects => {
+      :ticket    => ticket,
+      :recipient => User.find(2),
+    },
+    :locale  => 'en',
+  )
+
+=end
+
   def self.build(data)
 
     data[:string].gsub!( / \#\{ \s* ( .+? ) \s* \} /x ) { |placeholder|
@@ -9,12 +23,6 @@ module NotificationFactory
       callback        = $1
       callback_valid  = nil
 
-      # use quoted text
-      callback.gsub!( /\A ( \w+ ) \.body \z/x ) { |item|
-        callback_valid = true
-        item           = item + '.word_wrap( :line_width => 82 ).message_quote.chomp'
-      }
-
       # use config params
       callback.gsub!( /\A config\.( [\w\.]+ ) \z/x ) { |item|
         callback_valid = true
@@ -28,10 +36,27 @@ module NotificationFactory
         object_name   = $1
         object_method = $2
 
-        next if !data[:objects][object_name.to_sym]
+        if data[:objects][object_name.to_sym]
+          callback_valid = true
+          item           = "data[:objects]['#{object_name}'.to_sym]#{object_method}"
+        else
+          item = item
+        end
+      }
 
+      # use quoted text
+      callback.gsub!( /\A ( data\[:objects\]\['article'\.to_sym\] ) \.body \z/x ) { |item|
         callback_valid = true
-        item           = "data[:objects]['#{object_name}'.to_sym]#{object_method}"
+        if data[:objects][:article].content_type == 'text/html'
+          item           = item + '.html2text.message_quote.chomp'
+        else
+          item           = item + '.word_wrap( :line_width => 82 ).message_quote.chomp'
+        end
+      }
+
+      # do validaton, ignore some methodes
+      callback.gsub!( /\.(save|destroy|delete|remove|drop|update|create\(|new|all|where|find)/ix ) { |item|
+        callback_valid = false
       }
 
       if callback_valid
@@ -54,9 +79,19 @@ module NotificationFactory
       placeholder = Translation.translate( locale, string )
     }
 
-    return data[:string]
+    data[:string]
   end
 
+=begin
+
+  success = NotificationFactory.send(
+    :to      => 'somebody@example.com',
+    :subject => 'sime subject',
+    :body    => 'some body'
+  )
+
+=end
+
   def self.send(data)
     sender = Setting.get('notification_sender')
     Rails.logger.info "NOTICE: SEND NOTIFICATION TO: #{data[:recipient][:email]} (from #{sender})"
@@ -71,4 +106,4 @@ module NotificationFactory
       true
     )
   end
-end
+end

+ 166 - 10
test/unit/notification_factory_test.rb

@@ -2,17 +2,26 @@
 require 'test_helper'
 
 class NotificationFactoryTest < ActiveSupport::TestCase
-  test 'notifications' do
+  test 'notifications base' do
     ticket = Ticket.create(
-      :title           => 'some title äöüß',
-      :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,
+      :title         => 'some title äöüß',
+      :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,
+    )
+    article_plain = Ticket::Article.create(
+      :ticket_id     => ticket.id,
+      :type_id       => Ticket::Article::Type.where(:name => 'phone' ).first.id,
+      :sender_id     => Ticket::Article::Sender.where(:name => 'Customer' ).first.id,
+      :from          => 'Zammad Feedback <feedback@example.org>',
+      :body          => 'some text',
+      :internal      => false,
+      :updated_by_id => 1,
+      :created_by_id => 1,
     )
-
     tests = [
       {
         :locale => 'en',
@@ -44,6 +53,16 @@ class NotificationFactoryTest < ActiveSupport::TestCase
         :string => '\'i18n(#{ticket.state.name})\' ticket state',
         :result => '\'neu\' ticket state',
       },
+      {
+        :locale => 'de',
+        :string => 'Subject #{article.from}, Group: #{ticket.group.name}',
+        :result => 'Subject Zammad Feedback <feedback@example.org>, Group: Users',
+      },
+      {
+        :locale => 'de',
+        :string => 'Body #{article.body}, Group: #{ticket.group.name}',
+        :result => 'Body > some text, Group: Users',
+      },
       {
         :locale => 'de',
         :string => '\#{puts `ls`}',
@@ -55,11 +74,148 @@ class NotificationFactoryTest < ActiveSupport::TestCase
         :string  => test[:string],
         :objects => {
           :ticket    => ticket,
+          :article   => article_plain,
+          :recipient => User.find(2),
+        },
+        :locale  => test[:locale]
+      )
+      assert_equal( test[:result], result, "verify result" )
+    }
+
+    ticket.destroy
+  end
+
+  test 'notifications html' do
+    ticket = Ticket.create(
+      :title         => 'some title <b>äöüß</b> 2',
+      :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,
+    )
+    article_html = Ticket::Article.create(
+      :ticket_id     => ticket.id,
+      :type_id       => Ticket::Article::Type.where(:name => 'phone' ).first.id,
+      :sender_id     => Ticket::Article::Sender.where(:name => 'Customer' ).first.id,
+      :from          => 'Zammad Feedback <feedback@example.org>',
+      :body          => 'some <b>text</b><br>next line',
+      :content_type  => 'text/html',
+      :internal      => false,
+      :updated_by_id => 1,
+      :created_by_id => 1,
+    )
+    tests = [
+      {
+        :locale => 'de',
+        :string => 'Subject #{ticket.title}',
+        :result => 'Subject some title <b>äöüß</b> 2',
+      },
+      {
+        :locale => 'de',
+        :string => 'Subject #{article.from}, Group: #{ticket.group.name}',
+        :result => 'Subject Zammad Feedback <feedback@example.org>, Group: Users',
+      },
+      {
+        :locale => 'de',
+        :string => 'Body #{article.body}, Group: #{ticket.group.name}',
+        :result => 'Body > some text
+> next line, Group: Users',
+      },
+    ]
+    tests.each { |test|
+      result = NotificationFactory.build(
+        :string  => test[:string],
+        :objects => {
+          :ticket    => ticket,
+          :article   => article_html,
+          :recipient => User.find(2),
+        },
+        :locale  => test[:locale]
+      )
+      assert_equal( test[:result], result, "verify result" )
+    }
+
+    ticket.destroy
+  end
+
+  test 'notifications attack' do
+    ticket = Ticket.create(
+      :title         => 'some title <b>äöüß</b> 3',
+      :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,
+    )
+    article_html = Ticket::Article.create(
+      :ticket_id     => ticket.id,
+      :type_id       => Ticket::Article::Type.where(:name => 'phone' ).first.id,
+      :sender_id     => Ticket::Article::Sender.where(:name => 'Customer' ).first.id,
+      :from          => 'Zammad Feedback <feedback@example.org>',
+      :body          => 'some <b>text</b><br>next line',
+      :content_type  => 'text/html',
+      :internal      => false,
+      :updated_by_id => 1,
+      :created_by_id => 1,
+    )
+    tests = [
+      {
+        :locale => 'de',
+        :string => '\#{puts `ls`}',
+        :result => '\#{puts `ls`}',
+      },
+      {
+        :locale => 'de',
+        :string => 'attack#1 #{article.destroy}',
+        :result => 'attack#1 #{article.destroy}',
+      },
+      {
+        :locale => 'de',
+        :string => 'attack#2 #{Article.where}',
+        :result => 'attack#2 #{Article.where}',
+      },
+      {
+        :locale => 'de',
+        :string => 'attack#1 #{article.
+        destroy}',
+        :result => 'attack#1 #{article.
+        destroy}',
+      },
+      {
+        :locale => 'de',
+        :string => 'attack#1 #{article.find}',
+        :result => 'attack#1 #{article.find}',
+      },
+      {
+        :locale => 'de',
+        :string => 'attack#1 #{article.update}',
+        :result => 'attack#1 #{article.update}',
+      },
+      {
+        :locale => 'de',
+        :string => 'attack#1 #{article.all}',
+        :result => 'attack#1 #{article.all}',
+      },
+      {
+        :locale => 'de',
+        :string => 'attack#1 #{article.delete}',
+        :result => 'attack#1 #{article.delete}',
+      },
+    ]
+    tests.each { |test|
+      result = NotificationFactory.build(
+        :string  => test[:string],
+        :objects => {
+          :ticket    => ticket,
+          :article   => article_html,
           :recipient => User.find(2),
         },
         :locale  => test[:locale]
       )
-      assert_equal( result, test[:result], "verify result" )
+      assert_equal( test[:result], result, "verify result" )
     }
 
     ticket.destroy