From 5492f4f24f1514e44e41b1ebb3d06240b6071888 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Tue, 23 Oct 2018 05:03:26 +0200 Subject: [PATCH 01/11] Followup for issue #1394 - Reindex elastic search not possible because of /Twitter::NullObject. --- .../article/communicate_sms/background_job.rb | 1 + .../communicate_telegram/background_job.rb | 4 +- .../communicate_twitter/background_job.rb | 8 ++-- ...xed_twitter_ticket_article_preferences4.rb | 40 ------------------- ...ed_twitter_ticket_article_preferences6.rb} | 15 ++++++- lib/tweet_base.rb | 16 ++++++-- test/unit/ticket_article_twitter_test.rb | 4 +- 7 files changed, 34 insertions(+), 54 deletions(-) delete mode 100644 db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb rename db/migrate/{20180628000001_fixed_twitter_ticket_article_preferences5.rb => 20180806000001_fixed_twitter_ticket_article_preferences6.rb} (71%) diff --git a/app/models/observer/ticket/article/communicate_sms/background_job.rb b/app/models/observer/ticket/article/communicate_sms/background_job.rb index b5f62defc..c6ca40471 100644 --- a/app/models/observer/ticket/article/communicate_sms/background_job.rb +++ b/app/models/observer/ticket/article/communicate_sms/background_job.rb @@ -6,6 +6,7 @@ class Observer::Ticket::Article::CommunicateSms::BackgroundJob def perform article = Ticket::Article.find(@article_id) + # set retry count article.preferences['delivery_retry'] ||= 0 article.preferences['delivery_retry'] += 1 diff --git a/app/models/observer/ticket/article/communicate_telegram/background_job.rb b/app/models/observer/ticket/article/communicate_telegram/background_job.rb index edeb53e51..4d0d9e5a4 100644 --- a/app/models/observer/ticket/article/communicate_telegram/background_job.rb +++ b/app/models/observer/ticket/article/communicate_telegram/background_job.rb @@ -7,8 +7,8 @@ class Observer::Ticket::Article::CommunicateTelegram::BackgroundJob article = Ticket::Article.find(@article_id) # set retry count - record.preferences['delivery_retry'] ||= 0 - record.preferences['delivery_retry'] += 1 + article.preferences['delivery_retry'] ||= 0 + article.preferences['delivery_retry'] += 1 ticket = Ticket.lookup(id: article.ticket_id) log_error(article, "Can't find ticket.preferences for Ticket.find(#{article.ticket_id})") if !ticket.preferences diff --git a/app/models/observer/ticket/article/communicate_twitter/background_job.rb b/app/models/observer/ticket/article/communicate_twitter/background_job.rb index 7161fd851..323dcfd1d 100644 --- a/app/models/observer/ticket/article/communicate_twitter/background_job.rb +++ b/app/models/observer/ticket/article/communicate_twitter/background_job.rb @@ -7,8 +7,8 @@ class Observer::Ticket::Article::CommunicateTwitter::BackgroundJob article = Ticket::Article.find(@article_id) # set retry count - record.preferences['delivery_retry'] ||= 0 - record.preferences['delivery_retry'] += 1 + article.preferences['delivery_retry'] ||= 0 + article.preferences['delivery_retry'] += 1 ticket = Ticket.lookup(id: article.ticket_id) log_error(article, "Can't find ticket.preferences for Ticket.find(#{article.ticket_id})") if !ticket.preferences @@ -62,7 +62,7 @@ class Observer::Ticket::Article::CommunicateTwitter::BackgroundJob mention_ids.push user.id end article.to = to - article.preferences['twitter'] = { + article.preferences['twitter'] = TweetBase.preferences_cleanup( mention_ids: mention_ids, geo: tweet.geo, retweeted: tweet.retweeted?, @@ -74,7 +74,7 @@ class Observer::Ticket::Article::CommunicateTwitter::BackgroundJob favorited: tweet.favorited?, truncated: tweet.truncated?, created_at: tweet.created_at, - } + ) end else raise "Unknown tweet type '#{tweet.class}'" diff --git a/db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb b/db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb deleted file mode 100644 index e39216dfe..000000000 --- a/db/migrate/20170908000001_fixed_twitter_ticket_article_preferences4.rb +++ /dev/null @@ -1,40 +0,0 @@ -class FixedTwitterTicketArticlePreferences4 < ActiveRecord::Migration[5.0] - def up - - # return if it's a new setup - return if !Setting.find_by(name: 'system_init_done') - - # find article preferences with Twitter::NullObject and replace it with nill to prevent elasticsearch index issue - article_type_ids = Ticket::Article::Type.where(name: ['twitter status', 'twitter direct-message']).pluck(:id) - article_ids = Ticket::Article.where(type_id: article_type_ids).pluck(:id) - article_ids.each do |article_id| - article = Ticket::Article.find(article_id) - next if !article.preferences - - changed = false - article.preferences.each_value do |value| - next if value.class != ActiveSupport::HashWithIndifferentAccess - - value.each do |sub_key, sub_level| - if sub_level.class == NilClass - value[sub_key] = nil - next - end - if sub_level.class == Twitter::Place - value[sub_key] = sub_level.attrs - changed = true - next - end - next if sub_level.class != Twitter::NullObject - - value[sub_key] = nil - changed = true - end - end - next if !changed - - article.save! - end - - end -end diff --git a/db/migrate/20180628000001_fixed_twitter_ticket_article_preferences5.rb b/db/migrate/20180806000001_fixed_twitter_ticket_article_preferences6.rb similarity index 71% rename from db/migrate/20180628000001_fixed_twitter_ticket_article_preferences5.rb rename to db/migrate/20180806000001_fixed_twitter_ticket_article_preferences6.rb index b36f6a860..33fffa6ba 100644 --- a/db/migrate/20180628000001_fixed_twitter_ticket_article_preferences5.rb +++ b/db/migrate/20180806000001_fixed_twitter_ticket_article_preferences6.rb @@ -1,4 +1,4 @@ -class FixedTwitterTicketArticlePreferences5 < ActiveRecord::Migration[5.0] +class FixedTwitterTicketArticlePreferences6 < ActiveRecord::Migration[5.0] def up # return if it's a new setup @@ -21,7 +21,7 @@ class FixedTwitterTicketArticlePreferences5 < ActiveRecord::Migration[5.0] next end if sub_level.class == Twitter::Place || sub_level.class == Twitter::Geo - value[sub_key] = sub_level.attrs + value[sub_key] = sub_level.to_h changed = true next end @@ -31,6 +31,17 @@ class FixedTwitterTicketArticlePreferences5 < ActiveRecord::Migration[5.0] changed = true end end + + if article.preferences[:twitter]&.key?(:geo) && article.preferences[:twitter][:geo].nil? + article.preferences[:twitter][:geo] = {} + changed = true + end + + if article.preferences[:twitter]&.key?(:place) && article.preferences[:twitter][:place].nil? + article.preferences[:twitter][:place] = {} + changed = true + end + next if !changed article.save! diff --git a/lib/tweet_base.rb b/lib/tweet_base.rb index d6910cb36..bcd26bcdd 100644 --- a/lib/tweet_base.rb +++ b/lib/tweet_base.rb @@ -208,7 +208,7 @@ class TweetBase end article_preferences = { - twitter: twitter_preferences, + twitter: self.class.preferences_cleanup(twitter_preferences), links: [ { url: "https://twitter.com/statuses/#{tweet.id}", @@ -228,7 +228,7 @@ class TweetBase type_id: Ticket::Article::Type.find_by(name: article_type).id, sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, internal: false, - preferences: preferences_cleanup(article_preferences), + preferences: article_preferences, ) end @@ -366,7 +366,7 @@ class TweetBase false end - def preferences_cleanup(preferences) + def self.preferences_cleanup(preferences) # replace Twitter::NullObject with nill to prevent elasticsearch index issue preferences.each_value do |value| @@ -378,7 +378,7 @@ class TweetBase next end if sub_level.class == Twitter::Place || sub_level.class == Twitter::Geo - value[sub_key] = sub_level.attrs + value[sub_key] = sub_level.to_h next end next if sub_level.class != Twitter::NullObject @@ -386,6 +386,14 @@ class TweetBase value[sub_key] = nil end end + + if preferences[:geo].blank? + preferences[:geo] = {} + end + if preferences[:place].blank? + preferences[:place] = {} + end + preferences end diff --git a/test/unit/ticket_article_twitter_test.rb b/test/unit/ticket_article_twitter_test.rb index f17fe2890..f36fa8ce8 100644 --- a/test/unit/ticket_article_twitter_test.rb +++ b/test/unit/ticket_article_twitter_test.rb @@ -56,7 +56,7 @@ class TicketArticleTwitter < ActiveSupport::TestCase from: '@example', body: 'some tweet', internal: false, - preferences: TweetBase.new.preferences_cleanup(preferences), + preferences: TweetBase.preferences_cleanup(preferences), updated_by_id: 1, created_by_id: 1, ) @@ -97,7 +97,7 @@ class TicketArticleTwitter < ActiveSupport::TestCase from: '@example', body: 'some tweet', internal: false, - preferences: TweetBase.new.preferences_cleanup(preferences), + preferences: TweetBase.preferences_cleanup(preferences), updated_by_id: 1, created_by_id: 1, ) From 47120f058537066e6faf6a655181018519e947f4 Mon Sep 17 00:00:00 2001 From: Billy Zhou Date: Tue, 23 Oct 2018 01:15:54 +0800 Subject: [PATCH 02/11] Fixed regression introduced by 8fb46b0448 where replying to a phone ticket no longer works --- app/assets/javascripts/app/lib/app_post/utils.coffee | 2 +- public/assets/tests/html_utils.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/app/lib/app_post/utils.coffee b/app/assets/javascripts/app/lib/app_post/utils.coffee index e7392119b..8eb83c257 100644 --- a/app/assets/javascripts/app/lib/app_post/utils.coffee +++ b/app/assets/javascripts/app/lib/app_post/utils.coffee @@ -1028,7 +1028,7 @@ class App.Utils # the article we are replying to is an incoming call else if article.from?.match(/@/) - articleNew.to = article.from + articleNew.to = App.Utils.parseAddressListLocal(article.from).join(', ') # if sender is customer but in article.from is no email, try to get # customers email via customer user diff --git a/public/assets/tests/html_utils.js b/public/assets/tests/html_utils.js index c105987f4..e7ecd85eb 100644 --- a/public/assets/tests/html_utils.js +++ b/public/assets/tests/html_utils.js @@ -2944,7 +2944,7 @@ test('check getRecipientArticle format', function() { sender: { name: 'Customer', }, - from: article_customer.email, + from: 'article lastname ', to: 'some group', message_id: 'message_id22', created_by: { From a3e531af21370293fa806fc04b397023c7948d12 Mon Sep 17 00:00:00 2001 From: Felix Niklas Date: Tue, 23 Oct 2018 15:38:43 +0200 Subject: [PATCH 03/11] Avatars: replace image with initials when printing --- app/assets/javascripts/app/models/user.coffee | 1 + .../javascripts/app/views/avatar.jst.eco | 2 +- app/assets/stylesheets/print.scss | 29 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/app/models/user.coffee b/app/assets/javascripts/app/models/user.coffee index 4ae576bc3..5ce2b6d85 100644 --- a/app/assets/javascripts/app/models/user.coffee +++ b/app/assets/javascripts/app/models/user.coffee @@ -105,6 +105,7 @@ class App.User extends App.Model placement: placement vip: vip url: @imageUrl() + initials: @initials() isOutOfOffice: -> return false if @out_of_office isnt true diff --git a/app/assets/javascripts/app/views/avatar.jst.eco b/app/assets/javascripts/app/views/avatar.jst.eco index 423634fb4..294d400fd 100644 --- a/app/assets/javascripts/app/views/avatar.jst.eco +++ b/app/assets/javascripts/app/views/avatar.jst.eco @@ -1,3 +1,3 @@ -<%- @data %>> +<%- @data %> data-initials="<%- @initials %>"> <%- @Icon('crown') if @vip %> \ No newline at end of file diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss index d0f7588ff..7d67b68b8 100644 --- a/app/assets/stylesheets/print.scss +++ b/app/assets/stylesheets/print.scss @@ -201,6 +201,35 @@ th.js-tableHead:not([data-column-key="icon"]) { .avatar { border: 1px solid black; + + &:not(.avatar--unique) { + &:before { + content: attr(data-initials); + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + text-align: center; + font-size: 13px; + line-height: 40px; + } + + &.size-30:before { + font-size: 10px; + line-height: 32px; + } + + &.size-50:before { + font-size: 16px; + line-height: 52px; + } + + &.size-80:before { + font-size: 26px; + line-height: 84px; + } + } } From e0fd1e52ec78179390433f268fff3f91af03cad5 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Tue, 23 Oct 2018 10:53:17 +0200 Subject: [PATCH 04/11] Fixed usage of wrong assert (which resulted in always true/success by checking hard coded values). --- test/unit/aaa_string_test.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/unit/aaa_string_test.rb b/test/unit/aaa_string_test.rb index e1068e711..325e02c84 100644 --- a/test/unit/aaa_string_test.rb +++ b/test/unit/aaa_string_test.rb @@ -991,7 +991,7 @@ html.html2html_strict html = '' (body, attachments_inline) = HtmlSanitizer.replace_inline_images(html) assert_match(//, body) - assert(1, attachments_inline.count) + assert_equal(1, attachments_inline.count) assert_equal('image1.jpeg', attachments_inline[0][:filename]) assert_equal('image/jpeg', attachments_inline[0][:preferences]['Content-Type']) assert_match(/@#{Setting.get('fqdn')}/, attachments_inline[0][:preferences]['Content-ID']) @@ -1000,7 +1000,7 @@ html.html2html_strict html = 'abc' (body, attachments_inline) = HtmlSanitizer.replace_inline_images(html) assert_match(/abc/, body) - assert(1, attachments_inline.count) + assert_equal(1, attachments_inline.count) assert_equal('image1.jpeg', attachments_inline[0][:filename]) assert_equal('image/jpeg', attachments_inline[0][:preferences]['Content-Type']) assert_match(/@#{Setting.get('fqdn')}/, attachments_inline[0][:preferences]['Content-ID']) @@ -1009,7 +1009,7 @@ html.html2html_strict html = 'abc/, body) - assert(1, attachments_inline.count) + assert_equal(1, attachments_inline.count) assert_equal('image1.jpeg', attachments_inline[0][:filename]) assert_equal('image/jpeg', attachments_inline[0][:preferences]['Content-Type']) assert_match(/@#{Setting.get('fqdn')}/, attachments_inline[0][:preferences]['Content-ID']) @@ -1018,12 +1018,12 @@ html.html2html_strict html = 'abc' (body, attachments_inline) = HtmlSanitizer.replace_inline_images(html) assert_match(/abc/, body) - assert(0, attachments_inline.count) + assert_equal(0, attachments_inline.count) html = '

123

' (body, attachments_inline) = HtmlSanitizer.replace_inline_images(html) assert_match(/
\s+

123<\/p>\s+\s+<\/div>/, body) - assert(2, attachments_inline.count) + assert_equal(2, attachments_inline.count) assert_equal('image1.jpeg', attachments_inline[0][:filename]) assert_equal('image/jpeg', attachments_inline[0][:preferences]['Content-Type']) assert_match(/@#{Setting.get('fqdn')}/, attachments_inline[0][:preferences]['Content-ID']) From f074c0c7341e3f5cca9f1f2486437b0189646818 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 25 Oct 2018 01:46:43 +0200 Subject: [PATCH 05/11] Followup for issue #1394 - Reindex elastic search not possible because of /Twitter::NullObject. --- ...ed_twitter_ticket_article_preferences7.rb} | 2 +- lib/tweet_base.rb | 61 +++++++++- test/unit/ticket_article_twitter_test.rb | 113 +++++++++++++++--- 3 files changed, 153 insertions(+), 23 deletions(-) rename db/migrate/{20180806000001_fixed_twitter_ticket_article_preferences6.rb => 20180806000001_fixed_twitter_ticket_article_preferences7.rb} (96%) diff --git a/db/migrate/20180806000001_fixed_twitter_ticket_article_preferences6.rb b/db/migrate/20180806000001_fixed_twitter_ticket_article_preferences7.rb similarity index 96% rename from db/migrate/20180806000001_fixed_twitter_ticket_article_preferences6.rb rename to db/migrate/20180806000001_fixed_twitter_ticket_article_preferences7.rb index 33fffa6ba..5f39b5796 100644 --- a/db/migrate/20180806000001_fixed_twitter_ticket_article_preferences6.rb +++ b/db/migrate/20180806000001_fixed_twitter_ticket_article_preferences7.rb @@ -1,4 +1,4 @@ -class FixedTwitterTicketArticlePreferences6 < ActiveRecord::Migration[5.0] +class FixedTwitterTicketArticlePreferences7 < ActiveRecord::Migration[5.0] def up # return if it's a new setup diff --git a/lib/tweet_base.rb b/lib/tweet_base.rb index bcd26bcdd..98369b021 100644 --- a/lib/tweet_base.rb +++ b/lib/tweet_base.rb @@ -366,10 +366,50 @@ class TweetBase false end +=begin + + replace Twitter::Place and Twitter::Geo as hash and replace Twitter::NullObject with nil + + preferences = TweetBase.preferences_cleanup( + twitter: twitter_preferences, + links: [ + { + url: 'https://twitter.com/statuses/123', + target: '_blank', + name: 'on Twitter', + }, + ], + ) + +or + + preferences = { + twitter: TweetBase.preferences_cleanup(twitter_preferences), + links: [ + { + url: 'https://twitter.com/statuses/123', + target: '_blank', + name: 'on Twitter', + }, + ], + } + +=end + def self.preferences_cleanup(preferences) # replace Twitter::NullObject with nill to prevent elasticsearch index issue - preferences.each_value do |value| + preferences.each do |key, value| + + if value.class == Twitter::Place || value.class == Twitter::Geo + preferences[key] = value.to_h + next + end + if value.class == Twitter::NullObject + preferences[key] = nil + next + end + next if !value.is_a?(Hash) value.each do |sub_key, sub_level| @@ -387,11 +427,20 @@ class TweetBase end end - if preferences[:geo].blank? - preferences[:geo] = {} - end - if preferences[:place].blank? - preferences[:place] = {} + if preferences[:twitter] + if preferences[:twitter][:geo].blank? + preferences[:twitter][:geo] = {} + end + if preferences[:twitter][:place].blank? + preferences[:twitter][:place] = {} + end + else + if preferences[:geo].blank? + preferences[:geo] = {} + end + if preferences[:place].blank? + preferences[:place] = {} + end end preferences diff --git a/test/unit/ticket_article_twitter_test.rb b/test/unit/ticket_article_twitter_test.rb index f36fa8ce8..d23756021 100644 --- a/test/unit/ticket_article_twitter_test.rb +++ b/test/unit/ticket_article_twitter_test.rb @@ -40,7 +40,7 @@ class TicketArticleTwitter < ActiveSupport::TestCase truncated: false } preferences = { - twitter: twitter_preferences, + twitter: TweetBase.preferences_cleanup(twitter_preferences), links: [ { url: 'https://twitter.com/statuses/123', @@ -56,18 +56,58 @@ class TicketArticleTwitter < ActiveSupport::TestCase from: '@example', body: 'some tweet', internal: false, - preferences: TweetBase.preferences_cleanup(preferences), + preferences: preferences, updated_by_id: 1, created_by_id: 1, ) assert(article1.preferences[:twitter]) assert_equal(1_234_567_890, article1.preferences[:twitter][:mention_ids][0]) - assert_nil(article1.preferences[:twitter][:geo]) - assert_equal(NilClass, article1.preferences[:twitter][:geo].class) - assert_nil(article1.preferences[:twitter][:place]) - assert_equal(NilClass, article1.preferences[:twitter][:place].class) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article1.preferences[:twitter][:geo].class) + assert(article1.preferences[:twitter][:geo].blank?) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article1.preferences[:twitter][:place].class) + assert(article1.preferences[:twitter][:place].blank?) - twitter_preferences = { + twitter_preferences = { + mention_ids: [1_234_567_890], + geo: Twitter::NullObject.new, + retweeted: false, + possibly_sensitive: false, + in_reply_to_user_id: 1_234_567_890, + place: Twitter::NullObject.new, + retweet_count: 0, + source: 'Tweetbot for Mac', + favorited: false, + truncated: false + } + preferences = TweetBase.preferences_cleanup( + twitter: twitter_preferences, + links: [ + { + url: 'https://twitter.com/statuses/123', + target: '_blank', + name: 'on Twitter', + }, + ], + ) + article2 = Ticket::Article.create!( + ticket_id: ticket1.id, + type_id: Ticket::Article::Type.find_by(name: 'twitter status').id, + sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, + from: '@example', + body: 'some tweet', + internal: false, + preferences: preferences, + updated_by_id: 1, + created_by_id: 1, + ) + assert(article2.preferences[:twitter]) + assert_equal(1_234_567_890, article2.preferences[:twitter][:mention_ids][0]) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article2.preferences[:twitter][:geo].class) + assert(article2.preferences[:twitter][:geo].blank?) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article2.preferences[:twitter][:place].class) + assert(article2.preferences[:twitter][:place].blank?) + + twitter_preferences = { mention_ids: [1_234_567_890], geo: Twitter::Geo.new(coordinates: [1, 1]), retweeted: false, @@ -80,7 +120,7 @@ class TicketArticleTwitter < ActiveSupport::TestCase truncated: false } preferences = { - twitter: twitter_preferences, + twitter: TweetBase.preferences_cleanup(twitter_preferences), links: [ { url: 'https://twitter.com/statuses/123', @@ -90,23 +130,64 @@ class TicketArticleTwitter < ActiveSupport::TestCase ], } - article2 = Ticket::Article.create!( + article3 = Ticket::Article.create!( ticket_id: ticket1.id, type_id: Ticket::Article::Type.find_by(name: 'twitter status').id, sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, from: '@example', body: 'some tweet', internal: false, - preferences: TweetBase.preferences_cleanup(preferences), + preferences: preferences, updated_by_id: 1, created_by_id: 1, ) - assert(article2.preferences[:twitter]) - assert_equal(1_234_567_890, article2.preferences[:twitter][:mention_ids][0]) - assert_equal(ActiveSupport::HashWithIndifferentAccess, article2.preferences[:twitter][:geo].class) - assert_equal({ 'coordinates' => [1, 1] }, article2.preferences[:twitter][:geo]) - assert_equal(ActiveSupport::HashWithIndifferentAccess, article2.preferences[:twitter][:place].class) - assert_equal({ 'country' => 'da', 'name' => 'do', 'woeid' => 1, 'id' => 1 }, article2.preferences[:twitter][:place]) + assert(article3.preferences[:twitter]) + assert_equal(1_234_567_890, article3.preferences[:twitter][:mention_ids][0]) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article3.preferences[:twitter][:geo].class) + assert_equal({ 'coordinates' => [1, 1] }, article3.preferences[:twitter][:geo]) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article3.preferences[:twitter][:place].class) + assert_equal({ 'country' => 'da', 'name' => 'do', 'woeid' => 1, 'id' => 1 }, article3.preferences[:twitter][:place]) + + twitter_preferences = { + mention_ids: [1_234_567_890], + geo: Twitter::Geo.new(coordinates: [1, 1]), + retweeted: false, + possibly_sensitive: false, + in_reply_to_user_id: 1_234_567_890, + place: Twitter::Place.new(country: 'da', name: 'do', woeid: 1, id: 1), + retweet_count: 0, + source: 'Tweetbot for Mac', + favorited: false, + truncated: false + } + preferences = TweetBase.preferences_cleanup( + twitter: twitter_preferences, + links: [ + { + url: 'https://twitter.com/statuses/123', + target: '_blank', + name: 'on Twitter', + }, + ], + ) + + article4 = Ticket::Article.create!( + ticket_id: ticket1.id, + type_id: Ticket::Article::Type.find_by(name: 'twitter status').id, + sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, + from: '@example', + body: 'some tweet', + internal: false, + preferences: preferences, + updated_by_id: 1, + created_by_id: 1, + ) + assert(article4.preferences[:twitter]) + assert_equal(1_234_567_890, article4.preferences[:twitter][:mention_ids][0]) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article4.preferences[:twitter][:geo].class) + assert_equal({ 'coordinates' => [1, 1] }, article4.preferences[:twitter][:geo]) + assert_equal(ActiveSupport::HashWithIndifferentAccess, article4.preferences[:twitter][:place].class) + assert_equal({ 'country' => 'da', 'name' => 'do', 'woeid' => 1, 'id' => 1 }, article4.preferences[:twitter][:place]) end From dd583d753cdaa7ec0048ab8a3567cc02eb35c373 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 25 Oct 2018 01:43:16 +0200 Subject: [PATCH 06/11] Fixed mysql/mariadb issue (Mysql2::Error: Invalid default value for 'initialized_at'). --- db/migrate/20181017000001_cti_generic_api2.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/db/migrate/20181017000001_cti_generic_api2.rb b/db/migrate/20181017000001_cti_generic_api2.rb index ad2bbde74..9cd9975b7 100644 --- a/db/migrate/20181017000001_cti_generic_api2.rb +++ b/db/migrate/20181017000001_cti_generic_api2.rb @@ -6,7 +6,14 @@ class CtiGenericApi2 < ActiveRecord::Migration[5.1] return if !column_exists?(:cti_logs, :initialized_at) return if column_exists?(:cti_logs, :initialized_at_cleanup) - add_column :cti_logs, :initialized_at_cleanup, :timestamp, limit: 3, null: true + if ActiveRecord::Base.connection_config[:adapter] == 'mysql2' + # disable the MySQL strict_mode for the current connection + execute("SET sql_mode = ''") + add_column :cti_logs, :initialized_at_cleanup, :timestamp, limit: 3, null: true, default: '0000-00-00 00:00:00' + else + add_column :cti_logs, :initialized_at_cleanup, :timestamp, limit: 3, null: true + end + Cti::Log.connection.schema_cache.clear! Cti::Log.reset_column_information From 004d3c1cbbfaeef4abe0678235ce28ce7bb771eb Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 25 Oct 2018 07:29:39 +0200 Subject: [PATCH 07/11] Updated for 2.8.0. --- CHANGELOG.md | 5 ++--- VERSION | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be65f2d58..aba01afb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Change Log -## [2.7.0](https://github.com/zammad/zammad/tree/2.7.0) (2018-xx-xx) -[Full Changelog](https://github.com/zammad/zammad/compare/2.6.0...2.7.0) +## [2.8.0](https://github.com/zammad/zammad/tree/2.8.0) (2018-xx-xx) +[Full Changelog](https://github.com/zammad/zammad/compare/2.7.0...2.8.0) **Implemented enhancements:** @@ -13,4 +13,3 @@ -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file diff --git a/VERSION b/VERSION index e17ae7579..03d7e5272 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.7.x +2.8.x From 195e264cb8ad94b0e411a1f82e2fbcba2259eedd Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 25 Oct 2018 01:21:35 +0200 Subject: [PATCH 08/11] Added article to placeholder options. --- .../app/controllers/_ui_element/ticket_perform_action.coffee | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee index b1ff84895..7d30630b0 100644 --- a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee +++ b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee @@ -364,6 +364,11 @@ class App.UiElement.ticket_perform_action object: 'Ticket' display: 'Ticket' }, + { + prefix: 'article' + object: 'TicketArticle' + display: 'Article' + }, { prefix: 'user' object: 'User' From 96eaac4771c82ab6bf964c507d61f190b4a4a31f Mon Sep 17 00:00:00 2001 From: Denny Bresch Date: Wed, 24 Oct 2018 14:30:13 +0200 Subject: [PATCH 09/11] Fixed typo 'Mai' to 'May'. --- app/assets/javascripts/app/controllers/report.coffee | 4 ++-- app/assets/javascripts/app/controllers/time_accounting.coffee | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/app/controllers/report.coffee b/app/assets/javascripts/app/controllers/report.coffee index 51d9704cf..6476e3828 100644 --- a/app/assets/javascripts/app/controllers/report.coffee +++ b/app/assets/javascripts/app/controllers/report.coffee @@ -193,7 +193,7 @@ class Graph extends App.ControllerContent else if @params.timeRange is 'week' xaxis = [[0, 'Mon'], [1, 'Tue'], [2, 'Wed'], [3, 'Thr'], [4, 'Fri'], [5, 'Sat'], [6, 'Sun'] ] else - xaxis = [[0, 'Jan'], [1, 'Feb'], [2, 'Mar'], [3, 'Apr'], [4, 'Mai'], [5, 'Jun'], [6, 'Jul'], [7, 'Aug'], [8, 'Sep'], [9, 'Oct'], [10, 'Nov'], [11, 'Dec']] + xaxis = [[0, 'Jan'], [1, 'Feb'], [2, 'Mar'], [3, 'Apr'], [4, 'May'], [5, 'Jun'], [6, 'Jul'], [7, 'Aug'], [8, 'Sep'], [9, 'Oct'], [10, 'Nov'], [11, 'Dec']] dataPlot = [] for key, value of data @@ -489,7 +489,7 @@ class TimePicker extends App.Controller value: 4, }, { - display: 'Mai' + display: 'May' value: 5, }, { diff --git a/app/assets/javascripts/app/controllers/time_accounting.coffee b/app/assets/javascripts/app/controllers/time_accounting.coffee index fbd5058a2..f63f3b449 100644 --- a/app/assets/javascripts/app/controllers/time_accounting.coffee +++ b/app/assets/javascripts/app/controllers/time_accounting.coffee @@ -61,7 +61,7 @@ class Index extends App.ControllerSubContent value: 4, }, { - display: 'Mai' + display: 'May' value: 5, }, { From fc9b8de922e7ead161f353b01125e937d89eed03 Mon Sep 17 00:00:00 2001 From: Ryan Lue Date: Mon, 29 Oct 2018 16:18:03 +0800 Subject: [PATCH 10/11] Ignore in forward-email text field (fixes #2305) --- app/assets/javascripts/app/lib/app_post/utils.coffee | 2 +- public/assets/tests/html_utils.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/app/lib/app_post/utils.coffee b/app/assets/javascripts/app/lib/app_post/utils.coffee index 8eb83c257..44ae9459d 100644 --- a/app/assets/javascripts/app/lib/app_post/utils.coffee +++ b/app/assets/javascripts/app/lib/app_post/utils.coffee @@ -1146,7 +1146,7 @@ class App.Utils html.find('img').each( (index) -> src = $(@).attr('src') - if !src.match(/^data:/i) + if !src.match(/^(data|cid):/i) # may mean broken emails (see issue #2305) base64 = App.Utils._htmlImage2DataUrl(@) $(@).attr('src', base64) ) diff --git a/public/assets/tests/html_utils.js b/public/assets/tests/html_utils.js index e7ecd85eb..a9826538d 100644 --- a/public/assets/tests/html_utils.js +++ b/public/assets/tests/html_utils.js @@ -3079,6 +3079,11 @@ test("htmlImage2DataUrl", function() { result = App.Utils.htmlImage2DataUrl(source) equal(result, should, source) + source = 'some test' + should = 'some test' + result = App.Utils.htmlImage2DataUrl(source) + equal(result, should, source) + }); source = 'some test' From cefe250c8f5e318b2ee040cce3b02cbcfd524abe Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Mon, 29 Oct 2018 13:58:20 +0100 Subject: [PATCH 11/11] Fixed admin calendar sla test (time zone adjustment). --- test/browser/admin_calendar_sla_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/browser/admin_calendar_sla_test.rb b/test/browser/admin_calendar_sla_test.rb index bf86a050e..dde3c36bd 100644 --- a/test/browser/admin_calendar_sla_test.rb +++ b/test/browser/admin_calendar_sla_test.rb @@ -13,7 +13,7 @@ class AdminCalendarSlaTest < TestCase calendar_name = "ZZZ some calendar #{rand(99_999_999)}" sla_name = "ZZZ some sla #{rand(99_999_999)}" timezone = 'Europe/Berlin' - timezone_verify = 'Europe/Berlin (GMT+2)' + timezone_verify = "Europe/Berlin\s\\(GMT\\+(2|1)\\)" calendar_create( data: { name: calendar_name, @@ -66,7 +66,7 @@ class AdminCalendarSlaTest < TestCase ) watch_for( css: '.content.active .modal input.js-input', - value: Regexp.quote(timezone_verify), + value: timezone_verify, timeout: 4, ) modal_close()