Merge remote-tracking branch 'origin/stable-5.0' into antifascista-stable
This commit is contained in:
commit
089e4c36d3
17 changed files with 453 additions and 151 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
[Full Changelog](https://github.com/zammad/zammad/compare/5.0.2...5.0.3)
|
||||
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Possibility to specify the order of objects [294](https://github.com/zammad/zammad/issues/294) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)] [[UX/UI](https://github.com/zammad/zammad/labels/UX/UI)] [[object manager attribute](https://github.com/zammad/zammad/labels/object manager attribute)]
|
||||
|
|
126
Gemfile.lock
126
Gemfile.lock
|
@ -21,50 +21,50 @@ GEM
|
|||
specs:
|
||||
aasm (5.2.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
actioncable (6.0.4.4)
|
||||
actionpack (= 6.0.4.4)
|
||||
actioncable (6.0.4.7)
|
||||
actionpack (= 6.0.4.7)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (6.0.4.4)
|
||||
actionpack (= 6.0.4.4)
|
||||
activejob (= 6.0.4.4)
|
||||
activerecord (= 6.0.4.4)
|
||||
activestorage (= 6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
actionmailbox (6.0.4.7)
|
||||
actionpack (= 6.0.4.7)
|
||||
activejob (= 6.0.4.7)
|
||||
activerecord (= 6.0.4.7)
|
||||
activestorage (= 6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
mail (>= 2.7.1)
|
||||
actionmailer (6.0.4.4)
|
||||
actionpack (= 6.0.4.4)
|
||||
actionview (= 6.0.4.4)
|
||||
activejob (= 6.0.4.4)
|
||||
actionmailer (6.0.4.7)
|
||||
actionpack (= 6.0.4.7)
|
||||
actionview (= 6.0.4.7)
|
||||
activejob (= 6.0.4.7)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (6.0.4.4)
|
||||
actionview (= 6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
actionpack (6.0.4.7)
|
||||
actionview (= 6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
rack (~> 2.0, >= 2.0.8)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actiontext (6.0.4.4)
|
||||
actionpack (= 6.0.4.4)
|
||||
activerecord (= 6.0.4.4)
|
||||
activestorage (= 6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
actiontext (6.0.4.7)
|
||||
actionpack (= 6.0.4.7)
|
||||
activerecord (= 6.0.4.7)
|
||||
activestorage (= 6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
actionview (6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
activejob (6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
activejob (6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
activerecord (6.0.4.4)
|
||||
activemodel (= 6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
activemodel (6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
activerecord (6.0.4.7)
|
||||
activemodel (= 6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
activerecord-import (1.2.0)
|
||||
activerecord (>= 3.2)
|
||||
activerecord-nulldb-adapter (0.7.0)
|
||||
|
@ -75,12 +75,12 @@ GEM
|
|||
multi_json (~> 1.11, >= 1.11.2)
|
||||
rack (>= 2.0.8, < 3)
|
||||
railties (>= 5.2.4.1)
|
||||
activestorage (6.0.4.4)
|
||||
actionpack (= 6.0.4.4)
|
||||
activejob (= 6.0.4.4)
|
||||
activerecord (= 6.0.4.4)
|
||||
activestorage (6.0.4.7)
|
||||
actionpack (= 6.0.4.7)
|
||||
activejob (= 6.0.4.7)
|
||||
activerecord (= 6.0.4.7)
|
||||
marcel (~> 1.0.0)
|
||||
activesupport (6.0.4.4)
|
||||
activesupport (6.0.4.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
|
@ -291,7 +291,7 @@ GEM
|
|||
http_parser.rb (0.6.0)
|
||||
http_parser.rb (0.6.0-x86_64-linux-musl)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.8.10)
|
||||
i18n (1.10.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
icalendar (2.7.1)
|
||||
ice_cube (~> 0.16)
|
||||
|
@ -319,11 +319,11 @@ GEM
|
|||
logging (2.3.0)
|
||||
little-plugger (~> 1.1)
|
||||
multi_json (~> 1.14)
|
||||
loofah (2.13.0)
|
||||
loofah (2.14.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
lumberjack (1.2.8)
|
||||
marcel (1.0.1)
|
||||
marcel (1.0.2)
|
||||
memoizable (0.4.2)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
messagebird-rest (3.0.0)
|
||||
|
@ -331,8 +331,8 @@ GEM
|
|||
mime-types (3.3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2021.0225)
|
||||
mini_mime (1.1.1)
|
||||
mini_portile2 (2.6.1)
|
||||
mini_mime (1.1.2)
|
||||
mini_portile2 (2.8.0)
|
||||
mini_racer (0.2.9)
|
||||
libv8 (>= 6.9.411)
|
||||
minitest (5.15.0)
|
||||
|
@ -349,9 +349,8 @@ GEM
|
|||
net-ldap (0.17.0)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.8)
|
||||
nio4r (2.5.8-x86_64-linux-musl)
|
||||
nokogiri (1.12.5)
|
||||
mini_portile2 (~> 2.6.1)
|
||||
nokogiri (1.13.3)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.12.5-x86_64-linux-musl)
|
||||
mini_portile2 (~> 2.6.1)
|
||||
|
@ -443,7 +442,7 @@ GEM
|
|||
binding_of_caller (~> 1.0)
|
||||
pry (~> 0.13)
|
||||
public_suffix (4.0.6)
|
||||
puma (4.3.10)
|
||||
puma (4.3.11)
|
||||
nio4r (~> 2.0)
|
||||
puma (4.3.8-x86_64-linux-musl)
|
||||
nio4r (~> 2.0)
|
||||
|
@ -451,27 +450,26 @@ GEM
|
|||
activesupport (>= 3.0.0)
|
||||
pundit-matchers (1.7.0)
|
||||
rspec-rails (>= 3.0.0)
|
||||
racc (1.5.2)
|
||||
racc (1.5.2-x86_64-linux-musl)
|
||||
racc (1.6.0)
|
||||
rack (2.2.3)
|
||||
rack-livereload (0.3.17)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (6.0.4.4)
|
||||
actioncable (= 6.0.4.4)
|
||||
actionmailbox (= 6.0.4.4)
|
||||
actionmailer (= 6.0.4.4)
|
||||
actionpack (= 6.0.4.4)
|
||||
actiontext (= 6.0.4.4)
|
||||
actionview (= 6.0.4.4)
|
||||
activejob (= 6.0.4.4)
|
||||
activemodel (= 6.0.4.4)
|
||||
activerecord (= 6.0.4.4)
|
||||
activestorage (= 6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
rails (6.0.4.7)
|
||||
actioncable (= 6.0.4.7)
|
||||
actionmailbox (= 6.0.4.7)
|
||||
actionmailer (= 6.0.4.7)
|
||||
actionpack (= 6.0.4.7)
|
||||
actiontext (= 6.0.4.7)
|
||||
actionview (= 6.0.4.7)
|
||||
activejob (= 6.0.4.7)
|
||||
activemodel (= 6.0.4.7)
|
||||
activerecord (= 6.0.4.7)
|
||||
activestorage (= 6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 6.0.4.4)
|
||||
railties (= 6.0.4.7)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
|
@ -480,11 +478,11 @@ GEM
|
|||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.4.1)
|
||||
rails-html-sanitizer (1.4.2)
|
||||
loofah (~> 2.3)
|
||||
railties (6.0.4.4)
|
||||
actionpack (= 6.0.4.4)
|
||||
activesupport (= 6.0.4.4)
|
||||
railties (6.0.4.7)
|
||||
actionpack (= 6.0.4.7)
|
||||
activesupport (= 6.0.4.7)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.20.3, < 2.0)
|
||||
|
@ -610,7 +608,7 @@ GEM
|
|||
tins (~> 1.0)
|
||||
test-unit (3.4.7)
|
||||
power_assert
|
||||
thor (1.1.0)
|
||||
thor (1.2.1)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.10)
|
||||
timers (4.3.3)
|
||||
|
@ -666,7 +664,7 @@ GEM
|
|||
writeexcel (1.0.5)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.4.2)
|
||||
zeitwerk (2.5.4)
|
||||
zendesk_api (1.33.0)
|
||||
faraday (>= 0.9.0, < 2.0.0)
|
||||
hashie (>= 3.5.2, < 5.0.0)
|
||||
|
|
|
@ -2,6 +2,7 @@ class App.ControllerObserver extends App.Controller
|
|||
model: 'Ticket'
|
||||
template: 'tba'
|
||||
globalRerender: true
|
||||
lastAttributes: undefined
|
||||
|
||||
###
|
||||
observe:
|
||||
|
@ -25,7 +26,7 @@ class App.ControllerObserver extends App.Controller
|
|||
# rerender, e. g. on language change
|
||||
if @globalRerender
|
||||
@controllerBind('ui:rerender', =>
|
||||
@lastAttributres = undefined
|
||||
@lastAttributes = undefined
|
||||
@maybeRender(App[@model].fullLocal(@object_id))
|
||||
)
|
||||
|
||||
|
@ -43,32 +44,40 @@ class App.ControllerObserver extends App.Controller
|
|||
if !@subscribeId
|
||||
@subscribeId = object.subscribe(@subscribe)
|
||||
|
||||
# remember current attributes
|
||||
return if !@hasChanged(object)
|
||||
|
||||
@render(object)
|
||||
|
||||
hasChanged: (object) =>
|
||||
currentAttributes = {}
|
||||
|
||||
objectCloned = $.extend(true, {}, object)
|
||||
if @observe
|
||||
for key, active of @observe
|
||||
if active
|
||||
currentAttributes[key] = object[key]
|
||||
if active && !_.isFunction(value)
|
||||
currentAttributes[key] = objectCloned[key]
|
||||
|
||||
if @observeNot
|
||||
for key, value of object
|
||||
if key isnt 'cid' && !@observeNot[key] && !_.isFunction(value) && !_.isObject(value)
|
||||
for key, value of objectCloned
|
||||
if key isnt 'cid' && !@observeNot[key] && !_.isFunction(value)
|
||||
currentAttributes[key] = value
|
||||
|
||||
if !@lastAttributres
|
||||
@lastAttributres = {}
|
||||
else
|
||||
diff = difference(currentAttributes, @lastAttributres)
|
||||
if _.isEmpty(diff)
|
||||
@log 'debug', 'maybeRender no diff, no rerender'
|
||||
return
|
||||
if !@lastAttributes
|
||||
@lastAttributes = currentAttributes
|
||||
return true
|
||||
|
||||
diff = difference(currentAttributes, @lastAttributes)
|
||||
if _.isEmpty(diff)
|
||||
@log 'debug', 'maybeRender no diff, no rerender'
|
||||
return false
|
||||
|
||||
@log 'debug', 'maybeRender.diff', diff, @observe, @model
|
||||
@lastAttributres = currentAttributes
|
||||
@lastAttributes = currentAttributes
|
||||
|
||||
@render(object, diff)
|
||||
true
|
||||
|
||||
render: (object, diff) =>
|
||||
@log 'debug', 'render', @template, object, diff
|
||||
render: (object) =>
|
||||
@log 'debug', 'render', @template, object
|
||||
@html App.view(@template)(
|
||||
object: object
|
||||
)
|
||||
|
|
|
@ -202,7 +202,7 @@ class Object extends App.ControllerObserver
|
|||
value = $(e.target).html()
|
||||
org = App.Organization.find(@object_id)
|
||||
if org[name] isnt value
|
||||
@lastAttributres[name] = value
|
||||
@lastAttributes[name] = value
|
||||
data = {}
|
||||
data[name] = value
|
||||
org.updateAttributes(data)
|
||||
|
|
|
@ -257,7 +257,7 @@ class EmailReply extends App.Controller
|
|||
|
||||
quote_header = App.FullQuoteHeader.fullQuoteHeaderForward(article)
|
||||
|
||||
body = "<br/><div>---Begin forwarded message:---<br/><br/></div><div><blockquote type=\"cite\">#{quote_header}#{body}</blockquote></div><div><br></div>"
|
||||
body = "<br/><div>---#{App.i18n.translateInline('Begin forwarded message')}:---<br/><br/></div><div><blockquote type=\"cite\">#{quote_header}#{body}</blockquote></div><div><br></div>"
|
||||
|
||||
articleNew = {}
|
||||
articleNew.body = body
|
||||
|
|
|
@ -24,7 +24,7 @@ class Internal
|
|||
internal = true
|
||||
if article.internal == true
|
||||
internal = false
|
||||
ui.lastAttributres.internal = internal
|
||||
ui.lastAttributes.internal = internal
|
||||
article.updateAttributes(internal: internal)
|
||||
|
||||
# runtime update
|
||||
|
|
|
@ -218,11 +218,11 @@ class ArticleViewItem extends App.ControllerObserver
|
|||
)
|
||||
|
||||
@articleActions = new App.TicketZoomArticleActions(
|
||||
el: @$('.js-article-actions')
|
||||
ticket: @ticket
|
||||
article: article
|
||||
lastAttributres: @lastAttributres
|
||||
form_id: @form_id
|
||||
el: @$('.js-article-actions')
|
||||
ticket: @ticket
|
||||
article: article
|
||||
lastAttributes: @lastAttributes
|
||||
form_id: @form_id
|
||||
)
|
||||
|
||||
# set see more
|
||||
|
@ -305,34 +305,38 @@ class ArticleViewItem extends App.ControllerObserver
|
|||
e.stopPropagation()
|
||||
|
||||
article_id = $(e.target).closest('.ticket-article-item').data('id')
|
||||
article = App.TicketArticle.find(article_id)
|
||||
|
||||
@ajax(
|
||||
id: 'retrySecurityProcess'
|
||||
type: 'POST'
|
||||
url: "#{@apiPath}/ticket_articles/#{article_id}/retry_security_process"
|
||||
processData: true
|
||||
success: (data, status, xhr) =>
|
||||
if data.sign.success
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Verify sign success!')
|
||||
else if data.sign.comment
|
||||
comment = App.i18n.translateContent('Verify sign failed!') + ' ' + App.i18n.translateContent(data.sign.comment || '')
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: comment
|
||||
timeout: 2000
|
||||
success: (encryption_data, status, xhr) =>
|
||||
for data in encryption_data
|
||||
continue if article.preferences.security.type isnt data.type
|
||||
|
||||
if data.encryption.success
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Decryption success!')
|
||||
else if data.encryption.comment
|
||||
comment = App.i18n.translateContent('Decryption failed!') + ' ' + App.i18n.translateContent(data.encryption.comment || '')
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: comment
|
||||
timeout: 2000
|
||||
if data.sign.success
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Verify sign success!')
|
||||
else if data.sign.comment
|
||||
comment = App.i18n.translateContent('Verify sign failed!') + ' ' + App.i18n.translateContent(data.sign.comment || '')
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: comment
|
||||
timeout: 2000
|
||||
|
||||
if data.encryption.success
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Decryption success!')
|
||||
else if data.encryption.comment
|
||||
comment = App.i18n.translateContent('Decryption failed!') + ' ' + App.i18n.translateContent(data.encryption.comment || '')
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: comment
|
||||
timeout: 2000
|
||||
|
||||
error: (xhr) =>
|
||||
@notify
|
||||
|
|
|
@ -19,7 +19,7 @@ class App.TicketZoomTitle extends App.ControllerObserver
|
|||
title = $(e.target).ceg() || ''
|
||||
|
||||
# update title
|
||||
return if title is @lastAttributres.title
|
||||
return if title is @lastAttributes.title
|
||||
ticket = App.Ticket.find(@object_id)
|
||||
ticket.title = title
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ class Object extends App.ControllerObserver
|
|||
value = $(e.target).html()
|
||||
user = App.User.find(@object_id)
|
||||
if user[name] isnt value
|
||||
@lastAttributres[name] = value
|
||||
@lastAttributes[name] = value
|
||||
data = {}
|
||||
data[name] = value
|
||||
user.updateAttributes(data)
|
||||
|
|
|
@ -65,9 +65,9 @@ Date.prototype.getWeek = function() {
|
|||
|
||||
function difference(object1, object2) {
|
||||
var changes = {};
|
||||
for (var name in object1) {
|
||||
if (name in object2) {
|
||||
if (_.isObject(object2[name]) && !_.isArray(object2[name])) {
|
||||
_.uniq(Object.keys(object1).concat(Object.keys(object2))).forEach(function(name) {
|
||||
if (name in object1 && name in object2) {
|
||||
if (_.isObject(object1[name]) && !_.isArray(object1[name]) && _.isObject(object2[name]) && !_.isArray(object2[name])) {
|
||||
var diff = difference(object1[name], object2[name]);
|
||||
if (!_.isEmpty(diff)) {
|
||||
changes[name] = diff;
|
||||
|
@ -75,8 +75,10 @@ function difference(object1, object2) {
|
|||
} else if (!_.isEqual(object1[name], object2[name])) {
|
||||
changes[name] = object2[name];
|
||||
}
|
||||
} else {
|
||||
changes[name] = object2[name]
|
||||
}
|
||||
}
|
||||
})
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ when 'mysql2'
|
|||
# Because of missing ticket updates in high load environments
|
||||
# we changed the transaction isolation level equally to postgres
|
||||
# to READ COMMITTED which fixed the problem entirely #3877
|
||||
ActiveRecord::ConnectionAdapters::Mysql2Adapter.set_callback :checkout, :before do |conn|
|
||||
ActiveRecord::ConnectionAdapters::Mysql2Adapter.set_callback :checkout, :after do |conn|
|
||||
conn.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED')
|
||||
end
|
||||
when 'postgresql'
|
||||
|
|
0
contrib/backup/zammad_db_user_helper.sh
Normal file → Executable file
0
contrib/backup/zammad_db_user_helper.sh
Normal file → Executable file
|
@ -10,9 +10,11 @@ class SecureMailing
|
|||
end
|
||||
|
||||
def self.retry(article)
|
||||
result = []
|
||||
active_backends.each do |backend|
|
||||
"#{backend}::Retry".constantize.process(article)
|
||||
result << "#{backend}::Retry".constantize.process(article)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def self.outgoing(mail, security)
|
||||
|
|
|
@ -536,7 +536,9 @@ test('difference', function() {
|
|||
object2 = {
|
||||
key1: 123,
|
||||
}
|
||||
result = {}
|
||||
result = {
|
||||
key2: undefined
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
|
@ -547,38 +549,106 @@ test('difference', function() {
|
|||
key1: 123,
|
||||
key2: 124
|
||||
}
|
||||
result = {
|
||||
key2: 124
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
organization_id: 2,
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
organization_id: null,
|
||||
}
|
||||
result = {
|
||||
organization_id: null,
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
organization_id: null,
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
organization_id: 2,
|
||||
}
|
||||
result = {
|
||||
organization_id: 2,
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
preferences: { resolved: true },
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
preferences: {},
|
||||
}
|
||||
result = {
|
||||
preferences: { resolved: undefined }
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
preferences: { resolved: true },
|
||||
}
|
||||
result = {
|
||||
preferences: { resolved: true }
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
preferences: {},
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
preferences: { resolved: true },
|
||||
}
|
||||
result = {
|
||||
preferences: { resolved: true }
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
preferences: { resolved: false },
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
preferences: { resolved: true },
|
||||
}
|
||||
result = {
|
||||
preferences: { resolved: true }
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
preferences: { resolved: true },
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
preferences: { resolved: true },
|
||||
}
|
||||
result = {}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
organization_id: 2,
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
organization_id: null,
|
||||
}
|
||||
result = {
|
||||
organization_id: null,
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
object1 = {
|
||||
customer_id: 1,
|
||||
organization_id: null,
|
||||
}
|
||||
object2 = {
|
||||
customer_id: 1,
|
||||
organization_id: 2,
|
||||
}
|
||||
result = {
|
||||
organization_id: 2,
|
||||
}
|
||||
item = difference(object1, object2)
|
||||
deepEqual(item, result)
|
||||
|
||||
});
|
||||
|
||||
test('auth - not existing user', function(assert) {
|
||||
|
|
202
public/assets/tests/qunit/controller_observer.js
Normal file
202
public/assets/tests/qunit/controller_observer.js
Normal file
|
@ -0,0 +1,202 @@
|
|||
QUnit.test( "controller observer tests - observe", assert => {
|
||||
|
||||
App.Ticket.refresh([{
|
||||
id: 1,
|
||||
title: 'ticket',
|
||||
state_id: 1,
|
||||
customer_id: 33,
|
||||
organization_id: 1,
|
||||
owner_id: 1,
|
||||
preferences: { a: 1, b: 2 },
|
||||
}])
|
||||
|
||||
var observer1 = new App.ControllerObserver({
|
||||
object_id: 1,
|
||||
template: 'version',
|
||||
observe: {
|
||||
title: true,
|
||||
preferences: true,
|
||||
},
|
||||
})
|
||||
|
||||
var ticket = App.Ticket.find(1)
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track title changes
|
||||
ticket.title = 'title 2'
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.title = undefined
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.title = 'title 3'
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track no owner_id changes
|
||||
ticket.owner_id = 2
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track preferences changes
|
||||
ticket.preferences['a'] = 3
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.preferences['c'] = 3
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track no new_attribute1 changes
|
||||
ticket.new_attribute1 = 'na 3'
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.new_attribute2 = function() { console.log(1) }
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.new_attribute2 = function() { console.log(2) }
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track title changes
|
||||
ticket.title = function() { console.log(1) }
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.title = function() { console.log(2) }
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.title = 1
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
});
|
||||
|
||||
QUnit.test( "controller observer tests - observeNot", assert => {
|
||||
|
||||
App.Ticket.refresh([{
|
||||
id: 2,
|
||||
title: 'ticket',
|
||||
state_id: 1,
|
||||
customer_id: 33,
|
||||
organization_id: 1,
|
||||
owner_id: 1,
|
||||
preferences: { a: 1, b: 2 },
|
||||
}])
|
||||
|
||||
var observer1 = new App.ControllerObserver({
|
||||
object_id: 2,
|
||||
template: 'version',
|
||||
observeNot: {
|
||||
title: true,
|
||||
preferences: true,
|
||||
},
|
||||
})
|
||||
|
||||
var ticket = App.Ticket.find(2)
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track no title changes
|
||||
ticket.title = 'title 2'
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track owner_id changes
|
||||
ticket.owner_id = 2
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.owner_id = undefined
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.owner_id = 3
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track no preferences changes
|
||||
ticket.preferences['a'] = 3
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.preferences['c'] = 3
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track preferences2 changes
|
||||
ticket.preferences2 = {}
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.preferences2['a'] = 3
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.preferences2['a'] = 2
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.preferences2['c'] = 3
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track new_attribute1 changes
|
||||
ticket.new_attribute1 = 'na 3'
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track no new_attribute2 changes (because of function content)
|
||||
ticket.new_attribute2 = function() { console.log(1) }
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.new_attribute2 = function() { console.log(2) }
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
// track owner_id changes (pnly if content has no function content)
|
||||
ticket.owner_id = function() { console.log(1) }
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.owner_id = function() { console.log(2) }
|
||||
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
ticket.owner_id = 1
|
||||
|
||||
assert.equal(true, observer1.hasChanged(ticket))
|
||||
assert.equal(false, observer1.hasChanged(ticket))
|
||||
|
||||
});
|
|
@ -588,8 +588,7 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
end
|
||||
|
||||
context 'certificate not present at time of arrival' do
|
||||
|
||||
it 'retry' do
|
||||
let(:mail) do
|
||||
smime1 = create(:smime_certificate, :with_private, fixture: system_email_address)
|
||||
smime2 = create(:smime_certificate, :with_private, fixture: sender_email_address)
|
||||
|
||||
|
@ -612,6 +611,10 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
smime1.destroy
|
||||
smime2.destroy
|
||||
|
||||
mail
|
||||
end
|
||||
|
||||
it 'does retry successfully' do
|
||||
parsed_mail = Channel::EmailParser.new.parse(mail.to_s)
|
||||
ticket, article, _user, _mail = Channel::EmailParser.new.process({ group_id: group.id }, parsed_mail['raw'])
|
||||
expect(Ticket::Article.find(article.id).body).to eq('no visible content')
|
||||
|
@ -624,6 +627,17 @@ RSpec.describe 'Ticket zoom', type: :system do
|
|||
click '.js-securityRetryProcess'
|
||||
expect(page).to have_css('.article-content', text: 'somebody with some text')
|
||||
end
|
||||
|
||||
it 'does fail on retry (S/MIME function buttons no longer working in tickets #3957)' do
|
||||
parsed_mail = Channel::EmailParser.new.parse(mail.to_s)
|
||||
ticket, article, _user, _mail = Channel::EmailParser.new.process({ group_id: group.id }, parsed_mail['raw'])
|
||||
expect(Ticket::Article.find(article.id).body).to eq('no visible content')
|
||||
|
||||
visit "#ticket/zoom/#{ticket.id}"
|
||||
expect(page).to have_no_css('.article-content', text: 'somebody with some text')
|
||||
click '.js-securityRetryProcess'
|
||||
expect(page).to have_css('#notify', text: 'Decryption failed! Unable to find private key to decrypt')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ class ClearbitTest < ActiveSupport::TestCase
|
|||
organization6 = Organization.find_by('name LIKE ?', 'APIHub Inc%')
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'Organization', o_id: organization6.id))
|
||||
assert_equal(false, organization6.shared)
|
||||
assert_equal('The marketing data engine to deeply understand your customers, identify future prospects, & personalize every single marketing & sales interaction.', organization6.note)
|
||||
assert_equal('The Clearbit Data Activation Platform helps B2B teams understand customers, identify prospects, & personalize interactions with real-time intelligence.', organization6.note)
|
||||
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue