diff --git a/app/assets/javascripts/app/controllers/_settings/area_item_default_timezone.coffee b/app/assets/javascripts/app/controllers/_settings/area_item_default_timezone.coffee
new file mode 100644
index 000000000..b6933eed5
--- /dev/null
+++ b/app/assets/javascripts/app/controllers/_settings/area_item_default_timezone.coffee
@@ -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)
+ )
diff --git a/app/assets/javascripts/app/controllers/getting_started.coffee b/app/assets/javascripts/app/controllers/getting_started.coffee
index 263c0e570..f3817117b 100644
--- a/app/assets/javascripts/app/controllers/getting_started.coffee
+++ b/app/assets/javascripts/app/controllers/getting_started.coffee
@@ -340,6 +340,7 @@ class Base extends App.WizardFullScreen
@params = @formParam(e.target)
@params.logo = @logoPreview.attr('src')
@params.locale_default = App.i18n.detectBrowserLocale()
+ @params.timezone_default = App.i18n.detectBrowserTimezone()
store = (logoResizeDataUrl) =>
@params.logo_resize = logoResizeDataUrl
diff --git a/app/assets/javascripts/app/controllers/widget/default_timezone.coffee b/app/assets/javascripts/app/controllers/widget/default_timezone.coffee
new file mode 100644
index 000000000..a85b327c1
--- /dev/null
+++ b/app/assets/javascripts/app/controllers/widget/default_timezone.coffee
@@ -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')
diff --git a/app/assets/javascripts/app/lib/app_post/i18n.coffee b/app/assets/javascripts/app/lib/app_post/i18n.coffee
index 2cbdec418..c8bc27895 100644
--- a/app/assets/javascripts/app/lib/app_post/i18n.coffee
+++ b/app/assets/javascripts/app/lib/app_post/i18n.coffee
@@ -103,6 +103,17 @@ class App.i18n
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
@include App.LogInclude
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index c08ed2e71..e16e188ad 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,7 +1,8 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
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
assets = {}
@@ -41,4 +42,10 @@ class CalendarsController < ApplicationController
model_destroy_render(Calendar, params)
end
+ def timezones
+ render json: {
+ timezones: Calendar.timezones
+ }
+ end
+
end
diff --git a/app/controllers/getting_started_controller.rb b/app/controllers/getting_started_controller.rb
index 367e231bf..46ab046df 100644
--- a/app/controllers/getting_started_controller.rb
+++ b/app/controllers/getting_started_controller.rb
@@ -148,6 +148,11 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
settings[:locale_default] = params[:locale_default]
end
+ # add timezone_default
+ if params[:timezone_default].present?
+ settings[:timezone_default] = params[:timezone_default]
+ end
+
if messages.present?
render json: {
result: 'invalid',
diff --git a/app/models/ticket.rb b/app/models/ticket.rb
index 28dd42579..740120b55 100644
--- a/app/models/ticket.rb
+++ b/app/models/ticket.rb
@@ -1543,10 +1543,13 @@ result
end
objects = build_notification_template_objects(article)
- body = NotificationFactory::Renderer.new(objects, 'en-en', value['body'], false)
- .render
- .html2text
- .tr(' ', ' ') # convert non-breaking space to simple space
+ body = NotificationFactory::Renderer.new(
+ objects: objects,
+ locale: 'en-en',
+ 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
article = Ticket::Article.create(
diff --git a/app/models/transaction/notification.rb b/app/models/transaction/notification.rb
index 36d653bd3..ec0d41f5e 100644
--- a/app/models/transaction/notification.rb
+++ b/app/models/transaction/notification.rb
@@ -242,7 +242,7 @@ class Transaction::Notification
# only show allowed attributes
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
- #puts "AL #{attribute_list.inspect}"
+
user_related_changes = {}
@item[:changes].each do |key, value|
diff --git a/app/models/transaction/slack.rb b/app/models/transaction/slack.rb
index 5b972f792..b6b716ee8 100644
--- a/app/models/transaction/slack.rb
+++ b/app/models/transaction/slack.rb
@@ -84,7 +84,8 @@ class Transaction::Slack
result = NotificationFactory::Slack.template(
template: template,
- locale: user[:preferences][:locale],
+ locale: user[:preferences][:locale] || Setting.get('locale_default'),
+ timezone: user[:preferences][:timezone] || Setting.get('timezone_default'),
objects: {
ticket: ticket,
article: article,
diff --git a/app/models/translation.rb b/app/models/translation.rb
index acef5a6e5..9f627b5fb 100644
--- a/app/models/translation.rb
+++ b/app/models/translation.rb
@@ -215,6 +215,90 @@ translate strings in ruby context, e. g. for notifications
=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
all:
diff --git a/config/routes/calendar.rb b/config/routes/calendar.rb
index d83201939..caff7b5d4 100644
--- a/config/routes/calendar.rb
+++ b/config/routes/calendar.rb
@@ -2,11 +2,12 @@ Zammad::Application.routes.draw do
api_path = Rails.configuration.api_path
# calendars
- match api_path + '/calendars_init', to: 'calendars#init', via: :get
- match api_path + '/calendars', to: 'calendars#index', via: :get
- match api_path + '/calendars/:id', to: 'calendars#show', via: :get
- match api_path + '/calendars', to: 'calendars#create', via: :post
- match api_path + '/calendars/:id', to: 'calendars#update', via: :put
- match api_path + '/calendars/:id', to: 'calendars#destroy', via: :delete
+ match api_path + '/calendars_init', to: 'calendars#init', via: :get
+ match api_path + '/calendars/timezones', to: 'calendars#timezones', via: :get
+ match api_path + '/calendars', to: 'calendars#index', via: :get
+ match api_path + '/calendars/:id', to: 'calendars#show', via: :get
+ match api_path + '/calendars', to: 'calendars#create', via: :post
+ match api_path + '/calendars/:id', to: 'calendars#update', via: :put
+ match api_path + '/calendars/:id', to: 'calendars#destroy', via: :delete
end
diff --git a/db/migrate/20190208000001_setting_timezone_default.rb b/db/migrate/20190208000001_setting_timezone_default.rb
new file mode 100644
index 000000000..564563e48
--- /dev/null
+++ b/db/migrate/20190208000001_setting_timezone_default.rb
@@ -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
diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb
index 6d90cafb9..778538f0c 100644
--- a/db/seeds/settings.rb
+++ b/db/seeds/settings.rb
@@ -176,6 +176,26 @@ Setting.create_if_not_exists(
},
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(
title: 'Pretty Date',
name: 'pretty_date_format',
diff --git a/lib/notification_factory/mailer.rb b/lib/notification_factory/mailer.rb
index ee90b0bed..463e3bd87 100644
--- a/lib/notification_factory/mailer.rb
+++ b/lib/notification_factory/mailer.rb
@@ -228,6 +228,7 @@ retunes
result = NotificationFactory::Mailer.template(
template: 'password_reset',
locale: 'en-us',
+ timezone: 'America/Santiago',
objects: {
recipient: User.find(2),
},
@@ -236,6 +237,7 @@ retunes
result = NotificationFactory::Mailer.template(
templateInline: "Invitation to \#{config.product_name} at \#{config.fqdn}",
locale: 'en-us',
+ timezone: 'America/Santiago',
objects: {
recipient: User.find(2),
},
@@ -247,6 +249,7 @@ only raw subject/body
result = NotificationFactory::Mailer.template(
template: 'password_reset',
locale: 'en-us',
+ timezone: 'America/Santiago',
objects: {
recipient: User.find(2),
},
@@ -266,7 +269,13 @@ returns
def self.template(data)
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
template = NotificationFactory.template_read(
@@ -276,8 +285,19 @@ returns
type: 'mailer',
)
- message_subject = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:subject], false).render
- message_body = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:body]).render
+ message_subject = NotificationFactory::Renderer.new(
+ 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]
application_template = NotificationFactory.application_template_read(
@@ -286,7 +306,12 @@ returns
)
data[:objects][:message] = message_body
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
{
subject: message_subject,
diff --git a/lib/notification_factory/renderer.rb b/lib/notification_factory/renderer.rb
index bc7f5dfa8..eaf23d9af 100644
--- a/lib/notification_factory/renderer.rb
+++ b/lib/notification_factory/renderer.rb
@@ -5,27 +5,30 @@ class NotificationFactory::Renderer
examples how to use
message_subject = NotificationFactory::Renderer.new(
- {
+ objects: {
ticket: Ticket.first,
},
- 'de-de',
- 'some template #{ticket.title} {config.fqdn}',
- false
+ locale: 'de-de',
+ timezone: 'America/Port-au-Prince',
+ template: 'some template #{ticket.title} {config.fqdn}',
+ escape: false
).render
message_body = NotificationFactory::Renderer.new(
- {
+ objects: {
ticket: Ticket.first,
},
- 'de-de',
- 'some template #{ticket.title} #{config.fqdn}',
+ locale: 'de-de',
+ timezone: 'America/Port-au-Prince',
+ template: 'some template #{ticket.title} #{config.fqdn}',
).render
=end
- def initialize(objects, locale, template, escape = true)
+ def initialize(objects:, locale: nil, timezone: nil, template:, escape: true)
@objects = objects
@locale = locale || Setting.get('locale_default') || 'en-us'
+ @timezone = timezone || Setting.get('timezone_default')
@template = NotificationFactory::Template.new(template, escape)
@escape = escape
end
@@ -141,7 +144,8 @@ examples how to use
else
value
end
- escaping(placeholder, escape)
+
+ escaping(convert_to_timezone(placeholder), escape)
end
# c - config
@@ -159,15 +163,22 @@ examples how to use
end
# h - htmlEscape
- # h('fqdn', htmlEscape)
- def h(key)
- return key if !key
+ # h(htmlEscape)
+ def h(value)
+ return value if !value
- CGI.escapeHTML(key.to_s)
+ CGI.escapeHTML(convert_to_timezone(value).to_s)
end
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)
return key if escape == false
return key if escape.nil? && !@escape
diff --git a/lib/notification_factory/slack.rb b/lib/notification_factory/slack.rb
index 78f0814e5..85542268e 100644
--- a/lib/notification_factory/slack.rb
+++ b/lib/notification_factory/slack.rb
@@ -5,6 +5,7 @@ class NotificationFactory::Slack
result = NotificationFactory::Slack.template(
template: 'ticket_update',
locale: 'en-us',
+ timezone: 'Europe/Berlin',
objects: {
recipient: User.find(2),
ticket: Ticket.find(1)
@@ -23,7 +24,12 @@ returns
def self.template(data)
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
template = NotificationFactory.template_read(
@@ -33,8 +39,20 @@ returns
type: 'slack',
)
- message_subject = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:subject], false).render
- message_body = NotificationFactory::Renderer.new(data[:objects], data[:locale], template[:body], false).render
+ message_subject = NotificationFactory::Renderer.new(
+ 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]
application_template = NotificationFactory.application_template_read(
@@ -43,7 +61,13 @@ returns
)
data[:objects][:message] = message_body
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
{
subject: message_subject.strip!,
diff --git a/spec/factories/notification_factory/renderer.rb b/spec/factories/notification_factory/renderer.rb
index abc251d92..c957878c1 100644
--- a/spec/factories/notification_factory/renderer.rb
+++ b/spec/factories/notification_factory/renderer.rb
@@ -5,6 +5,6 @@ FactoryBot.define do
template ''
escape true
- initialize_with { new(objects, locale, template, escape) }
+ initialize_with { new(objects: objects, locale: locale, template: template, escape: escape) }
end
end
diff --git a/spec/models/translation_spec.rb b/spec/models/translation_spec.rb
index 94e2be0cd..1036cb801 100644
--- a/spec/models/translation_spec.rb
+++ b/spec/models/translation_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Translation do
Translation.sync('de-de')
end
- context 'default translations' do
+ context 'default string translations' do
it 'en with existing word' do
expect(Translation.translate('en', 'New')).to eq('New')
@@ -31,6 +31,82 @@ RSpec.describe Translation do
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
it 'translation is still the same' do
diff --git a/spec/requests/calendar_spec.rb b/spec/requests/calendar_spec.rb
index d2b900996..5f811e7ab 100644
--- a/spec/requests/calendar_spec.rb
+++ b/spec/requests/calendar_spec.rb
@@ -20,6 +20,12 @@ RSpec.describe 'Calendars', type: :request do
expect(json_response).to be_a_kind_of(Hash)
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
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']['Europe/Berlin']).to be_between(1, 2)
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
diff --git a/test/unit/notification_factory_renderer_test.rb b/test/unit/notification_factory_renderer_test.rb
index 759891d40..be5f7e249 100644
--- a/test/unit/notification_factory_renderer_test.rb
+++ b/test/unit/notification_factory_renderer_test.rb
@@ -39,149 +39,164 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
template = "\#{ticket.title}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(ticket.title), result)
template = "\#{ticket.created_at}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
- assert_equal(ticket.created_at.to_s, result)
+ assert_equal('11/12/2016 13:00 (Europe/Berlin)', result)
template = "\#{ticket.created_by.firstname}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('CurrentUser<b>xxx</b>', result)
template = "\#{ticket.updated_at}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
- assert_equal(ticket.updated_at.to_s, result)
+ assert_equal('11/12/2016 15:00 (Europe/Berlin)', result)
template = "\#{ticket.updated_by.firstname}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('CurrentUser<b>xxx</b>', result)
template = "\#{ticket.owner.firstname}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('Owner<b>xxx</b>', result)
template = "\#{ticket. title}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(ticket.title), result)
template = "\#{ticket.\n title}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(ticket.title), result)
template = "\#{ticket.\t title}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(ticket.title), result)
template = "\#{ticket.\t\n title\t}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(ticket.title), result)
template = "\#{ticket.\" title\t}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(ticket.title), result)
template = "\#{ticket.\" title}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(ticket.title), result)
template = "some test
\#{article.body}"
result = described_class.new(
- {
+ objects: {
article: article_html1,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('some test
> test hello
> some new line
', result)
result = described_class.new(
- {
+ objects: {
article: article_plain1,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('some test
> test <b>hello</b>
> some new line
', result)
result = described_class.new(
- {
+ objects: {
article: article_plain2,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('some test
> test <b>hello</b>
> some new line
', result)
@@ -192,11 +207,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
setting = 'fqdn'
template = "\#{config.#{setting}}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(Setting.get(setting), result)
@@ -204,11 +220,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
setting2 = 'product_name'
template = "some \#{config.#{setting1}} and \#{config.#{setting2}}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
@@ -216,11 +233,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
setting2 = 'product_name'
template = "some \#{ config.#{setting1}} and \#{\tconfig.#{setting2}}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal("some #{Setting.get(setting1)} and #{Setting.get(setting2)}", result)
end
@@ -230,41 +248,45 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
#template = "<%= t 'new' %>"
template = "\#{t('new')}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'de-de',
- template,
+ locale: 'de-de',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('neu', result)
template = "some text \#{t('new')} and \#{t('open')}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'de-de',
- template,
+ locale: 'de-de',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('some text neu and offen', result)
template = "some text \#{t('new') } and \#{ t('open')}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'de-de',
- template,
+ locale: 'de-de',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('some text neu and offen', result)
template = "some text \#{\nt('new') } and \#{ t('open')\t}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'de-de',
- template,
+ locale: 'de-de',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('some text neu and offen', result)
@@ -275,11 +297,12 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
template = "\#{t(ticket.state.name)}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'de-de',
- template,
+ locale: 'de-de',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal('neu', result)
@@ -289,111 +312,122 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
template = "\#{}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{no such object}'), result)
template = "\#{notexsiting.notexsiting}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
template = "\#{ticket.notexsiting}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
template = "\#{ticket.}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket. / no such method}'), result)
template = "\#{ticket.title.notexsiting}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.title.notexsiting / no such method}'), result)
template = "\#{ticket.notexsiting.notexsiting}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.notexsiting / no such method}'), result)
template = "\#{notexsiting}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
template = "\#{notexsiting.}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{notexsiting / no such object}'), result)
template = "\#{string}"
result = described_class.new(
- {
+ objects: {
string: 'some string',
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('some string'), result)
template = "\#{fixum}"
result = described_class.new(
- {
+ objects: {
fixum: 123,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('123'), result)
template = "\#{float}"
result = described_class.new(
- {
+ objects: {
float: 123.99,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('123.99'), result)
@@ -403,181 +437,199 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
template = "\#{ticket.title `echo 1`}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.title`echo1` / not allowed}'), result)
template = "\#{ticket.destroy}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
template = "\#{ticket.save}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.save / not allowed}'), result)
template = "\#{ticket.update}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.update / not allowed}'), result)
template = "\#{ticket.create}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
template = "\#{ticket.delete}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.delete / not allowed}'), result)
template = "\#{ticket.remove}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.remove / not allowed}'), result)
template = "\#{ticket.drop}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.drop / not allowed}'), result)
template = "\#{ticket.create}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.create / not allowed}'), result)
template = "\#{ticket.new}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.new / not allowed}'), result)
template = "\#{ticket.update_att}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.update_att / not allowed}'), result)
template = "\#{ticket.all}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.all / not allowed}'), result)
template = "\#{ticket.find}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.find / not allowed}'), result)
template = "\#{ticket.where}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.where / not allowed}'), result)
template = "\#{ticket. destroy}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML('#{ticket.destroy / not allowed}'), result)
template = "\#{ticket.\n destroy}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
template = "\#{ticket.\t destroy}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
template = "\#{ticket.\r destroy}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML("\#{ticket.destroy / not allowed}"), result)
@@ -587,51 +639,56 @@ class NotificationFactoryRendererTest < ActiveSupport::TestCase
template = "\#{ticket.title.first(3)}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(''), result)
template = "\#{ticket.title.last(4)}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML(''), result)
template = "\#{ticket.title.slice(3, 4)}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal(CGI.escapeHTML("\#{ticket.title.slice(3,4) / invalid parameter: 3,4}"), result)
template = "\#{ticket.title.first('some invalid parameter')}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal("\#{ticket.title.first(someinvalidparameter) / invalid parameter: someinvalidparameter}", result)
template = "\#{ticket.title.chomp(`cat /etc/passwd`)}"
result = described_class.new(
- {
+ objects: {
ticket: ticket,
},
- 'en-us',
- template,
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
+ template: template,
).render
assert_equal("\#{ticket.title.chomp(`cat/etc/passwd`) / not allowed}", result)
end
diff --git a/test/unit/notification_factory_slack_template_test.rb b/test/unit/notification_factory_slack_template_test.rb
index 2a1b23ae9..411b7e806 100644
--- a/test/unit/notification_factory_slack_template_test.rb
+++ b/test/unit/notification_factory_slack_template_test.rb
@@ -66,7 +66,8 @@ class NotificationFactorySlackTemplateTest < ActiveSupport::TestCase
changes = {}
result = NotificationFactory::Slack.template(
template: 'ticket_create',
- locale: 'es-us',
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
objects: {
ticket: ticket,
article: article,
@@ -97,12 +98,14 @@ class NotificationFactorySlackTemplateTest < ActiveSupport::TestCase
created_by_id: 1,
)
changes = {
- state: %w[aaa bbb],
- group: %w[xxx yyy],
+ state: %w[aaa bbb],
+ 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(
template: 'ticket_update',
- locale: 'es-us',
+ locale: 'en-us',
+ timezone: 'Europe/Berlin',
objects: {
ticket: ticket,
article: article,
@@ -111,14 +114,31 @@ class NotificationFactorySlackTemplateTest < ActiveSupport::TestCase
changes: changes,
},
)
+
assert_match('# Welcome to Zammad!', result[:subject])
assert_match('Userxxx', result[:body])
assert_match('state: aaa -> bbb', 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('longname', 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
diff --git a/test/unit/ticket_notification_test.rb b/test/unit/ticket_notification_test.rb
index f1e965127..1934dabe0 100644
--- a/test/unit/ticket_notification_test.rb
+++ b/test/unit/ticket_notification_test.rb
@@ -2,6 +2,7 @@ require 'test_helper'
class TicketNotificationTest < ActiveSupport::TestCase
setup do
+ Setting.set('timezone_default', 'Europe/Berlin')
Trigger.create_or_update(
name: 'auto reply - new ticket',
condition: {
@@ -78,7 +79,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
roles: roles,
groups: groups,
preferences: {
- locale: 'en-ca',
+ locale: 'en-us',
+ timezone: 'America/St_Lucia',
},
updated_by_id: 1,
created_by_id: 1,
@@ -1152,6 +1154,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
# en notification
result = NotificationFactory::Mailer.template(
locale: @agent2.preferences[:locale],
+ timezone: @agent2.preferences[:timezone],
template: 'ticket_update',
objects: {
ticket: ticket1,
@@ -1165,7 +1168,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
assert_match(/1 low/, result[:body])
assert_match(/2 normal/, 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_no_match(/pending_till/, 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_till'])
- # de notification
+ # de & Europe/Berlin notification
result = NotificationFactory::Mailer.template(
locale: @agent1.preferences[:locale],
+ timezone: @agent1.preferences[:timezone],
template: 'ticket_update',
objects: {
ticket: ticket1,
@@ -1198,7 +1202,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
assert_match(/1 niedrig/, result[:body])
assert_match(/2 normal/, 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_no_match(/pending_till/, result[:body])
assert_no_match(/i18n/, result[:body])
@@ -1229,6 +1233,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
# de notification
result = NotificationFactory::Mailer.template(
locale: @agent1.preferences[:locale],
+ timezone: @agent1.preferences[:timezone],
template: 'ticket_update',
objects: {
ticket: ticket1,
@@ -1254,6 +1259,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
# en notification
result = NotificationFactory::Mailer.template(
locale: @agent2.preferences[:locale],
+ timezone: @agent2.preferences[:timezone],
template: 'ticket_update',
objects: {
ticket: ticket1,
@@ -1276,6 +1282,22 @@ class TicketNotificationTest < ActiveSupport::TestCase
assert_no_match(/pending_till/, 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