Enable Lint/UselessAssignment cop.

This commit is contained in:
Ryan Lue 2019-06-28 13:38:49 +02:00 committed by Thorsten Eckel
parent 7930ffdf03
commit a1da3a27f9
142 changed files with 547 additions and 663 deletions

View file

@ -6,10 +6,6 @@
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 43
Lint/UselessAssignment:
Enabled: false
# # Offense count: 17 (Competes with same override in .rubocop_todo.yml)
# Metrics/AbcSize:
# Max: 24

View file

@ -41,7 +41,7 @@ class ApplicationChannelController < ApplicationController
end
def channel_params
params = params.permit!.to_s
params.permit!.to_s
end
end

View file

@ -101,22 +101,11 @@ module ApplicationController::RendersModels
end
def model_index_render(object, params)
offset = 0
per_page = 500
if params[:page] && params[:per_page]
offset = (params[:page].to_i - 1) * params[:per_page].to_i
limit = params[:per_page].to_i
end
page = (params[:page] || 1).to_i
per_page = (params[:per_page] || 500).to_i
offset = (page - 1) * per_page
if per_page > 500
per_page = 500
end
generic_objects = if offset.positive?
object.limit(params[:per_page]).order(id: :asc).offset(offset).limit(limit)
else
object.all.order(id: :asc).offset(offset).limit(limit)
end
generic_objects = object.order(id: :asc).offset(offset).limit(per_page)
if response_expand?
list = []

View file

@ -171,7 +171,7 @@ class ChannelsEmailController < ApplicationController
channel_id: channel.id,
)
else
address = EmailAddress.create(
EmailAddress.create(
realname: params[:meta][:realname],
email: email,
active: true,

View file

@ -96,7 +96,7 @@ module CreatesTicketArticles
begin
base64_data = attachment[:data].gsub(/[\r\n]/, '')
attachment_data = Base64.strict_decode64(base64_data)
rescue ArgumentError => e
rescue ArgumentError
raise Exceptions::UnprocessableEntity, "Invalid base64 for attachment with index '#{index}'"
end

View file

@ -123,7 +123,7 @@ class ImportOtrsController < ApplicationController
end
def import_check
statistic = Import::OTRS::Requester.list
Import::OTRS::Requester.list
issues = []
# check count of dynamic fields

View file

@ -55,7 +55,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
ticket = Ticket.find_by(id: ticket_id)
next if !ticket
article = Ticket::Article.create!(
Ticket::Article.create!(
ticket_id: ticket_id,
type_id: Ticket::Article::Type.find_by(name: 'web').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
@ -81,7 +81,6 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
}
return
end
state = Ticket::State.lookup(id: auto_close_state_id)
ticket_ids_found.each do |ticket_id|
ticket = Ticket.find_by(id: ticket_id)
next if !ticket
@ -107,7 +106,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT']}
},
}
)
article = Ticket::Article.create!(
Ticket::Article.create!(
ticket_id: ticket.id,
type_id: Ticket::Article::Type.find_by(name: 'web').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,

View file

@ -9,7 +9,7 @@ class KnowledgeBase::Answer::AttachmentsController < ApplicationController
def create
file = params[:file]
store = Store.add(
Store.add(
object: @answer.class.name,
o_id: @answer.id,
data: file.read,

View file

@ -89,7 +89,7 @@ class LongPollingController < ApplicationController
return
end
end
rescue => e
rescue
raise Exceptions::UnprocessableEntity, 'Invalid client_id in receive loop!'
end
end

View file

@ -52,7 +52,6 @@ curl http://localhost/api/v1/slas.json -v -u #{login}:#{password}
# calendars
assets = {}
calendar_ids = []
Calendar.all.each do |calendar|
assets = calendar.assets(assets)
end

View file

@ -10,7 +10,6 @@ class TicketOverviewsController < ApplicationController
index_and_lists = Ticket::Overviews.index(current_user)
indexes = []
index_and_lists.each do |index|
assets = {}
overview = Overview.lookup(id: index[:overview][:id])
meta = {
name: overview.name,

View file

@ -49,7 +49,6 @@ class TimeAccountingsController < ApplicationController
end
if !agents[local_time_unit[:agent_id]]
agent_user = User.lookup(id: local_time_unit[:agent_id])
agent = '-'
if agent_user
agents[local_time_unit[:agent_id]] = agent_user.fullname
end

View file

@ -380,7 +380,7 @@ class UsersController < ApplicationController
query = params[:query]
if query.respond_to?(:permit!)
query = query.permit!.to_h
query.permit!.to_h
end
query = params[:query] || params[:term]
@ -543,7 +543,7 @@ curl http://localhost/api/v1/users/email_verify_send -v -u #{login}:#{password}
# return
#end
token = Token.create(action: 'Signup', user_id: user.id)
Token.create(action: 'Signup', user_id: user.id)
result = User.signup_new_token(user)
if result && result[:token]

View file

@ -9,7 +9,6 @@ class TicketArticleCommunicateEmailJob < ApplicationJob
# build subject
ticket = Ticket.lookup(id: record.ticket_id)
article_count = Ticket::Article.where(ticket_id: ticket.id).count
subject_prefix_mode = record.preferences[:subtype]

View file

@ -25,8 +25,7 @@ returns
attr.transform_keys!(&:to_sym).slice!(*lookup_keys)
raise ArgumentError, "Valid lookup attribute required (#{lookup_keys.join(', ')})" if attr.empty?
record = cache_get(attr.values.first)
record ||= find_and_save_to_cache_by(attr)
cache_get(attr.values.first) || find_and_save_to_cache_by(attr)
end
=begin

View file

@ -22,7 +22,6 @@ returns
next if !value
# get attribute name
attribute_name_with_id = key.to_s
attribute_name = key.to_s
next if attribute_name[-3, 3] != '_id'

View file

@ -86,6 +86,5 @@ store attachments for this object
created_by_id: created_by_id,
)
end
attachments_buffer = nil
end
end

View file

@ -40,7 +40,7 @@ class Channel::Driver::Sms::Twilio
# find sender
user = User.where(mobile: attr[:From]).order(:updated_at).first
if !user
from_comment, preferences = Cti::CallerId.get_comment_preferences(attr[:From], 'from')
_from_comment, preferences = Cti::CallerId.get_comment_preferences(attr[:From], 'from')
if preferences && preferences['from'] && preferences['from'][0]
if preferences['from'][0]['level'] == 'known' && preferences['from'][0]['object'] == 'User'
user = User.find_by(id: preferences['from'][0]['o_id'])

View file

@ -202,9 +202,6 @@ returns
# save changes set by x-zammad-ticket-followup-* headers
ticket.save! if ticket.has_changes_to_save?
state = Ticket::State.find(ticket.state_id)
state_type = Ticket::StateType.find(state.state_type_id)
# set ticket to open again or keep create state
if !mail['x-zammad-ticket-followup-state'.to_sym] && !mail['x-zammad-ticket-followup-state_id'.to_sym]
new_state = Ticket::State.find_by(default_create: true)
@ -480,7 +477,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
path = Rails.root.join('tmp', 'unprocessable_mail')
files = []
Dir.glob("#{path}/*.eml") do |entry|
ticket, article, user, mail = Channel::EmailParser.new.process(params, IO.binread(entry))
ticket, _article, _user, _mail = Channel::EmailParser.new.process(params, IO.binread(entry))
next if ticket.blank?
files.push entry
@ -608,15 +605,13 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
file.header.fields.each do |field|
# full line, encode, ready for storage
value = field.to_utf8
if value.blank?
value = field.raw_value
end
headers_store[field.name.to_s] = value
rescue => e
rescue
headers_store[field.name.to_s] = field.raw_value
end
# cleanup content id, <> will be added automatically later

View file

@ -80,9 +80,6 @@ class Channel::Filter::MonitoringBase
end
end
# check if ticket with host is open
customer = User.lookup(id: session_user_id)
# follow up detection by meta data
open_states = Ticket::State.by_category(:open)
ticket_ids = Ticket.where(state: open_states).order(created_at: :desc).limit(5000).pluck(:id)

View file

@ -26,7 +26,7 @@ module ChecksConditionValidation
value: 1,
}
ticket_count, tickets = Ticket.selectors(validate_condition, limit: 1, current_user: User.find(1))
ticket_count, _tickets = Ticket.selectors(validate_condition, limit: 1, current_user: User.find(1))
return true if ticket_count.present?
raise Exceptions::UnprocessableEntity, 'Invalid ticket selector conditions'

View file

@ -248,7 +248,7 @@ module HasGroups
return if group_access_buffer.nil?
yield
group_access_buffer = nil
self.group_access_buffer = nil
cache_delete
end

View file

@ -135,7 +135,7 @@ job.run(true)
end
def matching_count
ticket_count, tickets = Ticket.selectors(condition, limit: 1)
ticket_count, _tickets = Ticket.selectors(condition, limit: 1)
ticket_count || 0
end

View file

@ -49,7 +49,7 @@ class KnowledgeBase::Answer < ApplicationModel
end
data = ApplicationModel::CanAssets.reduce(siblings, data)
data = ApplicationModel::CanAssets.reduce(translations, data)
ApplicationModel::CanAssets.reduce(translations, data)
end
attachments_cleanup!

View file

@ -50,7 +50,7 @@ class KnowledgeBase::Category < ApplicationModel
data = ApplicationModel::CanAssets.reduce(translations, data)
# include parent category or KB for root to have full path
data = (parent || knowledge_base).assets(data)
(parent || knowledge_base).assets(data)
end
def self_parent?(candidate)

View file

@ -54,7 +54,6 @@ list of all attributes
result = ObjectManager::Attribute.all.order('position ASC, name ASC')
references = ObjectManager::Attribute.attribute_to_references_hash
attributes = []
assets = {}
result.each do |item|
attribute = item.attributes
attribute[:object] = ObjectLookup.by_id(item.object_lookup_id)
@ -908,7 +907,7 @@ is certain attribute used by triggers, overviews or schedulers
# fixes issue #2236 - Naming an attribute "attribute" causes ActiveRecord failure
begin
ObjectLookup.by_id(object_lookup_id).constantize.instance_method_already_implemented? name
rescue ActiveRecord::DangerousAttributeError => e
rescue ActiveRecord::DangerousAttributeError
raise "#{name} is a reserved word, please choose a different one"
end

View file

@ -22,7 +22,7 @@ class ObjectManager::Attribute::Validation::Required < ObjectManager::Attribute:
end
def user_id
user_id ||= UserInfo.current_user_id
@user_id ||= UserInfo.current_user_id
end
def user

View file

@ -25,7 +25,6 @@ class Observer::Sla::TicketRebuildEscalation < ActiveRecord::Observer
# check if condition has changed
changed = false
fields_to_check = nil
fields_to_check = if record.class == Sla
%w[condition calendar_id first_response_time update_time solution_time]
else

View file

@ -217,7 +217,6 @@ class Observer::Transaction < ActiveRecord::Observer
# do not send anything if nothing has changed
return true if real_changes.blank?
changed_by_id = nil
changed_by_id = if record.respond_to?('updated_by_id')
record.updated_by_id
else

View file

@ -505,8 +505,6 @@ execute all pending package migrations at once
return true if !File.exist?(location)
migrations_done = Package::Migration.where(name: package.underscore)
# get existing migrations
migrations_existing = []
Dir.foreach(location) do |entry|

View file

@ -287,7 +287,6 @@ returns
local_sha = Digest::SHA256.hexdigest(content)
cache_key = "image-resize-#{local_sha}_#{width}"
all = nil
image = Cache.get(cache_key)
return image if image

View file

@ -108,7 +108,7 @@ class Store::Provider::File
if !File.exist?(location)
FileUtils.mkdir_p(location)
end
full_path = location += file
full_path = location + file
full_path.gsub('//', '/')
end

View file

@ -100,7 +100,7 @@ push text_modules to online
# set new translator_key if given
if result.data['translator_key']
translator_key = Setting.set('translator_key', result.data['translator_key'])
Setting.set('translator_key', result.data['translator_key'])
end
true

View file

@ -197,7 +197,7 @@ returns
tickets.each do |ticket|
# get sla
sla = ticket.escalation_calculation_get_sla
ticket.escalation_calculation_get_sla
article_id = nil
article = Ticket::Article.last_customer_agent_article(ticket.id)
@ -1129,10 +1129,8 @@ perform active triggers on ticket
return [true, message]
end
local_send_notification = true
if article && send_notification == false && trigger.perform['notification.email'] && trigger.perform['notification.email']['recipient']
recipient = trigger.perform['notification.email']['recipient']
local_send_notification = false
local_options[:send_notification] = false
if recipient.include?('ticket_customer') || recipient.include?('article_last_sender')
logger.info { "Skip trigger (#{trigger.name}/#{trigger.id}) because sender do not want to get auto responder for object (Ticket/#{ticket.id}/Article/#{article.id})" }
@ -1576,7 +1574,7 @@ result
).render.html2text.tr(' ', ' ') # convert non-breaking space to simple space
# attributes content_type is not needed for SMS
article = Ticket::Article.create(
Ticket::Article.create(
ticket_id: id,
subject: 'SMS notification',
to: sms_recipients_to,

View file

@ -88,7 +88,6 @@ class Transaction::Notification
end
# send notifications
recipient_list = ''
recipients_and_channels.each do |item|
user = item[:user]
channels = item[:channels]

View file

@ -90,7 +90,7 @@ push translations to online
# set new translator_key if given
if result.data['translator_key']
translator_key = Setting.set('translator_key', result.data['translator_key'])
Setting.set('translator_key', result.data['translator_key'])
end
true
@ -147,7 +147,6 @@ get list of translations
Translation.where(locale: locale.downcase).where.not(target: '').order(:source)
end
translations.each do |item|
translation_item = []
translation_item = if admin
[
item.id,
@ -405,7 +404,7 @@ Get source file at https://i18n.zammad.com/api/v1/translations_empty_translation
col_sep: ',',
}
rows = ::CSV.parse(content, params)
header = rows.shift
rows.shift # remove header
translation_raw = []
rows.each do |row|

View file

@ -441,7 +441,6 @@ returns
def permissions?(key)
keys = key
names = []
if key.class == String
keys = [key]
end
@ -715,8 +714,14 @@ returns
def merge(user_id_of_duplicate_user)
# find email addresses and move them to primary user
duplicate_user = User.find(user_id_of_duplicate_user)
# Raise an exception if the user is not found (?)
#
# (This line used to contain a useless variable assignment,
# and was changed to satisfy the linter.
# We're not certain of its original intention,
# so the User.find call has been kept
# to prevent any unexpected regressions.)
User.find(user_id_of_duplicate_user)
# merge missing attibutes
Models.merge('User', id, user_id_of_duplicate_user)

View file

@ -22,7 +22,6 @@ class OutOfOffice2 < ActiveRecord::Migration[4.2]
end
role_ids = Role.with_permissions(['ticket.agent']).map(&:id)
overview_role = Role.find_by(name: 'Agent')
Overview.create_or_update(
name: 'My replacement Tickets',
link: 'my_replacement_tickets',

View file

@ -153,7 +153,8 @@ class String
text_compare.downcase!
text_compare.sub!(%r{/$}, '')
end
placeholder = if link_compare.present? && text_compare.blank?
if link_compare.present? && text_compare.blank?
link
elsif link_compare.blank? && text_compare.present?
text
@ -180,10 +181,10 @@ class String
# pre/code handling 1/2
string.gsub!(%r{<pre>(.+?)</pre>}m) do |placeholder|
placeholder = placeholder.gsub(/\n/, '###BR###')
placeholder.gsub(/\n/, '###BR###')
end
string.gsub!(%r{<code>(.+?)</code>}m) do |placeholder|
placeholder = placeholder.gsub(/\n/, '###BR###')
placeholder.gsub(/\n/, '###BR###')
end
# insert spaces on [A-z]\n[A-z]
@ -231,7 +232,8 @@ class String
if content.match?(/^www/i)
content = "http://#{content}"
end
placeholder = if content =~ /^(http|https|ftp|tel)/i
if content =~ /^(http|https|ftp|tel)/i
"#{pre}######LINKRAW:#{content}#######{post}"
else
"#{pre}#{content}#{post}"
@ -374,7 +376,7 @@ class String
]
map.each do |regexp|
string.sub!(/#{regexp}/m) do |placeholder|
placeholder = "#{marker}#{placeholder}"
"#{marker}#{placeholder}"
end
end
return string
@ -388,7 +390,7 @@ class String
# search for signature separator "--\n"
string.sub!(/^\s{0,2}--\s{0,2}$/) do |placeholder|
placeholder = "#{marker}#{placeholder}"
"#{marker}#{placeholder}"
end
map = {}
@ -444,14 +446,12 @@ class String
#map['word-en-de'] = "[^#{marker}].{1,250}\s(wrote|schrieb):"
map.each_value do |regexp|
string.sub!(/#{regexp}/) do |placeholder|
placeholder = "#{marker}#{placeholder}"
end
"#{marker}#{placeholder}"
rescue
# regexp was not possible because of some string encoding issue, use next
Rails.logger.debug { "Invalid string/charset combination with regexp #{regexp} in string" }
end
end
string

View file

@ -155,7 +155,7 @@ class ExternalCredential::Twitter
# verify if webhook is already registered
begin
webhooks = client.webhooks_by_env_name(env_name)
rescue => e
rescue
begin
webhooks = client.webhooks
raise "Unable to get list of webooks. You use the wrong 'Dev environment label', only #{webhooks.inspect} available."

View file

@ -143,7 +143,7 @@ or if you only want to create 100 tickets
if !overviews.zero?
(1..overviews).each do
ActiveRecord::Base.transaction do
overview = Overview.create!(
Overview.create!(
name: "Filloverview::#{rand(999_999)}",
role_ids: [Role.find_by(name: 'Agent').id],
condition: {
@ -190,7 +190,7 @@ or if you only want to create 100 tickets
)
# create article
article = Ticket::Article.create!(
Ticket::Article.create!(
ticket_id: ticket.id,
from: customer.email,
to: 'some_recipient@example.com',

View file

@ -193,7 +193,6 @@ satinize html string based on whiltelist
end
end
new_string = ''
done = true
while done
new_string = Loofah.fragment(string).scrub!(scrubber_wipe).to_s
@ -205,7 +204,7 @@ satinize html string based on whiltelist
Loofah.fragment(string).scrub!(scrubber_link).to_s
end
rescue Timeout::Error => e
rescue Timeout::Error
UNPROCESSABLE_HTML_MSG
end
@ -237,7 +236,7 @@ cleanup html string:
string = cleanup_structure(string)
string
end
rescue Timeout::Error => e
rescue Timeout::Error
UNPROCESSABLE_HTML_MSG
end
@ -302,7 +301,6 @@ cleanup html string:
end
end
new_string = ''
done = true
while done
new_string = Loofah.fragment(string).scrub!(scrubber_structure).to_s

View file

@ -15,7 +15,7 @@ module Import
properties = @resource.get_all_properties!
result = normalize(properties)
flattened = flatten(result)
booleanized = booleanize_values(flattened)
booleanize_values(flattened)
end
end

View file

@ -5,7 +5,7 @@ module Import
def initialize(article)
import(article)
rescue Exceptions::UnprocessableEntity => e
rescue Exceptions::UnprocessableEntity
log "ERROR: Can't extract customer from Article #{article[:id]}"
end

View file

@ -18,7 +18,7 @@ module Import
def add(object, name, attribute)
ObjectManager::Attribute.add( attribute_config(object, name, attribute) )
ObjectManager::Attribute.migration_execute(false)
rescue => e
rescue
# rubocop:disable Style/SpecialGlobalVars
raise $!, "Problem with ObjectManager Attribute '#{name}': #{$!}", $!.backtrace
# rubocop:enable Style/SpecialGlobalVars

View file

@ -22,11 +22,6 @@ returns
def self.aggs(params_origin)
params = params_origin.dup
interval = params[:interval]
if params[:interval] == 'week'
interval = 'day'
end
result = []
if params[:interval] == 'month'
stop_interval = 12

View file

@ -263,7 +263,6 @@ class Report::Base
query, bind_params, tables = Ticket.selector2sql(data[:condition])
ticket_list = Ticket.where('tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end])
.where(query, *bind_params).joins(tables)
tickets = 0
time_min = 0
ticket_ids = []
ticket_list.each do |ticket|
@ -301,7 +300,6 @@ class Report::Base
query, bind_params, tables = Ticket.selector2sql(data[:condition])
ticket_list = Ticket.where('tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end])
.where(query, *bind_params).joins(tables)
tickets = 0
time_max = 0
ticket_ids = []
ticket_list.each do |ticket|
@ -334,7 +332,6 @@ class Report::Base
def self.ticket_condition(ticket_id, condition)
ticket = Ticket.lookup( id: ticket_id )
match = true
condition.each do |key, value|
if ticket[key.to_sym] != value
return false

View file

@ -17,10 +17,6 @@ returns
def self.aggs(params_origin)
params = params_origin.dup
interval = params[:interval]
if params[:interval] == 'week'
interval = 'day'
end
result = []
if params[:interval] == 'month'

View file

@ -26,11 +26,6 @@ returns
return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
end
interval = params[:interval]
if params[:interval] == 'week'
interval = 'day'
end
result = []
if params[:interval] == 'month'
stop_interval = 12
@ -113,7 +108,6 @@ returns
}
end
local_params = group_attributes(selector, params)
local_selector = params[:selector].clone
without_merged_tickets = {
'ticket_state.name' => {
'operator' => 'is not',

View file

@ -20,11 +20,6 @@ returns
params = params_origin.dup
ticket_state_ids = ticket_ids
interval = params[:interval]
if params[:interval] == 'week'
interval = 'day'
end
result = []
if params[:interval] == 'month'
stop_interval = 12

View file

@ -171,7 +171,7 @@ class SearchKnowledgeBaseBackend
}
end
if (scope = @params.fetch(:scope, nil))
if @params.fetch(:scope, nil)
scope = { terms: { scope_id: @cached_scope_ids } }
output[:query_extension][:bool][:must].push scope

View file

@ -37,7 +37,7 @@ class Sequencer
def mandatory_missing?
values = attribute_value.fetch_values(*mandatory)
values.none?(&:present?)
rescue KeyError => e
rescue KeyError
false
end
end

View file

@ -35,7 +35,7 @@ class Sequencer
# per request
def update_ticket_count
update_import_job
previous_page = next_page
next_page
end
attr_accessor :previous_page

View file

@ -23,7 +23,7 @@ class Service::GeoLocation::Gmaps
lat = result['results'].first['geometry']['location']['lat']
lng = result['results'].first['geometry']['location']['lng']
latlng = [lat, lng]
[lat, lng]
end
def self.reverse_geocode(lat, lng)

View file

@ -440,7 +440,6 @@ returns
files.push entry
end
files.sort.each do |entry|
filename = "#{path}/#{entry}"
next if entry !~ /^send/
message = Sessions.queue_file_read(path, entry)

View file

@ -72,7 +72,6 @@ class Sessions::Backend::TicketOverviewList < Sessions::Backend::Base
# push overview index
indexes = []
index_and_lists.each do |index|
assets = {}
overview = Overview.lookup(id: index[:overview][:id])
next if !overview

View file

@ -20,7 +20,6 @@ class Stats::TicketEscalation
).count
average = '-'
state = 'supergood'
state = if own_escalated.zero?
'supergood'
elsif own_escalated <= 1

View file

@ -23,7 +23,6 @@ class Stats::TicketResponseTime
def self.generate(user)
items = StatsStore.where('created_at > ? AND created_at < ?', Time.zone.now - 7.days, Time.zone.now).where(key: 'ticket:response_time')
count_total = items.count
total = 0
count_own = 0
own = 0

View file

@ -25,7 +25,6 @@ class Stats::TicketWaitingTime
average_per_agent = (average_per_agent / 60).round
end
state = 'supergood'
percent = 0
state = if handling_time <= 60
percent = handling_time.to_f / 60

View file

@ -24,7 +24,7 @@ namespace :zammad do
env
]
stdout, stderr, status = Open3.capture3(*command)
_stdout, stderr, status = Open3.capture3(*command)
next if status.success?

View file

@ -16,7 +16,7 @@ namespace :zammad do
'start',
]
stdout, stderr, status = Open3.capture3(*command)
_stdout, stderr, status = Open3.capture3(*command)
next if status.success?

View file

@ -16,7 +16,7 @@ namespace :zammad do
'stop',
]
stdout, stderr, status = Open3.capture3(*command)
_stdout, stderr, status = Open3.capture3(*command)
next if status.success?

View file

@ -20,7 +20,7 @@ namespace :zammad do
port
]
stdout, stderr, status = Open3.capture3(*command)
_stdout, stderr, status = Open3.capture3(*command)
next if status.success?

View file

@ -16,7 +16,7 @@ namespace :zammad do
'stop',
]
stdout, stderr, status = Open3.capture3(*command)
_stdout, stderr, status = Open3.capture3(*command)
next if status.success?

View file

@ -345,10 +345,6 @@ class TwitterSync
# import tweet
to = nil
from = nil
article_type = nil
in_reply_to = nil
twitter_preferences = {}
raise "Unknown tweet type '#{tweet.class}'" if tweet.class != Twitter::Tweet
article_type = 'twitter status'
@ -504,7 +500,6 @@ create a tweet ot direct message from an article
def get_state(channel, tweet, ticket = nil)
user_id = nil
user_id = if tweet.is_a?(Hash)
if tweet['user'] && tweet['user']['id']
tweet['user']['id']

View file

@ -64,7 +64,6 @@ before_fork
i: "#{dir}/tmp/pids/websocket.pid"
}
tls_options = {}
OptionParser.new do |opts|
opts.banner = 'Usage: websocket-server.rb start|stop [options]'

View file

@ -12,7 +12,7 @@ RSpec.describe Issue1977RemoveInvalidUserForeignKeys, type: :db_migration do
without_foreign_key(:online_notifications, column: :user_id)
create(:online_notification, user_id: 1337)
valid = create(:online_notification, user_id: existing_user_id)
create(:online_notification, user_id: existing_user_id)
expect do
migrate
@ -24,7 +24,7 @@ RSpec.describe Issue1977RemoveInvalidUserForeignKeys, type: :db_migration do
without_foreign_key(:recent_views, column: :created_by_id)
create(:recent_view, created_by_id: 1337)
valid = create(:recent_view, created_by_id: existing_user_id)
create(:recent_view, created_by_id: existing_user_id)
expect do
migrate
@ -35,8 +35,8 @@ RSpec.describe Issue1977RemoveInvalidUserForeignKeys, type: :db_migration do
without_foreign_key(:online_notifications, column: :user_id)
create(:avatar, object_lookup_id: ObjectLookup.by_name('User'), o_id: 1337)
valid_ticket = create(:avatar, object_lookup_id: ObjectLookup.by_name('Ticket'), o_id: 1337)
valid_user = create(:avatar, object_lookup_id: ObjectLookup.by_name('User'), o_id: existing_user_id)
create(:avatar, object_lookup_id: ObjectLookup.by_name('Ticket'), o_id: 1337)
create(:avatar, object_lookup_id: ObjectLookup.by_name('User'), o_id: existing_user_id)
expect do
migrate

View file

@ -4,13 +4,15 @@ RSpec.describe TicketUserTicketCounterJob, type: :job do
let!(:customer) { create(:user) }
let!(:tickets) do
ticket_states = {
let!(:ticket_states) do
{
open: Ticket::State.by_category(:open).first,
closed: Ticket::State.by_category(:closed).first,
}
end
tickets = {
let!(:tickets) do
{
open: [
create(:ticket, state_id: ticket_states[:open].id, customer_id: customer.id),
create(:ticket, state_id: ticket_states[:open].id, customer_id: customer.id),

View file

@ -67,6 +67,6 @@ RSpec.describe Import::Zendesk::ObjectAttribute::Dropdown do
expect(ObjectManager::Attribute).to receive(:add).with(expected_structure)
expect(ObjectManager::Attribute).to receive(:migration_execute)
created_instance = described_class.new('Ticket', 'example_field', attribute)
described_class.new('Ticket', 'example_field', attribute)
end
end

View file

@ -67,6 +67,6 @@ RSpec.describe Import::Zendesk::ObjectAttribute::Tagger do
expect(ObjectManager::Attribute).to receive(:add).with(expected_structure)
expect(ObjectManager::Attribute).to receive(:migration_execute)
created_instance = described_class.new('Ticket', 'example_field', attribute)
described_class.new('Ticket', 'example_field', attribute)
end
end

View file

@ -96,7 +96,7 @@ RSpec.describe Ldap::User do
connection = double()
expect(mocked_ldap).to receive(:connection).and_return(connection)
ldap_entry = build(:ldap_entry)
build(:ldap_entry)
expect(mocked_ldap).to receive(:base_dn)
expect(connection).to receive(:bind_as).and_return(true)
@ -108,7 +108,7 @@ RSpec.describe Ldap::User do
connection = double()
expect(mocked_ldap).to receive(:connection).and_return(connection)
ldap_entry = build(:ldap_entry)
build(:ldap_entry)
expect(mocked_ldap).to receive(:base_dn)
expect(connection).to receive(:bind_as).and_return(false)

View file

@ -32,7 +32,7 @@ RSpec.describe NotificationFactory::Renderer do
end
it 'correctly renders simple select attributes' do
attribute = create :object_manager_attribute_select, name: 'select'
create :object_manager_attribute_select, name: 'select'
ObjectManager::Attribute.migration_execute
ticket = create :ticket, customer: @user, select: 'key_1'
@ -52,7 +52,7 @@ RSpec.describe NotificationFactory::Renderer do
end
it 'correctly renders select attributes on chained user object' do
attribute = create :object_manager_attribute_select,
create :object_manager_attribute_select,
object_lookup_id: ObjectLookup.by_name('User'),
name: 'select'
ObjectManager::Attribute.migration_execute
@ -77,7 +77,7 @@ RSpec.describe NotificationFactory::Renderer do
end
it 'correctly renders select attributes on chained group object' do
attribute = create :object_manager_attribute_select,
create :object_manager_attribute_select,
object_lookup_id: ObjectLookup.by_name('Group'),
name: 'select'
ObjectManager::Attribute.migration_execute
@ -102,7 +102,7 @@ RSpec.describe NotificationFactory::Renderer do
end
it 'correctly renders select attributes on chained organization object' do
attribute = create :object_manager_attribute_select,
create :object_manager_attribute_select,
object_lookup_id: ObjectLookup.by_name('Organization'),
name: 'select'
ObjectManager::Attribute.migration_execute
@ -126,7 +126,7 @@ RSpec.describe NotificationFactory::Renderer do
end
it 'correctly renders tree select attributes' do
attribute = create :object_manager_attribute_tree_select, name: 'tree_select'
create :object_manager_attribute_tree_select, name: 'tree_select'
ObjectManager::Attribute.migration_execute
ticket = create :ticket, customer: @user, tree_select: 'Incident::Hardware::Laptop'

View file

@ -8,8 +8,6 @@ RSpec.describe Sequencer::Unit::Import::Common::Model::ResetPrimaryKeySequence,
expect(DbHelper).to receive(:import_post).with(model_class.table_name)
provided = process(
model_class: model_class,
)
process(model_class: model_class)
end
end

View file

@ -9,8 +9,8 @@ RSpec.describe Trigger do
another_agent = create(:admin_user, mobile: '+37061010000')
Group.lookup(id: 1).users << another_agent
channel = create(:channel, area: 'Sms::Notification')
trigger = create(:trigger,
create(:channel, area: 'Sms::Notification')
create(:trigger,
disable_notification: false,
perform: {
'notification.sms': {

View file

@ -257,7 +257,6 @@ RSpec.describe 'Monitoring', type: :request do
expect(json_response).to be_a_kind_of(Hash)
expect(json_response['token']).to be_truthy
token = json_response['token']
expect(json_response['error']).to be_falsey
end

View file

@ -11,7 +11,6 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does add new ticket text object' do
authenticated_as(admin_user)
post '/api/v1/object_manager_attributes', params: {}, as: :json
token = response.headers['CSRF-TOKEN']
# token based on headers
params = {
@ -59,7 +58,6 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does add new ticket text object - no default' do
authenticated_as(admin_user)
post '/api/v1/object_manager_attributes', params: {}, as: :json
token = response.headers['CSRF-TOKEN']
# token based on headers
params = {
@ -113,7 +111,6 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
authenticated_as(admin_user)
post "/api/v1/object_manager_attributes/#{object.id}", params: {}, as: :json
token = response.headers['CSRF-TOKEN']
# parameters for updating
params = {
@ -162,7 +159,6 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does add new ticket boolean object' do
authenticated_as(admin_user)
post '/api/v1/object_manager_attributes', params: {}, as: :json
token = response.headers['CSRF-TOKEN']
# token based on headers
params = {
@ -211,7 +207,6 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does add new user select object' do
authenticated_as(admin_user)
post '/api/v1/object_manager_attributes', params: {}, as: :json
token = response.headers['CSRF-TOKEN']
# token based on headers
params = {
@ -277,7 +272,6 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
expect(migration).to eq(true)
post "/api/v1/object_manager_attributes/#{object.id}", params: {}, as: :json
token = response.headers['CSRF-TOKEN']
# parameters for updating
params = {
@ -441,7 +435,7 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does ticket attributes cannot be removed when it is referenced by an overview (03)', db_strategy: :reset do
# 1. create a new ticket attribute and execute migration
migration = ObjectManager::Attribute.migration_execute
ObjectManager::Attribute.migration_execute
params = {
'name': 'test_attribute_referenced_by_an_overview',
@ -536,7 +530,7 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does ticket attributes cannot be removed when it is referenced by a trigger (04)', db_strategy: :reset do
# 1. create a new ticket attribute and execute migration
migration = ObjectManager::Attribute.migration_execute
ObjectManager::Attribute.migration_execute
params = {
'name': 'test_attribute_referenced_by_a_trigger',
@ -622,7 +616,7 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does ticket attributes cannot be removed when it is referenced by a scheduler (05)', db_strategy: :reset do
# 1. create a new ticket attribute and execute migration
migration = ObjectManager::Attribute.migration_execute
ObjectManager::Attribute.migration_execute
params = {
'name': 'test_attribute_referenced_by_a_scheduler',
@ -755,7 +749,7 @@ RSpec.describe 'ObjectManager Attributes', type: :request do
it 'does ticket attributes can be removed when it is referenced by an overview but by user object (06)', db_strategy: :reset do
# 1. create a new ticket attribute and execute migration
migration = ObjectManager::Attribute.migration_execute
ObjectManager::Attribute.migration_execute
params = {
'name': 'test_attribute_referenced_by_an_overview',

View file

@ -11,7 +11,6 @@ RSpec.describe 'Twilio SMS', type: :request do
it 'does basic call' do
# configure twilio channel
bot_id = 123_456_789
group_id = Group.find_by(name: 'Users').id
UserInfo.current_user_id = 1
@ -179,11 +178,8 @@ RSpec.describe 'Twilio SMS', type: :request do
Observer::Transaction.commit
Scheduler.worker(true)
# configure twilio channel
bot_id = 123_456_789
UserInfo.current_user_id = 1
channel = create(
create(
:channel,
area: 'Sms::Account',
options: {

View file

@ -68,7 +68,7 @@ RSpec.describe 'Ticket Article Attachments', type: :request do
it 'does test attachments for split' do
email_file_path = Rails.root.join('test', 'data', 'mail', 'mail024.box')
email_raw_string = File.read(email_file_path)
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
ticket_p, article_p, _user_p = Channel::EmailParser.new.process({}, email_raw_string)
authenticated_as(agent_user)
get '/api/v1/ticket_split', params: { form_id: '1234-2', ticket_id: ticket_p.id, article_id: article_p.id }, as: :json
@ -83,7 +83,7 @@ RSpec.describe 'Ticket Article Attachments', type: :request do
it 'does test attachments for forward' do
email_file_path = Rails.root.join('test', 'data', 'mail', 'mail008.box')
email_raw_string = File.read(email_file_path)
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
_ticket_p, article_p, _user_p = Channel::EmailParser.new.process({}, email_raw_string)
authenticated_as(agent_user)
post "/api/v1/ticket_attachment_upload_clone_by_article/#{article_p.id}", params: {}, as: :json
@ -98,7 +98,7 @@ RSpec.describe 'Ticket Article Attachments', type: :request do
email_file_path = Rails.root.join('test', 'data', 'mail', 'mail024.box')
email_raw_string = File.read(email_file_path)
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
_ticket_p, article_p, _user_p = Channel::EmailParser.new.process({}, email_raw_string)
post "/api/v1/ticket_attachment_upload_clone_by_article/#{article_p.id}", params: { form_id: '1234-2' }, as: :json
expect(response).to have_http_status(:ok)

View file

@ -110,7 +110,7 @@ Subject: some value 123
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email)
ticket_p, _article_p, user_p, _mail = Channel::EmailParser.new.process({}, email)
ticket_p.reload
expect(ticket_p.escalation_at).to be_truthy
expect(ticket_p.first_response_escalation_at.to_i).to be_within(90.seconds).of((ticket_p.created_at + 1.hour).to_i)

View file

@ -1951,7 +1951,6 @@ RSpec.describe 'Ticket', type: :request do
it 'does ticket search sorted (08.01)' do
title = "ticket pagination #{rand(999_999_999)}"
tickets = []
ticket1 = create(
:ticket,

View file

@ -24,7 +24,7 @@ RSpec.describe 'Time Accounting API endpoints', type: :request do
context 'when requesting a log report download' do
it 'responds with an Excel spreadsheet' do
group = create(:group)
create(:group)
ticket = create(:ticket, state: Ticket::State.lookup(name: 'open'), customer: customer )
article = create(:ticket_article, ticket: ticket, type: Ticket::Article::Type.lookup(name: 'note') )
@ -46,7 +46,7 @@ RSpec.describe 'Time Accounting API endpoints', type: :request do
it 'responds with an Excel spreadsheet' do
ObjectManager::Attribute.add attributes_for :object_manager_attribute_select
group = create(:group)
create(:group)
ticket = create(:ticket, state: Ticket::State.lookup(name: 'open'), customer: customer )
article = create(:ticket_article, ticket: ticket, type: Ticket::Article::Type.lookup(name: 'note') )

View file

@ -14,7 +14,7 @@ class AgentTicketActionLevel0Test < TestCase
tasks_close_all()
# create new ticket
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: '-NONE-',
@ -230,7 +230,7 @@ class AgentTicketActionLevel0Test < TestCase
sleep 12
# create new ticket
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -80,7 +80,7 @@ class AdminObjectManagerTest < TestCase
)
# create new ticket
ticket = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -283,7 +283,7 @@ class AdminObjectManagerTest < TestCase
)
# create new ticket
ticket = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -696,7 +696,7 @@ class AdminObjectManagerTest < TestCase
)
object_manager_attribute_migrate
ticket = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -41,7 +41,7 @@ class AdminOverviewTest < TestCase
name = "overview_#{rand(99_999_999)}"
ticket_titles = (1..3).map { |i| "Priority #{i} ticket" }
@browser = instance = browser_instance
@browser = browser_instance
login(
username: 'master@example.com',
password: 'test',

View file

@ -2,8 +2,6 @@ require 'browser_test_helper'
class AdminRoleTest < TestCase
def test_role_device
name = "some role #{rand(99_999_999)}"
@browser = browser_instance
login(
username: 'master@example.com',

View file

@ -67,7 +67,7 @@ class AgentNavigationAndTitleTest < TestCase
exists_not(css: '#navigation .js-menu .is-active')
# ticket zoom screen
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -315,7 +315,7 @@ class AgentTicketAttachmentTest < TestCase
)
tasks_close_all()
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'Nico',
group: 'Users',

View file

@ -13,7 +13,7 @@ class AgentTicketEmailReplyKeepBodyTest < TestCase
tasks_close_all()
# create new ticket
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -98,7 +98,7 @@ class AgentTicketEmailReplyKeepBodyTest < TestCase
end
def test_full_quote
@browser = instance = browser_instance
@browser = browser_instance
login(
username: 'master@example.com',
password: 'test',
@ -174,7 +174,7 @@ class AgentTicketEmailReplyKeepBodyTest < TestCase
# Regression test for issue #2344 - Missing translation for Full-Quote-Text "on xy wrote"
def test_full_quote_german_locale
@browser = instance = browser_instance
@browser = browser_instance
login(
username: 'master@example.com',
password: 'test',

View file

@ -101,7 +101,7 @@ class AgentTicketMacroTest < TestCase
ux_flow_next_up: ux_flow_next_up,
)
ticket = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -13,7 +13,7 @@ class AgentTicketOnlineNotificationTest < TestCase
tasks_close_all()
# create new ticket
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -66,7 +66,7 @@ class AgentTicketOnlineNotificationTest < TestCase
no_quote: true,
)
ticket2 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -92,7 +92,7 @@ class AgentTicketOnlineNotificationTest < TestCase
css: '.js-mark.hide',
)
ticket3 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -138,7 +138,7 @@ class AgentTicketOnlineNotificationTest < TestCase
items = browser2.find_elements(css: '.js-notificationsContainer .js-item.is-inactive')
assert_equal(1, items.count)
ticket4 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -179,7 +179,7 @@ class AgentTicketOnlineNotificationTest < TestCase
no_quote: true,
)
ticket5 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -260,7 +260,7 @@ class AgentTicketOnlineNotificationTest < TestCase
)
online_notitifcation_close_all(browser: browser2)
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -268,7 +268,7 @@ class AgentTicketOnlineNotificationTest < TestCase
body: 'online notification render #1',
},
)
ticket2 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -301,7 +301,7 @@ class AgentTicketOnlineNotificationTest < TestCase
css: '.js-notificationsContainer .js-items .js-item:nth-child(2) .activity-text',
value: 'render test 1',
)
ticket3 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -21,14 +21,14 @@ class AgentTicketOverviewGroupByOrganizationTest < TestCase
tasks_close_all()
# 1. Create a new test organization with special characters in its name
organization = organization_create(
organization_create(
data: {
name: 'äöüß & Test Organization',
}
)
# 2. Create a new user that belongs to the test organization
user = user_create(
user_create(
data: {
login: 'test user',
firstname: 'Max',
@ -40,7 +40,7 @@ class AgentTicketOverviewGroupByOrganizationTest < TestCase
)
# 3. Create a new ticket for the test user
ticket = ticket_create(
ticket_create(
data: {
customer: user_email,
title: 'test ticket',
@ -50,7 +50,7 @@ class AgentTicketOverviewGroupByOrganizationTest < TestCase
)
# 4. Create an overview grouping by organization
overview = overview_create(
overview_create(
data: {
name: overview_name,
roles: %w[Agent Admin Customer],

View file

@ -21,7 +21,7 @@ class AgentTicketOverviewTabTest < TestCase
body: "overview tab test #1 - #{title}",
}
)
ticket2 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -29,7 +29,7 @@ class AgentTicketOverviewTabTest < TestCase
body: "overview tab test #2 - #{title}",
}
)
ticket3 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -11,7 +11,7 @@ class AgentTicketTagTest < TestCase
tasks_close_all()
# set tag (by tab)
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -51,7 +51,7 @@ class AgentTicketTagTest < TestCase
)
# set tag (by blur)
ticket2 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -398,7 +398,7 @@ class AgentTicketTagTest < TestCase
click(css: '.content.active .js-create .js-submit')
# set tag (by tab)
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -456,7 +456,7 @@ class AgentTicketTagTest < TestCase
)
# new ticket with tags in zoom
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -12,7 +12,7 @@ class AgentTicketTaskChangedTest < TestCase
)
tasks_close_all()
ticket = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -22,7 +22,7 @@ class AgentTicketTimeAccountingTest < TestCase
type: 'on',
)
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -55,7 +55,7 @@ class AgentTicketTimeAccountingTest < TestCase
value: '4',
)
ticket2 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',
@ -161,7 +161,7 @@ class AgentTicketTimeAccountingTest < TestCase
type: 'on',
)
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -29,7 +29,7 @@ class AgentTicketUpdate1Test < TestCase
sleep 1
# confirm on zoom
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -12,7 +12,7 @@ class AgentTicketUpdate5Test < TestCase
# create ticket
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'Nico',
group: 'Users',

View file

@ -21,7 +21,7 @@ class AgentTicketZoomHideTest < TestCase
)
# create two tickets
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'Nico',
group: 'Users',
@ -30,7 +30,7 @@ class AgentTicketZoomHideTest < TestCase
}
)
ticket2 = ticket_create(
ticket_create(
data: {
customer: 'Nico',
group: 'Users',

View file

@ -213,7 +213,7 @@ class CustomerTicketCreateTest < TestCase
)
tasks_close_all()
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

View file

@ -11,7 +11,7 @@ class UserSwitchCache < TestCase
url: browser_url,
)
tasks_close_all()
ticket1 = ticket_create(
ticket_create(
data: {
customer: 'nico',
group: 'Users',

Some files were not shown because too many files have changed in this diff Show more