Fixes #1589 - No localised time displayed in trigger (autoreply/slack/...) notifications.
This commit is contained in:
parent
487f36a5a5
commit
63214c9327
22 changed files with 696 additions and 217 deletions
|
@ -0,0 +1,35 @@
|
||||||
|
class App.SettingsAreaItemDefaultTimezone extends App.SettingsAreaItem
|
||||||
|
result: {}
|
||||||
|
|
||||||
|
render: =>
|
||||||
|
@fetchTimezones()
|
||||||
|
|
||||||
|
localRender: (data) =>
|
||||||
|
options = {}
|
||||||
|
for timezone, offset of data.timezones
|
||||||
|
if !offset.toString().match(/(\+|\-)/)
|
||||||
|
offset = "+#{offset}"
|
||||||
|
options[timezone] = "#{timezone} (GMT#{offset})"
|
||||||
|
configure_attributes = [
|
||||||
|
{ name: 'timezone_default', display: '', tag: 'searchable_select', null: false, class: 'input', options: options, default: @setting.state_current.value },
|
||||||
|
]
|
||||||
|
|
||||||
|
@html App.view(@template)(
|
||||||
|
setting: @setting
|
||||||
|
)
|
||||||
|
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @el.find('.form-item')
|
||||||
|
model: { configure_attributes: configure_attributes, className: '' }
|
||||||
|
autofocus: false
|
||||||
|
)
|
||||||
|
|
||||||
|
fetchTimezones: =>
|
||||||
|
@ajax(
|
||||||
|
id: 'calendar_timezones'
|
||||||
|
type: 'GET'
|
||||||
|
url: "#{@apiPath}/calendars/timezones"
|
||||||
|
success: (data) =>
|
||||||
|
@result = data
|
||||||
|
@localRender(data)
|
||||||
|
)
|
|
@ -340,6 +340,7 @@ class Base extends App.WizardFullScreen
|
||||||
@params = @formParam(e.target)
|
@params = @formParam(e.target)
|
||||||
@params.logo = @logoPreview.attr('src')
|
@params.logo = @logoPreview.attr('src')
|
||||||
@params.locale_default = App.i18n.detectBrowserLocale()
|
@params.locale_default = App.i18n.detectBrowserLocale()
|
||||||
|
@params.timezone_default = App.i18n.detectBrowserTimezone()
|
||||||
|
|
||||||
store = (logoResizeDataUrl) =>
|
store = (logoResizeDataUrl) =>
|
||||||
@params.logo_resize = logoResizeDataUrl
|
@params.logo_resize = logoResizeDataUrl
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
class DefaultTimezone extends App.Controller
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
check = =>
|
||||||
|
timezone = App.i18n.detectBrowserTimezone()
|
||||||
|
return if !timezone
|
||||||
|
|
||||||
|
# check system timezone_default
|
||||||
|
if _.isEmpty(@Config('timezone_default')) && @permissionCheck('admin.system')
|
||||||
|
App.Setting.fetchFull(
|
||||||
|
=> @updateSetting(timezone)
|
||||||
|
force: false
|
||||||
|
)
|
||||||
|
|
||||||
|
# prepare user based timezone
|
||||||
|
# check current user timezone
|
||||||
|
#preferences = App.Session.get('preferences')
|
||||||
|
#return if !preferences
|
||||||
|
#return if !_.isEmpty(preferences.timezone)
|
||||||
|
#@ajax(
|
||||||
|
# id: "i18n-set-user-timezone"
|
||||||
|
# type: 'PUT'
|
||||||
|
# url: "#{App.Config.get('api_path')}/users/preferences"
|
||||||
|
# data: JSON.stringify(timezone: timezone)
|
||||||
|
# processData: true
|
||||||
|
#)
|
||||||
|
|
||||||
|
App.Event.bind('auth:login', (session) =>
|
||||||
|
@delay(check, 8500, 'default_timezone')
|
||||||
|
)
|
||||||
|
|
||||||
|
updateSetting: (timezone) ->
|
||||||
|
App.Setting.set('timezone_default', timezone)
|
||||||
|
|
||||||
|
App.Config.set('default_timezone', DefaultTimezone, 'Widgets')
|
|
@ -103,6 +103,17 @@ class App.i18n
|
||||||
|
|
||||||
window.navigator.userLanguage || window.navigator.language || 'en-us'
|
window.navigator.userLanguage || window.navigator.language || 'en-us'
|
||||||
|
|
||||||
|
@detectBrowserTimezone: ->
|
||||||
|
return if !window.Intl
|
||||||
|
return if !window.Intl.DateTimeFormat
|
||||||
|
DateTimeFormat = Intl.DateTimeFormat()
|
||||||
|
return if !DateTimeFormat
|
||||||
|
return if !DateTimeFormat.resolvedOptions
|
||||||
|
resolvedOptions = DateTimeFormat.resolvedOptions()
|
||||||
|
return if !resolvedOptions
|
||||||
|
return if !resolvedOptions.timeZone
|
||||||
|
resolvedOptions.timeZone
|
||||||
|
|
||||||
class _i18nSingleton extends Spine.Module
|
class _i18nSingleton extends Spine.Module
|
||||||
@include App.LogInclude
|
@include App.LogInclude
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class CalendarsController < ApplicationController
|
class CalendarsController < ApplicationController
|
||||||
prepend_before_action { authentication_check(permission: 'admin.calendar') }
|
prepend_before_action -> { authentication_check(permission: 'admin.calendar') }, only: %i[init index show create update destroy]
|
||||||
|
prepend_before_action -> { authentication_check(permission: 'admin') }, only: %i[timezones]
|
||||||
|
|
||||||
def init
|
def init
|
||||||
assets = {}
|
assets = {}
|
||||||
|
@ -41,4 +42,10 @@ class CalendarsController < ApplicationController
|
||||||
model_destroy_render(Calendar, params)
|
model_destroy_render(Calendar, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def timezones
|
||||||
|
render json: {
|
||||||
|
timezones: Calendar.timezones
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -148,6 +148,11 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
|
||||||
settings[:locale_default] = params[:locale_default]
|
settings[:locale_default] = params[:locale_default]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# add timezone_default
|
||||||
|
if params[:timezone_default].present?
|
||||||
|
settings[:timezone_default] = params[:timezone_default]
|
||||||
|
end
|
||||||
|
|
||||||
if messages.present?
|
if messages.present?
|
||||||
render json: {
|
render json: {
|
||||||
result: 'invalid',
|
result: 'invalid',
|
||||||
|
|
|
@ -1543,10 +1543,13 @@ result
|
||||||
end
|
end
|
||||||
|
|
||||||
objects = build_notification_template_objects(article)
|
objects = build_notification_template_objects(article)
|
||||||
body = NotificationFactory::Renderer.new(objects, 'en-en', value['body'], false)
|
body = NotificationFactory::Renderer.new(
|
||||||
.render
|
objects: objects,
|
||||||
.html2text
|
locale: 'en-en',
|
||||||
.tr(' ', ' ') # convert non-breaking space to simple space
|
timezone: Setting.get('timezone_default'),
|
||||||
|
template: value['body'],
|
||||||
|
escape: false
|
||||||
|
).render.html2text.tr(' ', ' ') # convert non-breaking space to simple space
|
||||||
|
|
||||||
# attributes content_type is not needed for SMS
|
# attributes content_type is not needed for SMS
|
||||||
article = Ticket::Article.create(
|
article = Ticket::Article.create(
|
||||||
|
|
|
@ -242,7 +242,7 @@ class Transaction::Notification
|
||||||
|
|
||||||
# only show allowed attributes
|
# only show allowed attributes
|
||||||
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
|
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
|
||||||
#puts "AL #{attribute_list.inspect}"
|
|
||||||
user_related_changes = {}
|
user_related_changes = {}
|
||||||
@item[:changes].each do |key, value|
|
@item[:changes].each do |key, value|
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,8 @@ class Transaction::Slack
|
||||||
|
|
||||||
result = NotificationFactory::Slack.template(
|
result = NotificationFactory::Slack.template(
|
||||||
template: template,
|
template: template,
|
||||||
locale: user[:preferences][:locale],
|
locale: user[:preferences][:locale] || Setting.get('locale_default'),
|
||||||
|
timezone: user[:preferences][:timezone] || Setting.get('timezone_default'),
|
||||||
objects: {
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
article: article,
|
article: article,
|
||||||
|
|
|
@ -215,6 +215,90 @@ translate strings in ruby context, e. g. for notifications
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
translate timestampes in ruby context, e. g. for notifications
|
||||||
|
|
||||||
|
translated = Translation.timestamp('de-de', 'Europe/Berlin', '2018-10-10T10:00:00Z0')
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
translated = Translation.timestamp('de-de', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.timestamp(locale, timezone, timestamp)
|
||||||
|
|
||||||
|
if timestamp.class == String
|
||||||
|
begin
|
||||||
|
timestamp_parsed = Time.zone.parse(timestamp)
|
||||||
|
return timestamp.to_s if !timestamp_parsed
|
||||||
|
|
||||||
|
timestamp = timestamp_parsed
|
||||||
|
rescue
|
||||||
|
return timestamp.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
record = Translation.where(locale: locale, source: 'timestamp', format: 'time').pluck(:target).first
|
||||||
|
return timestamp.to_s if !record
|
||||||
|
|
||||||
|
begin
|
||||||
|
timestamp = timestamp.in_time_zone(timezone)
|
||||||
|
rescue
|
||||||
|
return timestamp.to_s
|
||||||
|
end
|
||||||
|
record.sub!('dd', format('%02d', timestamp.day))
|
||||||
|
record.sub!('d', timestamp.day.to_s)
|
||||||
|
record.sub!('mm', format('%02d', timestamp.month))
|
||||||
|
record.sub!('m', timestamp.month.to_s)
|
||||||
|
record.sub!('yyyy', timestamp.year.to_s)
|
||||||
|
record.sub!('yy', timestamp.year.to_s.last(2))
|
||||||
|
record.sub!('SS', format('%02d', timestamp.sec.to_s))
|
||||||
|
record.sub!('MM', format('%02d', timestamp.min.to_s))
|
||||||
|
record.sub!('HH', format('%02d', timestamp.hour.to_s))
|
||||||
|
"#{record} (#{timezone})"
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
translate date in ruby context, e. g. for notifications
|
||||||
|
|
||||||
|
translated = Translation.date('de-de', '2018-10-10')
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
translated = Translation.date('de-de', Date.parse('2018-10-10'))
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.date(locale, date)
|
||||||
|
|
||||||
|
if date.class == String
|
||||||
|
begin
|
||||||
|
date_parsed = Date.parse(date)
|
||||||
|
return date.to_s if !date_parsed
|
||||||
|
|
||||||
|
date = date_parsed
|
||||||
|
rescue
|
||||||
|
return date.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return date.to_s if date.class != Date
|
||||||
|
|
||||||
|
record = Translation.where(locale: locale, source: 'date', format: 'time').pluck(:target).first
|
||||||
|
return date.to_s if !record
|
||||||
|
|
||||||
|
record.sub!('dd', format('%02d', date.day))
|
||||||
|
record.sub!('d', date.day.to_s)
|
||||||
|
record.sub!('mm', format('%02d', date.month))
|
||||||
|
record.sub!('m', date.month.to_s)
|
||||||
|
record.sub!('yyyy', date.year.to_s)
|
||||||
|
record.sub!('yy', date.year.to_s.last(2))
|
||||||
|
record
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
load translations from local
|
load translations from local
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|
|
@ -2,11 +2,12 @@ Zammad::Application.routes.draw do
|
||||||
api_path = Rails.configuration.api_path
|
api_path = Rails.configuration.api_path
|
||||||
|
|
||||||
# calendars
|
# calendars
|
||||||
match api_path + '/calendars_init', to: 'calendars#init', via: :get
|
match api_path + '/calendars_init', to: 'calendars#init', via: :get
|
||||||
match api_path + '/calendars', to: 'calendars#index', via: :get
|
match api_path + '/calendars/timezones', to: 'calendars#timezones', via: :get
|
||||||
match api_path + '/calendars/:id', to: 'calendars#show', via: :get
|
match api_path + '/calendars', to: 'calendars#index', via: :get
|
||||||
match api_path + '/calendars', to: 'calendars#create', via: :post
|
match api_path + '/calendars/:id', to: 'calendars#show', via: :get
|
||||||
match api_path + '/calendars/:id', to: 'calendars#update', via: :put
|
match api_path + '/calendars', to: 'calendars#create', via: :post
|
||||||
match api_path + '/calendars/:id', to: 'calendars#destroy', via: :delete
|
match api_path + '/calendars/:id', to: 'calendars#update', via: :put
|
||||||
|
match api_path + '/calendars/:id', to: 'calendars#destroy', via: :delete
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
27
db/migrate/20190208000001_setting_timezone_default.rb
Normal file
27
db/migrate/20190208000001_setting_timezone_default.rb
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
class SettingTimezoneDefault < ActiveRecord::Migration[5.1]
|
||||||
|
def up
|
||||||
|
# return if it's a new setup
|
||||||
|
return if !Setting.find_by(name: 'system_init_done')
|
||||||
|
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Timezone',
|
||||||
|
name: 'timezone_default',
|
||||||
|
area: 'System::Branding',
|
||||||
|
description: 'Defines the system default timezone.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
name: 'timezone_default',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: '',
|
||||||
|
preferences: {
|
||||||
|
prio: 9,
|
||||||
|
controller: 'SettingsAreaItemDefaultTimezone',
|
||||||
|
permission: ['admin.system'],
|
||||||
|
},
|
||||||
|
frontend: true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -176,6 +176,26 @@ Setting.create_if_not_exists(
|
||||||
},
|
},
|
||||||
frontend: true
|
frontend: true
|
||||||
)
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Timezone',
|
||||||
|
name: 'timezone_default',
|
||||||
|
area: 'System::Branding',
|
||||||
|
description: 'Defines the system default timezone.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
name: 'timezone_default',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: '',
|
||||||
|
preferences: {
|
||||||
|
prio: 9,
|
||||||
|
controller: 'SettingsAreaItemDefaultTimezone',
|
||||||
|
permission: ['admin.system'],
|
||||||
|
},
|
||||||
|
frontend: true
|
||||||
|
)
|
||||||
Setting.create_or_update(
|
Setting.create_or_update(
|
||||||
title: 'Pretty Date',
|
title: 'Pretty Date',
|
||||||
name: 'pretty_date_format',
|
name: 'pretty_date_format',
|
||||||
|
|
|
@ -228,6 +228,7 @@ retunes
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
template: 'password_reset',
|
template: 'password_reset',
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
|
timezone: 'America/Santiago',
|
||||||
objects: {
|
objects: {
|
||||||
recipient: User.find(2),
|
recipient: User.find(2),
|
||||||
},
|
},
|
||||||
|
@ -236,6 +237,7 @@ retunes
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
templateInline: "Invitation to \#{config.product_name} at \#{config.fqdn}",
|
templateInline: "Invitation to \#{config.product_name} at \#{config.fqdn}",
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
|
timezone: 'America/Santiago',
|
||||||
objects: {
|
objects: {
|
||||||
recipient: User.find(2),
|
recipient: User.find(2),
|
||||||
},
|
},
|
||||||
|
@ -247,6 +249,7 @@ only raw subject/body
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
template: 'password_reset',
|
template: 'password_reset',
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
|
timezone: 'America/Santiago',
|
||||||
objects: {
|
objects: {
|
||||||
recipient: User.find(2),
|
recipient: User.find(2),
|
||||||
},
|
},
|
||||||
|
@ -266,7 +269,13 @@ returns
|
||||||
def self.template(data)
|
def self.template(data)
|
||||||
|
|
||||||
if data[:templateInline]
|
if data[:templateInline]
|
||||||
return NotificationFactory::Renderer.new(data[:objects], data[:locale], data[:templateInline], data[:quote]).render
|
return NotificationFactory::Renderer.new(
|
||||||
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: data[:templateInline],
|
||||||
|
escape: data[:quote]
|
||||||
|
).render
|
||||||
end
|
end
|
||||||
|
|
||||||
template = NotificationFactory.template_read(
|
template = NotificationFactory.template_read(
|
||||||
|
@ -276,8 +285,19 @@ returns
|
||||||
type: 'mailer',
|
type: 'mailer',
|
||||||
)
|
)
|
||||||
|
|
||||||
message_subject = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:subject], false).render
|
message_subject = NotificationFactory::Renderer.new(
|
||||||
message_body = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:body]).render
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: template[:subject],
|
||||||
|
escape: false
|
||||||
|
).render
|
||||||
|
message_body = NotificationFactory::Renderer.new(
|
||||||
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: template[:body]
|
||||||
|
).render
|
||||||
|
|
||||||
if !data[:raw]
|
if !data[:raw]
|
||||||
application_template = NotificationFactory.application_template_read(
|
application_template = NotificationFactory.application_template_read(
|
||||||
|
@ -286,7 +306,12 @@ returns
|
||||||
)
|
)
|
||||||
data[:objects][:message] = message_body
|
data[:objects][:message] = message_body
|
||||||
data[:objects][:standalone] = data[:standalone]
|
data[:objects][:standalone] = data[:standalone]
|
||||||
message_body = NotificationFactory::Renderer.new(data[:objects], data[:locale], application_template).render
|
message_body = NotificationFactory::Renderer.new(
|
||||||
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: application_template
|
||||||
|
).render
|
||||||
end
|
end
|
||||||
{
|
{
|
||||||
subject: message_subject,
|
subject: message_subject,
|
||||||
|
|
|
@ -5,27 +5,30 @@ class NotificationFactory::Renderer
|
||||||
examples how to use
|
examples how to use
|
||||||
|
|
||||||
message_subject = NotificationFactory::Renderer.new(
|
message_subject = NotificationFactory::Renderer.new(
|
||||||
{
|
objects: {
|
||||||
ticket: Ticket.first,
|
ticket: Ticket.first,
|
||||||
},
|
},
|
||||||
'de-de',
|
locale: 'de-de',
|
||||||
'some template <b>#{ticket.title}</b> {config.fqdn}',
|
timezone: 'America/Port-au-Prince',
|
||||||
false
|
template: 'some template <b>#{ticket.title}</b> {config.fqdn}',
|
||||||
|
escape: false
|
||||||
).render
|
).render
|
||||||
|
|
||||||
message_body = NotificationFactory::Renderer.new(
|
message_body = NotificationFactory::Renderer.new(
|
||||||
{
|
objects: {
|
||||||
ticket: Ticket.first,
|
ticket: Ticket.first,
|
||||||
},
|
},
|
||||||
'de-de',
|
locale: 'de-de',
|
||||||
'some template <b>#{ticket.title}</b> #{config.fqdn}',
|
timezone: 'America/Port-au-Prince',
|
||||||
|
template: 'some template <b>#{ticket.title}</b> #{config.fqdn}',
|
||||||
).render
|
).render
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def initialize(objects, locale, template, escape = true)
|
def initialize(objects:, locale: nil, timezone: nil, template:, escape: true)
|
||||||
@objects = objects
|
@objects = objects
|
||||||
@locale = locale || Setting.get('locale_default') || 'en-us'
|
@locale = locale || Setting.get('locale_default') || 'en-us'
|
||||||
|
@timezone = timezone || Setting.get('timezone_default')
|
||||||
@template = NotificationFactory::Template.new(template, escape)
|
@template = NotificationFactory::Template.new(template, escape)
|
||||||
@escape = escape
|
@escape = escape
|
||||||
end
|
end
|
||||||
|
@ -141,7 +144,8 @@ examples how to use
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
escaping(placeholder, escape)
|
|
||||||
|
escaping(convert_to_timezone(placeholder), escape)
|
||||||
end
|
end
|
||||||
|
|
||||||
# c - config
|
# c - config
|
||||||
|
@ -159,15 +163,22 @@ examples how to use
|
||||||
end
|
end
|
||||||
|
|
||||||
# h - htmlEscape
|
# h - htmlEscape
|
||||||
# h('fqdn', htmlEscape)
|
# h(htmlEscape)
|
||||||
def h(key)
|
def h(value)
|
||||||
return key if !key
|
return value if !value
|
||||||
|
|
||||||
CGI.escapeHTML(key.to_s)
|
CGI.escapeHTML(convert_to_timezone(value).to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def convert_to_timezone(value)
|
||||||
|
return Translation.timestamp(@locale, @timezone, value) if value.class == ActiveSupport::TimeWithZone
|
||||||
|
return Translation.date(@locale, value) if value.class == Date
|
||||||
|
|
||||||
|
value
|
||||||
|
end
|
||||||
|
|
||||||
def escaping(key, escape)
|
def escaping(key, escape)
|
||||||
return key if escape == false
|
return key if escape == false
|
||||||
return key if escape.nil? && !@escape
|
return key if escape.nil? && !@escape
|
||||||
|
|
|
@ -5,6 +5,7 @@ class NotificationFactory::Slack
|
||||||
result = NotificationFactory::Slack.template(
|
result = NotificationFactory::Slack.template(
|
||||||
template: 'ticket_update',
|
template: 'ticket_update',
|
||||||
locale: 'en-us',
|
locale: 'en-us',
|
||||||
|
timezone: 'Europe/Berlin',
|
||||||
objects: {
|
objects: {
|
||||||
recipient: User.find(2),
|
recipient: User.find(2),
|
||||||
ticket: Ticket.find(1)
|
ticket: Ticket.find(1)
|
||||||
|
@ -23,7 +24,12 @@ returns
|
||||||
def self.template(data)
|
def self.template(data)
|
||||||
|
|
||||||
if data[:templateInline]
|
if data[:templateInline]
|
||||||
return NotificationFactory::Renderer.new(data[:objects], data[:locale], data[:templateInline]).render
|
return NotificationFactory::Renderer.new(
|
||||||
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: data[:templateInline]
|
||||||
|
).render
|
||||||
end
|
end
|
||||||
|
|
||||||
template = NotificationFactory.template_read(
|
template = NotificationFactory.template_read(
|
||||||
|
@ -33,8 +39,20 @@ returns
|
||||||
type: 'slack',
|
type: 'slack',
|
||||||
)
|
)
|
||||||
|
|
||||||
message_subject = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:subject], false).render
|
message_subject = NotificationFactory::Renderer.new(
|
||||||
message_body = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:body], false).render
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: template[:subject],
|
||||||
|
escape: false
|
||||||
|
).render
|
||||||
|
message_body = NotificationFactory::Renderer.new(
|
||||||
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: template[:body],
|
||||||
|
escape: false
|
||||||
|
).render
|
||||||
|
|
||||||
if !data[:raw]
|
if !data[:raw]
|
||||||
application_template = NotificationFactory.application_template_read(
|
application_template = NotificationFactory.application_template_read(
|
||||||
|
@ -43,7 +61,13 @@ returns
|
||||||
)
|
)
|
||||||
data[:objects][:message] = message_body
|
data[:objects][:message] = message_body
|
||||||
data[:objects][:standalone] = data[:standalone]
|
data[:objects][:standalone] = data[:standalone]
|
||||||
message_body = NotificationFactory::Renderer.new(data[:objects], data[:locale], application_template, false).render
|
message_body = NotificationFactory::Renderer.new(
|
||||||
|
objects: data[:objects],
|
||||||
|
locale: data[:locale],
|
||||||
|
timezone: data[:timezone],
|
||||||
|
template: application_template,
|
||||||
|
escape: false
|
||||||
|
).render
|
||||||
end
|
end
|
||||||
{
|
{
|
||||||
subject: message_subject.strip!,
|
subject: message_subject.strip!,
|
||||||
|
|
|
@ -5,6 +5,6 @@ FactoryBot.define do
|
||||||
template ''
|
template ''
|
||||||
escape true
|
escape true
|
||||||
|
|
||||||
initialize_with { new(objects, locale, template, escape) }
|
initialize_with { new(objects: objects, locale: locale, template: template, escape: escape) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ RSpec.describe Translation do
|
||||||
Translation.sync('de-de')
|
Translation.sync('de-de')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'default translations' do
|
context 'default string translations' do
|
||||||
|
|
||||||
it 'en with existing word' do
|
it 'en with existing word' do
|
||||||
expect(Translation.translate('en', 'New')).to eq('New')
|
expect(Translation.translate('en', 'New')).to eq('New')
|
||||||
|
@ -31,6 +31,82 @@ RSpec.describe Translation do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'default timestamp translations' do
|
||||||
|
|
||||||
|
it 'de-de with array' do
|
||||||
|
expect(Translation.timestamp('de-de', 'Europe/Berlin', ['some value'])).to eq('["some value"]')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not_existing with timestamp as string' do
|
||||||
|
expect(Translation.timestamp('not_existing', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('2018-10-10 10:00:00 UTC')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not_existing with time object' do
|
||||||
|
expect(Translation.timestamp('not_existing', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))).to eq('2018-10-10 10:00:00 UTC')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not_existing with invalid timestamp string' do
|
||||||
|
expect(Translation.timestamp('not_existing', 'Europe/Berlin', 'something')).to eq('something')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en-us with invalid time zone' do
|
||||||
|
expect(Translation.timestamp('en-us', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('10/10/2018 12:00 (Europe/Berlin)')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en-us with timestamp as string' do
|
||||||
|
expect(Translation.timestamp('en-us', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('10/10/2018 12:00 (Europe/Berlin)')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en-us with time object' do
|
||||||
|
expect(Translation.timestamp('en-us', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))).to eq('10/10/2018 12:00 (Europe/Berlin)')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'de-de with timestamp as string' do
|
||||||
|
expect(Translation.timestamp('de-de', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('10.10.2018 12:00 (Europe/Berlin)')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'de-de with time object' do
|
||||||
|
expect(Translation.timestamp('de-de', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))).to eq('10.10.2018 12:00 (Europe/Berlin)')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'default date translations' do
|
||||||
|
|
||||||
|
it 'de-de with array' do
|
||||||
|
expect(Translation.date('de-de', ['some value'])).to eq('["some value"]')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not_existing with date as string' do
|
||||||
|
expect(Translation.date('not_existing', '2018-10-10')).to eq('2018-10-10')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not_existing with date object' do
|
||||||
|
expect(Translation.date('not_existing', Date.parse('2018-10-10'))).to eq('2018-10-10')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not_existing with invalid data as string' do
|
||||||
|
expect(Translation.date('not_existing', 'something')).to eq('something')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en-us with date as string' do
|
||||||
|
expect(Translation.date('en-us', '2018-10-10')).to eq('10/10/2018')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'en-us with date object' do
|
||||||
|
expect(Translation.date('en-us', Date.parse('2018-10-10'))).to eq('10/10/2018')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'de-de with date as string' do
|
||||||
|
expect(Translation.date('de-de', '2018-10-10')).to eq('10.10.2018')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'de-de with date object' do
|
||||||
|
expect(Translation.date('de-de', Date.parse('2018-10-10'))).to eq('10.10.2018')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
context 'remote_translation_need_update? tests' do
|
context 'remote_translation_need_update? tests' do
|
||||||
|
|
||||||
it 'translation is still the same' do
|
it 'translation is still the same' do
|
||||||
|
|
|
@ -20,6 +20,12 @@ RSpec.describe 'Calendars', type: :request do
|
||||||
|
|
||||||
expect(json_response).to be_a_kind_of(Hash)
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
expect(json_response['error']).to eq('authentication failed')
|
expect(json_response['error']).to eq('authentication failed')
|
||||||
|
|
||||||
|
get '/api/v1/calendars/timezones', as: :json
|
||||||
|
expect(response).to have_http_status(401)
|
||||||
|
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['error']).to eq('authentication failed')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does calendar index with admin' do
|
it 'does calendar index with admin' do
|
||||||
|
@ -58,6 +64,13 @@ RSpec.describe 'Calendars', type: :request do
|
||||||
expect(json_response['timezones']['America/Sitka']).to be_between(-9, -8)
|
expect(json_response['timezones']['America/Sitka']).to be_between(-9, -8)
|
||||||
expect(json_response['timezones']['Europe/Berlin']).to be_between(1, 2)
|
expect(json_response['timezones']['Europe/Berlin']).to be_between(1, 2)
|
||||||
expect(json_response['assets']).to be_truthy
|
expect(json_response['assets']).to be_truthy
|
||||||
|
|
||||||
|
# timezones
|
||||||
|
get '/api/v1/calendars/timezones', as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['timezones']).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['timezones']['America/New_York']).to be_truthy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -39,149 +39,164 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
template = "\#{ticket.title}"
|
template = "\#{ticket.title}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML(ticket.title), result)
|
assert_equal(CGI.escapeHTML(ticket.title), result)
|
||||||
|
|
||||||
template = "\#{ticket.created_at}"
|
template = "\#{ticket.created_at}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(ticket.created_at.to_s, result)
|
assert_equal('11/12/2016 13:00 (Europe/Berlin)', result)
|
||||||
|
|
||||||
template = "\#{ticket.created_by.firstname}"
|
template = "\#{ticket.created_by.firstname}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('CurrentUser<b>xxx</b>', result)
|
assert_equal('CurrentUser<b>xxx</b>', result)
|
||||||
|
|
||||||
template = "\#{ticket.updated_at}"
|
template = "\#{ticket.updated_at}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(ticket.updated_at.to_s, result)
|
assert_equal('11/12/2016 15:00 (Europe/Berlin)', result)
|
||||||
|
|
||||||
template = "\#{ticket.updated_by.firstname}"
|
template = "\#{ticket.updated_by.firstname}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('CurrentUser<b>xxx</b>', result)
|
assert_equal('CurrentUser<b>xxx</b>', result)
|
||||||
|
|
||||||
template = "\#{ticket.owner.firstname}"
|
template = "\#{ticket.owner.firstname}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('Owner<b>xxx</b>', result)
|
assert_equal('Owner<b>xxx</b>', result)
|
||||||
|
|
||||||
template = "\#{ticket. title}"
|
template = "\#{ticket. title}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML(ticket.title), result)
|
assert_equal(CGI.escapeHTML(ticket.title), result)
|
||||||
|
|
||||||
template = "\#{ticket.\n title}"
|
template = "\#{ticket.\n title}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML(ticket.title), result)
|
assert_equal(CGI.escapeHTML(ticket.title), result)
|
||||||
|
|
||||||
template = "\#{ticket.\t title}"
|
template = "\#{ticket.\t title}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML(ticket.title), result)
|
assert_equal(CGI.escapeHTML(ticket.title), result)
|
||||||
|
|
||||||
template = "\#{ticket.\t\n title\t}"
|
template = "\#{ticket.\t\n title\t}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML(ticket.title), result)
|
assert_equal(CGI.escapeHTML(ticket.title), result)
|
||||||
|
|
||||||
template = "\#{ticket.\" title\t}"
|
template = "\#{ticket.\" title\t}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML(ticket.title), result)
|
assert_equal(CGI.escapeHTML(ticket.title), result)
|
||||||
|
|
||||||
template = "\#{<a href=\"/test123\">ticket.\" title</a>}"
|
template = "\#{<a href=\"/test123\">ticket.\" title</a>}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML(ticket.title), result)
|
assert_equal(CGI.escapeHTML(ticket.title), result)
|
||||||
|
|
||||||
template = "some test<br>\#{article.body}"
|
template = "some test<br>\#{article.body}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
article: article_html1,
|
article: article_html1,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('some test<br>> test hello<br>> some new line<br>', result)
|
assert_equal('some test<br>> test hello<br>> some new line<br>', result)
|
||||||
|
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
article: article_plain1,
|
article: article_plain1,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('some test<br>> test <b>hello</b><br>> some new line<br>', result)
|
assert_equal('some test<br>> test <b>hello</b><br>> some new line<br>', result)
|
||||||
|
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
article: article_plain2,
|
article: article_plain2,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('some test<br>> test <b>hello</b><br>> some new line<br>', result)
|
assert_equal('some test<br>> test <b>hello</b><br>> some new line<br>', result)
|
||||||
|
|
||||||
|
@ -192,11 +207,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
setting = 'fqdn'
|
setting = 'fqdn'
|
||||||
template = "\#{config.#{setting}}"
|
template = "\#{config.#{setting}}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(Setting.get(setting), result)
|
assert_equal(Setting.get(setting), result)
|
||||||
|
|
||||||
|
@ -204,11 +220,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
setting2 = 'product_name'
|
setting2 = 'product_name'
|
||||||
template = "some \#{config.#{setting1}} and \#{config.#{setting2}}"
|
template = "some \#{config.#{setting1}} and \#{config.#{setting2}}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
|
assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
|
||||||
|
|
||||||
|
@ -216,11 +233,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
setting2 = 'product_name'
|
setting2 = 'product_name'
|
||||||
template = "some \#{ config.#{setting1}} and \#{\tconfig.#{setting2}}"
|
template = "some \#{ config.#{setting1}} and \#{\tconfig.#{setting2}}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
|
assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
|
||||||
end
|
end
|
||||||
|
@ -230,41 +248,45 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
#template = "<%= t 'new' %>"
|
#template = "<%= t 'new' %>"
|
||||||
template = "\#{t('new')}"
|
template = "\#{t('new')}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'de-de',
|
locale: 'de-de',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('neu', result)
|
assert_equal('neu', result)
|
||||||
|
|
||||||
template = "some text \#{t('new')} and \#{t('open')}"
|
template = "some text \#{t('new')} and \#{t('open')}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'de-de',
|
locale: 'de-de',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('some text neu and offen', result)
|
assert_equal('some text neu and offen', result)
|
||||||
|
|
||||||
template = "some text \#{t('new') } and \#{ t('open')}"
|
template = "some text \#{t('new') } and \#{ t('open')}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'de-de',
|
locale: 'de-de',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('some text neu and offen', result)
|
assert_equal('some text neu and offen', result)
|
||||||
|
|
||||||
template = "some text \#{\nt('new') } and \#{ t('open')\t}"
|
template = "some text \#{\nt('new') } and \#{ t('open')\t}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'de-de',
|
locale: 'de-de',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal('some text neu and offen', result)
|
assert_equal('some text neu and offen', result)
|
||||||
|
|
||||||
|
@ -275,11 +297,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
template = "\#{t(ticket.state.name)}"
|
template = "\#{t(ticket.state.name)}"
|
||||||
|
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'de-de',
|
locale: 'de-de',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
|
|
||||||
assert_equal('neu', result)
|
assert_equal('neu', result)
|
||||||
|
@ -289,111 +312,122 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
template = "\#{}"
|
template = "\#{}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{no such object}'), result)
|
assert_equal(CGI.escapeHTML('#{no such object}'), result)
|
||||||
|
|
||||||
template = "\#{notexsiting.notexsiting}"
|
template = "\#{notexsiting.notexsiting}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
|
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.notexsiting}"
|
template = "\#{ticket.notexsiting}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.}"
|
template = "\#{ticket.}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket. / no such method}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket. / no such method}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.title.notexsiting}"
|
template = "\#{ticket.title.notexsiting}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.title.notexsiting / no such method}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.title.notexsiting / no such method}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.notexsiting.notexsiting}"
|
template = "\#{ticket.notexsiting.notexsiting}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
|
||||||
|
|
||||||
template = "\#{notexsiting}"
|
template = "\#{notexsiting}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
|
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
|
||||||
|
|
||||||
template = "\#{notexsiting.}"
|
template = "\#{notexsiting.}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
|
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
|
||||||
|
|
||||||
template = "\#{string}"
|
template = "\#{string}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
string: 'some string',
|
string: 'some string',
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('some string'), result)
|
assert_equal(CGI.escapeHTML('some string'), result)
|
||||||
|
|
||||||
template = "\#{fixum}"
|
template = "\#{fixum}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
fixum: 123,
|
fixum: 123,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('123'), result)
|
assert_equal(CGI.escapeHTML('123'), result)
|
||||||
|
|
||||||
template = "\#{float}"
|
template = "\#{float}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
float: 123.99,
|
float: 123.99,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('123.99'), result)
|
assert_equal(CGI.escapeHTML('123.99'), result)
|
||||||
|
|
||||||
|
@ -403,181 +437,199 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
template = "\#{ticket.title `echo 1`}"
|
template = "\#{ticket.title `echo 1`}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.title`echo1` / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.title`echo1` / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.destroy}"
|
template = "\#{ticket.destroy}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.save}"
|
template = "\#{ticket.save}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.save / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.save / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.update}"
|
template = "\#{ticket.update}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.update / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.update / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.create}"
|
template = "\#{ticket.create}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.delete}"
|
template = "\#{ticket.delete}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.delete / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.delete / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.remove}"
|
template = "\#{ticket.remove}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.remove / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.remove / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.drop}"
|
template = "\#{ticket.drop}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.drop / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.drop / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.create}"
|
template = "\#{ticket.create}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.new}"
|
template = "\#{ticket.new}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.new / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.new / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.update_att}"
|
template = "\#{ticket.update_att}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.update_att / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.update_att / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.all}"
|
template = "\#{ticket.all}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.all / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.all / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.find}"
|
template = "\#{ticket.find}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.find / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.find / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.where}"
|
template = "\#{ticket.where}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.where / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.where / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket. destroy}"
|
template = "\#{ticket. destroy}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
|
assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
|
||||||
|
|
||||||
template = "\#{ticket.\n destroy}"
|
template = "\#{ticket.\n destroy}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
|
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
|
||||||
|
|
||||||
template = "\#{ticket.\t destroy}"
|
template = "\#{ticket.\t destroy}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
|
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
|
||||||
|
|
||||||
template = "\#{ticket.\r destroy}"
|
template = "\#{ticket.\r destroy}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
|
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
|
||||||
|
|
||||||
|
@ -587,51 +639,56 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
template = "\#{ticket.title.first(3)}"
|
template = "\#{ticket.title.first(3)}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('<b>'), result)
|
assert_equal(CGI.escapeHTML('<b>'), result)
|
||||||
|
|
||||||
template = "\#{ticket.title.last(4)}"
|
template = "\#{ticket.title.last(4)}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML('</b>'), result)
|
assert_equal(CGI.escapeHTML('</b>'), result)
|
||||||
|
|
||||||
template = "\#{ticket.title.slice(3, 4)}"
|
template = "\#{ticket.title.slice(3, 4)}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal(CGI.escapeHTML("\#{ticket.title.slice(3,4) / invalid parameter: 3,4}"), result)
|
assert_equal(CGI.escapeHTML("\#{ticket.title.slice(3,4) / invalid parameter: 3,4}"), result)
|
||||||
|
|
||||||
template = "\#{ticket.title.first('some invalid parameter')}"
|
template = "\#{ticket.title.first('some invalid parameter')}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal("\#{ticket.title.first(someinvalidparameter) / invalid parameter: someinvalidparameter}", result)
|
assert_equal("\#{ticket.title.first(someinvalidparameter) / invalid parameter: someinvalidparameter}", result)
|
||||||
|
|
||||||
template = "\#{ticket.title.chomp(`cat /etc/passwd`)}"
|
template = "\#{ticket.title.chomp(`cat /etc/passwd`)}"
|
||||||
result = described_class.new(
|
result = described_class.new(
|
||||||
{
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
},
|
},
|
||||||
'en-us',
|
locale: 'en-us',
|
||||||
template,
|
timezone: 'Europe/Berlin',
|
||||||
|
template: template,
|
||||||
).render
|
).render
|
||||||
assert_equal("\#{ticket.title.chomp(`cat/etc/passwd`) / not allowed}", result)
|
assert_equal("\#{ticket.title.chomp(`cat/etc/passwd`) / not allowed}", result)
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,7 +66,8 @@ class NotificationFactorySlackTemplateTest < ActiveSupport::TestCase
|
||||||
changes = {}
|
changes = {}
|
||||||
result = NotificationFactory::Slack.template(
|
result = NotificationFactory::Slack.template(
|
||||||
template: 'ticket_create',
|
template: 'ticket_create',
|
||||||
locale: 'es-us',
|
locale: 'en-us',
|
||||||
|
timezone: 'Europe/Berlin',
|
||||||
objects: {
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
article: article,
|
article: article,
|
||||||
|
@ -97,12 +98,14 @@ class NotificationFactorySlackTemplateTest < ActiveSupport::TestCase
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
changes = {
|
changes = {
|
||||||
state: %w[aaa bbb],
|
state: %w[aaa bbb],
|
||||||
group: %w[xxx yyy],
|
group: %w[xxx yyy],
|
||||||
|
pending_time: [Time.zone.parse('2019-04-01T10:00:00Z0'), Time.zone.parse('2019-04-01T23:00:00Z0')],
|
||||||
}
|
}
|
||||||
result = NotificationFactory::Slack.template(
|
result = NotificationFactory::Slack.template(
|
||||||
template: 'ticket_update',
|
template: 'ticket_update',
|
||||||
locale: 'es-us',
|
locale: 'en-us',
|
||||||
|
timezone: 'Europe/Berlin',
|
||||||
objects: {
|
objects: {
|
||||||
ticket: ticket,
|
ticket: ticket,
|
||||||
article: article,
|
article: article,
|
||||||
|
@ -111,14 +114,31 @@ class NotificationFactorySlackTemplateTest < ActiveSupport::TestCase
|
||||||
changes: changes,
|
changes: changes,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert_match('# Welcome to Zammad!', result[:subject])
|
assert_match('# Welcome to Zammad!', result[:subject])
|
||||||
assert_match('User<b>xxx</b>', result[:body])
|
assert_match('User<b>xxx</b>', result[:body])
|
||||||
assert_match('state: aaa -> bbb', result[:body])
|
assert_match('state: aaa -> bbb', result[:body])
|
||||||
assert_match('group: xxx -> yyy', result[:body])
|
assert_match('group: xxx -> yyy', result[:body])
|
||||||
|
assert_match('pending_time: 04/01/2019 12:00 (Europe/Berlin) -> 04/02/2019 01:00 (Europe/Berlin)', result[:body])
|
||||||
assert_no_match('Dein', result[:body])
|
assert_no_match('Dein', result[:body])
|
||||||
assert_no_match('longname', result[:body])
|
assert_no_match('longname', result[:body])
|
||||||
assert_match('Current User', result[:body])
|
assert_match('Current User', result[:body])
|
||||||
|
|
||||||
|
# en notification
|
||||||
|
ticket.escalation_at = Time.zone.parse('2019-04-01T10:00:00Z')
|
||||||
|
result = NotificationFactory::Slack.template(
|
||||||
|
template: 'ticket_escalation',
|
||||||
|
locale: 'en-us',
|
||||||
|
timezone: 'Europe/Berlin',
|
||||||
|
objects: {
|
||||||
|
ticket: ticket,
|
||||||
|
article: article,
|
||||||
|
recipient: agent1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_match('# Welcome to Zammad!', result[:subject])
|
||||||
|
assert_match('is escalated since "04/01/2019 12:00 (Europe/Berlin)"!', result[:body])
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@ require 'test_helper'
|
||||||
|
|
||||||
class TicketNotificationTest < ActiveSupport::TestCase
|
class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
setup do
|
setup do
|
||||||
|
Setting.set('timezone_default', 'Europe/Berlin')
|
||||||
Trigger.create_or_update(
|
Trigger.create_or_update(
|
||||||
name: 'auto reply - new ticket',
|
name: 'auto reply - new ticket',
|
||||||
condition: {
|
condition: {
|
||||||
|
@ -78,7 +79,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
roles: roles,
|
roles: roles,
|
||||||
groups: groups,
|
groups: groups,
|
||||||
preferences: {
|
preferences: {
|
||||||
locale: 'en-ca',
|
locale: 'en-us',
|
||||||
|
timezone: 'America/St_Lucia',
|
||||||
},
|
},
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
|
@ -1152,6 +1154,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
# en notification
|
# en notification
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
locale: @agent2.preferences[:locale],
|
locale: @agent2.preferences[:locale],
|
||||||
|
timezone: @agent2.preferences[:timezone],
|
||||||
template: 'ticket_update',
|
template: 'ticket_update',
|
||||||
objects: {
|
objects: {
|
||||||
ticket: ticket1,
|
ticket: ticket1,
|
||||||
|
@ -1165,7 +1168,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
assert_match(/1 low/, result[:body])
|
assert_match(/1 low/, result[:body])
|
||||||
assert_match(/2 normal/, result[:body])
|
assert_match(/2 normal/, result[:body])
|
||||||
assert_match(/Pending till/, result[:body])
|
assert_match(/Pending till/, result[:body])
|
||||||
assert_match(/2015-01-11 23:33:47 UTC/, result[:body])
|
assert_match('01/11/2015 19:33 (America/St_Lucia)', result[:body])
|
||||||
assert_match(/update/, result[:body])
|
assert_match(/update/, result[:body])
|
||||||
assert_no_match(/pending_till/, result[:body])
|
assert_no_match(/pending_till/, result[:body])
|
||||||
assert_no_match(/i18n/, result[:body])
|
assert_no_match(/i18n/, result[:body])
|
||||||
|
@ -1181,9 +1184,10 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
assert_not(human_changes['pending_time'])
|
assert_not(human_changes['pending_time'])
|
||||||
assert_not(human_changes['pending_till'])
|
assert_not(human_changes['pending_till'])
|
||||||
|
|
||||||
# de notification
|
# de & Europe/Berlin notification
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
locale: @agent1.preferences[:locale],
|
locale: @agent1.preferences[:locale],
|
||||||
|
timezone: @agent1.preferences[:timezone],
|
||||||
template: 'ticket_update',
|
template: 'ticket_update',
|
||||||
objects: {
|
objects: {
|
||||||
ticket: ticket1,
|
ticket: ticket1,
|
||||||
|
@ -1198,7 +1202,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
assert_match(/1 niedrig/, result[:body])
|
assert_match(/1 niedrig/, result[:body])
|
||||||
assert_match(/2 normal/, result[:body])
|
assert_match(/2 normal/, result[:body])
|
||||||
assert_match(/Warten/, result[:body])
|
assert_match(/Warten/, result[:body])
|
||||||
assert_match(/2015-01-11 23:33:47 UTC/, result[:body])
|
assert_match('12.01.2015 00:33 (Europe/Berlin)', result[:body])
|
||||||
assert_match(/aktualis/, result[:body])
|
assert_match(/aktualis/, result[:body])
|
||||||
assert_no_match(/pending_till/, result[:body])
|
assert_no_match(/pending_till/, result[:body])
|
||||||
assert_no_match(/i18n/, result[:body])
|
assert_no_match(/i18n/, result[:body])
|
||||||
|
@ -1229,6 +1233,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
# de notification
|
# de notification
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
locale: @agent1.preferences[:locale],
|
locale: @agent1.preferences[:locale],
|
||||||
|
timezone: @agent1.preferences[:timezone],
|
||||||
template: 'ticket_update',
|
template: 'ticket_update',
|
||||||
objects: {
|
objects: {
|
||||||
ticket: ticket1,
|
ticket: ticket1,
|
||||||
|
@ -1254,6 +1259,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
# en notification
|
# en notification
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
locale: @agent2.preferences[:locale],
|
locale: @agent2.preferences[:locale],
|
||||||
|
timezone: @agent2.preferences[:timezone],
|
||||||
template: 'ticket_update',
|
template: 'ticket_update',
|
||||||
objects: {
|
objects: {
|
||||||
ticket: ticket1,
|
ticket: ticket1,
|
||||||
|
@ -1276,6 +1282,22 @@ class TicketNotificationTest < ActiveSupport::TestCase
|
||||||
assert_no_match(/pending_till/, result[:body])
|
assert_no_match(/pending_till/, result[:body])
|
||||||
assert_no_match(/i18n/, result[:body])
|
assert_no_match(/i18n/, result[:body])
|
||||||
|
|
||||||
|
# en notification
|
||||||
|
ticket1.escalation_at = Time.zone.parse('2019-04-01T10:00:00Z')
|
||||||
|
result = NotificationFactory::Mailer.template(
|
||||||
|
locale: @agent2.preferences[:locale],
|
||||||
|
timezone: @agent2.preferences[:timezone],
|
||||||
|
template: 'ticket_escalation',
|
||||||
|
objects: {
|
||||||
|
ticket: ticket1,
|
||||||
|
article: article,
|
||||||
|
recipient: @agent2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_match('Ticket is escalated (some notification template test 1 Bobs\'s resumé', result[:subject])
|
||||||
|
assert_match('is escalated since "04/01/2019 06:00 (America/St_Lucia)"!', result[:body])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue